PageRenderTime 176ms CodeModel.GetById 111ms app.highlight 54ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/regressiontests/test_client_regress/models.py

https://code.google.com/p/mango-py/
Python | 916 lines | 791 code | 91 blank | 34 comment | 9 complexity | 9dc52a73f401da9b5cb04d62072ea62c MD5 | raw file
  1# -*- coding: utf-8 -*-
  2"""
  3Regression tests for the Test Client, especially the customized assertions.
  4"""
  5import os
  6
  7from django.conf import settings
  8from django.core.exceptions import SuspiciousOperation
  9from django.core.urlresolvers import reverse
 10from django.template import (TemplateDoesNotExist, TemplateSyntaxError,
 11    Context, Template, loader)
 12import django.template.context
 13from django.test import Client, TestCase
 14from django.test.client import encode_file
 15from django.test.utils import ContextList
 16
 17
 18class AssertContainsTests(TestCase):
 19    def setUp(self):
 20        self.old_templates = settings.TEMPLATE_DIRS
 21        settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates'),)
 22
 23    def tearDown(self):
 24        settings.TEMPLATE_DIRS = self.old_templates
 25
 26    def test_contains(self):
 27        "Responses can be inspected for content, including counting repeated substrings"
 28        response = self.client.get('/test_client_regress/no_template_view/')
 29
 30        self.assertNotContains(response, 'never')
 31        self.assertContains(response, 'never', 0)
 32        self.assertContains(response, 'once')
 33        self.assertContains(response, 'once', 1)
 34        self.assertContains(response, 'twice')
 35        self.assertContains(response, 'twice', 2)
 36
 37        try:
 38            self.assertContains(response, 'text', status_code=999)
 39        except AssertionError, e:
 40            self.assertIn("Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
 41        try:
 42            self.assertContains(response, 'text', status_code=999, msg_prefix='abc')
 43        except AssertionError, e:
 44            self.assertIn("abc: Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
 45
 46        try:
 47            self.assertNotContains(response, 'text', status_code=999)
 48        except AssertionError, e:
 49            self.assertIn("Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
 50        try:
 51            self.assertNotContains(response, 'text', status_code=999, msg_prefix='abc')
 52        except AssertionError, e:
 53            self.assertIn("abc: Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
 54
 55        try:
 56            self.assertNotContains(response, 'once')
 57        except AssertionError, e:
 58            self.assertIn("Response should not contain 'once'", str(e))
 59        try:
 60            self.assertNotContains(response, 'once', msg_prefix='abc')
 61        except AssertionError, e:
 62            self.assertIn("abc: Response should not contain 'once'", str(e))
 63
 64        try:
 65            self.assertContains(response, 'never', 1)
 66        except AssertionError, e:
 67            self.assertIn("Found 0 instances of 'never' in response (expected 1)", str(e))
 68        try:
 69            self.assertContains(response, 'never', 1, msg_prefix='abc')
 70        except AssertionError, e:
 71            self.assertIn("abc: Found 0 instances of 'never' in response (expected 1)", str(e))
 72
 73        try:
 74            self.assertContains(response, 'once', 0)
 75        except AssertionError, e:
 76            self.assertIn("Found 1 instances of 'once' in response (expected 0)", str(e))
 77        try:
 78            self.assertContains(response, 'once', 0, msg_prefix='abc')
 79        except AssertionError, e:
 80            self.assertIn("abc: Found 1 instances of 'once' in response (expected 0)", str(e))
 81
 82        try:
 83            self.assertContains(response, 'once', 2)
 84        except AssertionError, e:
 85            self.assertIn("Found 1 instances of 'once' in response (expected 2)", str(e))
 86        try:
 87            self.assertContains(response, 'once', 2, msg_prefix='abc')
 88        except AssertionError, e:
 89            self.assertIn("abc: Found 1 instances of 'once' in response (expected 2)", str(e))
 90
 91        try:
 92            self.assertContains(response, 'twice', 1)
 93        except AssertionError, e:
 94            self.assertIn("Found 2 instances of 'twice' in response (expected 1)", str(e))
 95        try:
 96            self.assertContains(response, 'twice', 1, msg_prefix='abc')
 97        except AssertionError, e:
 98            self.assertIn("abc: Found 2 instances of 'twice' in response (expected 1)", str(e))
 99
100        try:
101            self.assertContains(response, 'thrice')
102        except AssertionError, e:
103            self.assertIn("Couldn't find 'thrice' in response", str(e))
104        try:
105            self.assertContains(response, 'thrice', msg_prefix='abc')
106        except AssertionError, e:
107            self.assertIn("abc: Couldn't find 'thrice' in response", str(e))
108
109        try:
110            self.assertContains(response, 'thrice', 3)
111        except AssertionError, e:
112            self.assertIn("Found 0 instances of 'thrice' in response (expected 3)", str(e))
113        try:
114            self.assertContains(response, 'thrice', 3, msg_prefix='abc')
115        except AssertionError, e:
116            self.assertIn("abc: Found 0 instances of 'thrice' in response (expected 3)", str(e))
117
118    def test_unicode_contains(self):
119        "Unicode characters can be found in template context"
120        #Regression test for #10183
121        r = self.client.get('/test_client_regress/check_unicode/')
122        self.assertContains(r, u'???')
123        self.assertContains(r, '\xe5\xb3\xa0'.decode('utf-8'))
124
125    def test_unicode_not_contains(self):
126        "Unicode characters can be searched for, and not found in template context"
127        #Regression test for #10183
128        r = self.client.get('/test_client_regress/check_unicode/')
129        self.assertNotContains(r, u'???')
130        self.assertNotContains(r, '\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91'.decode('utf-8'))
131
132
133class AssertTemplateUsedTests(TestCase):
134    fixtures = ['testdata.json']
135
136    def test_no_context(self):
137        "Template usage assertions work then templates aren't in use"
138        response = self.client.get('/test_client_regress/no_template_view/')
139
140        # Check that the no template case doesn't mess with the template assertions
141        self.assertTemplateNotUsed(response, 'GET Template')
142
143        try:
144            self.assertTemplateUsed(response, 'GET Template')
145        except AssertionError, e:
146            self.assertIn("No templates used to render the response", str(e))
147
148        try:
149            self.assertTemplateUsed(response, 'GET Template', msg_prefix='abc')
150        except AssertionError, e:
151            self.assertIn("abc: No templates used to render the response", str(e))
152
153    def test_single_context(self):
154        "Template assertions work when there is a single context"
155        response = self.client.get('/test_client/post_view/', {})
156
157        try:
158            self.assertTemplateNotUsed(response, 'Empty GET Template')
159        except AssertionError, e:
160            self.assertIn("Template 'Empty GET Template' was used unexpectedly in rendering the response", str(e))
161
162        try:
163            self.assertTemplateNotUsed(response, 'Empty GET Template', msg_prefix='abc')
164        except AssertionError, e:
165            self.assertIn("abc: Template 'Empty GET Template' was used unexpectedly in rendering the response", str(e))
166
167        try:
168            self.assertTemplateUsed(response, 'Empty POST Template')
169        except AssertionError, e:
170            self.assertIn("Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template", str(e))
171
172        try:
173            self.assertTemplateUsed(response, 'Empty POST Template', msg_prefix='abc')
174        except AssertionError, e:
175            self.assertIn("abc: Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template", str(e))
176
177    def test_multiple_context(self):
178        "Template assertions work when there are multiple contexts"
179        post_data = {
180            'text': 'Hello World',
181            'email': 'foo@example.com',
182            'value': 37,
183            'single': 'b',
184            'multi': ('b','c','e')
185        }
186        response = self.client.post('/test_client/form_view_with_template/', post_data)
187        self.assertContains(response, 'POST data OK')
188        try:
189            self.assertTemplateNotUsed(response, "form_view.html")
190        except AssertionError, e:
191            self.assertIn("Template 'form_view.html' was used unexpectedly in rendering the response", str(e))
192
193        try:
194            self.assertTemplateNotUsed(response, 'base.html')
195        except AssertionError, e:
196            self.assertIn("Template 'base.html' was used unexpectedly in rendering the response", str(e))
197
198        try:
199            self.assertTemplateUsed(response, "Valid POST Template")
200        except AssertionError, e:
201            self.assertIn("Template 'Valid POST Template' was not a template used to render the response. Actual template(s) used: form_view.html, base.html", str(e))
202
203class AssertRedirectsTests(TestCase):
204    def test_redirect_page(self):
205        "An assertion is raised if the original page couldn't be retrieved as expected"
206        # This page will redirect with code 301, not 302
207        response = self.client.get('/test_client/permanent_redirect_view/')
208        try:
209            self.assertRedirects(response, '/test_client/get_view/')
210        except AssertionError, e:
211            self.assertIn("Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
212
213        try:
214            self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
215        except AssertionError, e:
216            self.assertIn("abc: Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
217
218    def test_lost_query(self):
219        "An assertion is raised if the redirect location doesn't preserve GET parameters"
220        response = self.client.get('/test_client/redirect_view/', {'var': 'value'})
221        try:
222            self.assertRedirects(response, '/test_client/get_view/')
223        except AssertionError, e:
224            self.assertIn("Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'", str(e))
225
226        try:
227            self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
228        except AssertionError, e:
229            self.assertIn("abc: Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'", str(e))
230
231    def test_incorrect_target(self):
232        "An assertion is raised if the response redirects to another target"
233        response = self.client.get('/test_client/permanent_redirect_view/')
234        try:
235            # Should redirect to get_view
236            self.assertRedirects(response, '/test_client/some_view/')
237        except AssertionError, e:
238            self.assertIn("Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
239
240    def test_target_page(self):
241        "An assertion is raised if the response redirect target cannot be retrieved as expected"
242        response = self.client.get('/test_client/double_redirect_view/')
243        try:
244            # The redirect target responds with a 301 code, not 200
245            self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/')
246        except AssertionError, e:
247            self.assertIn("Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)", str(e))
248
249        try:
250            # The redirect target responds with a 301 code, not 200
251            self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/', msg_prefix='abc')
252        except AssertionError, e:
253            self.assertIn("abc: Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)", str(e))
254
255    def test_redirect_chain(self):
256        "You can follow a redirect chain of multiple redirects"
257        response = self.client.get('/test_client_regress/redirects/further/more/', {}, follow=True)
258        self.assertRedirects(response, '/test_client_regress/no_template_view/',
259            status_code=301, target_status_code=200)
260
261        self.assertEqual(len(response.redirect_chain), 1)
262        self.assertEqual(response.redirect_chain[0], ('http://testserver/test_client_regress/no_template_view/', 301))
263
264    def test_multiple_redirect_chain(self):
265        "You can follow a redirect chain of multiple redirects"
266        response = self.client.get('/test_client_regress/redirects/', {}, follow=True)
267        self.assertRedirects(response, '/test_client_regress/no_template_view/',
268            status_code=301, target_status_code=200)
269
270        self.assertEqual(len(response.redirect_chain), 3)
271        self.assertEqual(response.redirect_chain[0], ('http://testserver/test_client_regress/redirects/further/', 301))
272        self.assertEqual(response.redirect_chain[1], ('http://testserver/test_client_regress/redirects/further/more/', 301))
273        self.assertEqual(response.redirect_chain[2], ('http://testserver/test_client_regress/no_template_view/', 301))
274
275    def test_redirect_chain_to_non_existent(self):
276        "You can follow a chain to a non-existent view"
277        response = self.client.get('/test_client_regress/redirect_to_non_existent_view2/', {}, follow=True)
278        self.assertRedirects(response, '/test_client_regress/non_existent_view/',
279            status_code=301, target_status_code=404)
280
281    def test_redirect_chain_to_self(self):
282        "Redirections to self are caught and escaped"
283        response = self.client.get('/test_client_regress/redirect_to_self/', {}, follow=True)
284        # The chain of redirects stops once the cycle is detected.
285        self.assertRedirects(response, '/test_client_regress/redirect_to_self/',
286            status_code=301, target_status_code=301)
287        self.assertEqual(len(response.redirect_chain), 2)
288
289    def test_circular_redirect(self):
290        "Circular redirect chains are caught and escaped"
291        response = self.client.get('/test_client_regress/circular_redirect_1/', {}, follow=True)
292        # The chain of redirects will get back to the starting point, but stop there.
293        self.assertRedirects(response, '/test_client_regress/circular_redirect_2/',
294            status_code=301, target_status_code=301)
295        self.assertEqual(len(response.redirect_chain), 4)
296
297    def test_redirect_chain_post(self):
298        "A redirect chain will be followed from an initial POST post"
299        response = self.client.post('/test_client_regress/redirects/',
300            {'nothing': 'to_send'}, follow=True)
301        self.assertRedirects(response,
302            '/test_client_regress/no_template_view/', 301, 200)
303        self.assertEqual(len(response.redirect_chain), 3)
304
305    def test_redirect_chain_head(self):
306        "A redirect chain will be followed from an initial HEAD request"
307        response = self.client.head('/test_client_regress/redirects/',
308            {'nothing': 'to_send'}, follow=True)
309        self.assertRedirects(response,
310            '/test_client_regress/no_template_view/', 301, 200)
311        self.assertEqual(len(response.redirect_chain), 3)
312
313    def test_redirect_chain_options(self):
314        "A redirect chain will be followed from an initial OPTIONS request"
315        response = self.client.options('/test_client_regress/redirects/',
316            {'nothing': 'to_send'}, follow=True)
317        self.assertRedirects(response,
318            '/test_client_regress/no_template_view/', 301, 200)
319        self.assertEqual(len(response.redirect_chain), 3)
320
321    def test_redirect_chain_put(self):
322        "A redirect chain will be followed from an initial PUT request"
323        response = self.client.put('/test_client_regress/redirects/',
324            {'nothing': 'to_send'}, follow=True)
325        self.assertRedirects(response,
326            '/test_client_regress/no_template_view/', 301, 200)
327        self.assertEqual(len(response.redirect_chain), 3)
328
329    def test_redirect_chain_delete(self):
330        "A redirect chain will be followed from an initial DELETE request"
331        response = self.client.delete('/test_client_regress/redirects/',
332            {'nothing': 'to_send'}, follow=True)
333        self.assertRedirects(response,
334            '/test_client_regress/no_template_view/', 301, 200)
335        self.assertEqual(len(response.redirect_chain), 3)
336
337    def test_redirect_chain_on_non_redirect_page(self):
338        "An assertion is raised if the original page couldn't be retrieved as expected"
339        # This page will redirect with code 301, not 302
340        response = self.client.get('/test_client/get_view/', follow=True)
341        try:
342            self.assertRedirects(response, '/test_client/get_view/')
343        except AssertionError, e:
344            self.assertIn("Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
345
346        try:
347            self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
348        except AssertionError, e:
349            self.assertIn("abc: Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
350
351    def test_redirect_on_non_redirect_page(self):
352        "An assertion is raised if the original page couldn't be retrieved as expected"
353        # This page will redirect with code 301, not 302
354        response = self.client.get('/test_client/get_view/')
355        try:
356            self.assertRedirects(response, '/test_client/get_view/')
357        except AssertionError, e:
358            self.assertIn("Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
359
360        try:
361            self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
362        except AssertionError, e:
363            self.assertIn("abc: Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
364
365
366class AssertFormErrorTests(TestCase):
367    def test_unknown_form(self):
368        "An assertion is raised if the form name is unknown"
369        post_data = {
370            'text': 'Hello World',
371            'email': 'not an email address',
372            'value': 37,
373            'single': 'b',
374            'multi': ('b','c','e')
375        }
376        response = self.client.post('/test_client/form_view/', post_data)
377        self.assertEqual(response.status_code, 200)
378        self.assertTemplateUsed(response, "Invalid POST Template")
379
380        try:
381            self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.')
382        except AssertionError, e:
383            self.assertIn("The form 'wrong_form' was not used to render the response", str(e))
384        try:
385            self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.', msg_prefix='abc')
386        except AssertionError, e:
387            self.assertIn("abc: The form 'wrong_form' was not used to render the response", str(e))
388
389    def test_unknown_field(self):
390        "An assertion is raised if the field name is unknown"
391        post_data = {
392            'text': 'Hello World',
393            'email': 'not an email address',
394            'value': 37,
395            'single': 'b',
396            'multi': ('b','c','e')
397        }
398        response = self.client.post('/test_client/form_view/', post_data)
399        self.assertEqual(response.status_code, 200)
400        self.assertTemplateUsed(response, "Invalid POST Template")
401
402        try:
403            self.assertFormError(response, 'form', 'some_field', 'Some error.')
404        except AssertionError, e:
405            self.assertIn("The form 'form' in context 0 does not contain the field 'some_field'", str(e))
406        try:
407            self.assertFormError(response, 'form', 'some_field', 'Some error.', msg_prefix='abc')
408        except AssertionError, e:
409            self.assertIn("abc: The form 'form' in context 0 does not contain the field 'some_field'", str(e))
410
411    def test_noerror_field(self):
412        "An assertion is raised if the field doesn't have any errors"
413        post_data = {
414            'text': 'Hello World',
415            'email': 'not an email address',
416            'value': 37,
417            'single': 'b',
418            'multi': ('b','c','e')
419        }
420        response = self.client.post('/test_client/form_view/', post_data)
421        self.assertEqual(response.status_code, 200)
422        self.assertTemplateUsed(response, "Invalid POST Template")
423
424        try:
425            self.assertFormError(response, 'form', 'value', 'Some error.')
426        except AssertionError, e:
427            self.assertIn("The field 'value' on form 'form' in context 0 contains no errors", str(e))
428        try:
429            self.assertFormError(response, 'form', 'value', 'Some error.', msg_prefix='abc')
430        except AssertionError, e:
431            self.assertIn("abc: The field 'value' on form 'form' in context 0 contains no errors", str(e))
432
433    def test_unknown_error(self):
434        "An assertion is raised if the field doesn't contain the provided error"
435        post_data = {
436            'text': 'Hello World',
437            'email': 'not an email address',
438            'value': 37,
439            'single': 'b',
440            'multi': ('b','c','e')
441        }
442        response = self.client.post('/test_client/form_view/', post_data)
443        self.assertEqual(response.status_code, 200)
444        self.assertTemplateUsed(response, "Invalid POST Template")
445
446        try:
447            self.assertFormError(response, 'form', 'email', 'Some error.')
448        except AssertionError, e:
449            self.assertIn("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.'])", str(e))
450        try:
451            self.assertFormError(response, 'form', 'email', 'Some error.', msg_prefix='abc')
452        except AssertionError, e:
453            self.assertIn("abc: 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.'])", str(e))
454
455    def test_unknown_nonfield_error(self):
456        """
457        Checks that an assertion is raised if the form's non field errors
458        doesn't contain the provided error.
459        """
460        post_data = {
461            'text': 'Hello World',
462            'email': 'not an email address',
463            'value': 37,
464            'single': 'b',
465            'multi': ('b','c','e')
466        }
467        response = self.client.post('/test_client/form_view/', post_data)
468        self.assertEqual(response.status_code, 200)
469        self.assertTemplateUsed(response, "Invalid POST Template")
470
471        try:
472            self.assertFormError(response, 'form', None, 'Some error.')
473        except AssertionError, e:
474            self.assertIn("The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e))
475        try:
476            self.assertFormError(response, 'form', None, 'Some error.', msg_prefix='abc')
477        except AssertionError, e:
478            self.assertIn("abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e))
479
480class LoginTests(TestCase):
481    fixtures = ['testdata']
482
483    def test_login_different_client(self):
484        "Check that using a different test client doesn't violate authentication"
485
486        # Create a second client, and log in.
487        c = Client()
488        login = c.login(username='testclient', password='password')
489        self.assertTrue(login, 'Could not log in')
490
491        # Get a redirection page with the second client.
492        response = c.get("/test_client_regress/login_protected_redirect_view/")
493
494        # At this points, the self.client isn't logged in.
495        # Check that assertRedirects uses the original client, not the
496        # default client.
497        self.assertRedirects(response, "http://testserver/test_client_regress/get_view/")
498
499
500class SessionEngineTests(TestCase):
501    fixtures = ['testdata']
502
503    def setUp(self):
504        self.old_SESSION_ENGINE = settings.SESSION_ENGINE
505        settings.SESSION_ENGINE = 'regressiontests.test_client_regress.session'
506
507    def tearDown(self):
508        settings.SESSION_ENGINE = self.old_SESSION_ENGINE
509
510    def test_login(self):
511        "A session engine that modifies the session key can be used to log in"
512        login = self.client.login(username='testclient', password='password')
513        self.assertTrue(login, 'Could not log in')
514
515        # Try to access a login protected page.
516        response = self.client.get("/test_client/login_protected_view/")
517        self.assertEqual(response.status_code, 200)
518        self.assertEqual(response.context['user'].username, 'testclient')
519
520class URLEscapingTests(TestCase):
521    def test_simple_argument_get(self):
522        "Get a view that has a simple string argument"
523        response = self.client.get(reverse('arg_view', args=['Slartibartfast']))
524        self.assertEqual(response.status_code, 200)
525        self.assertEqual(response.content, 'Howdy, Slartibartfast')
526
527    def test_argument_with_space_get(self):
528        "Get a view that has a string argument that requires escaping"
529        response = self.client.get(reverse('arg_view', args=['Arthur Dent']))
530        self.assertEqual(response.status_code, 200)
531        self.assertEqual(response.content, 'Hi, Arthur')
532
533    def test_simple_argument_post(self):
534        "Post for a view that has a simple string argument"
535        response = self.client.post(reverse('arg_view', args=['Slartibartfast']))
536        self.assertEqual(response.status_code, 200)
537        self.assertEqual(response.content, 'Howdy, Slartibartfast')
538
539    def test_argument_with_space_post(self):
540        "Post for a view that has a string argument that requires escaping"
541        response = self.client.post(reverse('arg_view', args=['Arthur Dent']))
542        self.assertEqual(response.status_code, 200)
543        self.assertEqual(response.content, 'Hi, Arthur')
544
545class ExceptionTests(TestCase):
546    fixtures = ['testdata.json']
547
548    def test_exception_cleared(self):
549        "#5836 - A stale user exception isn't re-raised by the test client."
550
551        login = self.client.login(username='testclient',password='password')
552        self.assertTrue(login, 'Could not log in')
553        try:
554            response = self.client.get("/test_client_regress/staff_only/")
555            self.fail("General users should not be able to visit this page")
556        except SuspiciousOperation:
557            pass
558
559        # At this point, an exception has been raised, and should be cleared.
560
561        # This next operation should be successful; if it isn't we have a problem.
562        login = self.client.login(username='staff', password='password')
563        self.assertTrue(login, 'Could not log in')
564        try:
565            self.client.get("/test_client_regress/staff_only/")
566        except SuspiciousOperation:
567            self.fail("Staff should be able to visit this page")
568
569class TemplateExceptionTests(TestCase):
570    def setUp(self):
571        # Reset the loaders so they don't try to render cached templates.
572        if loader.template_source_loaders is not None:
573            for template_loader in loader.template_source_loaders:
574                if hasattr(template_loader, 'reset'):
575                    template_loader.reset()
576        self.old_templates = settings.TEMPLATE_DIRS
577        settings.TEMPLATE_DIRS = ()
578
579    def tearDown(self):
580        settings.TEMPLATE_DIRS = self.old_templates
581
582    def test_no_404_template(self):
583        "Missing templates are correctly reported by test client"
584        try:
585            response = self.client.get("/no_such_view/")
586            self.fail("Should get error about missing template")
587        except TemplateDoesNotExist:
588            pass
589
590    def test_bad_404_template(self):
591        "Errors found when rendering 404 error templates are re-raised"
592        settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'bad_templates'),)
593        try:
594            response = self.client.get("/no_such_view/")
595            self.fail("Should get error about syntax error in template")
596        except TemplateSyntaxError:
597            pass
598
599# We need two different tests to check URLconf substitution -  one to check
600# it was changed, and another one (without self.urls) to check it was reverted on
601# teardown. This pair of tests relies upon the alphabetical ordering of test execution.
602class UrlconfSubstitutionTests(TestCase):
603    urls = 'regressiontests.test_client_regress.urls'
604
605    def test_urlconf_was_changed(self):
606        "TestCase can enforce a custom URLconf on a per-test basis"
607        url = reverse('arg_view', args=['somename'])
608        self.assertEqual(url, '/arg_view/somename/')
609
610# This test needs to run *after* UrlconfSubstitutionTests; the zz prefix in the
611# name is to ensure alphabetical ordering.
612class zzUrlconfSubstitutionTests(TestCase):
613    def test_urlconf_was_reverted(self):
614        "URLconf is reverted to original value after modification in a TestCase"
615        url = reverse('arg_view', args=['somename'])
616        self.assertEqual(url, '/test_client_regress/arg_view/somename/')
617
618class ContextTests(TestCase):
619    fixtures = ['testdata']
620
621    def test_single_context(self):
622        "Context variables can be retrieved from a single context"
623        response = self.client.get("/test_client_regress/request_data/", data={'foo':'whiz'})
624        self.assertEqual(response.context.__class__, Context)
625        self.assertTrue('get-foo' in response.context)
626        self.assertEqual(response.context['get-foo'], 'whiz')
627        self.assertEqual(response.context['request-foo'], 'whiz')
628        self.assertEqual(response.context['data'], 'sausage')
629
630        try:
631            response.context['does-not-exist']
632            self.fail('Should not be able to retrieve non-existent key')
633        except KeyError, e:
634            self.assertEqual(e.args[0], 'does-not-exist')
635
636    def test_inherited_context(self):
637        "Context variables can be retrieved from a list of contexts"
638        response = self.client.get("/test_client_regress/request_data_extended/", data={'foo':'whiz'})
639        self.assertEqual(response.context.__class__, ContextList)
640        self.assertEqual(len(response.context), 2)
641        self.assertTrue('get-foo' in response.context)
642        self.assertEqual(response.context['get-foo'], 'whiz')
643        self.assertEqual(response.context['request-foo'], 'whiz')
644        self.assertEqual(response.context['data'], 'bacon')
645
646        try:
647            response.context['does-not-exist']
648            self.fail('Should not be able to retrieve non-existent key')
649        except KeyError, e:
650            self.assertEqual(e.args[0], 'does-not-exist')
651
652    def test_15368(self):
653        # Need to insert a context processor that assumes certain things about
654        # the request instance. This triggers a bug caused by some ways of
655        # copying RequestContext.
656        try:
657            django.template.context._standard_context_processors = (lambda request: {'path': request.special_path},)
658            response = self.client.get("/test_client_regress/request_context_view/")
659            self.assertContains(response, 'Path: /test_client_regress/request_context_view/')
660        finally:
661            django.template.context._standard_context_processors = None
662
663
664class SessionTests(TestCase):
665    fixtures = ['testdata.json']
666
667    def test_session(self):
668        "The session isn't lost if a user logs in"
669        # The session doesn't exist to start.
670        response = self.client.get('/test_client_regress/check_session/')
671        self.assertEqual(response.status_code, 200)
672        self.assertEqual(response.content, 'NO')
673
674        # This request sets a session variable.
675        response = self.client.get('/test_client_regress/set_session/')
676        self.assertEqual(response.status_code, 200)
677        self.assertEqual(response.content, 'set_session')
678
679        # Check that the session has been modified
680        response = self.client.get('/test_client_regress/check_session/')
681        self.assertEqual(response.status_code, 200)
682        self.assertEqual(response.content, 'YES')
683
684        # Log in
685        login = self.client.login(username='testclient',password='password')
686        self.assertTrue(login, 'Could not log in')
687
688        # Session should still contain the modified value
689        response = self.client.get('/test_client_regress/check_session/')
690        self.assertEqual(response.status_code, 200)
691        self.assertEqual(response.content, 'YES')
692
693    def test_logout(self):
694        """Logout should work whether the user is logged in or not (#9978)."""
695        self.client.logout()
696        login = self.client.login(username='testclient',password='password')
697        self.assertTrue(login, 'Could not log in')
698        self.client.logout()
699        self.client.logout()
700
701class RequestMethodTests(TestCase):
702    def test_get(self):
703        "Request a view via request method GET"
704        response = self.client.get('/test_client_regress/request_methods/')
705        self.assertEqual(response.status_code, 200)
706        self.assertEqual(response.content, 'request method: GET')
707
708    def test_post(self):
709        "Request a view via request method POST"
710        response = self.client.post('/test_client_regress/request_methods/')
711        self.assertEqual(response.status_code, 200)
712        self.assertEqual(response.content, 'request method: POST')
713
714    def test_head(self):
715        "Request a view via request method HEAD"
716        response = self.client.head('/test_client_regress/request_methods/')
717        self.assertEqual(response.status_code, 200)
718        # A HEAD request doesn't return any content.
719        self.assertNotEqual(response.content, 'request method: HEAD')
720        self.assertEqual(response.content, '')
721
722    def test_options(self):
723        "Request a view via request method OPTIONS"
724        response = self.client.options('/test_client_regress/request_methods/')
725        self.assertEqual(response.status_code, 200)
726        self.assertEqual(response.content, 'request method: OPTIONS')
727
728    def test_put(self):
729        "Request a view via request method PUT"
730        response = self.client.put('/test_client_regress/request_methods/')
731        self.assertEqual(response.status_code, 200)
732        self.assertEqual(response.content, 'request method: PUT')
733
734    def test_delete(self):
735        "Request a view via request method DELETE"
736        response = self.client.delete('/test_client_regress/request_methods/')
737        self.assertEqual(response.status_code, 200)
738        self.assertEqual(response.content, 'request method: DELETE')
739
740class RequestMethodStringDataTests(TestCase):
741    def test_post(self):
742        "Request a view with string data via request method POST"
743        # Regression test for #11371
744        data = u'{"test": "json"}'
745        response = self.client.post('/test_client_regress/request_methods/', data=data, content_type='application/json')
746        self.assertEqual(response.status_code, 200)
747        self.assertEqual(response.content, 'request method: POST')
748
749    def test_put(self):
750        "Request a view with string data via request method PUT"
751        # Regression test for #11371
752        data = u'{"test": "json"}'
753        response = self.client.put('/test_client_regress/request_methods/', data=data, content_type='application/json')
754        self.assertEqual(response.status_code, 200)
755        self.assertEqual(response.content, 'request method: PUT')
756
757class QueryStringTests(TestCase):
758    def test_get_like_requests(self):
759        # See: https://code.djangoproject.com/ticket/10571.
760        # Removed 'put' and 'delete' here as they are 'GET-like requests'
761        for method_name in ('get','head','options'):
762            # A GET-like request can pass a query string as data
763            method = getattr(self.client, method_name)
764            response = method("/test_client_regress/request_data/", data={'foo':'whiz'})
765            self.assertEqual(response.context['get-foo'], 'whiz')
766            self.assertEqual(response.context['request-foo'], 'whiz')
767
768            # A GET-like request can pass a query string as part of the URL
769            response = method("/test_client_regress/request_data/?foo=whiz")
770            self.assertEqual(response.context['get-foo'], 'whiz')
771            self.assertEqual(response.context['request-foo'], 'whiz')
772
773            # Data provided in the URL to a GET-like request is overridden by actual form data
774            response = method("/test_client_regress/request_data/?foo=whiz", data={'foo':'bang'})
775            self.assertEqual(response.context['get-foo'], 'bang')
776            self.assertEqual(response.context['request-foo'], 'bang')
777
778            response = method("/test_client_regress/request_data/?foo=whiz", data={'bar':'bang'})
779            self.assertEqual(response.context['get-foo'], None)
780            self.assertEqual(response.context['get-bar'], 'bang')
781            self.assertEqual(response.context['request-foo'], None)
782            self.assertEqual(response.context['request-bar'], 'bang')
783
784    def test_post_like_requests(self):
785        # A POST-like request can pass a query string as data
786        response = self.client.post("/test_client_regress/request_data/", data={'foo':'whiz'})
787        self.assertEqual(response.context['get-foo'], None)
788        self.assertEqual(response.context['post-foo'], 'whiz')
789
790        # A POST-like request can pass a query string as part of the URL
791        response = self.client.post("/test_client_regress/request_data/?foo=whiz")
792        self.assertEqual(response.context['get-foo'], 'whiz')
793        self.assertEqual(response.context['post-foo'], None)
794        self.assertEqual(response.context['request-foo'], 'whiz')
795
796        # POST data provided in the URL augments actual form data
797        response = self.client.post("/test_client_regress/request_data/?foo=whiz", data={'foo':'bang'})
798        self.assertEqual(response.context['get-foo'], 'whiz')
799        self.assertEqual(response.context['post-foo'], 'bang')
800        self.assertEqual(response.context['request-foo'], 'bang')
801
802        response = self.client.post("/test_client_regress/request_data/?foo=whiz", data={'bar':'bang'})
803        self.assertEqual(response.context['get-foo'], 'whiz')
804        self.assertEqual(response.context['get-bar'], None)
805        self.assertEqual(response.context['post-foo'], None)
806        self.assertEqual(response.context['post-bar'], 'bang')
807        self.assertEqual(response.context['request-foo'], 'whiz')
808        self.assertEqual(response.context['request-bar'], 'bang')
809
810class UnicodePayloadTests(TestCase):
811    def test_simple_unicode_payload(self):
812        "A simple ASCII-only unicode JSON document can be POSTed"
813        # Regression test for #10571
814        json = u'{"english": "mountain pass"}'
815        response = self.client.post("/test_client_regress/parse_unicode_json/", json,
816                                    content_type="application/json")
817        self.assertEqual(response.content, json)
818        response = self.client.put("/test_client_regress/parse_unicode_json/", json,
819                                    content_type="application/json")
820        self.assertEqual(response.content, json)
821
822    def test_unicode_payload_utf8(self):
823        "A non-ASCII unicode data encoded as UTF-8 can be POSTed"
824        # Regression test for #10571
825        json = u'{"dog": "??????"}'
826        response = self.client.post("/test_client_regress/parse_unicode_json/", json,
827                                    content_type="application/json; charset=utf-8")
828        self.assertEqual(response.content, json.encode('utf-8'))
829        response = self.client.put("/test_client_regress/parse_unicode_json/", json,
830                                    content_type="application/json; charset=utf-8")
831        self.assertEqual(response.content, json.encode('utf-8'))
832
833    def test_unicode_payload_utf16(self):
834        "A non-ASCII unicode data encoded as UTF-16 can be POSTed"
835        # Regression test for #10571
836        json = u'{"dog": "??????"}'
837        response = self.client.post("/test_client_regress/parse_unicode_json/", json,
838                                    content_type="application/json; charset=utf-16")
839        self.assertEqual(response.content, json.encode('utf-16'))
840        response = self.client.put("/test_client_regress/parse_unicode_json/", json,
841                                    content_type="application/json; charset=utf-16")
842        self.assertEqual(response.content, json.encode('utf-16'))
843
844    def test_unicode_payload_non_utf(self):
845        "A non-ASCII unicode data as a non-UTF based encoding can be POSTed"
846        #Regression test for #10571
847        json = u'{"dog": "??????"}'
848        response = self.client.post("/test_client_regress/parse_unicode_json/", json,
849                                    content_type="application/json; charset=koi8-r")
850        self.assertEqual(response.content, json.encode('koi8-r'))
851        response = self.client.put("/test_client_regress/parse_unicode_json/", json,
852                                    content_type="application/json; charset=koi8-r")
853        self.assertEqual(response.content, json.encode('koi8-r'))
854
855class DummyFile(object):
856    def __init__(self, filename):
857        self.name = filename
858    def read(self):
859        return 'TEST_FILE_CONTENT'
860
861class UploadedFileEncodingTest(TestCase):
862    def test_file_encoding(self):
863        encoded_file = encode_file('TEST_BOUNDARY', 'TEST_KEY', DummyFile('test_name.bin'))
864        self.assertEqual('--TEST_BOUNDARY', encoded_file[0])
865        self.assertEqual('Content-Disposition: form-data; name="TEST_KEY"; filename="test_name.bin"', encoded_file[1])
866        self.assertEqual('TEST_FILE_CONTENT', encoded_file[-1])
867
868    def test_guesses_content_type_on_file_encoding(self):
869        self.assertEqual('Content-Type: application/octet-stream',
870                         encode_file('IGNORE', 'IGNORE', DummyFile("file.bin"))[2])
871        self.assertEqual('Content-Type: text/plain',
872                         encode_file('IGNORE', 'IGNORE', DummyFile("file.txt"))[2])
873        self.assertIn(encode_file('IGNORE', 'IGNORE', DummyFile("file.zip"))[2], (
874                        'Content-Type: application/x-compress',
875                        'Content-Type: application/x-zip',
876                        'Content-Type: application/x-zip-compressed',
877                        'Content-Type: application/zip',))
878        self.assertEqual('Content-Type: application/octet-stream',
879                         encode_file('IGNORE', 'IGNORE', DummyFile("file.unknown"))[2])
880
881class RequestHeadersTest(TestCase):
882    def test_client_headers(self):
883        "A test client can receive custom headers"
884        response = self.client.get("/test_client_regress/check_headers/", HTTP_X_ARG_CHECK='Testing 123')
885        self.assertEqual(response.content, "HTTP_X_ARG_CHECK: Testing 123")
886        self.assertEqual(response.status_code, 200)
887
888    def test_client_headers_redirect(self):
889        "Test client headers are preserved through redirects"
890        response = self.client.get("/test_client_regress/check_headers_redirect/", follow=True, HTTP_X_ARG_CHECK='Testing 123')
891        self.assertEqual(response.content, "HTTP_X_ARG_CHECK: Testing 123")
892        self.assertRedirects(response, '/test_client_regress/check_headers/',
893            status_code=301, target_status_code=200)
894
895class ResponseTemplateDeprecationTests(TestCase):
896    """
897    Response.template still works backwards-compatibly, but with pending deprecation warning. Refs #12226.
898
899    """
900    def test_response_template_data(self):
901        response = self.client.get("/test_client_regress/request_data/", data={'foo':'whiz'})
902        self.assertEqual(response.template.__class__, Template)
903        self.assertEqual(response.template.name, 'base.html')
904
905    def test_response_no_template(self):
906        response = self.client.get("/test_client_regress/request_methods/")
907        self.assertEqual(response.template, None)
908
909class RawPostDataTest(TestCase):
910    "Access to request.raw_post_data from the test client."
911    def test_raw_post_data(self):
912        # Refs #14753
913        try:
914            response = self.client.get("/test_client_regress/raw_post_data/")
915        except AssertionError:
916            self.fail("Accessing request.raw_post_data from a view fetched with GET by the test client shouldn't fail.")