summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBaptiste Mispelon <bmispelon@gmail.com>2022-02-14 12:27:26 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-14 12:46:46 +0100
commit9bb13def5d416ff3d5d1928a2def5babac0e19f6 (patch)
tree62e69d4a28e054f4fd0089ff01d8eeace64d2402
parent261885e4c16a252999ac6ff7d911b7dc50f862f9 (diff)
Refs #33348 -- Made SimpleTestCase.assertFormsetErrors() raise an error when form_index is too big.
-rw-r--r--django/contrib/admin/helpers.py4
-rw-r--r--django/test/testcases.py10
-rw-r--r--tests/test_utils/tests.py27
3 files changed, 40 insertions, 1 deletions
diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
index aea13b94d7..9c78e758f0 100644
--- a/django/contrib/admin/helpers.py
+++ b/django/contrib/admin/helpers.py
@@ -446,6 +446,10 @@ class InlineAdminFormSet:
return self.formset.is_bound
@property
+ def total_form_count(self):
+ return self.formset.total_form_count
+
+ @property
def media(self):
media = self.opts.media + self.formset.media
for fs in self:
diff --git a/django/test/testcases.py b/django/test/testcases.py
index 0d24bf0d40..a29b77c277 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -686,13 +686,21 @@ class SimpleTestCase(unittest.TestCase):
for i, context in enumerate(contexts):
if formset not in context or not hasattr(context[formset], "forms"):
continue
+ formset_repr = repr(context[formset])
if not context[formset].is_bound:
- formset_repr = repr(context[formset])
self.fail(
f"{msg_prefix}The formset {formset_repr} is not bound, it will "
f"never have any errors."
)
found_formset = True
+ if form_index is not None:
+ form_count = context[formset].total_form_count()
+ if form_index >= form_count:
+ form_or_forms = "forms" if form_count > 1 else "form"
+ self.fail(
+ f"{msg_prefix}The formset {formset_repr} only has "
+ f"{form_count} {form_or_forms}."
+ )
for err in errors:
if field is not None:
if field in context[formset].forms[form_index].errors:
diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py
index bfc9633122..038e79732b 100644
--- a/tests/test_utils/tests.py
+++ b/tests/test_utils/tests.py
@@ -1629,6 +1629,33 @@ class AssertFormsetErrorTests(SimpleTestCase):
)
self.assertFormsetError(response, "formset", None, None, "error")
+ def test_form_index_too_big(self):
+ msg = (
+ "The formset <TestFormset: bound=True valid=False total_forms=1> only has "
+ "1 form."
+ )
+ response = mock.Mock(context=[{}, {"formset": TestFormset.invalid()}])
+ with self.assertRaisesMessage(AssertionError, msg):
+ self.assertFormsetError(response, "formset", 2, "field", "error")
+
+ def test_form_index_too_big_plural(self):
+ formset = TestFormset(
+ {
+ "form-TOTAL_FORMS": "2",
+ "form-INITIAL_FORMS": "0",
+ "form-0-field": "valid",
+ "form-1-field": "valid",
+ }
+ )
+ formset.full_clean()
+ msg = (
+ "The formset <TestFormset: bound=True valid=True total_forms=2> only has 2 "
+ "forms."
+ )
+ response = mock.Mock(context=[{}, {"formset": formset}])
+ with self.assertRaisesMessage(AssertionError, msg):
+ self.assertFormsetError(response, "formset", 2, "field", "error")
+
def test_formset_named_form(self):
formset = TestFormset.invalid()
# The mocked context emulates the template-based rendering of the