diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index b8efdca4f2..bc18b11a45 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -35,167 +35,179 @@ class TestDataMixin: ) +class ExtraAssertMixin: + + def assertRaisesPrefixedMessage( + self, + method, + *method_args, + expected_msg, + msg_prefix="abc", + **method_kwargs, + ): + """ + `method` raises an AssertionError with and without a prefixed message. + + :param method: The assertion method to test. + :param method_args: Positional arguments to pass to the method. + :param expected_msg: The expected base error message (required keyword-only). + :param msg_prefix: Optional prefix to be added to the message in the second + subTest. + :param method_kwargs: Keyword arguments to pass to the method. + + Used internally for testing Django's assertions. + """ + with ( + self.subTest("without prefix"), + self.assertRaisesMessage(AssertionError, expected_msg), + ): + method(*method_args, **method_kwargs) + + with ( + self.subTest("with prefix"), + self.assertRaisesMessage(AssertionError, f"{msg_prefix}: {expected_msg}"), + ): + method(*method_args, **method_kwargs, msg_prefix=msg_prefix) + + @override_settings(ROOT_URLCONF="test_client_regress.urls") -class AssertContainsTests(SimpleTestCase): - def test_contains(self): - "Responses can be inspected for content, including counting repeated substrings" +class AssertContainsTests(ExtraAssertMixin, SimpleTestCase): + + def test_basic_contains_not_contains(self): response = self.client.get("/no_template_view/") - self.assertNotContains(response, "never") - self.assertContains(response, "never", 0) - self.assertContains(response, "once") - self.assertContains(response, "once", 1) - self.assertContains(response, "twice") - self.assertContains(response, "twice", 2) + with self.subTest("assertNotContains"): + self.assertNotContains(response, "never") - try: - self.assertContains(response, "text", status_code=999) - except AssertionError as e: - self.assertIn( - "Couldn't retrieve content: Response code was 200 (expected 999)", - str(e), - ) - try: - self.assertContains(response, "text", status_code=999, msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: Couldn't retrieve content: Response code was 200 (expected 999)", - str(e), - ) + cases = [ + ("never", 0), + ("once", None), + ("once", 1), + ("twice", None), + ("twice", 2), + ] - try: - self.assertNotContains(response, "text", status_code=999) - except AssertionError as e: - self.assertIn( - "Couldn't retrieve content: Response code was 200 (expected 999)", - str(e), - ) - try: - self.assertNotContains(response, "text", status_code=999, msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: Couldn't retrieve content: Response code was 200 (expected 999)", - str(e), - ) + for text, expected_count in cases: + with self.subTest(text=text, expected_count=expected_count): + if expected_count is not None: + self.assertContains(response, text, count=expected_count) + else: + self.assertContains(response, text) - try: - self.assertNotContains(response, "once") - except AssertionError as e: - self.assertIn( - "'once' unexpectedly found in the following response\n" - f"{response.content}", - str(e), - ) - try: - self.assertNotContains(response, "once", msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: 'once' unexpectedly found in the following response\n" - f"{response.content}", - str(e), - ) + def test_contains_with_wrong_status_code(self): + response = self.client.get("/no_template_view/") + msg = "Couldn't retrieve content: Response code was 200 (expected 999)" + self.assertRaisesPrefixedMessage( + self.assertContains, + response, + "text", + status_code=999, + expected_msg=msg, + ) - try: - self.assertContains(response, "never", 1) - except AssertionError as e: - self.assertIn( - "Found 0 instances of 'never' (expected 1) in the following response\n" - f"{response.content}", - str(e), - ) - try: - self.assertContains(response, "never", 1, msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: Found 0 instances of 'never' (expected 1) in the following " - f"response\n{response.content}", - str(e), - ) + def test_not_contains_with_wrong_status_code(self): + response = self.client.get("/no_template_view/") + msg = "Couldn't retrieve content: Response code was 200 (expected 999)" + self.assertRaisesPrefixedMessage( + self.assertNotContains, + response, + "text", + status_code=999, + expected_msg=msg, + ) - try: - self.assertContains(response, "once", 0) - except AssertionError as e: - self.assertIn( - "Found 1 instances of 'once' (expected 0) in the following response\n" - f"{response.content}", - str(e), - ) - try: - self.assertContains(response, "once", 0, msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: Found 1 instances of 'once' (expected 0) in the following " - f"response\n{response.content}", - str(e), - ) + def test_not_contains_failure(self): + response = self.client.get("/no_template_view/") + msg = f"'once' unexpectedly found in the following response\n{response.content}" + self.assertRaisesPrefixedMessage( + self.assertNotContains, + response, + "once", + expected_msg=msg, + ) - try: - self.assertContains(response, "once", 2) - except AssertionError as e: - self.assertIn( - "Found 1 instances of 'once' (expected 2) in the following response\n" - f"{response.content}", - str(e), - ) - try: - self.assertContains(response, "once", 2, msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: Found 1 instances of 'once' (expected 2) in the following " - f"response\n{response.content}", - str(e), - ) + def test_count_mismatch(self): + response = self.client.get("/no_template_view/") + msg = ( + "Found 0 instances of 'never' (expected 1) in the following response\n" + f"{response.content}" + ) + self.assertRaisesPrefixedMessage( + self.assertContains, + response, + "never", + count=1, + expected_msg=msg, + ) - try: - self.assertContains(response, "twice", 1) - except AssertionError as e: - self.assertIn( - "Found 2 instances of 'twice' (expected 1) in the following response\n" - f"{response.content}", - str(e), - ) - try: - self.assertContains(response, "twice", 1, msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: Found 2 instances of 'twice' (expected 1) in the following " - f"response\n{response.content}", - str(e), - ) + def test_unexpected_presence(self): + response = self.client.get("/no_template_view/") + msg = ( + "Found 1 instances of 'once' (expected 0) in the following " + f"response\n{response.content}" + ) + self.assertRaisesPrefixedMessage( + self.assertContains, + response, + "once", + count=0, + expected_msg=msg, + ) - try: - self.assertContains(response, "thrice") - except AssertionError as e: - self.assertIn( - f"Couldn't find 'thrice' in the following response\n{response.content}", - str(e), - ) - try: - self.assertContains(response, "thrice", msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: Couldn't find 'thrice' in the following response\n" - f"{response.content}", - str(e), - ) + def test_insufficient_count(self): + response = self.client.get("/no_template_view/") + msg = ( + "Found 1 instances of 'once' (expected 2) in the following response\n" + f"{response.content}" + ) + self.assertRaisesPrefixedMessage( + self.assertContains, + response, + "once", + 2, + expected_msg=msg, + ) - try: - self.assertContains(response, "thrice", 3) - except AssertionError as e: - self.assertIn( - "Found 0 instances of 'thrice' (expected 3) in the following response\n" - f"{response.content}", - str(e), - ) - try: - self.assertContains(response, "thrice", 3, msg_prefix="abc") - except AssertionError as e: - self.assertIn( - "abc: Found 0 instances of 'thrice' (expected 3) in the following " - f"response\n{response.content}", - str(e), - ) + def test_excessive_count(self): + response = self.client.get("/no_template_view/") + msg = ( + "Found 2 instances of 'twice' (expected 1) in the following response\n" + f"{response.content}" + ) + self.assertRaisesPrefixedMessage( + self.assertContains, + response, + "twice", + count=1, + expected_msg=msg, + ) + def test_missing_content(self): + response = self.client.get("/no_template_view/") + msg = f"Couldn't find 'thrice' in the following response\n{response.content}" + self.assertRaisesPrefixedMessage( + self.assertContains, + response, + "thrice", + expected_msg=msg, + msg_prefix="Custom prexix", + ) + + def test_missing_content_with_count(self): + response = self.client.get("/no_template_view/") + msg = ( + "Found 0 instances of 'thrice' (expected 3) in the following " + f"response\n{response.content}" + ) + self.assertRaisesPrefixedMessage( + self.assertContains, + response, + "thrice", + 3, + expected_msg=msg, + ) + + def test_long_content(self): long_content = ( b"This is a very very very very very very very very long message which " b"exceeds the max limit of truncation."