1. """
    
  2. Regression tests for the Test Client, especially the customized assertions.
    
  3. """
    
  4. import itertools
    
  5. import os
    
  6. 
    
  7. from django.contrib.auth.models import User
    
  8. from django.contrib.auth.signals import user_logged_in, user_logged_out
    
  9. from django.http import HttpResponse
    
  10. from django.template import Context, RequestContext, TemplateSyntaxError, engines
    
  11. from django.template.response import SimpleTemplateResponse
    
  12. from django.test import (
    
  13.     Client,
    
  14.     SimpleTestCase,
    
  15.     TestCase,
    
  16.     modify_settings,
    
  17.     override_settings,
    
  18. )
    
  19. from django.test.client import RedirectCycleError, RequestFactory, encode_file
    
  20. from django.test.utils import ContextList
    
  21. from django.urls import NoReverseMatch, reverse
    
  22. from django.utils.translation import gettext_lazy
    
  23. 
    
  24. from .models import CustomUser
    
  25. from .views import CustomTestException
    
  26. 
    
  27. 
    
  28. class TestDataMixin:
    
  29.     @classmethod
    
  30.     def setUpTestData(cls):
    
  31.         cls.u1 = User.objects.create_user(username="testclient", password="password")
    
  32.         cls.staff = User.objects.create_user(
    
  33.             username="staff", password="password", is_staff=True
    
  34.         )
    
  35. 
    
  36. 
    
  37. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  38. class AssertContainsTests(SimpleTestCase):
    
  39.     def test_contains(self):
    
  40.         "Responses can be inspected for content, including counting repeated substrings"
    
  41.         response = self.client.get("/no_template_view/")
    
  42. 
    
  43.         self.assertNotContains(response, "never")
    
  44.         self.assertContains(response, "never", 0)
    
  45.         self.assertContains(response, "once")
    
  46.         self.assertContains(response, "once", 1)
    
  47.         self.assertContains(response, "twice")
    
  48.         self.assertContains(response, "twice", 2)
    
  49. 
    
  50.         try:
    
  51.             self.assertContains(response, "text", status_code=999)
    
  52.         except AssertionError as e:
    
  53.             self.assertIn(
    
  54.                 "Couldn't retrieve content: Response code was 200 (expected 999)",
    
  55.                 str(e),
    
  56.             )
    
  57.         try:
    
  58.             self.assertContains(response, "text", status_code=999, msg_prefix="abc")
    
  59.         except AssertionError as e:
    
  60.             self.assertIn(
    
  61.                 "abc: Couldn't retrieve content: Response code was 200 (expected 999)",
    
  62.                 str(e),
    
  63.             )
    
  64. 
    
  65.         try:
    
  66.             self.assertNotContains(response, "text", status_code=999)
    
  67.         except AssertionError as e:
    
  68.             self.assertIn(
    
  69.                 "Couldn't retrieve content: Response code was 200 (expected 999)",
    
  70.                 str(e),
    
  71.             )
    
  72.         try:
    
  73.             self.assertNotContains(response, "text", status_code=999, msg_prefix="abc")
    
  74.         except AssertionError as e:
    
  75.             self.assertIn(
    
  76.                 "abc: Couldn't retrieve content: Response code was 200 (expected 999)",
    
  77.                 str(e),
    
  78.             )
    
  79. 
    
  80.         try:
    
  81.             self.assertNotContains(response, "once")
    
  82.         except AssertionError as e:
    
  83.             self.assertIn("Response should not contain 'once'", str(e))
    
  84.         try:
    
  85.             self.assertNotContains(response, "once", msg_prefix="abc")
    
  86.         except AssertionError as e:
    
  87.             self.assertIn("abc: Response should not contain 'once'", str(e))
    
  88. 
    
  89.         try:
    
  90.             self.assertContains(response, "never", 1)
    
  91.         except AssertionError as e:
    
  92.             self.assertIn(
    
  93.                 "Found 0 instances of 'never' in response (expected 1)", str(e)
    
  94.             )
    
  95.         try:
    
  96.             self.assertContains(response, "never", 1, msg_prefix="abc")
    
  97.         except AssertionError as e:
    
  98.             self.assertIn(
    
  99.                 "abc: Found 0 instances of 'never' in response (expected 1)", str(e)
    
  100.             )
    
  101. 
    
  102.         try:
    
  103.             self.assertContains(response, "once", 0)
    
  104.         except AssertionError as e:
    
  105.             self.assertIn(
    
  106.                 "Found 1 instances of 'once' in response (expected 0)", str(e)
    
  107.             )
    
  108.         try:
    
  109.             self.assertContains(response, "once", 0, msg_prefix="abc")
    
  110.         except AssertionError as e:
    
  111.             self.assertIn(
    
  112.                 "abc: Found 1 instances of 'once' in response (expected 0)", str(e)
    
  113.             )
    
  114. 
    
  115.         try:
    
  116.             self.assertContains(response, "once", 2)
    
  117.         except AssertionError as e:
    
  118.             self.assertIn(
    
  119.                 "Found 1 instances of 'once' in response (expected 2)", str(e)
    
  120.             )
    
  121.         try:
    
  122.             self.assertContains(response, "once", 2, msg_prefix="abc")
    
  123.         except AssertionError as e:
    
  124.             self.assertIn(
    
  125.                 "abc: Found 1 instances of 'once' in response (expected 2)", str(e)
    
  126.             )
    
  127. 
    
  128.         try:
    
  129.             self.assertContains(response, "twice", 1)
    
  130.         except AssertionError as e:
    
  131.             self.assertIn(
    
  132.                 "Found 2 instances of 'twice' in response (expected 1)", str(e)
    
  133.             )
    
  134.         try:
    
  135.             self.assertContains(response, "twice", 1, msg_prefix="abc")
    
  136.         except AssertionError as e:
    
  137.             self.assertIn(
    
  138.                 "abc: Found 2 instances of 'twice' in response (expected 1)", str(e)
    
  139.             )
    
  140. 
    
  141.         try:
    
  142.             self.assertContains(response, "thrice")
    
  143.         except AssertionError as e:
    
  144.             self.assertIn("Couldn't find 'thrice' in response", str(e))
    
  145.         try:
    
  146.             self.assertContains(response, "thrice", msg_prefix="abc")
    
  147.         except AssertionError as e:
    
  148.             self.assertIn("abc: Couldn't find 'thrice' in response", str(e))
    
  149. 
    
  150.         try:
    
  151.             self.assertContains(response, "thrice", 3)
    
  152.         except AssertionError as e:
    
  153.             self.assertIn(
    
  154.                 "Found 0 instances of 'thrice' in response (expected 3)", str(e)
    
  155.             )
    
  156.         try:
    
  157.             self.assertContains(response, "thrice", 3, msg_prefix="abc")
    
  158.         except AssertionError as e:
    
  159.             self.assertIn(
    
  160.                 "abc: Found 0 instances of 'thrice' in response (expected 3)", str(e)
    
  161.             )
    
  162. 
    
  163.     def test_unicode_contains(self):
    
  164.         "Unicode characters can be found in template context"
    
  165.         # Regression test for #10183
    
  166.         r = self.client.get("/check_unicode/")
    
  167.         self.assertContains(r, "さかき")
    
  168.         self.assertContains(r, b"\xe5\xb3\xa0".decode())
    
  169. 
    
  170.     def test_unicode_not_contains(self):
    
  171.         "Unicode characters can be searched for, and not found in template context"
    
  172.         # Regression test for #10183
    
  173.         r = self.client.get("/check_unicode/")
    
  174.         self.assertNotContains(r, "はたけ")
    
  175.         self.assertNotContains(r, b"\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91".decode())
    
  176. 
    
  177.     def test_binary_contains(self):
    
  178.         r = self.client.get("/check_binary/")
    
  179.         self.assertContains(r, b"%PDF-1.4\r\n%\x93\x8c\x8b\x9e")
    
  180.         with self.assertRaises(AssertionError):
    
  181.             self.assertContains(r, b"%PDF-1.4\r\n%\x93\x8c\x8b\x9e", count=2)
    
  182. 
    
  183.     def test_binary_not_contains(self):
    
  184.         r = self.client.get("/check_binary/")
    
  185.         self.assertNotContains(r, b"%ODF-1.4\r\n%\x93\x8c\x8b\x9e")
    
  186.         with self.assertRaises(AssertionError):
    
  187.             self.assertNotContains(r, b"%PDF-1.4\r\n%\x93\x8c\x8b\x9e")
    
  188. 
    
  189.     def test_nontext_contains(self):
    
  190.         r = self.client.get("/no_template_view/")
    
  191.         self.assertContains(r, gettext_lazy("once"))
    
  192. 
    
  193.     def test_nontext_not_contains(self):
    
  194.         r = self.client.get("/no_template_view/")
    
  195.         self.assertNotContains(r, gettext_lazy("never"))
    
  196. 
    
  197.     def test_assert_contains_renders_template_response(self):
    
  198.         """
    
  199.         An unrendered SimpleTemplateResponse may be used in assertContains().
    
  200.         """
    
  201.         template = engines["django"].from_string("Hello")
    
  202.         response = SimpleTemplateResponse(template)
    
  203.         self.assertContains(response, "Hello")
    
  204. 
    
  205.     def test_assert_contains_using_non_template_response(self):
    
  206.         """auto-rendering does not affect responses that aren't
    
  207.         instances (or subclasses) of SimpleTemplateResponse.
    
  208.         Refs #15826.
    
  209.         """
    
  210.         response = HttpResponse("Hello")
    
  211.         self.assertContains(response, "Hello")
    
  212. 
    
  213.     def test_assert_not_contains_renders_template_response(self):
    
  214.         """
    
  215.         An unrendered SimpleTemplateResponse may be used in assertNotContains().
    
  216.         """
    
  217.         template = engines["django"].from_string("Hello")
    
  218.         response = SimpleTemplateResponse(template)
    
  219.         self.assertNotContains(response, "Bye")
    
  220. 
    
  221.     def test_assert_not_contains_using_non_template_response(self):
    
  222.         """
    
  223.         auto-rendering does not affect responses that aren't instances (or
    
  224.         subclasses) of SimpleTemplateResponse.
    
  225.         """
    
  226.         response = HttpResponse("Hello")
    
  227.         self.assertNotContains(response, "Bye")
    
  228. 
    
  229. 
    
  230. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  231. class AssertTemplateUsedTests(TestDataMixin, TestCase):
    
  232.     def test_no_context(self):
    
  233.         "Template usage assertions work then templates aren't in use"
    
  234.         response = self.client.get("/no_template_view/")
    
  235. 
    
  236.         # The no template case doesn't mess with the template assertions
    
  237.         self.assertTemplateNotUsed(response, "GET Template")
    
  238. 
    
  239.         try:
    
  240.             self.assertTemplateUsed(response, "GET Template")
    
  241.         except AssertionError as e:
    
  242.             self.assertIn("No templates used to render the response", str(e))
    
  243. 
    
  244.         try:
    
  245.             self.assertTemplateUsed(response, "GET Template", msg_prefix="abc")
    
  246.         except AssertionError as e:
    
  247.             self.assertIn("abc: No templates used to render the response", str(e))
    
  248. 
    
  249.         msg = "No templates used to render the response"
    
  250.         with self.assertRaisesMessage(AssertionError, msg):
    
  251.             self.assertTemplateUsed(response, "GET Template", count=2)
    
  252. 
    
  253.     def test_single_context(self):
    
  254.         "Template assertions work when there is a single context"
    
  255.         response = self.client.get("/post_view/", {})
    
  256.         msg = (
    
  257.             ": Template 'Empty GET Template' was used unexpectedly in "
    
  258.             "rendering the response"
    
  259.         )
    
  260.         with self.assertRaisesMessage(AssertionError, msg):
    
  261.             self.assertTemplateNotUsed(response, "Empty GET Template")
    
  262.         with self.assertRaisesMessage(AssertionError, "abc" + msg):
    
  263.             self.assertTemplateNotUsed(response, "Empty GET Template", msg_prefix="abc")
    
  264.         msg = (
    
  265.             ": Template 'Empty POST Template' was not a template used to "
    
  266.             "render the response. Actual template(s) used: Empty GET Template"
    
  267.         )
    
  268.         with self.assertRaisesMessage(AssertionError, msg):
    
  269.             self.assertTemplateUsed(response, "Empty POST Template")
    
  270.         with self.assertRaisesMessage(AssertionError, "abc" + msg):
    
  271.             self.assertTemplateUsed(response, "Empty POST Template", msg_prefix="abc")
    
  272.         msg = (
    
  273.             ": Template 'Empty GET Template' was expected to be rendered 2 "
    
  274.             "time(s) but was actually rendered 1 time(s)."
    
  275.         )
    
  276.         with self.assertRaisesMessage(AssertionError, msg):
    
  277.             self.assertTemplateUsed(response, "Empty GET Template", count=2)
    
  278.         with self.assertRaisesMessage(AssertionError, "abc" + msg):
    
  279.             self.assertTemplateUsed(
    
  280.                 response, "Empty GET Template", msg_prefix="abc", count=2
    
  281.             )
    
  282. 
    
  283.     def test_multiple_context(self):
    
  284.         "Template assertions work when there are multiple contexts"
    
  285.         post_data = {
    
  286.             "text": "Hello World",
    
  287.             "email": "[email protected]",
    
  288.             "value": 37,
    
  289.             "single": "b",
    
  290.             "multi": ("b", "c", "e"),
    
  291.         }
    
  292.         response = self.client.post("/form_view_with_template/", post_data)
    
  293.         self.assertContains(response, "POST data OK")
    
  294.         msg = "Template '%s' was used unexpectedly in rendering the response"
    
  295.         with self.assertRaisesMessage(AssertionError, msg % "form_view.html"):
    
  296.             self.assertTemplateNotUsed(response, "form_view.html")
    
  297.         with self.assertRaisesMessage(AssertionError, msg % "base.html"):
    
  298.             self.assertTemplateNotUsed(response, "base.html")
    
  299.         msg = (
    
  300.             "Template 'Valid POST Template' was not a template used to render "
    
  301.             "the response. Actual template(s) used: form_view.html, base.html"
    
  302.         )
    
  303.         with self.assertRaisesMessage(AssertionError, msg):
    
  304.             self.assertTemplateUsed(response, "Valid POST Template")
    
  305.         msg = (
    
  306.             "Template 'base.html' was expected to be rendered 2 time(s) but "
    
  307.             "was actually rendered 1 time(s)."
    
  308.         )
    
  309.         with self.assertRaisesMessage(AssertionError, msg):
    
  310.             self.assertTemplateUsed(response, "base.html", count=2)
    
  311. 
    
  312.     def test_template_rendered_multiple_times(self):
    
  313.         """Template assertions work when a template is rendered multiple times."""
    
  314.         response = self.client.get("/render_template_multiple_times/")
    
  315. 
    
  316.         self.assertTemplateUsed(response, "base.html", count=2)
    
  317. 
    
  318. 
    
  319. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  320. class AssertRedirectsTests(SimpleTestCase):
    
  321.     def test_redirect_page(self):
    
  322.         "An assertion is raised if the original page couldn't be retrieved as expected"
    
  323.         # This page will redirect with code 301, not 302
    
  324.         response = self.client.get("/permanent_redirect_view/")
    
  325.         try:
    
  326.             self.assertRedirects(response, "/get_view/")
    
  327.         except AssertionError as e:
    
  328.             self.assertIn(
    
  329.                 "Response didn't redirect as expected: Response code was 301 "
    
  330.                 "(expected 302)",
    
  331.                 str(e),
    
  332.             )
    
  333. 
    
  334.         try:
    
  335.             self.assertRedirects(response, "/get_view/", msg_prefix="abc")
    
  336.         except AssertionError as e:
    
  337.             self.assertIn(
    
  338.                 "abc: Response didn't redirect as expected: Response code was 301 "
    
  339.                 "(expected 302)",
    
  340.                 str(e),
    
  341.             )
    
  342. 
    
  343.     def test_lost_query(self):
    
  344.         """
    
  345.         An assertion is raised if the redirect location doesn't preserve GET
    
  346.         parameters.
    
  347.         """
    
  348.         response = self.client.get("/redirect_view/", {"var": "value"})
    
  349.         try:
    
  350.             self.assertRedirects(response, "/get_view/")
    
  351.         except AssertionError as e:
    
  352.             self.assertIn(
    
  353.                 "Response redirected to '/get_view/?var=value', expected '/get_view/'",
    
  354.                 str(e),
    
  355.             )
    
  356. 
    
  357.         try:
    
  358.             self.assertRedirects(response, "/get_view/", msg_prefix="abc")
    
  359.         except AssertionError as e:
    
  360.             self.assertIn(
    
  361.                 "abc: Response redirected to '/get_view/?var=value', expected "
    
  362.                 "'/get_view/'",
    
  363.                 str(e),
    
  364.             )
    
  365. 
    
  366.     def test_incorrect_target(self):
    
  367.         "An assertion is raised if the response redirects to another target"
    
  368.         response = self.client.get("/permanent_redirect_view/")
    
  369.         try:
    
  370.             # Should redirect to get_view
    
  371.             self.assertRedirects(response, "/some_view/")
    
  372.         except AssertionError as e:
    
  373.             self.assertIn(
    
  374.                 "Response didn't redirect as expected: Response code was 301 "
    
  375.                 "(expected 302)",
    
  376.                 str(e),
    
  377.             )
    
  378. 
    
  379.     def test_target_page(self):
    
  380.         """
    
  381.         An assertion is raised if the response redirect target cannot be
    
  382.         retrieved as expected.
    
  383.         """
    
  384.         response = self.client.get("/double_redirect_view/")
    
  385.         try:
    
  386.             # The redirect target responds with a 301 code, not 200
    
  387.             self.assertRedirects(response, "http://testserver/permanent_redirect_view/")
    
  388.         except AssertionError as e:
    
  389.             self.assertIn(
    
  390.                 "Couldn't retrieve redirection page '/permanent_redirect_view/': "
    
  391.                 "response code was 301 (expected 200)",
    
  392.                 str(e),
    
  393.             )
    
  394. 
    
  395.         try:
    
  396.             # The redirect target responds with a 301 code, not 200
    
  397.             self.assertRedirects(
    
  398.                 response, "http://testserver/permanent_redirect_view/", msg_prefix="abc"
    
  399.             )
    
  400.         except AssertionError as e:
    
  401.             self.assertIn(
    
  402.                 "abc: Couldn't retrieve redirection page '/permanent_redirect_view/': "
    
  403.                 "response code was 301 (expected 200)",
    
  404.                 str(e),
    
  405.             )
    
  406. 
    
  407.     def test_redirect_chain(self):
    
  408.         "You can follow a redirect chain of multiple redirects"
    
  409.         response = self.client.get("/redirects/further/more/", {}, follow=True)
    
  410.         self.assertRedirects(
    
  411.             response, "/no_template_view/", status_code=302, target_status_code=200
    
  412.         )
    
  413. 
    
  414.         self.assertEqual(len(response.redirect_chain), 1)
    
  415.         self.assertEqual(response.redirect_chain[0], ("/no_template_view/", 302))
    
  416. 
    
  417.     def test_multiple_redirect_chain(self):
    
  418.         "You can follow a redirect chain of multiple redirects"
    
  419.         response = self.client.get("/redirects/", {}, follow=True)
    
  420.         self.assertRedirects(
    
  421.             response, "/no_template_view/", status_code=302, target_status_code=200
    
  422.         )
    
  423. 
    
  424.         self.assertEqual(len(response.redirect_chain), 3)
    
  425.         self.assertEqual(response.redirect_chain[0], ("/redirects/further/", 302))
    
  426.         self.assertEqual(response.redirect_chain[1], ("/redirects/further/more/", 302))
    
  427.         self.assertEqual(response.redirect_chain[2], ("/no_template_view/", 302))
    
  428. 
    
  429.     def test_redirect_chain_to_non_existent(self):
    
  430.         "You can follow a chain to a nonexistent view."
    
  431.         response = self.client.get("/redirect_to_non_existent_view2/", {}, follow=True)
    
  432.         self.assertRedirects(
    
  433.             response, "/non_existent_view/", status_code=302, target_status_code=404
    
  434.         )
    
  435. 
    
  436.     def test_redirect_chain_to_self(self):
    
  437.         "Redirections to self are caught and escaped"
    
  438.         with self.assertRaises(RedirectCycleError) as context:
    
  439.             self.client.get("/redirect_to_self/", {}, follow=True)
    
  440.         response = context.exception.last_response
    
  441.         # The chain of redirects stops once the cycle is detected.
    
  442.         self.assertRedirects(
    
  443.             response, "/redirect_to_self/", status_code=302, target_status_code=302
    
  444.         )
    
  445.         self.assertEqual(len(response.redirect_chain), 2)
    
  446. 
    
  447.     def test_redirect_to_self_with_changing_query(self):
    
  448.         "Redirections don't loop forever even if query is changing"
    
  449.         with self.assertRaises(RedirectCycleError):
    
  450.             self.client.get(
    
  451.                 "/redirect_to_self_with_changing_query_view/",
    
  452.                 {"counter": "0"},
    
  453.                 follow=True,
    
  454.             )
    
  455. 
    
  456.     def test_circular_redirect(self):
    
  457.         "Circular redirect chains are caught and escaped"
    
  458.         with self.assertRaises(RedirectCycleError) as context:
    
  459.             self.client.get("/circular_redirect_1/", {}, follow=True)
    
  460.         response = context.exception.last_response
    
  461.         # The chain of redirects will get back to the starting point, but stop there.
    
  462.         self.assertRedirects(
    
  463.             response, "/circular_redirect_2/", status_code=302, target_status_code=302
    
  464.         )
    
  465.         self.assertEqual(len(response.redirect_chain), 4)
    
  466. 
    
  467.     def test_redirect_chain_post(self):
    
  468.         "A redirect chain will be followed from an initial POST post"
    
  469.         response = self.client.post("/redirects/", {"nothing": "to_send"}, follow=True)
    
  470.         self.assertRedirects(response, "/no_template_view/", 302, 200)
    
  471.         self.assertEqual(len(response.redirect_chain), 3)
    
  472. 
    
  473.     def test_redirect_chain_head(self):
    
  474.         "A redirect chain will be followed from an initial HEAD request"
    
  475.         response = self.client.head("/redirects/", {"nothing": "to_send"}, follow=True)
    
  476.         self.assertRedirects(response, "/no_template_view/", 302, 200)
    
  477.         self.assertEqual(len(response.redirect_chain), 3)
    
  478. 
    
  479.     def test_redirect_chain_options(self):
    
  480.         "A redirect chain will be followed from an initial OPTIONS request"
    
  481.         response = self.client.options("/redirects/", follow=True)
    
  482.         self.assertRedirects(response, "/no_template_view/", 302, 200)
    
  483.         self.assertEqual(len(response.redirect_chain), 3)
    
  484. 
    
  485.     def test_redirect_chain_put(self):
    
  486.         "A redirect chain will be followed from an initial PUT request"
    
  487.         response = self.client.put("/redirects/", follow=True)
    
  488.         self.assertRedirects(response, "/no_template_view/", 302, 200)
    
  489.         self.assertEqual(len(response.redirect_chain), 3)
    
  490. 
    
  491.     def test_redirect_chain_delete(self):
    
  492.         "A redirect chain will be followed from an initial DELETE request"
    
  493.         response = self.client.delete("/redirects/", follow=True)
    
  494.         self.assertRedirects(response, "/no_template_view/", 302, 200)
    
  495.         self.assertEqual(len(response.redirect_chain), 3)
    
  496. 
    
  497.     @modify_settings(ALLOWED_HOSTS={"append": "otherserver"})
    
  498.     def test_redirect_to_different_host(self):
    
  499.         "The test client will preserve scheme, host and port changes"
    
  500.         response = self.client.get("/redirect_other_host/", follow=True)
    
  501.         self.assertRedirects(
    
  502.             response,
    
  503.             "https://otherserver:8443/no_template_view/",
    
  504.             status_code=302,
    
  505.             target_status_code=200,
    
  506.         )
    
  507.         # We can't use is_secure() or get_host()
    
  508.         # because response.request is a dictionary, not an HttpRequest
    
  509.         self.assertEqual(response.request.get("wsgi.url_scheme"), "https")
    
  510.         self.assertEqual(response.request.get("SERVER_NAME"), "otherserver")
    
  511.         self.assertEqual(response.request.get("SERVER_PORT"), "8443")
    
  512.         # assertRedirects() can follow redirect to 'otherserver' too.
    
  513.         response = self.client.get("/redirect_other_host/", follow=False)
    
  514.         self.assertRedirects(
    
  515.             response,
    
  516.             "https://otherserver:8443/no_template_view/",
    
  517.             status_code=302,
    
  518.             target_status_code=200,
    
  519.         )
    
  520. 
    
  521.     def test_redirect_chain_on_non_redirect_page(self):
    
  522.         """
    
  523.         An assertion is raised if the original page couldn't be retrieved as
    
  524.         expected.
    
  525.         """
    
  526.         # This page will redirect with code 301, not 302
    
  527.         response = self.client.get("/get_view/", follow=True)
    
  528.         try:
    
  529.             self.assertRedirects(response, "/get_view/")
    
  530.         except AssertionError as e:
    
  531.             self.assertIn(
    
  532.                 "Response didn't redirect as expected: Response code was 200 "
    
  533.                 "(expected 302)",
    
  534.                 str(e),
    
  535.             )
    
  536. 
    
  537.         try:
    
  538.             self.assertRedirects(response, "/get_view/", msg_prefix="abc")
    
  539.         except AssertionError as e:
    
  540.             self.assertIn(
    
  541.                 "abc: Response didn't redirect as expected: Response code was 200 "
    
  542.                 "(expected 302)",
    
  543.                 str(e),
    
  544.             )
    
  545. 
    
  546.     def test_redirect_on_non_redirect_page(self):
    
  547.         "An assertion is raised if the original page couldn't be retrieved as expected"
    
  548.         # This page will redirect with code 301, not 302
    
  549.         response = self.client.get("/get_view/")
    
  550.         try:
    
  551.             self.assertRedirects(response, "/get_view/")
    
  552.         except AssertionError as e:
    
  553.             self.assertIn(
    
  554.                 "Response didn't redirect as expected: Response code was 200 "
    
  555.                 "(expected 302)",
    
  556.                 str(e),
    
  557.             )
    
  558. 
    
  559.         try:
    
  560.             self.assertRedirects(response, "/get_view/", msg_prefix="abc")
    
  561.         except AssertionError as e:
    
  562.             self.assertIn(
    
  563.                 "abc: Response didn't redirect as expected: Response code was 200 "
    
  564.                 "(expected 302)",
    
  565.                 str(e),
    
  566.             )
    
  567. 
    
  568.     def test_redirect_scheme(self):
    
  569.         """
    
  570.         An assertion is raised if the response doesn't have the scheme
    
  571.         specified in expected_url.
    
  572.         """
    
  573. 
    
  574.         # For all possible True/False combinations of follow and secure
    
  575.         for follow, secure in itertools.product([True, False], repeat=2):
    
  576.             # always redirects to https
    
  577.             response = self.client.get(
    
  578.                 "/https_redirect_view/", follow=follow, secure=secure
    
  579.             )
    
  580.             # the goal scheme is https
    
  581.             self.assertRedirects(
    
  582.                 response, "https://testserver/secure_view/", status_code=302
    
  583.             )
    
  584.             with self.assertRaises(AssertionError):
    
  585.                 self.assertRedirects(
    
  586.                     response, "http://testserver/secure_view/", status_code=302
    
  587.                 )
    
  588. 
    
  589.     def test_redirect_fetch_redirect_response(self):
    
  590.         """Preserve extra headers of requests made with django.test.Client."""
    
  591.         methods = (
    
  592.             "get",
    
  593.             "post",
    
  594.             "head",
    
  595.             "options",
    
  596.             "put",
    
  597.             "patch",
    
  598.             "delete",
    
  599.             "trace",
    
  600.         )
    
  601.         for method in methods:
    
  602.             with self.subTest(method=method):
    
  603.                 req_method = getattr(self.client, method)
    
  604.                 response = req_method(
    
  605.                     "/redirect_based_on_extra_headers_1/",
    
  606.                     follow=False,
    
  607.                     HTTP_REDIRECT="val",
    
  608.                 )
    
  609.                 self.assertRedirects(
    
  610.                     response,
    
  611.                     "/redirect_based_on_extra_headers_2/",
    
  612.                     fetch_redirect_response=True,
    
  613.                     status_code=302,
    
  614.                     target_status_code=302,
    
  615.                 )
    
  616. 
    
  617. 
    
  618. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  619. class LoginTests(TestDataMixin, TestCase):
    
  620.     def test_login_different_client(self):
    
  621.         "Using a different test client doesn't violate authentication"
    
  622. 
    
  623.         # Create a second client, and log in.
    
  624.         c = Client()
    
  625.         login = c.login(username="testclient", password="password")
    
  626.         self.assertTrue(login, "Could not log in")
    
  627. 
    
  628.         # Get a redirection page with the second client.
    
  629.         response = c.get("/login_protected_redirect_view/")
    
  630. 
    
  631.         # At this points, the self.client isn't logged in.
    
  632.         # assertRedirects uses the original client, not the default client.
    
  633.         self.assertRedirects(response, "/get_view/")
    
  634. 
    
  635. 
    
  636. @override_settings(
    
  637.     SESSION_ENGINE="test_client_regress.session",
    
  638.     ROOT_URLCONF="test_client_regress.urls",
    
  639. )
    
  640. class SessionEngineTests(TestDataMixin, TestCase):
    
  641.     def test_login(self):
    
  642.         "A session engine that modifies the session key can be used to log in"
    
  643.         login = self.client.login(username="testclient", password="password")
    
  644.         self.assertTrue(login, "Could not log in")
    
  645. 
    
  646.         # Try to access a login protected page.
    
  647.         response = self.client.get("/login_protected_view/")
    
  648.         self.assertEqual(response.status_code, 200)
    
  649.         self.assertEqual(response.context["user"].username, "testclient")
    
  650. 
    
  651. 
    
  652. @override_settings(
    
  653.     ROOT_URLCONF="test_client_regress.urls",
    
  654. )
    
  655. class URLEscapingTests(SimpleTestCase):
    
  656.     def test_simple_argument_get(self):
    
  657.         "Get a view that has a simple string argument"
    
  658.         response = self.client.get(reverse("arg_view", args=["Slartibartfast"]))
    
  659.         self.assertEqual(response.status_code, 200)
    
  660.         self.assertEqual(response.content, b"Howdy, Slartibartfast")
    
  661. 
    
  662.     def test_argument_with_space_get(self):
    
  663.         "Get a view that has a string argument that requires escaping"
    
  664.         response = self.client.get(reverse("arg_view", args=["Arthur Dent"]))
    
  665.         self.assertEqual(response.status_code, 200)
    
  666.         self.assertEqual(response.content, b"Hi, Arthur")
    
  667. 
    
  668.     def test_simple_argument_post(self):
    
  669.         "Post for a view that has a simple string argument"
    
  670.         response = self.client.post(reverse("arg_view", args=["Slartibartfast"]))
    
  671.         self.assertEqual(response.status_code, 200)
    
  672.         self.assertEqual(response.content, b"Howdy, Slartibartfast")
    
  673. 
    
  674.     def test_argument_with_space_post(self):
    
  675.         "Post for a view that has a string argument that requires escaping"
    
  676.         response = self.client.post(reverse("arg_view", args=["Arthur Dent"]))
    
  677.         self.assertEqual(response.status_code, 200)
    
  678.         self.assertEqual(response.content, b"Hi, Arthur")
    
  679. 
    
  680. 
    
  681. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  682. class ExceptionTests(TestDataMixin, TestCase):
    
  683.     def test_exception_cleared(self):
    
  684.         "#5836 - A stale user exception isn't re-raised by the test client."
    
  685. 
    
  686.         login = self.client.login(username="testclient", password="password")
    
  687.         self.assertTrue(login, "Could not log in")
    
  688.         with self.assertRaises(CustomTestException):
    
  689.             self.client.get("/staff_only/")
    
  690. 
    
  691.         # At this point, an exception has been raised, and should be cleared.
    
  692. 
    
  693.         # This next operation should be successful; if it isn't we have a problem.
    
  694.         login = self.client.login(username="staff", password="password")
    
  695.         self.assertTrue(login, "Could not log in")
    
  696.         self.client.get("/staff_only/")
    
  697. 
    
  698. 
    
  699. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  700. class TemplateExceptionTests(SimpleTestCase):
    
  701.     @override_settings(
    
  702.         TEMPLATES=[
    
  703.             {
    
  704.                 "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  705.                 "DIRS": [os.path.join(os.path.dirname(__file__), "bad_templates")],
    
  706.             }
    
  707.         ]
    
  708.     )
    
  709.     def test_bad_404_template(self):
    
  710.         "Errors found when rendering 404 error templates are re-raised"
    
  711.         with self.assertRaises(TemplateSyntaxError):
    
  712.             self.client.get("/no_such_view/")
    
  713. 
    
  714. 
    
  715. # We need two different tests to check URLconf substitution -  one to check
    
  716. # it was changed, and another one (without self.urls) to check it was reverted on
    
  717. # teardown. This pair of tests relies upon the alphabetical ordering of test execution.
    
  718. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  719. class UrlconfSubstitutionTests(SimpleTestCase):
    
  720.     def test_urlconf_was_changed(self):
    
  721.         "TestCase can enforce a custom URLconf on a per-test basis"
    
  722.         url = reverse("arg_view", args=["somename"])
    
  723.         self.assertEqual(url, "/arg_view/somename/")
    
  724. 
    
  725. 
    
  726. # This test needs to run *after* UrlconfSubstitutionTests; the zz prefix in the
    
  727. # name is to ensure alphabetical ordering.
    
  728. class zzUrlconfSubstitutionTests(SimpleTestCase):
    
  729.     def test_urlconf_was_reverted(self):
    
  730.         """URLconf is reverted to original value after modification in a TestCase
    
  731. 
    
  732.         This will not find a match as the default ROOT_URLCONF is empty.
    
  733.         """
    
  734.         with self.assertRaises(NoReverseMatch):
    
  735.             reverse("arg_view", args=["somename"])
    
  736. 
    
  737. 
    
  738. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  739. class ContextTests(TestDataMixin, TestCase):
    
  740.     def test_single_context(self):
    
  741.         "Context variables can be retrieved from a single context"
    
  742.         response = self.client.get("/request_data/", data={"foo": "whiz"})
    
  743.         self.assertIsInstance(response.context, RequestContext)
    
  744.         self.assertIn("get-foo", response.context)
    
  745.         self.assertEqual(response.context["get-foo"], "whiz")
    
  746.         self.assertEqual(response.context["data"], "sausage")
    
  747. 
    
  748.         with self.assertRaisesMessage(KeyError, "does-not-exist"):
    
  749.             response.context["does-not-exist"]
    
  750. 
    
  751.     def test_inherited_context(self):
    
  752.         "Context variables can be retrieved from a list of contexts"
    
  753.         response = self.client.get("/request_data_extended/", data={"foo": "whiz"})
    
  754.         self.assertEqual(response.context.__class__, ContextList)
    
  755.         self.assertEqual(len(response.context), 2)
    
  756.         self.assertIn("get-foo", response.context)
    
  757.         self.assertEqual(response.context["get-foo"], "whiz")
    
  758.         self.assertEqual(response.context["data"], "bacon")
    
  759. 
    
  760.         with self.assertRaisesMessage(KeyError, "does-not-exist"):
    
  761.             response.context["does-not-exist"]
    
  762. 
    
  763.     def test_contextlist_keys(self):
    
  764.         c1 = Context()
    
  765.         c1.update({"hello": "world", "goodbye": "john"})
    
  766.         c1.update({"hello": "dolly", "dolly": "parton"})
    
  767.         c2 = Context()
    
  768.         c2.update({"goodbye": "world", "python": "rocks"})
    
  769.         c2.update({"goodbye": "dolly"})
    
  770. 
    
  771.         k = ContextList([c1, c2])
    
  772.         # None, True and False are builtins of BaseContext, and present
    
  773.         # in every Context without needing to be added.
    
  774.         self.assertEqual(
    
  775.             {"None", "True", "False", "hello", "goodbye", "python", "dolly"}, k.keys()
    
  776.         )
    
  777. 
    
  778.     def test_contextlist_get(self):
    
  779.         c1 = Context({"hello": "world", "goodbye": "john"})
    
  780.         c2 = Context({"goodbye": "world", "python": "rocks"})
    
  781.         k = ContextList([c1, c2])
    
  782.         self.assertEqual(k.get("hello"), "world")
    
  783.         self.assertEqual(k.get("goodbye"), "john")
    
  784.         self.assertEqual(k.get("python"), "rocks")
    
  785.         self.assertEqual(k.get("nonexistent", "default"), "default")
    
  786. 
    
  787.     def test_15368(self):
    
  788.         # Need to insert a context processor that assumes certain things about
    
  789.         # the request instance. This triggers a bug caused by some ways of
    
  790.         # copying RequestContext.
    
  791.         with self.settings(
    
  792.             TEMPLATES=[
    
  793.                 {
    
  794.                     "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  795.                     "APP_DIRS": True,
    
  796.                     "OPTIONS": {
    
  797.                         "context_processors": [
    
  798.                             "test_client_regress.context_processors.special",
    
  799.                         ],
    
  800.                     },
    
  801.                 }
    
  802.             ]
    
  803.         ):
    
  804.             response = self.client.get("/request_context_view/")
    
  805.             self.assertContains(response, "Path: /request_context_view/")
    
  806. 
    
  807.     def test_nested_requests(self):
    
  808.         """
    
  809.         response.context is not lost when view call another view.
    
  810.         """
    
  811.         response = self.client.get("/nested_view/")
    
  812.         self.assertIsInstance(response.context, RequestContext)
    
  813.         self.assertEqual(response.context["nested"], "yes")
    
  814. 
    
  815. 
    
  816. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  817. class SessionTests(TestDataMixin, TestCase):
    
  818.     def test_session(self):
    
  819.         "The session isn't lost if a user logs in"
    
  820.         # The session doesn't exist to start.
    
  821.         response = self.client.get("/check_session/")
    
  822.         self.assertEqual(response.status_code, 200)
    
  823.         self.assertEqual(response.content, b"NO")
    
  824. 
    
  825.         # This request sets a session variable.
    
  826.         response = self.client.get("/set_session/")
    
  827.         self.assertEqual(response.status_code, 200)
    
  828.         self.assertEqual(response.content, b"set_session")
    
  829. 
    
  830.         # The session has been modified
    
  831.         response = self.client.get("/check_session/")
    
  832.         self.assertEqual(response.status_code, 200)
    
  833.         self.assertEqual(response.content, b"YES")
    
  834. 
    
  835.         # Log in
    
  836.         login = self.client.login(username="testclient", password="password")
    
  837.         self.assertTrue(login, "Could not log in")
    
  838. 
    
  839.         # Session should still contain the modified value
    
  840.         response = self.client.get("/check_session/")
    
  841.         self.assertEqual(response.status_code, 200)
    
  842.         self.assertEqual(response.content, b"YES")
    
  843. 
    
  844.     def test_session_initiated(self):
    
  845.         session = self.client.session
    
  846.         session["session_var"] = "foo"
    
  847.         session.save()
    
  848. 
    
  849.         response = self.client.get("/check_session/")
    
  850.         self.assertEqual(response.content, b"foo")
    
  851. 
    
  852.     def test_logout(self):
    
  853.         """Logout should work whether the user is logged in or not (#9978)."""
    
  854.         self.client.logout()
    
  855.         login = self.client.login(username="testclient", password="password")
    
  856.         self.assertTrue(login, "Could not log in")
    
  857.         self.client.logout()
    
  858.         self.client.logout()
    
  859. 
    
  860.     def test_logout_with_user(self):
    
  861.         """Logout should send user_logged_out signal if user was logged in."""
    
  862. 
    
  863.         def listener(*args, **kwargs):
    
  864.             listener.executed = True
    
  865.             self.assertEqual(kwargs["sender"], User)
    
  866. 
    
  867.         listener.executed = False
    
  868. 
    
  869.         user_logged_out.connect(listener)
    
  870.         self.client.login(username="testclient", password="password")
    
  871.         self.client.logout()
    
  872.         user_logged_out.disconnect(listener)
    
  873.         self.assertTrue(listener.executed)
    
  874. 
    
  875.     @override_settings(AUTH_USER_MODEL="test_client_regress.CustomUser")
    
  876.     def test_logout_with_custom_user(self):
    
  877.         """Logout should send user_logged_out signal if custom user was logged in."""
    
  878. 
    
  879.         def listener(*args, **kwargs):
    
  880.             self.assertEqual(kwargs["sender"], CustomUser)
    
  881.             listener.executed = True
    
  882. 
    
  883.         listener.executed = False
    
  884.         u = CustomUser.custom_objects.create(email="[email protected]")
    
  885.         u.set_password("password")
    
  886.         u.save()
    
  887. 
    
  888.         user_logged_out.connect(listener)
    
  889.         self.client.login(username="[email protected]", password="password")
    
  890.         self.client.logout()
    
  891.         user_logged_out.disconnect(listener)
    
  892.         self.assertTrue(listener.executed)
    
  893. 
    
  894.     @override_settings(
    
  895.         AUTHENTICATION_BACKENDS=(
    
  896.             "django.contrib.auth.backends.ModelBackend",
    
  897.             "test_client_regress.auth_backends.CustomUserBackend",
    
  898.         )
    
  899.     )
    
  900.     def test_logout_with_custom_auth_backend(self):
    
  901.         "Request a logout after logging in with custom authentication backend"
    
  902. 
    
  903.         def listener(*args, **kwargs):
    
  904.             self.assertEqual(kwargs["sender"], CustomUser)
    
  905.             listener.executed = True
    
  906. 
    
  907.         listener.executed = False
    
  908.         u = CustomUser.custom_objects.create(email="[email protected]")
    
  909.         u.set_password("password")
    
  910.         u.save()
    
  911. 
    
  912.         user_logged_out.connect(listener)
    
  913.         self.client.login(username="[email protected]", password="password")
    
  914.         self.client.logout()
    
  915.         user_logged_out.disconnect(listener)
    
  916.         self.assertTrue(listener.executed)
    
  917. 
    
  918.     def test_logout_without_user(self):
    
  919.         """Logout should send signal even if user not authenticated."""
    
  920. 
    
  921.         def listener(user, *args, **kwargs):
    
  922.             listener.user = user
    
  923.             listener.executed = True
    
  924. 
    
  925.         listener.executed = False
    
  926. 
    
  927.         user_logged_out.connect(listener)
    
  928.         self.client.login(username="incorrect", password="password")
    
  929.         self.client.logout()
    
  930.         user_logged_out.disconnect(listener)
    
  931. 
    
  932.         self.assertTrue(listener.executed)
    
  933.         self.assertIsNone(listener.user)
    
  934. 
    
  935.     def test_login_with_user(self):
    
  936.         """Login should send user_logged_in signal on successful login."""
    
  937. 
    
  938.         def listener(*args, **kwargs):
    
  939.             listener.executed = True
    
  940. 
    
  941.         listener.executed = False
    
  942. 
    
  943.         user_logged_in.connect(listener)
    
  944.         self.client.login(username="testclient", password="password")
    
  945.         user_logged_out.disconnect(listener)
    
  946. 
    
  947.         self.assertTrue(listener.executed)
    
  948. 
    
  949.     def test_login_without_signal(self):
    
  950.         """Login shouldn't send signal if user wasn't logged in"""
    
  951. 
    
  952.         def listener(*args, **kwargs):
    
  953.             listener.executed = True
    
  954. 
    
  955.         listener.executed = False
    
  956. 
    
  957.         user_logged_in.connect(listener)
    
  958.         self.client.login(username="incorrect", password="password")
    
  959.         user_logged_in.disconnect(listener)
    
  960. 
    
  961.         self.assertFalse(listener.executed)
    
  962. 
    
  963. 
    
  964. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  965. class RequestMethodTests(SimpleTestCase):
    
  966.     def test_get(self):
    
  967.         "Request a view via request method GET"
    
  968.         response = self.client.get("/request_methods/")
    
  969.         self.assertEqual(response.status_code, 200)
    
  970.         self.assertEqual(response.content, b"request method: GET")
    
  971. 
    
  972.     def test_post(self):
    
  973.         "Request a view via request method POST"
    
  974.         response = self.client.post("/request_methods/")
    
  975.         self.assertEqual(response.status_code, 200)
    
  976.         self.assertEqual(response.content, b"request method: POST")
    
  977. 
    
  978.     def test_head(self):
    
  979.         "Request a view via request method HEAD"
    
  980.         response = self.client.head("/request_methods/")
    
  981.         self.assertEqual(response.status_code, 200)
    
  982.         # A HEAD request doesn't return any content.
    
  983.         self.assertNotEqual(response.content, b"request method: HEAD")
    
  984.         self.assertEqual(response.content, b"")
    
  985. 
    
  986.     def test_options(self):
    
  987.         "Request a view via request method OPTIONS"
    
  988.         response = self.client.options("/request_methods/")
    
  989.         self.assertEqual(response.status_code, 200)
    
  990.         self.assertEqual(response.content, b"request method: OPTIONS")
    
  991. 
    
  992.     def test_put(self):
    
  993.         "Request a view via request method PUT"
    
  994.         response = self.client.put("/request_methods/")
    
  995.         self.assertEqual(response.status_code, 200)
    
  996.         self.assertEqual(response.content, b"request method: PUT")
    
  997. 
    
  998.     def test_delete(self):
    
  999.         "Request a view via request method DELETE"
    
  1000.         response = self.client.delete("/request_methods/")
    
  1001.         self.assertEqual(response.status_code, 200)
    
  1002.         self.assertEqual(response.content, b"request method: DELETE")
    
  1003. 
    
  1004.     def test_patch(self):
    
  1005.         "Request a view via request method PATCH"
    
  1006.         response = self.client.patch("/request_methods/")
    
  1007.         self.assertEqual(response.status_code, 200)
    
  1008.         self.assertEqual(response.content, b"request method: PATCH")
    
  1009. 
    
  1010. 
    
  1011. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  1012. class RequestMethodStringDataTests(SimpleTestCase):
    
  1013.     def test_post(self):
    
  1014.         "Request a view with string data via request method POST"
    
  1015.         # Regression test for #11371
    
  1016.         data = '{"test": "json"}'
    
  1017.         response = self.client.post(
    
  1018.             "/request_methods/", data=data, content_type="application/json"
    
  1019.         )
    
  1020.         self.assertEqual(response.status_code, 200)
    
  1021.         self.assertEqual(response.content, b"request method: POST")
    
  1022. 
    
  1023.     def test_put(self):
    
  1024.         "Request a view with string data via request method PUT"
    
  1025.         # Regression test for #11371
    
  1026.         data = '{"test": "json"}'
    
  1027.         response = self.client.put(
    
  1028.             "/request_methods/", data=data, content_type="application/json"
    
  1029.         )
    
  1030.         self.assertEqual(response.status_code, 200)
    
  1031.         self.assertEqual(response.content, b"request method: PUT")
    
  1032. 
    
  1033.     def test_patch(self):
    
  1034.         "Request a view with string data via request method PATCH"
    
  1035.         # Regression test for #17797
    
  1036.         data = '{"test": "json"}'
    
  1037.         response = self.client.patch(
    
  1038.             "/request_methods/", data=data, content_type="application/json"
    
  1039.         )
    
  1040.         self.assertEqual(response.status_code, 200)
    
  1041.         self.assertEqual(response.content, b"request method: PATCH")
    
  1042. 
    
  1043.     def test_empty_string_data(self):
    
  1044.         "Request a view with empty string data via request method GET/POST/HEAD"
    
  1045.         # Regression test for #21740
    
  1046.         response = self.client.get("/body/", data="", content_type="application/json")
    
  1047.         self.assertEqual(response.content, b"")
    
  1048.         response = self.client.post("/body/", data="", content_type="application/json")
    
  1049.         self.assertEqual(response.content, b"")
    
  1050.         response = self.client.head("/body/", data="", content_type="application/json")
    
  1051.         self.assertEqual(response.content, b"")
    
  1052. 
    
  1053.     def test_json_bytes(self):
    
  1054.         response = self.client.post(
    
  1055.             "/body/", data=b"{'value': 37}", content_type="application/json"
    
  1056.         )
    
  1057.         self.assertEqual(response.content, b"{'value': 37}")
    
  1058. 
    
  1059.     def test_json(self):
    
  1060.         response = self.client.get("/json_response/")
    
  1061.         self.assertEqual(response.json(), {"key": "value"})
    
  1062. 
    
  1063.     def test_json_charset(self):
    
  1064.         response = self.client.get("/json_response_latin1/")
    
  1065.         self.assertEqual(response.charset, "latin1")
    
  1066.         self.assertEqual(response.json(), {"a": "Å"})
    
  1067. 
    
  1068.     def test_json_structured_suffixes(self):
    
  1069.         valid_types = (
    
  1070.             "application/vnd.api+json",
    
  1071.             "application/vnd.api.foo+json",
    
  1072.             "application/json; charset=utf-8",
    
  1073.             "application/activity+json",
    
  1074.             "application/activity+json; charset=utf-8",
    
  1075.         )
    
  1076.         for content_type in valid_types:
    
  1077.             response = self.client.get(
    
  1078.                 "/json_response/", {"content_type": content_type}
    
  1079.             )
    
  1080.             self.assertEqual(response.headers["Content-Type"], content_type)
    
  1081.             self.assertEqual(response.json(), {"key": "value"})
    
  1082. 
    
  1083.     def test_json_multiple_access(self):
    
  1084.         response = self.client.get("/json_response/")
    
  1085.         self.assertIs(response.json(), response.json())
    
  1086. 
    
  1087.     def test_json_wrong_header(self):
    
  1088.         response = self.client.get("/body/")
    
  1089.         msg = (
    
  1090.             'Content-Type header is "text/html; charset=utf-8", not "application/json"'
    
  1091.         )
    
  1092.         with self.assertRaisesMessage(ValueError, msg):
    
  1093.             self.assertEqual(response.json(), {"key": "value"})
    
  1094. 
    
  1095. 
    
  1096. @override_settings(
    
  1097.     ROOT_URLCONF="test_client_regress.urls",
    
  1098. )
    
  1099. class QueryStringTests(SimpleTestCase):
    
  1100.     def test_get_like_requests(self):
    
  1101.         for method_name in ("get", "head"):
    
  1102.             # A GET-like request can pass a query string as data (#10571)
    
  1103.             method = getattr(self.client, method_name)
    
  1104.             response = method("/request_data/", data={"foo": "whiz"})
    
  1105.             self.assertEqual(response.context["get-foo"], "whiz")
    
  1106. 
    
  1107.             # A GET-like request can pass a query string as part of the URL
    
  1108.             response = method("/request_data/?foo=whiz")
    
  1109.             self.assertEqual(response.context["get-foo"], "whiz")
    
  1110. 
    
  1111.             # Data provided in the URL to a GET-like request is overridden by
    
  1112.             # actual form data.
    
  1113.             response = method("/request_data/?foo=whiz", data={"foo": "bang"})
    
  1114.             self.assertEqual(response.context["get-foo"], "bang")
    
  1115. 
    
  1116.             response = method("/request_data/?foo=whiz", data={"bar": "bang"})
    
  1117.             self.assertIsNone(response.context["get-foo"])
    
  1118.             self.assertEqual(response.context["get-bar"], "bang")
    
  1119. 
    
  1120.     def test_post_like_requests(self):
    
  1121.         # A POST-like request can pass a query string as data
    
  1122.         response = self.client.post("/request_data/", data={"foo": "whiz"})
    
  1123.         self.assertIsNone(response.context["get-foo"])
    
  1124.         self.assertEqual(response.context["post-foo"], "whiz")
    
  1125. 
    
  1126.         # A POST-like request can pass a query string as part of the URL
    
  1127.         response = self.client.post("/request_data/?foo=whiz")
    
  1128.         self.assertEqual(response.context["get-foo"], "whiz")
    
  1129.         self.assertIsNone(response.context["post-foo"])
    
  1130. 
    
  1131.         # POST data provided in the URL augments actual form data
    
  1132.         response = self.client.post("/request_data/?foo=whiz", data={"foo": "bang"})
    
  1133.         self.assertEqual(response.context["get-foo"], "whiz")
    
  1134.         self.assertEqual(response.context["post-foo"], "bang")
    
  1135. 
    
  1136.         response = self.client.post("/request_data/?foo=whiz", data={"bar": "bang"})
    
  1137.         self.assertEqual(response.context["get-foo"], "whiz")
    
  1138.         self.assertIsNone(response.context["get-bar"])
    
  1139.         self.assertIsNone(response.context["post-foo"])
    
  1140.         self.assertEqual(response.context["post-bar"], "bang")
    
  1141. 
    
  1142. 
    
  1143. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  1144. class PayloadEncodingTests(SimpleTestCase):
    
  1145.     """Regression tests for #10571."""
    
  1146. 
    
  1147.     def test_simple_payload(self):
    
  1148.         """A simple ASCII-only text can be POSTed."""
    
  1149.         text = "English: mountain pass"
    
  1150.         response = self.client.post(
    
  1151.             "/parse_encoded_text/", text, content_type="text/plain"
    
  1152.         )
    
  1153.         self.assertEqual(response.content, text.encode())
    
  1154. 
    
  1155.     def test_utf8_payload(self):
    
  1156.         """Non-ASCII data encoded as UTF-8 can be POSTed."""
    
  1157.         text = "dog: собака"
    
  1158.         response = self.client.post(
    
  1159.             "/parse_encoded_text/", text, content_type="text/plain; charset=utf-8"
    
  1160.         )
    
  1161.         self.assertEqual(response.content, text.encode())
    
  1162. 
    
  1163.     def test_utf16_payload(self):
    
  1164.         """Non-ASCII data encoded as UTF-16 can be POSTed."""
    
  1165.         text = "dog: собака"
    
  1166.         response = self.client.post(
    
  1167.             "/parse_encoded_text/", text, content_type="text/plain; charset=utf-16"
    
  1168.         )
    
  1169.         self.assertEqual(response.content, text.encode("utf-16"))
    
  1170. 
    
  1171.     def test_non_utf_payload(self):
    
  1172.         """Non-ASCII data as a non-UTF based encoding can be POSTed."""
    
  1173.         text = "dog: собака"
    
  1174.         response = self.client.post(
    
  1175.             "/parse_encoded_text/", text, content_type="text/plain; charset=koi8-r"
    
  1176.         )
    
  1177.         self.assertEqual(response.content, text.encode("koi8-r"))
    
  1178. 
    
  1179. 
    
  1180. class DummyFile:
    
  1181.     def __init__(self, filename):
    
  1182.         self.name = filename
    
  1183. 
    
  1184.     def read(self):
    
  1185.         return b"TEST_FILE_CONTENT"
    
  1186. 
    
  1187. 
    
  1188. class UploadedFileEncodingTest(SimpleTestCase):
    
  1189.     def test_file_encoding(self):
    
  1190.         encoded_file = encode_file(
    
  1191.             "TEST_BOUNDARY", "TEST_KEY", DummyFile("test_name.bin")
    
  1192.         )
    
  1193.         self.assertEqual(b"--TEST_BOUNDARY", encoded_file[0])
    
  1194.         self.assertEqual(
    
  1195.             b'Content-Disposition: form-data; name="TEST_KEY"; '
    
  1196.             b'filename="test_name.bin"',
    
  1197.             encoded_file[1],
    
  1198.         )
    
  1199.         self.assertEqual(b"TEST_FILE_CONTENT", encoded_file[-1])
    
  1200. 
    
  1201.     def test_guesses_content_type_on_file_encoding(self):
    
  1202.         self.assertEqual(
    
  1203.             b"Content-Type: application/octet-stream",
    
  1204.             encode_file("IGNORE", "IGNORE", DummyFile("file.bin"))[2],
    
  1205.         )
    
  1206.         self.assertEqual(
    
  1207.             b"Content-Type: text/plain",
    
  1208.             encode_file("IGNORE", "IGNORE", DummyFile("file.txt"))[2],
    
  1209.         )
    
  1210.         self.assertIn(
    
  1211.             encode_file("IGNORE", "IGNORE", DummyFile("file.zip"))[2],
    
  1212.             (
    
  1213.                 b"Content-Type: application/x-compress",
    
  1214.                 b"Content-Type: application/x-zip",
    
  1215.                 b"Content-Type: application/x-zip-compressed",
    
  1216.                 b"Content-Type: application/zip",
    
  1217.             ),
    
  1218.         )
    
  1219.         self.assertEqual(
    
  1220.             b"Content-Type: application/octet-stream",
    
  1221.             encode_file("IGNORE", "IGNORE", DummyFile("file.unknown"))[2],
    
  1222.         )
    
  1223. 
    
  1224. 
    
  1225. @override_settings(
    
  1226.     ROOT_URLCONF="test_client_regress.urls",
    
  1227. )
    
  1228. class RequestHeadersTest(SimpleTestCase):
    
  1229.     def test_client_headers(self):
    
  1230.         "A test client can receive custom headers"
    
  1231.         response = self.client.get("/check_headers/", HTTP_X_ARG_CHECK="Testing 123")
    
  1232.         self.assertEqual(response.content, b"HTTP_X_ARG_CHECK: Testing 123")
    
  1233.         self.assertEqual(response.status_code, 200)
    
  1234. 
    
  1235.     def test_client_headers_redirect(self):
    
  1236.         "Test client headers are preserved through redirects"
    
  1237.         response = self.client.get(
    
  1238.             "/check_headers_redirect/", follow=True, HTTP_X_ARG_CHECK="Testing 123"
    
  1239.         )
    
  1240.         self.assertEqual(response.content, b"HTTP_X_ARG_CHECK: Testing 123")
    
  1241.         self.assertRedirects(
    
  1242.             response, "/check_headers/", status_code=302, target_status_code=200
    
  1243.         )
    
  1244. 
    
  1245. 
    
  1246. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  1247. class ReadLimitedStreamTest(SimpleTestCase):
    
  1248.     """
    
  1249.     HttpRequest.body, HttpRequest.read(), and HttpRequest.read(BUFFER) have
    
  1250.     proper LimitedStream behavior.
    
  1251. 
    
  1252.     Refs #14753, #15785
    
  1253.     """
    
  1254. 
    
  1255.     def test_body_from_empty_request(self):
    
  1256.         """HttpRequest.body on a test client GET request should return
    
  1257.         the empty string."""
    
  1258.         self.assertEqual(self.client.get("/body/").content, b"")
    
  1259. 
    
  1260.     def test_read_from_empty_request(self):
    
  1261.         """HttpRequest.read() on a test client GET request should return the
    
  1262.         empty string."""
    
  1263.         self.assertEqual(self.client.get("/read_all/").content, b"")
    
  1264. 
    
  1265.     def test_read_numbytes_from_empty_request(self):
    
  1266.         """HttpRequest.read(LARGE_BUFFER) on a test client GET request should
    
  1267.         return the empty string."""
    
  1268.         self.assertEqual(self.client.get("/read_buffer/").content, b"")
    
  1269. 
    
  1270.     def test_read_from_nonempty_request(self):
    
  1271.         """HttpRequest.read() on a test client PUT request with some payload
    
  1272.         should return that payload."""
    
  1273.         payload = b"foobar"
    
  1274.         self.assertEqual(
    
  1275.             self.client.put(
    
  1276.                 "/read_all/", data=payload, content_type="text/plain"
    
  1277.             ).content,
    
  1278.             payload,
    
  1279.         )
    
  1280. 
    
  1281.     def test_read_numbytes_from_nonempty_request(self):
    
  1282.         """HttpRequest.read(LARGE_BUFFER) on a test client PUT request with
    
  1283.         some payload should return that payload."""
    
  1284.         payload = b"foobar"
    
  1285.         self.assertEqual(
    
  1286.             self.client.put(
    
  1287.                 "/read_buffer/", data=payload, content_type="text/plain"
    
  1288.             ).content,
    
  1289.             payload,
    
  1290.         )
    
  1291. 
    
  1292. 
    
  1293. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  1294. class RequestFactoryStateTest(SimpleTestCase):
    
  1295.     """Regression tests for #15929."""
    
  1296. 
    
  1297.     # These tests are checking that certain middleware don't change certain
    
  1298.     # global state. Alternatively, from the point of view of a test, they are
    
  1299.     # ensuring test isolation behavior. So, unusually, it doesn't make sense to
    
  1300.     # run the tests individually, and if any are failing it is confusing to run
    
  1301.     # them with any other set of tests.
    
  1302. 
    
  1303.     def common_test_that_should_always_pass(self):
    
  1304.         request = RequestFactory().get("/")
    
  1305.         request.session = {}
    
  1306.         self.assertFalse(hasattr(request, "user"))
    
  1307. 
    
  1308.     def test_request(self):
    
  1309.         self.common_test_that_should_always_pass()
    
  1310. 
    
  1311.     def test_request_after_client(self):
    
  1312.         # apart from the next line the three tests are identical
    
  1313.         self.client.get("/")
    
  1314.         self.common_test_that_should_always_pass()
    
  1315. 
    
  1316.     def test_request_after_client_2(self):
    
  1317.         # This test is executed after the previous one
    
  1318.         self.common_test_that_should_always_pass()
    
  1319. 
    
  1320. 
    
  1321. @override_settings(ROOT_URLCONF="test_client_regress.urls")
    
  1322. class RequestFactoryEnvironmentTests(SimpleTestCase):
    
  1323.     """
    
  1324.     Regression tests for #8551 and #17067: ensure that environment variables
    
  1325.     are set correctly in RequestFactory.
    
  1326.     """
    
  1327. 
    
  1328.     def test_should_set_correct_env_variables(self):
    
  1329.         request = RequestFactory().get("/path/")
    
  1330. 
    
  1331.         self.assertEqual(request.META.get("REMOTE_ADDR"), "127.0.0.1")
    
  1332.         self.assertEqual(request.META.get("SERVER_NAME"), "testserver")
    
  1333.         self.assertEqual(request.META.get("SERVER_PORT"), "80")
    
  1334.         self.assertEqual(request.META.get("SERVER_PROTOCOL"), "HTTP/1.1")
    
  1335.         self.assertEqual(
    
  1336.             request.META.get("SCRIPT_NAME") + request.META.get("PATH_INFO"), "/path/"
    
  1337.         )
    
  1338. 
    
  1339.     def test_cookies(self):
    
  1340.         factory = RequestFactory()
    
  1341.         factory.cookies.load('A="B"; C="D"; Path=/; Version=1')
    
  1342.         request = factory.get("/")
    
  1343.         self.assertEqual(request.META["HTTP_COOKIE"], 'A="B"; C="D"')