Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
338 changes: 189 additions & 149 deletions tests/test_client_regress/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,167 +35,179 @@ def setUpTestData(cls):
)


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."
Expand Down Expand Up @@ -373,7 +385,7 @@ def test_template_rendered_multiple_times(self):


@override_settings(ROOT_URLCONF="test_client_regress.urls")
class AssertRedirectsTests(SimpleTestCase):
class AssertRedirectsTests(ExtraAssertMixin, SimpleTestCase):
def test_redirect_page(self):
"An assertion is raised if the original page couldn't be retrieved as expected"
# This page will redirect with code 301, not 302
Expand All @@ -396,6 +408,34 @@ def test_redirect_page(self):
str(e),
)

def test_followed_redirect_unexpected_initial_status_code(self):
response = self.client.get("/permanent_redirect_view/", follow=True)
msg = (
"Initial response didn't redirect as expected: Response code was 301 "
"(expected 302)"
)
self.assertRaisesPrefixedMessage(
self.assertRedirects,
response,
"/get_view/",
expected_msg=msg,
)

def test_followed_redirect_unexpected_final_status_code(self):
response = self.client.get("/redirect_view/", follow=True)
msg = (
"Response didn't redirect as expected: Final Response code was 200 "
"(expected 403)"
)
self.assertRaisesPrefixedMessage(
self.assertRedirects,
response,
"/get_view/",
status_code=302,
target_status_code=403,
expected_msg=msg,
)

def test_lost_query(self):
"""
An assertion is raised if the redirect location doesn't preserve GET
Expand Down