Ticket #4476: 4476_mixed.diff
File 4476_mixed.diff, 12.5 KB (added by , 16 years ago) |
---|
-
django/test/client.py
diff --git a/django/test/client.py b/django/test/client.py index 96d0c89..d7230cd 100644
a b 1 1 import urllib 2 from urlparse import urlparse, urlunparse 2 from urlparse import urlparse, urlunparse, urlsplit 3 3 import sys 4 4 import os 5 5 try: … … from django.contrib.auth import authenticate, login 12 12 from django.core.handlers.base import BaseHandler 13 13 from django.core.handlers.wsgi import WSGIRequest 14 14 from django.core.signals import got_request_exception 15 from django.http import SimpleCookie, HttpRequest 15 from django.http import SimpleCookie, HttpRequest, QueryDict 16 16 from django.template import TemplateDoesNotExist 17 17 from django.test import signals 18 18 from django.utils.functional import curry … … class Client(object): 261 261 262 262 return response 263 263 264 def get(self, path, data={}, **extra):264 def get(self, path, data={}, follow=False, **extra): 265 265 """ 266 266 Requests a response from the server using GET. 267 267 """ … … class Client(object): 275 275 } 276 276 r.update(extra) 277 277 278 return self.request(**r) 278 response = self.request(**r) 279 if follow: 280 response = self._handle_redirects(response) 281 return response 279 282 280 def post(self, path, data={}, content_type=MULTIPART_CONTENT, **extra): 283 def post(self, path, data={}, content_type=MULTIPART_CONTENT, 284 follow=False, **extra): 281 285 """ 282 286 Requests a response from the server using POST. 283 287 """ … … class Client(object): 297 301 } 298 302 r.update(extra) 299 303 300 return self.request(**r) 304 response = self.request(**r) 305 if follow: 306 response = self._handle_redirects(response) 307 return response 301 308 302 309 def head(self, path, data={}, **extra): 303 310 """ … … class Client(object): 352 359 353 360 return self.request(**r) 354 361 355 def delete(self, path, data={}, **extra):362 def delete(self, path, data={}, follow=True, **extra): 356 363 """ 357 364 Send a DELETE request to the server. 358 365 """ … … class Client(object): 365 372 } 366 373 r.update(extra) 367 374 368 return self.request(**r) 375 response = self.request(**r) 376 if follow: 377 response = self._handle_redirects(response) 378 return response 369 379 370 380 def login(self, **credentials): 371 381 """ … … class Client(object): 416 426 session = __import__(settings.SESSION_ENGINE, {}, {}, ['']).SessionStore() 417 427 session.delete(session_key=self.cookies[settings.SESSION_COOKIE_NAME].value) 418 428 self.cookies = SimpleCookie() 429 430 def _handle_redirects(self, response): 431 "Follows any redirects by requesting responses from the server using GET." 432 433 response.redirect_chain = [] 434 while response.status_code in (301, 302, 303, 307): 435 url = response['Location'] 436 scheme, netloc, path, query, fragment = urlsplit(url) 437 438 redirect_chain = response.redirect_chain 439 redirect_chain.append((url, response.status_code)) 440 441 # The test client doesn't handle external links, 442 # but since the situation is simulated in test_client, 443 # we fake things here by ignoring the netloc portion of the 444 # redirected URL. 445 response = self.get(path, QueryDict(query), follow=False) 446 response.redirect_chain = redirect_chain 447 448 # Prevent loops 449 if response.redirect_chain[-1] in response.redirect_chain[0:-1]: 450 break 451 return response 452 -
django/test/testcases.py
diff --git a/django/test/testcases.py b/django/test/testcases.py index eed252b..6c4f5bb 100644
a b class TransactionTestCase(unittest.TestCase): 269 269 clear_url_caches() 270 270 271 271 def assertRedirects(self, response, expected_url, status_code=302, 272 target_status_code=200, host=None ):272 target_status_code=200, host=None, redirect_level=-1): 273 273 """Asserts that a response redirected to a specific URL, and that the 274 redirect URL c anbe loaded.274 redirect URL could be loaded. 275 275 276 276 Note that assertRedirects won't work for external links since it uses 277 277 TestClient to do a request. 278 279 Note that assertRedirects only works properly if follow was set to True 280 in the request. 278 281 """ 279 self.assertEqual(response.status_code, status_code, 282 283 redirect_url = response.get('Location', '') 284 redirect_status_code = response.status_code 285 if not hasattr(response, 'redirect_chain'): 286 # follow wasn't set to True. Be backwards compatible... 287 import warnings 288 warnings.warn( 289 "For using TestCase.assertRedirects() you have to call get() and/or post() with follow=True", 290 PendingDeprecationWarning, 291 ) 292 scheme, netloc, path, query, fragment = urlsplit(redirect_url) 293 final_response = response.client.get(path, QueryDict(query)) 294 response = final_response 295 else: 296 chain = response.redirect_chain 297 redirect_url = chain[redirect_level][0] 298 redirect_status_code = chain[redirect_level][1] 299 scheme, netloc, path, query, fragment = urlsplit(redirect_url) 300 301 self.assertEqual(redirect_status_code, status_code, 280 302 ("Response didn't redirect as expected: Response code was %d" 281 " (expected %d)" % (response.status_code, status_code))) 282 url = response['Location'] 283 scheme, netloc, path, query, fragment = urlsplit(url) 303 " (expected %d)" % (redirect_status_code, status_code))) 304 284 305 e_scheme, e_netloc, e_path, e_query, e_fragment = urlsplit(expected_url) 285 306 if not (e_scheme or e_netloc): 286 307 expected_url = urlunsplit(('http', host or 'testserver', e_path, 287 308 e_query, e_fragment)) 288 self.assertEqual( url, expected_url,289 "Response redirected to '%s', expected '%s'" % ( url, expected_url))309 self.assertEqual(redirect_url, expected_url, 310 "Response redirected to '%s', expected '%s'" % (redirect_url, expected_url)) 290 311 291 # Get the redirection page, using the same client that was used 292 # to obtain the original response. 293 redirect_response = response.client.get(path, QueryDict(query)) 294 self.assertEqual(redirect_response.status_code, target_status_code, 312 self.assertEqual(response.status_code, target_status_code, 295 313 ("Couldn't retrieve redirection page '%s': response code was %d" 296 314 " (expected %d)") % 297 (path, re direct_response.status_code, target_status_code))315 (path, response.status_code, target_status_code)) 298 316 299 317 def assertContains(self, response, text, count=None, status_code=200): 300 318 """ … … class TestCase(TransactionTestCase): 430 448 restore_transaction_methods() 431 449 transaction.rollback() 432 450 transaction.leave_transaction_management() 433 connection.close() 434 No newline at end of file 451 connection.close() -
docs/topics/testing.txt
diff --git a/docs/topics/testing.txt b/docs/topics/testing.txt index bd68f6b..e0b7878 100644
a b arguments at time of construction: 478 478 Once you have a ``Client`` instance, you can call any of the following 479 479 methods: 480 480 481 .. method:: Client.get(path, data={}) 481 .. method:: Client.get(path, data={}, follow=False) 482 483 .. versionchanged:: 1.1 484 The ``follow`` argument is new in this version. 482 485 483 486 Makes a GET request on the provided ``path`` and returns a ``Response`` 484 487 object, which is documented below. … … arguments at time of construction: 505 508 If you provide URL both an encoded GET data and a data argument, 506 509 the data argument will take precedence. 507 510 508 .. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT) 511 If you set ``follow`` to ``True`` the client will follow any redirects 512 and a ``redirect_chain``attribute will be set in the response object 513 containing tuples of the intermediate urls and status codes. 514 515 If you had an url ``/redirect_me/`` that redirected to ``/final/``, this is 516 what you'd see:: 517 518 >>> response = c.get('/redirect_me/') 519 >>> response.redirect_chain 520 [(u'/final/', 301)] 521 522 523 .. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT, follow=False) 524 525 .. versionchanged:: 1.1 526 The ``follow`` argument is new in this version. 509 527 510 528 Makes a POST request on the provided ``path`` and returns a 511 529 ``Response`` object, which is documented below. … … arguments at time of construction: 568 586 to retrieve the username and password, and could interrogate request.GET 569 587 to determine if the user was a visitor. 570 588 589 If you set ``follow`` to ``True`` the client will follow any redirects 590 and a ``redirect_chain``attribute will be set in the response object 591 containing tuples of the intermediate urls and status codes. 592 571 593 .. method:: Client.head(path, data={}) 572 594 573 595 .. versionadded:: development … … applications: 1025 1047 Asserts that the template with the given name was *not* used in rendering 1026 1048 the response. 1027 1049 1028 .. method:: assertRedirects(response, expected_url, status_code=302, target_status_code=200 )1050 .. method:: assertRedirects(response, expected_url, status_code=302, target_status_code=200, redirect_level=-1) 1029 1051 1030 1052 Asserts that the response return a ``status_code`` redirect status, it 1031 redirected to ``expected_url`` (including any GET data), and the subsequent1053 redirected to ``expected_url`` (including any GET data), and the final 1032 1054 page was received with ``target_status_code``. 1033 1055 1056 If you are expecting multiple levels of redirects, you can specify to 1057 which ``redirect_level`` the ``expected_url`` and ``status_code`` are 1058 matched against. A value of -2 checks against the latest redirect in 1059 the chain. 1060 1034 1061 E-mail services 1035 1062 --------------- 1036 1063 -
tests/regressiontests/test_client_regress/models.py
diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py index 7015f71..af50b43 100644
a b class AssertRedirectsTests(TestCase): 148 148 except AssertionError, e: 149 149 self.assertEquals(str(e), "Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)") 150 150 151 def test_redirect_chain(self): 152 # First with GET 153 response = self.client.get('/test_client_regress/redirects/', {}, True) 154 self.assertRedirects(response, 155 '/test_client_regress/redirects/further/', 301, 404, redirect_level=0) 156 self.assertRedirects(response, 157 '/test_client_regress/redirects/further/more/', 301, 404, redirect_level=1) 158 self.assertRedirects(response, 159 '/test_client_regress/redirects/further/more/end/', 301, 404, redirect_level=2) 160 161 # Now with POST 162 response = self.client.post('/test_client_regress/redirects/', 163 {'nothing': 'to_send'}, follow=True) 164 self.assertRedirects(response, 165 '/test_client_regress/redirects/further/more/end/', 301, 404) 166 151 167 class AssertFormErrorTests(TestCase): 152 168 def test_unknown_form(self): 153 169 "An assertion is raised if the form name is unknown" -
tests/regressiontests/test_client_regress/urls.py
diff --git a/tests/regressiontests/test_client_regress/urls.py b/tests/regressiontests/test_client_regress/urls.py index e7db15a..4b38699 100644
a b 1 1 from django.conf.urls.defaults import * 2 from django.views.generic.simple import redirect_to 2 3 import views 3 4 4 5 urlpatterns = patterns('', … … urlpatterns = patterns('', 8 9 (r'^request_data/$', views.request_data), 9 10 url(r'^arg_view/(?P<name>.+)/$', views.view_with_argument, name='arg_view'), 10 11 (r'^login_protected_redirect_view/$', views.login_protected_redirect_view), 12 (r'^redirects/$', redirect_to, {'url': 'further/'}), 13 (r'^redirects/further/$', redirect_to, {'url': 'more/'}), 14 (r'^redirects/further/more/$', redirect_to, {'url': 'end/'}), 11 15 (r'^set_session/$', views.set_session_view), 12 16 (r'^check_session/$', views.check_session_view), 13 17 (r'^request_methods/$', views.request_methods_view),