From 6a98bcbab5ad67f3172780f38bacff8a9b0e0549 Mon Sep 17 00:00:00 2001 From: Christophe Henry Date: Mon, 16 Dec 2024 14:38:18 +0100 Subject: [PATCH] Fix dsfr_input_class_attr triggering eaunexpected validation in DsfrBaseForm.__init__ --- dsfr/test/test_forms.py | 54 +++++++++++++++++++++++++++++++++++++++++ dsfr/utils.py | 3 ++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 dsfr/test/test_forms.py diff --git a/dsfr/test/test_forms.py b/dsfr/test/test_forms.py new file mode 100644 index 000000000..f31dba9a7 --- /dev/null +++ b/dsfr/test/test_forms.py @@ -0,0 +1,54 @@ +from typing import NoReturn + +from django import forms +from django.test import SimpleTestCase + + +from dsfr.forms import DsfrBaseForm + + +class DsfrBaseFormTestCase(SimpleTestCase): + class TestForm(DsfrBaseForm): + book_format = forms.ChoiceField( + label="Format", + choices=( + ("PAPER", "Papier"), + ("NUM", "Numérique"), + ), + ) + book_format2 = forms.ChoiceField( + label="Format", + choices=( + ("PAPER", "Papier"), + ("NUM", "Numérique"), + ), + widget=forms.RadioSelect, + ) + user_id = forms.CharField(widget=forms.HiddenInput) + + def test_init_sets_attributes(self): + form = self.TestForm(data={}) + self.assertEqual(form.fields["book_format"].widget.attrs["class"], "fr-select") + self.assertEqual( + form.fields["book_format"].widget.group_class, "fr-select-group" + ) + self.assertEqual(form.fields["book_format2"].widget.attrs["dsfr"], "dsfr") + self.assertEqual( + form.fields["book_format2"].widget.group_class, "fr-radio-group" + ) + self.assertEqual(form.fields["user_id"].widget.attrs, {}) + + def test_init_dont_trigger_form_validation(self): + test_ctx = self + + class AssertForm(self.TestForm): + @property + def errors(self) -> NoReturn: + test_ctx.fail("No validation expected") + + # __init__ should not trigger validation + AssertForm(data={}) + + with self.assertRaises(self.failureException): + # is_valid should trigger validation + AssertForm(data={}).is_valid() diff --git a/dsfr/utils.py b/dsfr/utils.py index afcc99315..6ce1812ec 100644 --- a/dsfr/utils.py +++ b/dsfr/utils.py @@ -133,7 +133,8 @@ def dsfr_input_class_attr(bf: BoundField): ): bf.field.widget.attrs["class"] = "fr-input" - if bf.errors: + # bf.errors triggers form validation. We need to check form._errors to prevent that + if bf.form._errors and bf.errors: bf.field.widget.attrs.update( {"aria-invalid": "true", "aria-describedby": f"{bf.auto_id}-desc-error"} )