Fixed #4988 -- In the test client, Added tracking of the client and request that caused a response so that the assertRedirects check can use the correct client when following a redirect. Well spotted, alex@gc-web.de.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6039 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2007-09-03 11:21:40 +00:00
parent afc6985267
commit 3bf4ef0c77
7 changed files with 57 additions and 14 deletions

View File

@ -182,6 +182,10 @@ class Client:
if self.exc_info: if self.exc_info:
raise self.exc_info[1], None, self.exc_info[2] raise self.exc_info[1], None, self.exc_info[2]
# Save the client and request that stimulated the response
response.client = self
response.request = request
# Add any rendered template detail to the response # Add any rendered template detail to the response
# If there was only one template rendered (the most likely case), # If there was only one template rendered (the most likely case),
# flatten the list to a single element # flatten the list to a single element

View File

@ -80,7 +80,9 @@ class TestCase(unittest.TestCase):
self.assertEqual(url, expected_url, self.assertEqual(url, expected_url,
"Response redirected to '%s', expected '%s'" % (url, expected_url)) "Response redirected to '%s', expected '%s'" % (url, expected_url))
redirect_response = self.client.get(path, QueryDict(query)) # Get the redirection page, using the same client that was used
# to obtain the original response.
redirect_response = response.client.get(path, QueryDict(query))
self.assertEqual(redirect_response.status_code, target_status_code, self.assertEqual(redirect_response.status_code, target_status_code,
"Couldn't retrieve redirection page '%s': response code was %d (expected %d)" % "Couldn't retrieve redirection page '%s': response code was %d (expected %d)" %
(path, redirect_response.status_code, target_status_code)) (path, redirect_response.status_code, target_status_code))

View File

@ -577,13 +577,25 @@ Specifically, a ``Response`` object has the following attributes:
=============== ========================================================== =============== ==========================================================
Attribute Description Attribute Description
=============== ========================================================== =============== ==========================================================
``status_code`` The HTTP status of the response, as an integer. See ``client`` The test client that was used to make the request that
RFC2616_ for a full list of HTTP status codes. resulted in the response.
``content`` The body of the response, as a string. This is the final ``content`` The body of the response, as a string. This is the final
page content as rendered by the view, or any error page content as rendered by the view, or any error
message (such as the URL for a 302 redirect). message (such as the URL for a 302 redirect).
``context`` The template ``Context`` instance that was used to render
the template that produced the response content.
If the rendered page used multiple templates, then
``context`` will be a list of ``Context``
objects, in the order in which they were rendered.
``request`` The request data that stimulated the response.
``status_code`` The HTTP status of the response, as an integer. See
RFC2616_ for a full list of HTTP status codes.
``template`` The ``Template`` instance that was used to render the ``template`` The ``Template`` instance that was used to render the
final content. Use ``template.name`` to get the final content. Use ``template.name`` to get the
template's file name, if the template was loaded from a template's file name, if the template was loaded from a
@ -594,13 +606,6 @@ Specifically, a ``Response`` object has the following attributes:
using `template inheritance`_ -- then ``template`` will using `template inheritance`_ -- then ``template`` will
be a list of ``Template`` instances, in the order in be a list of ``Template`` instances, in the order in
which they were rendered. which they were rendered.
``context`` The template ``Context`` instance that was used to render
the template that produced the response content.
As with ``template``, if the rendered page used multiple
templates, then ``context`` will be a list of ``Context``
objects, in the order in which they were rendered.
=============== ========================================================== =============== ==========================================================
.. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html .. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
@ -828,7 +833,7 @@ useful for testing Web applications:
``assertRedirects(response, expected_url, status_code=302, target_status_code=200)`` ``assertRedirects(response, expected_url, status_code=302, target_status_code=200)``
Asserts that the response return a ``status_code`` redirect status, Asserts that the response return a ``status_code`` redirect status,
it redirected to ``expected_url`` (including any GET data), and the subsequent it redirected to ``expected_url`` (including any GET data), and the subsequent
page was received with ``target_status_code``. page was received with ``target_status_code``.
``assertTemplateUsed(response, template_name)`` ``assertTemplateUsed(response, template_name)``

View File

@ -234,7 +234,8 @@ class ClientTest(TestCase):
self.assertRedirects(response, '/accounts/login/?next=/test_client/login_protected_view/') self.assertRedirects(response, '/accounts/login/?next=/test_client/login_protected_view/')
# Log in # Log in
self.client.login(username='testclient', password='password') login = self.client.login(username='testclient', password='password')
self.assertTrue(login, 'Could not log in')
# Request a page that requires a login # Request a page that requires a login
response = self.client.get('/test_client/login_protected_view/') response = self.client.get('/test_client/login_protected_view/')

View File

@ -212,7 +212,7 @@ class AssertFormErrorTests(TestCase):
except AssertionError, e: except AssertionError, e:
self.assertEqual(str(e), "The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])") self.assertEqual(str(e), "The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])")
class AssertFileUploadTests(TestCase): class FileUploadTests(TestCase):
def test_simple_upload(self): def test_simple_upload(self):
fd = open(os.path.join(os.path.dirname(__file__), "views.py")) fd = open(os.path.join(os.path.dirname(__file__), "views.py"))
post_data = { post_data = {
@ -221,3 +221,22 @@ class AssertFileUploadTests(TestCase):
} }
response = self.client.post('/test_client_regress/file_upload/', post_data) response = self.client.post('/test_client_regress/file_upload/', post_data)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
class LoginTests(TestCase):
fixtures = ['testdata']
def test_login_different_client(self):
"Check that using a different test client doesn't violate authentication"
# Create a second client, and log in.
c = Client()
login = c.login(username='testclient', password='password')
self.assertTrue(login, 'Could not log in')
# Get a redirection page with the second client.
response = c.get("/test_client_regress/login_protected_redirect_view/")
# At this points, the self.client isn't logged in.
# Check that assertRedirects uses the original client, not the
# default client.
self.assertRedirects(response, "/test_client_regress/get_view/")

View File

@ -4,4 +4,6 @@ import views
urlpatterns = patterns('', urlpatterns = patterns('',
(r'^no_template_view/$', views.no_template_view), (r'^no_template_view/$', views.no_template_view),
(r'^file_upload/$', views.file_upload_view), (r'^file_upload/$', views.file_upload_view),
(r'^get_view/$', views.get_view),
(r'^login_protected_redirect_view/$', views.login_protected_redirect_view)
) )

View File

@ -1,5 +1,6 @@
from django.contrib.auth.decorators import login_required
from django.core.mail import EmailMessage, SMTPConnection from django.core.mail import EmailMessage, SMTPConnection
from django.http import HttpResponse, HttpResponseServerError from django.http import HttpResponse, HttpResponseRedirect, HttpResponseServerError
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
def no_template_view(request): def no_template_view(request):
@ -18,3 +19,12 @@ def file_upload_view(request):
else: else:
return HttpResponseServerError() return HttpResponseServerError()
def get_view(request):
"A simple login protected view"
return HttpResponse("Hello world")
get_view = login_required(get_view)
def login_protected_redirect_view(request):
"A view that redirects all requests to the GET view"
return HttpResponseRedirect('/test_client_regress/get_view/')
login_protected_redirect_view = login_required(login_protected_redirect_view)