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/",
openSUSE Build Service is sponsored by