File test-helper1.patch of Package python-Django.39541
From 32fd8dec5618bd09eccdeb9dbf512043193d68ef Mon Sep 17 00:00:00 2001
From: Natalia <124304+nessita@users.noreply.github.com>
Date: Mon, 19 May 2025 22:46:00 -0300
Subject: [PATCH] [4.2.x] Added helpers in csrf_tests and logging_tests to
assert logs from `log_response()`.
Backport of ad6f99889838ccc2c30b3c02ed3868c9b565e81b from main.
---
tests/csrf_tests/tests.py | 53 ++++++++++++++++++------------------
tests/logging_tests/tests.py | 42 ++++++++++++++++++++--------
2 files changed, 57 insertions(+), 38 deletions(-)
diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py
index ba8f87d6ac74..b8d928151e7b 100644
--- a/tests/csrf_tests/tests.py
+++ b/tests/csrf_tests/tests.py
@@ -1,3 +1,4 @@
+import logging
import re
from django.conf import settings
@@ -57,6 +58,21 @@ def assertMaskedSecretCorrect(self, masked_secret, secret):
actual = _unmask_cipher_token(masked_secret)
self.assertEqual(actual, secret)
+ def assertForbiddenReason(
+ self, response, logger_cm, reason, levelno=logging.WARNING
+ ):
+ self.assertEqual(
+ records_len := len(logger_cm.records),
+ 1,
+ f"Unexpected number of records for {logger_cm=} in {levelno=} (expected 1, "
+ f"got {records_len}).",
+ )
+ record = logger_cm.records[0]
+ self.assertEqual(record.getMessage(), "Forbidden (%s): " % reason)
+ self.assertEqual(record.levelno, levelno)
+ self.assertEqual(record.status_code, 403)
+ self.assertEqual(response.status_code, 403)
+
class CsrfFunctionTests(CsrfFunctionTestMixin, SimpleTestCase):
def test_unmask_cipher_token(self):
@@ -347,8 +363,7 @@ def _check_bad_or_missing_cookie(self, cookie, expected):
mw.process_request(req)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(403, resp.status_code)
- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % expected)
+ self.assertForbiddenReason(resp, cm, expected)
def test_no_csrf_cookie(self):
"""
@@ -373,9 +388,8 @@ def _check_bad_or_missing_token(
mw.process_request(req)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(403, resp.status_code)
self.assertEqual(resp["Content-Type"], "text/html; charset=utf-8")
- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % expected)
+ self.assertForbiddenReason(resp, cm, expected)
def test_csrf_cookie_bad_or_missing_token(self):
"""
@@ -480,18 +494,12 @@ def test_put_and_delete_rejected(self):
mw = CsrfViewMiddleware(post_form_view)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(403, resp.status_code)
- self.assertEqual(
- cm.records[0].getMessage(), "Forbidden (%s): " % REASON_NO_CSRF_COOKIE
- )
+ self.assertForbiddenReason(resp, cm, REASON_NO_CSRF_COOKIE)
req = self._get_request(method="DELETE")
with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(403, resp.status_code)
- self.assertEqual(
- cm.records[0].getMessage(), "Forbidden (%s): " % REASON_NO_CSRF_COOKIE
- )
+ self.assertForbiddenReason(resp, cm, REASON_NO_CSRF_COOKIE)
def test_put_and_delete_allowed(self):
"""
@@ -879,11 +887,7 @@ def test_reading_post_data_raises_unreadable_post_error(self):
mw.process_request(req)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
resp = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(resp.status_code, 403)
- self.assertEqual(
- cm.records[0].getMessage(),
- "Forbidden (%s): " % REASON_CSRF_TOKEN_MISSING,
- )
+ self.assertForbiddenReason(resp, cm, REASON_CSRF_TOKEN_MISSING)
def test_reading_post_data_raises_os_error(self):
"""
@@ -908,9 +912,8 @@ def test_bad_origin_bad_domain(self):
self.assertIs(mw._origin_verified(req), False)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(response.status_code, 403)
msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
+ self.assertForbiddenReason(response, cm, msg)
@override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_bad_origin_null_origin(self):
@@ -923,9 +926,8 @@ def test_bad_origin_null_origin(self):
self.assertIs(mw._origin_verified(req), False)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(response.status_code, 403)
msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
+ self.assertForbiddenReason(response, cm, msg)
@override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_bad_origin_bad_protocol(self):
@@ -939,9 +941,8 @@ def test_bad_origin_bad_protocol(self):
self.assertIs(mw._origin_verified(req), False)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(response.status_code, 403)
msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
+ self.assertForbiddenReason(response, cm, msg)
@override_settings(
ALLOWED_HOSTS=["www.example.com"],
@@ -966,9 +967,8 @@ def test_bad_origin_csrf_trusted_origin_bad_protocol(self):
self.assertIs(mw._origin_verified(req), False)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(response.status_code, 403)
msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
+ self.assertForbiddenReason(response, cm, msg)
self.assertEqual(mw.allowed_origins_exact, {"http://no-match.com"})
self.assertEqual(
mw.allowed_origin_subdomains,
@@ -992,9 +992,8 @@ def test_bad_origin_cannot_be_parsed(self):
self.assertIs(mw._origin_verified(req), False)
with self.assertLogs("django.security.csrf", "WARNING") as cm:
response = mw.process_view(req, post_form_view, (), {})
- self.assertEqual(response.status_code, 403)
msg = REASON_BAD_ORIGIN % req.META["HTTP_ORIGIN"]
- self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % msg)
+ self.assertForbiddenReason(response, cm, msg)
@override_settings(ALLOWED_HOSTS=["www.example.com"])
def test_good_origin_insecure(self):
diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py
index 2138a7fe50f3..4ffa49a1b805 100644
--- a/tests/logging_tests/tests.py
+++ b/tests/logging_tests/tests.py
@@ -94,6 +94,28 @@ def test_django_logger_debug(self):
class LoggingAssertionMixin:
+
+ def assertLogRecord(
+ self,
+ logger_cm,
+ level,
+ msg,
+ status_code,
+ exc_class=None,
+ ):
+ self.assertEqual(
+ records_len := len(logger_cm.records),
+ 1,
+ f"Wrong number of calls for {logger_cm=} in {level=} (expected 1, got "
+ f"{records_len}).",
+ )
+ record = logger_cm.records[0]
+ self.assertEqual(record.getMessage(), msg)
+ self.assertEqual(record.status_code, status_code)
+ if exc_class:
+ self.assertIsNotNone(record.exc_info)
+ self.assertEqual(record.exc_info[0], exc_class)
+
def assertLogsRequest(
self, url, level, msg, status_code, logger="django.request", exc_class=None
):
@@ -102,17 +124,7 @@ def assertLogsRequest(
self.client.get(url)
except views.UncaughtException:
pass
- self.assertEqual(
- len(cm.records),
- 1,
- "Wrong number of calls for logger %r in %r level." % (logger, level),
- )
- record = cm.records[0]
- self.assertEqual(record.getMessage(), msg)
- self.assertEqual(record.status_code, status_code)
- if exc_class:
- self.assertIsNotNone(record.exc_info)
- self.assertEqual(record.exc_info[0], exc_class)
+ self.assertLogRecord(cm, level, msg, status_code, exc_class)
@override_settings(DEBUG=True, ROOT_URLCONF="logging_tests.urls")
@@ -135,6 +147,14 @@ def test_page_not_found_warning(self):
msg="Not Found: /does_not_exist/",
)
+ async def test_async_page_not_found_warning(self):
+ logger = "django.request"
+ level = "WARNING"
+ with self.assertLogs(logger, level) as cm:
+ await self.async_client.get("/does_not_exist/")
+
+ self.assertLogRecord(cm, level, "Not Found: /does_not_exist/", 404)
+
def test_page_not_found_raised(self):
self.assertLogsRequest(
url="/does_not_exist_raised/",