From e8f74aa5291b29f6a55e5673f1175985e47c7345 Mon Sep 17 00:00:00 2001 From: Colin Maudry Date: Sun, 5 Jul 2026 20:46:54 +0200 Subject: [PATCH] =?UTF-8?q?feat(abonnement):=20message=20'changement=20?= =?UTF-8?q?=C3=A0=20la=20prochaine=20=C3=A9ch=C3=A9ance'=20sous=20les=20ca?= =?UTF-8?q?rds=20(#109)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajoute la fonction _change_hint et étend le callback _select_plan pour afficher un hint "changement à la prochaine échéance" quand l'utilisateur sélectionne un plan différent du plan courant. Co-Authored-By: Claude Haiku 4.5 --- src/pages/compte/abonnement_mes_infos.py | 25 ++++++++++++-- tests/subscriptions/test_mes_infos_plan.py | 39 ++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/pages/compte/abonnement_mes_infos.py b/src/pages/compte/abonnement_mes_infos.py index a6a67dc..f6e311a 100644 --- a/src/pages/compte/abonnement_mes_infos.py +++ b/src/pages/compte/abonnement_mes_infos.py @@ -85,18 +85,39 @@ def _selection_state(selected): ) +def _change_hint(selected: str, sub_info: dict | None) -> tuple[str, str]: + sub_info = sub_info or {} + current = sub_info.get("current_plan") + if ( + not current + or sub_info.get("status") not in ("active", "trial") + or selected == current + ): + return "d-none", "" + echeance = sub_info.get("echeance") + return ( + "text-muted mt-2", + f"Le changement d'abonnement sera appliqué à la prochaine échéance : {echeance}.", + ) + + @callback( Output("inf-plan-hidden", "value"), Output("plan-card-simple", "className"), Output("plan-card-soutien", "className"), Output("inf-plan-invite", "className"), + Output("inf-change-hint", "className"), + Output("inf-change-hint", "children"), Input("plan-card-simple", "n_clicks"), Input("plan-card-soutien", "n_clicks"), + State("inf-sub-info", "data"), prevent_initial_call=True, ) -def _select_plan(_n_simple, _n_soutien): +def _select_plan(_n_simple, _n_soutien, sub_info): selected = "simple" if ctx.triggered_id == "plan-card-simple" else "soutien" - return _selection_state(selected) + value, cls_simple, cls_soutien, cls_invite = _selection_state(selected) + hint_cls, hint_txt = _change_hint(selected, sub_info) + return value, cls_simple, cls_soutien, cls_invite, hint_cls, hint_txt def _legal_note(): diff --git a/tests/subscriptions/test_mes_infos_plan.py b/tests/subscriptions/test_mes_infos_plan.py index 99829c4..6474b91 100644 --- a/tests/subscriptions/test_mes_infos_plan.py +++ b/tests/subscriptions/test_mes_infos_plan.py @@ -77,3 +77,42 @@ def test_selectable_cards_preselects_current_plan(): text = str(m._selectable_cards(trial_for=lambda key: None, selected="soutien")) # la card soutien est marquée sélectionnée, pas la card simple assert "plan-selectable selected" in text + + +def test_change_hint_shown_when_plan_differs(): + from src.pages.compte import abonnement_mes_infos as m + + cls, txt = m._change_hint( + "soutien", + {"current_plan": "simple", "status": "active", "echeance": "1er janvier"}, + ) + assert cls != "d-none" + assert "prochaine échéance : 1er janvier" in txt + + +def test_change_hint_hidden_when_same_plan(): + from src.pages.compte import abonnement_mes_infos as m + + cls, txt = m._change_hint( + "simple", + {"current_plan": "simple", "status": "active", "echeance": "1er janvier"}, + ) + assert cls == "d-none" + assert txt == "" + + +def test_change_hint_hidden_for_pending(): + from src.pages.compte import abonnement_mes_infos as m + + cls, _ = m._change_hint( + "soutien", + {"current_plan": "simple", "status": "pending", "echeance": None}, + ) + assert cls == "d-none" + + +def test_change_hint_hidden_in_subscribe_mode(): + from src.pages.compte import abonnement_mes_infos as m + + cls, _ = m._change_hint("soutien", {}) + assert cls == "d-none"