refactor(pricing): 3 Cloud en rangée + DictIA LOCAL bloc dédié 'Vous en êtes propriétaire'
Restructure _pricing_tiers.html : les 3 forfaits Cloud (Basic 189$/Essentiel 349$/Pro 549$ recommandé) sont maintenant en grid responsive 1/2/3 cols, et DictIA LOCAL est sorti de la grille principale pour devenir un bloc large dédié 'propriété' avec : - badge 'Au Québec · par InnovA AI' (SVG map-pin, sans emoji 🇨🇦) - H3 'Vous en êtes propriétaire.' avec grad-text - 5 bullets checkmark (PC+GPU RTX, 100 % local, assemblé QC, installation incluse, achat direct < 34 700 $) - CTA 'Voir les serveurs disponibles' → /contact?plan=dictia-local - mockup serveur à droite (SVG rack + 6 specs : Interface web, PC gaming, RTX 5070 Ti 16 Go, WhisperX+Mistral, DictIA pré-installé, Votre propriété) - pricing tagline visible '5 998 $ An 1 · 500 $/an dès An 2' - decorative orbs background (b1 + b3) pour distinguer du grid Cloud Aussi mis à jour /tarifs (H1 'Trois forfaits Cloud + DictIA LOCAL' au lieu de 'Quatre forfaits') et tests pour refléter le nouveau slug /contact?plan=dictia-local (au lieu du /checkout/dictia-local d'avant). Conserve V3 radii (rounded-none/rounded/rounded-full), palette brand (b1/b2/b3/navy), OQLF NBSP, ARIA WCAG, zéro emoji. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -360,28 +360,32 @@ def test_pricing_recommended_tier_is_cloud_pro():
|
||||
|
||||
|
||||
def test_pricing_cta_labels_v7():
|
||||
"""CTAs reflect v7.0 forfait choice (Démarrer en Cloud / Choisir Essentiel / Commander Pro / Configurer DictIA Local)."""
|
||||
"""CTAs reflect v7.0 forfait choice — 3 Cloud go to /checkout, DictIA LOCAL goes to /contact?plan=dictia-local."""
|
||||
client = app.test_client()
|
||||
body = client.get('/').data.decode('utf-8')
|
||||
for slug in ['cloud-basic', 'cloud-essentiel', 'cloud-pro', 'dictia-local']:
|
||||
# 3 Cloud forfaits use /checkout/<slug>
|
||||
for slug in ['cloud-basic', 'cloud-essentiel', 'cloud-pro']:
|
||||
assert f'href="/checkout/{slug}"' in body, f"Missing checkout link for {slug}"
|
||||
# CTA labels match the macro callers in _pricing_tiers.html
|
||||
assert 'Démarrer en Cloud' in body or 'Démarrer en Cloud' in body
|
||||
assert 'Choisir Essentiel' in body
|
||||
assert 'Commander Pro' in body
|
||||
assert 'Configurer DictIA Local' in body
|
||||
# DictIA LOCAL now has a dedicated block with a contact CTA (no /checkout slug)
|
||||
assert 'Voir les serveurs disponibles' in body, "Missing DictIA LOCAL block CTA label"
|
||||
assert '/contact?plan=dictia-local' in body, "Missing DictIA LOCAL contact CTA href"
|
||||
|
||||
|
||||
def test_pricing_features_use_safe_filter_no_double_escape():
|
||||
"""Pricing card features piped through | safe — ' ' must render single-escaped, not double."""
|
||||
client = app.test_client()
|
||||
body = client.get('/').data.decode('utf-8')
|
||||
# Capacity chips use NBSP
|
||||
# Capacity chips use NBSP (3 Cloud forfaits)
|
||||
assert '~165 h audio/mois' in body, "Missing Cloud BASIC capacity chip"
|
||||
assert '100 Go' in body, "Missing Cloud BASIC storage chip"
|
||||
assert '~660 h audio/mois' in body, "Missing Cloud PRO capacity chip"
|
||||
assert '500 Go' in body, "Missing Cloud PRO storage chip"
|
||||
assert '2 To SSD' in body, "Missing DictIA LOCAL storage chip"
|
||||
# DictIA LOCAL dedicated block — server visual mockup uses NBSP for GPU spec
|
||||
assert 'RTX 5070 Ti 16 Go' in body, "Missing DictIA LOCAL GPU spec line in dedicated block"
|
||||
# WhisperX precision claim w/ NBSP
|
||||
assert 'WhisperX Large-v3' in body, "Missing WhisperX Large-v3 mention"
|
||||
# Loi 25 with NBSP
|
||||
@@ -462,8 +466,9 @@ def test_pricing_cta_url_no_double_slash():
|
||||
"""pricing_card uses cta_url.rstrip('/') so href never has '//' (regression guard)."""
|
||||
client = app.test_client()
|
||||
body = client.get('/').data.decode('utf-8')
|
||||
# All 4 CTAs use the default cta_url='/checkout' (no trailing slash) — so /checkout/<slug>
|
||||
for slug in ['cloud-basic', 'cloud-essentiel', 'cloud-pro', 'dictia-local']:
|
||||
# The 3 Cloud forfaits use the default cta_url='/checkout' (no trailing slash) — so /checkout/<slug>
|
||||
# DictIA LOCAL is presented in a dedicated block with /contact?plan=dictia-local (not via pricing_card macro)
|
||||
for slug in ['cloud-basic', 'cloud-essentiel', 'cloud-pro']:
|
||||
assert f'href="/checkout/{slug}"' in body, f"Missing single-slash href for {slug}"
|
||||
assert f'href="/checkout//{slug}"' not in body, f"Double-slash regression for {slug}"
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ def test_tarifs_has_h1_with_anchor():
|
||||
|
||||
|
||||
def test_tarifs_renders_4_pricing_cards_v7():
|
||||
"""Tarifs page renders the v7.0 4 forfaits + Pro+ chip."""
|
||||
"""Tarifs page renders the v7.0 3 Cloud forfaits + DictIA LOCAL dedicated block + Pro+ chip."""
|
||||
client = app.test_client()
|
||||
body = client.get('/tarifs').data.decode('utf-8')
|
||||
for tier in ['Cloud BASIC', 'Cloud ESSENTIEL', 'Cloud PRO', 'DictIA LOCAL']:
|
||||
@@ -45,11 +45,15 @@ def test_tarifs_renders_4_pricing_cards_v7():
|
||||
assert '549 $' in body
|
||||
assert '485 $' in body # Cloud Pro onboarding
|
||||
assert '5 998 $' in body # DictIA Local An 1
|
||||
# Checkout slugs
|
||||
# 3 Cloud forfaits use checkout slugs
|
||||
assert 'href="/checkout/cloud-basic"' in body
|
||||
assert 'href="/checkout/cloud-essentiel"' in body
|
||||
assert 'href="/checkout/cloud-pro"' in body
|
||||
assert 'href="/checkout/dictia-local"' in body
|
||||
# DictIA LOCAL has its own dedicated block with a contact CTA (no /checkout slug)
|
||||
assert '/contact?plan=dictia-local' in body, "Missing DictIA LOCAL block contact CTA"
|
||||
assert 'Vous en êtes' in body or 'Vous en êtes' in body, \
|
||||
"Missing DictIA LOCAL block headline 'Vous en êtes propriétaire'"
|
||||
assert 'Serveur DictIA' in body, "Missing DictIA LOCAL block server visual mockup label"
|
||||
# Pro+ chip with /contact link
|
||||
assert 'Pro+' in body
|
||||
assert '/contact?pro-plus=1' in body
|
||||
|
||||
Reference in New Issue
Block a user