fix(abonnement): erreur Dash au chargement de mes-infos en mode configure

Le callback _toggle_submit référence inf-cb-retractation/inf-cb-cgu en
Input sans condition, mais ces cases n'étaient rendues qu'en mode
"subscribe". Elles sont maintenant toujours montées (masquées et
pré-cochées en mode configure) pour que Dash trouve toujours ces ids.
This commit is contained in:
Colin Maudry
2026-07-06 11:01:26 +02:00
parent ad028b9e6b
commit 92e30979d9
2 changed files with 73 additions and 36 deletions
+40 -36
View File
@@ -128,40 +128,44 @@ def _legal_note():
) )
def _consent_checklists(): def _consent_checklists(hidden: bool = False):
return [ default_value = ["ok"] if hidden else []
dcc.Checklist( return html.Div(
id="inf-cb-retractation", [
options=[ dcc.Checklist(
{ id="inf-cb-retractation",
"label": "Je renonce à mon droit de rétractation légal de 14 jours.", options=[
"value": "ok", {
} "label": "Je renonce à mon droit de rétractation légal de 14 jours.",
], "value": "ok",
value=[], }
className="mb-2", ],
), value=default_value,
dcc.Checklist( className="mb-2",
id="inf-cb-cgu", ),
options=[ dcc.Checklist(
{ id="inf-cb-cgu",
"label": [ options=[
"J'ai lu et accepte les ", {
html.A( "label": [
"conditions générales d'utilisation du service", "J'ai lu et accepte les ",
href="#", html.A(
id="inf-cgu-link", "conditions générales d'utilisation du service",
style={"cursor": "pointer"}, href="#",
), id="inf-cgu-link",
".", style={"cursor": "pointer"},
], ),
"value": "ok", ".",
} ],
], "value": "ok",
value=[], }
className="mb-4", ],
), value=default_value,
] className="mb-4",
),
],
className="d-none" if hidden else None,
)
def _cgu_modal(): def _cgu_modal():
@@ -356,7 +360,7 @@ def layout(**query):
), ),
dbc.Row([col1, col2], className="g-4 mb-4"), dbc.Row([col1, col2], className="g-4 mb-4"),
_legal_note(), _legal_note(),
*(_consent_checklists() if mode == "subscribe" else []), _consent_checklists(hidden=(mode == "configure")),
_submit_button(mode), _submit_button(mode),
], ],
) )
@@ -374,7 +378,7 @@ def layout(**query):
if prefill if prefill
else None, else None,
form, form,
_cgu_modal() if mode == "subscribe" else None, _cgu_modal(),
] ]
), ),
) )
@@ -116,3 +116,36 @@ def test_change_hint_hidden_in_subscribe_mode():
cls, _ = m._change_hint("soutien", {}) cls, _ = m._change_hint("soutien", {})
assert cls == "d-none" assert cls == "d-none"
def test_consent_checklists_ids_always_present_in_configure_mode():
# Régression : le callback _toggle_submit référence inf-cb-retractation
# et inf-cb-cgu en Input inconditionnellement, donc ces composants
# doivent exister dans le layout même en mode "configure" (sinon Dash
# lève "A nonexistent object was used in an Input").
from src.pages.compte import abonnement_mes_infos as m
div = m._consent_checklists(hidden=True)
text = str(div)
assert "inf-cb-retractation" in text
assert "inf-cb-cgu" in text
assert "d-none" in div.className
def test_consent_checklists_pre_accepted_when_hidden():
from src.pages.compte import abonnement_mes_infos as m
div = m._consent_checklists(hidden=True)
retractation, cgu = div.children
assert retractation.value == ["ok"]
assert cgu.value == ["ok"]
def test_consent_checklists_visible_and_empty_in_subscribe_mode():
from src.pages.compte import abonnement_mes_infos as m
div = m._consent_checklists(hidden=False)
retractation, cgu = div.children
assert retractation.value == []
assert cgu.value == []
assert div.className is None