1
# -*- coding: utf-8 -*-
3
Regression tests for the Test Client, especially the customized assertions.
8
from django.conf import settings
9
from django.core.exceptions import SuspiciousOperation
10
from django.core.urlresolvers import reverse
11
from django.template import (TemplateDoesNotExist, TemplateSyntaxError,
12
Context, Template, loader)
13
import django.template.context
14
from django.test import Client, TestCase
15
from django.test.client import encode_file, RequestFactory
16
from django.test.utils import ContextList
17
from django.template.response import SimpleTemplateResponse
18
from django.http import HttpResponse
21
class AssertContainsTests(TestCase):
23
self.old_templates = settings.TEMPLATE_DIRS
24
settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates'),)
27
settings.TEMPLATE_DIRS = self.old_templates
29
def test_contains(self):
30
"Responses can be inspected for content, including counting repeated substrings"
31
response = self.client.get('/test_client_regress/no_template_view/')
33
self.assertNotContains(response, 'never')
34
self.assertContains(response, 'never', 0)
35
self.assertContains(response, 'once')
36
self.assertContains(response, 'once', 1)
37
self.assertContains(response, 'twice')
38
self.assertContains(response, 'twice', 2)
41
self.assertContains(response, 'text', status_code=999)
42
except AssertionError, e:
43
self.assertIn("Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
45
self.assertContains(response, 'text', status_code=999, msg_prefix='abc')
46
except AssertionError, e:
47
self.assertIn("abc: Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
50
self.assertNotContains(response, 'text', status_code=999)
51
except AssertionError, e:
52
self.assertIn("Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
54
self.assertNotContains(response, 'text', status_code=999, msg_prefix='abc')
55
except AssertionError, e:
56
self.assertIn("abc: Couldn't retrieve content: Response code was 200 (expected 999)", str(e))
59
self.assertNotContains(response, 'once')
60
except AssertionError, e:
61
self.assertIn("Response should not contain 'once'", str(e))
63
self.assertNotContains(response, 'once', msg_prefix='abc')
64
except AssertionError, e:
65
self.assertIn("abc: Response should not contain 'once'", str(e))
68
self.assertContains(response, 'never', 1)
69
except AssertionError, e:
70
self.assertIn("Found 0 instances of 'never' in response (expected 1)", str(e))
72
self.assertContains(response, 'never', 1, msg_prefix='abc')
73
except AssertionError, e:
74
self.assertIn("abc: Found 0 instances of 'never' in response (expected 1)", str(e))
77
self.assertContains(response, 'once', 0)
78
except AssertionError, e:
79
self.assertIn("Found 1 instances of 'once' in response (expected 0)", str(e))
81
self.assertContains(response, 'once', 0, msg_prefix='abc')
82
except AssertionError, e:
83
self.assertIn("abc: Found 1 instances of 'once' in response (expected 0)", str(e))
86
self.assertContains(response, 'once', 2)
87
except AssertionError, e:
88
self.assertIn("Found 1 instances of 'once' in response (expected 2)", str(e))
90
self.assertContains(response, 'once', 2, msg_prefix='abc')
91
except AssertionError, e:
92
self.assertIn("abc: Found 1 instances of 'once' in response (expected 2)", str(e))
95
self.assertContains(response, 'twice', 1)
96
except AssertionError, e:
97
self.assertIn("Found 2 instances of 'twice' in response (expected 1)", str(e))
99
self.assertContains(response, 'twice', 1, msg_prefix='abc')
100
except AssertionError, e:
101
self.assertIn("abc: Found 2 instances of 'twice' in response (expected 1)", str(e))
104
self.assertContains(response, 'thrice')
105
except AssertionError, e:
106
self.assertIn("Couldn't find 'thrice' in response", str(e))
108
self.assertContains(response, 'thrice', msg_prefix='abc')
109
except AssertionError, e:
110
self.assertIn("abc: Couldn't find 'thrice' in response", str(e))
113
self.assertContains(response, 'thrice', 3)
114
except AssertionError, e:
115
self.assertIn("Found 0 instances of 'thrice' in response (expected 3)", str(e))
117
self.assertContains(response, 'thrice', 3, msg_prefix='abc')
118
except AssertionError, e:
119
self.assertIn("abc: Found 0 instances of 'thrice' in response (expected 3)", str(e))
121
def test_unicode_contains(self):
122
"Unicode characters can be found in template context"
123
#Regression test for #10183
124
r = self.client.get('/test_client_regress/check_unicode/')
125
self.assertContains(r, u'さかき')
126
self.assertContains(r, '\xe5\xb3\xa0'.decode('utf-8'))
128
def test_unicode_not_contains(self):
129
"Unicode characters can be searched for, and not found in template context"
130
#Regression test for #10183
131
r = self.client.get('/test_client_regress/check_unicode/')
132
self.assertNotContains(r, u'はたけ')
133
self.assertNotContains(r, '\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91'.decode('utf-8'))
135
def test_assert_contains_renders_template_response(self):
136
""" Test that we can pass in an unrendered SimpleTemplateReponse
137
without throwing an error.
140
response = SimpleTemplateResponse(Template('Hello'), status=200)
141
self.assertContains(response, 'Hello')
143
def test_assert_contains_using_non_template_response(self):
144
""" Test that auto-rendering does not affect responses that aren't
145
instances (or subclasses) of SimpleTemplateResponse.
148
response = HttpResponse('Hello')
149
self.assertContains(response, 'Hello')
151
def test_assert_not_contains_renders_template_response(self):
152
""" Test that we can pass in an unrendered SimpleTemplateReponse
153
without throwing an error.
156
response = SimpleTemplateResponse(Template('Hello'), status=200)
157
self.assertNotContains(response, 'Bye')
159
def test_assert_not_contains_using_non_template_response(self):
160
""" Test that auto-rendering does not affect responses that aren't
161
instances (or subclasses) of SimpleTemplateResponse.
164
response = HttpResponse('Hello')
165
self.assertNotContains(response, 'Bye')
167
class AssertTemplateUsedTests(TestCase):
168
fixtures = ['testdata.json']
170
def test_no_context(self):
171
"Template usage assertions work then templates aren't in use"
172
response = self.client.get('/test_client_regress/no_template_view/')
174
# Check that the no template case doesn't mess with the template assertions
175
self.assertTemplateNotUsed(response, 'GET Template')
178
self.assertTemplateUsed(response, 'GET Template')
179
except AssertionError, e:
180
self.assertIn("No templates used to render the response", str(e))
183
self.assertTemplateUsed(response, 'GET Template', msg_prefix='abc')
184
except AssertionError, e:
185
self.assertIn("abc: No templates used to render the response", str(e))
187
def test_single_context(self):
188
"Template assertions work when there is a single context"
189
response = self.client.get('/test_client/post_view/', {})
192
self.assertTemplateNotUsed(response, 'Empty GET Template')
193
except AssertionError, e:
194
self.assertIn("Template 'Empty GET Template' was used unexpectedly in rendering the response", str(e))
197
self.assertTemplateNotUsed(response, 'Empty GET Template', msg_prefix='abc')
198
except AssertionError, e:
199
self.assertIn("abc: Template 'Empty GET Template' was used unexpectedly in rendering the response", str(e))
202
self.assertTemplateUsed(response, 'Empty POST Template')
203
except AssertionError, e:
204
self.assertIn("Template 'Empty POST Template' was not a template used to render the response. Actual template(s) used: Empty GET Template", str(e))
207
self.assertTemplateUsed(response, 'Empty POST Template', msg_prefix='abc')
208
except AssertionError, e:
209
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))
211
def test_multiple_context(self):
212
"Template assertions work when there are multiple contexts"
214
'text': 'Hello World',
215
'email': 'foo@example.com',
218
'multi': ('b','c','e')
220
response = self.client.post('/test_client/form_view_with_template/', post_data)
221
self.assertContains(response, 'POST data OK')
223
self.assertTemplateNotUsed(response, "form_view.html")
224
except AssertionError, e:
225
self.assertIn("Template 'form_view.html' was used unexpectedly in rendering the response", str(e))
228
self.assertTemplateNotUsed(response, 'base.html')
229
except AssertionError, e:
230
self.assertIn("Template 'base.html' was used unexpectedly in rendering the response", str(e))
233
self.assertTemplateUsed(response, "Valid POST Template")
234
except AssertionError, e:
235
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))
237
class AssertRedirectsTests(TestCase):
238
def test_redirect_page(self):
239
"An assertion is raised if the original page couldn't be retrieved as expected"
240
# This page will redirect with code 301, not 302
241
response = self.client.get('/test_client/permanent_redirect_view/')
243
self.assertRedirects(response, '/test_client/get_view/')
244
except AssertionError, e:
245
self.assertIn("Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
248
self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
249
except AssertionError, e:
250
self.assertIn("abc: Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
252
def test_lost_query(self):
253
"An assertion is raised if the redirect location doesn't preserve GET parameters"
254
response = self.client.get('/test_client/redirect_view/', {'var': 'value'})
256
self.assertRedirects(response, '/test_client/get_view/')
257
except AssertionError, e:
258
self.assertIn("Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'", str(e))
261
self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
262
except AssertionError, e:
263
self.assertIn("abc: Response redirected to 'http://testserver/test_client/get_view/?var=value', expected 'http://testserver/test_client/get_view/'", str(e))
265
def test_incorrect_target(self):
266
"An assertion is raised if the response redirects to another target"
267
response = self.client.get('/test_client/permanent_redirect_view/')
269
# Should redirect to get_view
270
self.assertRedirects(response, '/test_client/some_view/')
271
except AssertionError, e:
272
self.assertIn("Response didn't redirect as expected: Response code was 301 (expected 302)", str(e))
274
def test_target_page(self):
275
"An assertion is raised if the response redirect target cannot be retrieved as expected"
276
response = self.client.get('/test_client/double_redirect_view/')
278
# The redirect target responds with a 301 code, not 200
279
self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/')
280
except AssertionError, e:
281
self.assertIn("Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)", str(e))
284
# The redirect target responds with a 301 code, not 200
285
self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/', msg_prefix='abc')
286
except AssertionError, e:
287
self.assertIn("abc: Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)", str(e))
289
def test_redirect_chain(self):
290
"You can follow a redirect chain of multiple redirects"
291
response = self.client.get('/test_client_regress/redirects/further/more/', {}, follow=True)
292
self.assertRedirects(response, '/test_client_regress/no_template_view/',
293
status_code=301, target_status_code=200)
295
self.assertEqual(len(response.redirect_chain), 1)
296
self.assertEqual(response.redirect_chain[0], ('http://testserver/test_client_regress/no_template_view/', 301))
298
def test_multiple_redirect_chain(self):
299
"You can follow a redirect chain of multiple redirects"
300
response = self.client.get('/test_client_regress/redirects/', {}, follow=True)
301
self.assertRedirects(response, '/test_client_regress/no_template_view/',
302
status_code=301, target_status_code=200)
304
self.assertEqual(len(response.redirect_chain), 3)
305
self.assertEqual(response.redirect_chain[0], ('http://testserver/test_client_regress/redirects/further/', 301))
306
self.assertEqual(response.redirect_chain[1], ('http://testserver/test_client_regress/redirects/further/more/', 301))
307
self.assertEqual(response.redirect_chain[2], ('http://testserver/test_client_regress/no_template_view/', 301))
309
def test_redirect_chain_to_non_existent(self):
310
"You can follow a chain to a non-existent view"
311
response = self.client.get('/test_client_regress/redirect_to_non_existent_view2/', {}, follow=True)
312
self.assertRedirects(response, '/test_client_regress/non_existent_view/',
313
status_code=301, target_status_code=404)
315
def test_redirect_chain_to_self(self):
316
"Redirections to self are caught and escaped"
317
response = self.client.get('/test_client_regress/redirect_to_self/', {}, follow=True)
318
# The chain of redirects stops once the cycle is detected.
319
self.assertRedirects(response, '/test_client_regress/redirect_to_self/',
320
status_code=301, target_status_code=301)
321
self.assertEqual(len(response.redirect_chain), 2)
323
def test_circular_redirect(self):
324
"Circular redirect chains are caught and escaped"
325
response = self.client.get('/test_client_regress/circular_redirect_1/', {}, follow=True)
326
# The chain of redirects will get back to the starting point, but stop there.
327
self.assertRedirects(response, '/test_client_regress/circular_redirect_2/',
328
status_code=301, target_status_code=301)
329
self.assertEqual(len(response.redirect_chain), 4)
331
def test_redirect_chain_post(self):
332
"A redirect chain will be followed from an initial POST post"
333
response = self.client.post('/test_client_regress/redirects/',
334
{'nothing': 'to_send'}, follow=True)
335
self.assertRedirects(response,
336
'/test_client_regress/no_template_view/', 301, 200)
337
self.assertEqual(len(response.redirect_chain), 3)
339
def test_redirect_chain_head(self):
340
"A redirect chain will be followed from an initial HEAD request"
341
response = self.client.head('/test_client_regress/redirects/',
342
{'nothing': 'to_send'}, follow=True)
343
self.assertRedirects(response,
344
'/test_client_regress/no_template_view/', 301, 200)
345
self.assertEqual(len(response.redirect_chain), 3)
347
def test_redirect_chain_options(self):
348
"A redirect chain will be followed from an initial OPTIONS request"
349
response = self.client.options('/test_client_regress/redirects/',
350
{'nothing': 'to_send'}, follow=True)
351
self.assertRedirects(response,
352
'/test_client_regress/no_template_view/', 301, 200)
353
self.assertEqual(len(response.redirect_chain), 3)
355
def test_redirect_chain_put(self):
356
"A redirect chain will be followed from an initial PUT request"
357
response = self.client.put('/test_client_regress/redirects/',
358
{'nothing': 'to_send'}, follow=True)
359
self.assertRedirects(response,
360
'/test_client_regress/no_template_view/', 301, 200)
361
self.assertEqual(len(response.redirect_chain), 3)
363
def test_redirect_chain_delete(self):
364
"A redirect chain will be followed from an initial DELETE request"
365
response = self.client.delete('/test_client_regress/redirects/',
366
{'nothing': 'to_send'}, follow=True)
367
self.assertRedirects(response,
368
'/test_client_regress/no_template_view/', 301, 200)
369
self.assertEqual(len(response.redirect_chain), 3)
371
def test_redirect_to_different_host(self):
372
"The test client will preserve scheme, host and port changes"
373
response = self.client.get('/test_client_regress/redirect_other_host/', follow=True)
374
self.assertRedirects(response,
375
'https://otherserver:8443/test_client_regress/no_template_view/',
376
status_code=301, target_status_code=200)
377
# We can't use is_secure() or get_host()
378
# because response.request is a dictionary, not an HttpRequest
379
self.assertEqual(response.request.get('wsgi.url_scheme'), 'https')
380
self.assertEqual(response.request.get('SERVER_NAME'), 'otherserver')
381
self.assertEqual(response.request.get('SERVER_PORT'), '8443')
383
def test_redirect_chain_on_non_redirect_page(self):
384
"An assertion is raised if the original page couldn't be retrieved as expected"
385
# This page will redirect with code 301, not 302
386
response = self.client.get('/test_client/get_view/', follow=True)
388
self.assertRedirects(response, '/test_client/get_view/')
389
except AssertionError, e:
390
self.assertIn("Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
393
self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
394
except AssertionError, e:
395
self.assertIn("abc: Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
397
def test_redirect_on_non_redirect_page(self):
398
"An assertion is raised if the original page couldn't be retrieved as expected"
399
# This page will redirect with code 301, not 302
400
response = self.client.get('/test_client/get_view/')
402
self.assertRedirects(response, '/test_client/get_view/')
403
except AssertionError, e:
404
self.assertIn("Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
407
self.assertRedirects(response, '/test_client/get_view/', msg_prefix='abc')
408
except AssertionError, e:
409
self.assertIn("abc: Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
412
class AssertFormErrorTests(TestCase):
413
def test_unknown_form(self):
414
"An assertion is raised if the form name is unknown"
416
'text': 'Hello World',
417
'email': 'not an email address',
420
'multi': ('b','c','e')
422
response = self.client.post('/test_client/form_view/', post_data)
423
self.assertEqual(response.status_code, 200)
424
self.assertTemplateUsed(response, "Invalid POST Template")
427
self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.')
428
except AssertionError, e:
429
self.assertIn("The form 'wrong_form' was not used to render the response", str(e))
431
self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.', msg_prefix='abc')
432
except AssertionError, e:
433
self.assertIn("abc: The form 'wrong_form' was not used to render the response", str(e))
435
def test_unknown_field(self):
436
"An assertion is raised if the field name is unknown"
438
'text': 'Hello World',
439
'email': 'not an email address',
442
'multi': ('b','c','e')
444
response = self.client.post('/test_client/form_view/', post_data)
445
self.assertEqual(response.status_code, 200)
446
self.assertTemplateUsed(response, "Invalid POST Template")
449
self.assertFormError(response, 'form', 'some_field', 'Some error.')
450
except AssertionError, e:
451
self.assertIn("The form 'form' in context 0 does not contain the field 'some_field'", str(e))
453
self.assertFormError(response, 'form', 'some_field', 'Some error.', msg_prefix='abc')
454
except AssertionError, e:
455
self.assertIn("abc: The form 'form' in context 0 does not contain the field 'some_field'", str(e))
457
def test_noerror_field(self):
458
"An assertion is raised if the field doesn't have any errors"
460
'text': 'Hello World',
461
'email': 'not an email address',
464
'multi': ('b','c','e')
466
response = self.client.post('/test_client/form_view/', post_data)
467
self.assertEqual(response.status_code, 200)
468
self.assertTemplateUsed(response, "Invalid POST Template")
471
self.assertFormError(response, 'form', 'value', 'Some error.')
472
except AssertionError, e:
473
self.assertIn("The field 'value' on form 'form' in context 0 contains no errors", str(e))
475
self.assertFormError(response, 'form', 'value', 'Some error.', msg_prefix='abc')
476
except AssertionError, e:
477
self.assertIn("abc: The field 'value' on form 'form' in context 0 contains no errors", str(e))
479
def test_unknown_error(self):
480
"An assertion is raised if the field doesn't contain the provided error"
482
'text': 'Hello World',
483
'email': 'not an email address',
486
'multi': ('b','c','e')
488
response = self.client.post('/test_client/form_view/', post_data)
489
self.assertEqual(response.status_code, 200)
490
self.assertTemplateUsed(response, "Invalid POST Template")
493
self.assertFormError(response, 'form', 'email', 'Some error.')
494
except AssertionError, e:
495
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))
497
self.assertFormError(response, 'form', 'email', 'Some error.', msg_prefix='abc')
498
except AssertionError, e:
499
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))
501
def test_unknown_nonfield_error(self):
503
Checks that an assertion is raised if the form's non field errors
504
doesn't contain the provided error.
507
'text': 'Hello World',
508
'email': 'not an email address',
511
'multi': ('b','c','e')
513
response = self.client.post('/test_client/form_view/', post_data)
514
self.assertEqual(response.status_code, 200)
515
self.assertTemplateUsed(response, "Invalid POST Template")
518
self.assertFormError(response, 'form', None, 'Some error.')
519
except AssertionError, e:
520
self.assertIn("The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e))
522
self.assertFormError(response, 'form', None, 'Some error.', msg_prefix='abc')
523
except AssertionError, e:
524
self.assertIn("abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e))
526
class LoginTests(TestCase):
527
fixtures = ['testdata']
529
def test_login_different_client(self):
530
"Check that using a different test client doesn't violate authentication"
532
# Create a second client, and log in.
534
login = c.login(username='testclient', password='password')
535
self.assertTrue(login, 'Could not log in')
537
# Get a redirection page with the second client.
538
response = c.get("/test_client_regress/login_protected_redirect_view/")
540
# At this points, the self.client isn't logged in.
541
# Check that assertRedirects uses the original client, not the
543
self.assertRedirects(response, "http://testserver/test_client_regress/get_view/")
546
class SessionEngineTests(TestCase):
547
fixtures = ['testdata']
550
self.old_SESSION_ENGINE = settings.SESSION_ENGINE
551
settings.SESSION_ENGINE = 'regressiontests.test_client_regress.session'
554
settings.SESSION_ENGINE = self.old_SESSION_ENGINE
556
def test_login(self):
557
"A session engine that modifies the session key can be used to log in"
558
login = self.client.login(username='testclient', password='password')
559
self.assertTrue(login, 'Could not log in')
561
# Try to access a login protected page.
562
response = self.client.get("/test_client/login_protected_view/")
563
self.assertEqual(response.status_code, 200)
564
self.assertEqual(response.context['user'].username, 'testclient')
567
class URLEscapingTests(TestCase):
568
def test_simple_argument_get(self):
569
"Get a view that has a simple string argument"
570
response = self.client.get(reverse('arg_view', args=['Slartibartfast']))
571
self.assertEqual(response.status_code, 200)
572
self.assertEqual(response.content, 'Howdy, Slartibartfast')
574
def test_argument_with_space_get(self):
575
"Get a view that has a string argument that requires escaping"
576
response = self.client.get(reverse('arg_view', args=['Arthur Dent']))
577
self.assertEqual(response.status_code, 200)
578
self.assertEqual(response.content, 'Hi, Arthur')
580
def test_simple_argument_post(self):
581
"Post for a view that has a simple string argument"
582
response = self.client.post(reverse('arg_view', args=['Slartibartfast']))
583
self.assertEqual(response.status_code, 200)
584
self.assertEqual(response.content, 'Howdy, Slartibartfast')
586
def test_argument_with_space_post(self):
587
"Post for a view that has a string argument that requires escaping"
588
response = self.client.post(reverse('arg_view', args=['Arthur Dent']))
589
self.assertEqual(response.status_code, 200)
590
self.assertEqual(response.content, 'Hi, Arthur')
592
class ExceptionTests(TestCase):
593
fixtures = ['testdata.json']
595
def test_exception_cleared(self):
596
"#5836 - A stale user exception isn't re-raised by the test client."
598
login = self.client.login(username='testclient',password='password')
599
self.assertTrue(login, 'Could not log in')
601
response = self.client.get("/test_client_regress/staff_only/")
602
self.fail("General users should not be able to visit this page")
603
except SuspiciousOperation:
606
# At this point, an exception has been raised, and should be cleared.
608
# This next operation should be successful; if it isn't we have a problem.
609
login = self.client.login(username='staff', password='password')
610
self.assertTrue(login, 'Could not log in')
612
self.client.get("/test_client_regress/staff_only/")
613
except SuspiciousOperation:
614
self.fail("Staff should be able to visit this page")
616
class TemplateExceptionTests(TestCase):
618
# Reset the loaders so they don't try to render cached templates.
619
if loader.template_source_loaders is not None:
620
for template_loader in loader.template_source_loaders:
621
if hasattr(template_loader, 'reset'):
622
template_loader.reset()
623
self.old_templates = settings.TEMPLATE_DIRS
624
settings.TEMPLATE_DIRS = ()
627
settings.TEMPLATE_DIRS = self.old_templates
629
def test_no_404_template(self):
630
"Missing templates are correctly reported by test client"
632
response = self.client.get("/no_such_view/")
633
self.fail("Should get error about missing template")
634
except TemplateDoesNotExist:
637
def test_bad_404_template(self):
638
"Errors found when rendering 404 error templates are re-raised"
639
settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'bad_templates'),)
641
response = self.client.get("/no_such_view/")
642
self.fail("Should get error about syntax error in template")
643
except TemplateSyntaxError:
646
# We need two different tests to check URLconf substitution - one to check
647
# it was changed, and another one (without self.urls) to check it was reverted on
648
# teardown. This pair of tests relies upon the alphabetical ordering of test execution.
649
class UrlconfSubstitutionTests(TestCase):
650
urls = 'regressiontests.test_client_regress.urls'
652
def test_urlconf_was_changed(self):
653
"TestCase can enforce a custom URLconf on a per-test basis"
654
url = reverse('arg_view', args=['somename'])
655
self.assertEqual(url, '/arg_view/somename/')
657
# This test needs to run *after* UrlconfSubstitutionTests; the zz prefix in the
658
# name is to ensure alphabetical ordering.
659
class zzUrlconfSubstitutionTests(TestCase):
660
def test_urlconf_was_reverted(self):
661
"URLconf is reverted to original value after modification in a TestCase"
662
url = reverse('arg_view', args=['somename'])
663
self.assertEqual(url, '/test_client_regress/arg_view/somename/')
665
class ContextTests(TestCase):
666
fixtures = ['testdata']
668
def test_single_context(self):
669
"Context variables can be retrieved from a single context"
670
response = self.client.get("/test_client_regress/request_data/", data={'foo':'whiz'})
671
self.assertEqual(response.context.__class__, Context)
672
self.assertTrue('get-foo' in response.context)
673
self.assertEqual(response.context['get-foo'], 'whiz')
674
self.assertEqual(response.context['request-foo'], 'whiz')
675
self.assertEqual(response.context['data'], 'sausage')
678
response.context['does-not-exist']
679
self.fail('Should not be able to retrieve non-existent key')
681
self.assertEqual(e.args[0], 'does-not-exist')
683
def test_inherited_context(self):
684
"Context variables can be retrieved from a list of contexts"
685
response = self.client.get("/test_client_regress/request_data_extended/", data={'foo':'whiz'})
686
self.assertEqual(response.context.__class__, ContextList)
687
self.assertEqual(len(response.context), 2)
688
self.assertTrue('get-foo' in response.context)
689
self.assertEqual(response.context['get-foo'], 'whiz')
690
self.assertEqual(response.context['request-foo'], 'whiz')
691
self.assertEqual(response.context['data'], 'bacon')
694
response.context['does-not-exist']
695
self.fail('Should not be able to retrieve non-existent key')
697
self.assertEqual(e.args[0], 'does-not-exist')
699
def test_15368(self):
700
# Need to insert a context processor that assumes certain things about
701
# the request instance. This triggers a bug caused by some ways of
702
# copying RequestContext.
704
django.template.context._standard_context_processors = (lambda request: {'path': request.special_path},)
705
response = self.client.get("/test_client_regress/request_context_view/")
706
self.assertContains(response, 'Path: /test_client_regress/request_context_view/')
708
django.template.context._standard_context_processors = None
711
class SessionTests(TestCase):
712
fixtures = ['testdata.json']
714
def test_session(self):
715
"The session isn't lost if a user logs in"
716
# The session doesn't exist to start.
717
response = self.client.get('/test_client_regress/check_session/')
718
self.assertEqual(response.status_code, 200)
719
self.assertEqual(response.content, 'NO')
721
# This request sets a session variable.
722
response = self.client.get('/test_client_regress/set_session/')
723
self.assertEqual(response.status_code, 200)
724
self.assertEqual(response.content, 'set_session')
726
# Check that the session has been modified
727
response = self.client.get('/test_client_regress/check_session/')
728
self.assertEqual(response.status_code, 200)
729
self.assertEqual(response.content, 'YES')
732
login = self.client.login(username='testclient',password='password')
733
self.assertTrue(login, 'Could not log in')
735
# Session should still contain the modified value
736
response = self.client.get('/test_client_regress/check_session/')
737
self.assertEqual(response.status_code, 200)
738
self.assertEqual(response.content, 'YES')
740
def test_logout(self):
741
"""Logout should work whether the user is logged in or not (#9978)."""
743
login = self.client.login(username='testclient',password='password')
744
self.assertTrue(login, 'Could not log in')
748
class RequestMethodTests(TestCase):
750
"Request a view via request method GET"
751
response = self.client.get('/test_client_regress/request_methods/')
752
self.assertEqual(response.status_code, 200)
753
self.assertEqual(response.content, 'request method: GET')
756
"Request a view via request method POST"
757
response = self.client.post('/test_client_regress/request_methods/')
758
self.assertEqual(response.status_code, 200)
759
self.assertEqual(response.content, 'request method: POST')
762
"Request a view via request method HEAD"
763
response = self.client.head('/test_client_regress/request_methods/')
764
self.assertEqual(response.status_code, 200)
765
# A HEAD request doesn't return any content.
766
self.assertNotEqual(response.content, 'request method: HEAD')
767
self.assertEqual(response.content, '')
769
def test_options(self):
770
"Request a view via request method OPTIONS"
771
response = self.client.options('/test_client_regress/request_methods/')
772
self.assertEqual(response.status_code, 200)
773
self.assertEqual(response.content, 'request method: OPTIONS')
776
"Request a view via request method PUT"
777
response = self.client.put('/test_client_regress/request_methods/')
778
self.assertEqual(response.status_code, 200)
779
self.assertEqual(response.content, 'request method: PUT')
781
def test_delete(self):
782
"Request a view via request method DELETE"
783
response = self.client.delete('/test_client_regress/request_methods/')
784
self.assertEqual(response.status_code, 200)
785
self.assertEqual(response.content, 'request method: DELETE')
787
class RequestMethodStringDataTests(TestCase):
789
"Request a view with string data via request method POST"
790
# Regression test for #11371
791
data = u'{"test": "json"}'
792
response = self.client.post('/test_client_regress/request_methods/', data=data, content_type='application/json')
793
self.assertEqual(response.status_code, 200)
794
self.assertEqual(response.content, 'request method: POST')
797
"Request a view with string data via request method PUT"
798
# Regression test for #11371
799
data = u'{"test": "json"}'
800
response = self.client.put('/test_client_regress/request_methods/', data=data, content_type='application/json')
801
self.assertEqual(response.status_code, 200)
802
self.assertEqual(response.content, 'request method: PUT')
804
class QueryStringTests(TestCase):
805
def test_get_like_requests(self):
806
# See: https://code.djangoproject.com/ticket/10571.
807
# Removed 'put' and 'delete' here as they are 'GET-like requests'
808
for method_name in ('get','head','options'):
809
# A GET-like request can pass a query string as data
810
method = getattr(self.client, method_name)
811
response = method("/test_client_regress/request_data/", data={'foo':'whiz'})
812
self.assertEqual(response.context['get-foo'], 'whiz')
813
self.assertEqual(response.context['request-foo'], 'whiz')
815
# A GET-like request can pass a query string as part of the URL
816
response = method("/test_client_regress/request_data/?foo=whiz")
817
self.assertEqual(response.context['get-foo'], 'whiz')
818
self.assertEqual(response.context['request-foo'], 'whiz')
820
# Data provided in the URL to a GET-like request is overridden by actual form data
821
response = method("/test_client_regress/request_data/?foo=whiz", data={'foo':'bang'})
822
self.assertEqual(response.context['get-foo'], 'bang')
823
self.assertEqual(response.context['request-foo'], 'bang')
825
response = method("/test_client_regress/request_data/?foo=whiz", data={'bar':'bang'})
826
self.assertEqual(response.context['get-foo'], None)
827
self.assertEqual(response.context['get-bar'], 'bang')
828
self.assertEqual(response.context['request-foo'], None)
829
self.assertEqual(response.context['request-bar'], 'bang')
831
def test_post_like_requests(self):
832
# A POST-like request can pass a query string as data
833
response = self.client.post("/test_client_regress/request_data/", data={'foo':'whiz'})
834
self.assertEqual(response.context['get-foo'], None)
835
self.assertEqual(response.context['post-foo'], 'whiz')
837
# A POST-like request can pass a query string as part of the URL
838
response = self.client.post("/test_client_regress/request_data/?foo=whiz")
839
self.assertEqual(response.context['get-foo'], 'whiz')
840
self.assertEqual(response.context['post-foo'], None)
841
self.assertEqual(response.context['request-foo'], 'whiz')
843
# POST data provided in the URL augments actual form data
844
response = self.client.post("/test_client_regress/request_data/?foo=whiz", data={'foo':'bang'})
845
self.assertEqual(response.context['get-foo'], 'whiz')
846
self.assertEqual(response.context['post-foo'], 'bang')
847
self.assertEqual(response.context['request-foo'], 'bang')
849
response = self.client.post("/test_client_regress/request_data/?foo=whiz", data={'bar':'bang'})
850
self.assertEqual(response.context['get-foo'], 'whiz')
851
self.assertEqual(response.context['get-bar'], None)
852
self.assertEqual(response.context['post-foo'], None)
853
self.assertEqual(response.context['post-bar'], 'bang')
854
self.assertEqual(response.context['request-foo'], 'whiz')
855
self.assertEqual(response.context['request-bar'], 'bang')
857
class UnicodePayloadTests(TestCase):
858
def test_simple_unicode_payload(self):
859
"A simple ASCII-only unicode JSON document can be POSTed"
860
# Regression test for #10571
861
json = u'{"english": "mountain pass"}'
862
response = self.client.post("/test_client_regress/parse_unicode_json/", json,
863
content_type="application/json")
864
self.assertEqual(response.content, json)
865
response = self.client.put("/test_client_regress/parse_unicode_json/", json,
866
content_type="application/json")
867
self.assertEqual(response.content, json)
869
def test_unicode_payload_utf8(self):
870
"A non-ASCII unicode data encoded as UTF-8 can be POSTed"
871
# Regression test for #10571
872
json = u'{"dog": "собака"}'
873
response = self.client.post("/test_client_regress/parse_unicode_json/", json,
874
content_type="application/json; charset=utf-8")
875
self.assertEqual(response.content, json.encode('utf-8'))
876
response = self.client.put("/test_client_regress/parse_unicode_json/", json,
877
content_type="application/json; charset=utf-8")
878
self.assertEqual(response.content, json.encode('utf-8'))
880
def test_unicode_payload_utf16(self):
881
"A non-ASCII unicode data encoded as UTF-16 can be POSTed"
882
# Regression test for #10571
883
json = u'{"dog": "собака"}'
884
response = self.client.post("/test_client_regress/parse_unicode_json/", json,
885
content_type="application/json; charset=utf-16")
886
self.assertEqual(response.content, json.encode('utf-16'))
887
response = self.client.put("/test_client_regress/parse_unicode_json/", json,
888
content_type="application/json; charset=utf-16")
889
self.assertEqual(response.content, json.encode('utf-16'))
891
def test_unicode_payload_non_utf(self):
892
"A non-ASCII unicode data as a non-UTF based encoding can be POSTed"
893
#Regression test for #10571
894
json = u'{"dog": "собака"}'
895
response = self.client.post("/test_client_regress/parse_unicode_json/", json,
896
content_type="application/json; charset=koi8-r")
897
self.assertEqual(response.content, json.encode('koi8-r'))
898
response = self.client.put("/test_client_regress/parse_unicode_json/", json,
899
content_type="application/json; charset=koi8-r")
900
self.assertEqual(response.content, json.encode('koi8-r'))
902
class DummyFile(object):
903
def __init__(self, filename):
906
return 'TEST_FILE_CONTENT'
908
class UploadedFileEncodingTest(TestCase):
909
def test_file_encoding(self):
910
encoded_file = encode_file('TEST_BOUNDARY', 'TEST_KEY', DummyFile('test_name.bin'))
911
self.assertEqual('--TEST_BOUNDARY', encoded_file[0])
912
self.assertEqual('Content-Disposition: form-data; name="TEST_KEY"; filename="test_name.bin"', encoded_file[1])
913
self.assertEqual('TEST_FILE_CONTENT', encoded_file[-1])
915
def test_guesses_content_type_on_file_encoding(self):
916
self.assertEqual('Content-Type: application/octet-stream',
917
encode_file('IGNORE', 'IGNORE', DummyFile("file.bin"))[2])
918
self.assertEqual('Content-Type: text/plain',
919
encode_file('IGNORE', 'IGNORE', DummyFile("file.txt"))[2])
920
self.assertIn(encode_file('IGNORE', 'IGNORE', DummyFile("file.zip"))[2], (
921
'Content-Type: application/x-compress',
922
'Content-Type: application/x-zip',
923
'Content-Type: application/x-zip-compressed',
924
'Content-Type: application/zip',))
925
self.assertEqual('Content-Type: application/octet-stream',
926
encode_file('IGNORE', 'IGNORE', DummyFile("file.unknown"))[2])
928
class RequestHeadersTest(TestCase):
929
def test_client_headers(self):
930
"A test client can receive custom headers"
931
response = self.client.get("/test_client_regress/check_headers/", HTTP_X_ARG_CHECK='Testing 123')
932
self.assertEqual(response.content, "HTTP_X_ARG_CHECK: Testing 123")
933
self.assertEqual(response.status_code, 200)
935
def test_client_headers_redirect(self):
936
"Test client headers are preserved through redirects"
937
response = self.client.get("/test_client_regress/check_headers_redirect/", follow=True, HTTP_X_ARG_CHECK='Testing 123')
938
self.assertEqual(response.content, "HTTP_X_ARG_CHECK: Testing 123")
939
self.assertRedirects(response, '/test_client_regress/check_headers/',
940
status_code=301, target_status_code=200)
942
class ResponseTemplateDeprecationTests(TestCase):
944
Response.template still works backwards-compatibly, but with pending deprecation warning. Refs #12226.
948
self.save_warnings_state()
949
warnings.filterwarnings('ignore', category=DeprecationWarning)
952
self.restore_warnings_state()
954
def test_response_template_data(self):
955
response = self.client.get("/test_client_regress/request_data/", data={'foo':'whiz'})
956
self.assertEqual(response.template.__class__, Template)
957
self.assertEqual(response.template.name, 'base.html')
959
def test_response_no_template(self):
960
response = self.client.get("/test_client_regress/request_methods/")
961
self.assertEqual(response.template, None)
964
class ReadLimitedStreamTest(TestCase):
966
Tests that ensure that HttpRequest.body, HttpRequest.read() and
967
HttpRequest.read(BUFFER) have proper LimitedStream behavior.
972
def test_body_from_empty_request(self):
973
"""HttpRequest.body on a test client GET request should return
975
self.assertEquals(self.client.get("/test_client_regress/body/").content, '')
977
def test_read_from_empty_request(self):
978
"""HttpRequest.read() on a test client GET request should return the
980
self.assertEquals(self.client.get("/test_client_regress/read_all/").content, '')
982
def test_read_numbytes_from_empty_request(self):
983
"""HttpRequest.read(LARGE_BUFFER) on a test client GET request should
984
return the empty string."""
985
self.assertEquals(self.client.get("/test_client_regress/read_buffer/").content, '')
987
def test_read_from_nonempty_request(self):
988
"""HttpRequest.read() on a test client PUT request with some payload
989
should return that payload."""
991
self.assertEquals(self.client.put("/test_client_regress/read_all/",
993
content_type='text/plain').content, payload)
995
def test_read_numbytes_from_nonempty_request(self):
996
"""HttpRequest.read(LARGE_BUFFER) on a test client PUT request with
997
some payload should return that payload."""
999
self.assertEquals(self.client.put("/test_client_regress/read_buffer/",
1001
content_type='text/plain').content, payload)
1004
class RequestFactoryStateTest(TestCase):
1005
"""Regression tests for #15929."""
1006
# These tests are checking that certain middleware don't change certain
1007
# global state. Alternatively, from the point of view of a test, they are
1008
# ensuring test isolation behavior. So, unusually, it doesn't make sense to
1009
# run the tests individually, and if any are failing it is confusing to run
1010
# them with any other set of tests.
1013
self.factory = RequestFactory()
1015
def common_test_that_should_always_pass(self):
1016
request = self.factory.get('/')
1017
request.session = {}
1018
self.assertFalse(hasattr(request, 'user'))
1020
def test_request(self):
1021
self.common_test_that_should_always_pass()
1023
def test_request_after_client(self):
1024
# apart from the next line the three tests are identical
1025
self.client.get('/')
1026
self.common_test_that_should_always_pass()
1028
def test_request_after_client_2(self):
1029
# This test is executed after the previous one
1030
self.common_test_that_should_always_pass()
1033
class RequestFactoryEnvironmentTests(TestCase):
1035
Regression tests for #8551 and #17067: ensure that environment variables
1036
are set correctly in RequestFactory.
1040
self.factory = RequestFactory()
1042
def test_should_set_correct_env_variables(self):
1043
request = self.factory.get('/path/')
1045
self.assertEqual(request.META.get('REMOTE_ADDR'), '127.0.0.1')
1046
self.assertEqual(request.META.get('SERVER_NAME'), 'testserver')
1047
self.assertEqual(request.META.get('SERVER_PORT'), '80')
1048
self.assertEqual(request.META.get('SERVER_PROTOCOL'), 'HTTP/1.1')
1049
self.assertEqual(request.META.get('SCRIPT_NAME') +
1050
request.META.get('PATH_INFO'), '/path/')