feat(5.16+5.17): tipografie/antet branded + tipuri cont, planuri si enforcement

PRD 5.16 — propagare design finalizata (system font stack, fara IBM Plex self-hostat):
- US-001/002/008: tokeni --font-ui/--font-mono (system stack) + scala --fs-*; zero
  @font-face si zero /static/fonts/; landing aliniat la acelasi stack
- US-003: RAR online = dot compact in antet + meniu burger; banda rosie DOAR pe blocat
  (invariant zero-silent-failures pastrat)
- US-010: antet "ROMFAST AUTOPASS" + nume service + /login brandeit 2 coloane + badge plan;
  meniu burger cu separatoare; gate strict pe is_authenticated
- US-011: selector tema pill icon+eticheta (reuse THEMES)
- US-004/005/006/007: bug-fix editor prestatii (picker cod+denumire, add_extra in mod
  operatii, cod ales se salveaza fara "+", Renunta inchide via closest)
- US-012/013: landing Autentificare->/login; wizard import colapsat + 4 pasi pe tokeni
- fix VERIFY E2E: contoare duplicate pe 390px (inline display:flex batea @media) -> CSS + test-lock

PRD 5.17 — tipuri de cont + trial Pro 30z + enforcement DUR:
- US-001/002/008: accounts.tier + trial_until (migrare aditiva defensiva); app/plans.py
  sursa unica (PLANS, FREE_MONTHLY_LIMIT=60, effective_tier(now injectabil), monthly_usage,
  CONSUMED_STATUSES); create_account trial Pro 30z; CLI set-tier (protejat id=1, audit)
- US-003/004/005: enforce volum 60/luna INAINTE de build_key pe ambele canale
  (PLAN_LIMITA_LUNARA, 3 niveluri + log_event); gate API Pro+ (PLAN_FARA_API 403 actionabil);
  valideaza/nomenclator raman permise; downgrade lazy; flag AUTOPASS_ENFORCE_PLANS (kill-switch)
- US-006: badge plan antet + linie burger + consum N/60 + warn>=80% + 6 stari + copy RO
  pluralizat + banner one-time trial->Gratuit + pagina Cont

Regresie: 1380 passed, 0 failed, 1 deselected (live). E2E browser pe 390/1280 confirmat.
Backend trimitere (worker/masina stari/idempotenta/contract RAR) NEATINS. Lucrul 5.18
(corpus kNN) ramane separat, necomis.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-29 06:01:05 +00:00
parent 9eccb9f6fa
commit c9f9a1ca0e
37 changed files with 3433 additions and 449 deletions

View File

@@ -291,3 +291,94 @@ def test_import_forms_pastreaza_csrf(client):
if "mapare-coloane" in text_map: # s-a primit fragmentul de mapare
assert 'name="csrf_token"' in text_map, \
"name='csrf_token' nu a fost gasit in formularul mapare-coloane"
# ---------------------------------------------------------------------------
# US-013 Teste: import colapsat + tokeni scala + pill-uri cu dot (PRD 5.16)
# ---------------------------------------------------------------------------
def test_import_colapsat_implicit(client):
"""Pe Acasa (first-run, fara trimiteri), sectiunea de import e deschisa implicit.
La first-run (are_trimiteri=False), <details> trebuie sa aiba atributul `open`.
Summary-ul trebuie sa contina textul slim 'Importa fisier' (bara colapsabila).
Verifica si ca <details id="import-details"> este prezent pe pagina principala.
"""
r = client.get("/")
assert r.status_code == 200
text = r.text
# Elementul <details> trebuie sa fie prezent
assert 'id="import-details"' in text, \
"Elementul <details id='import-details'> lipseste de pe pagina principala"
# La first-run (nu exista trimiteri), details trebuie sa fie deschis (atribut open)
assert 'id="import-details" open' in text, \
"La first-run, <details id='import-details'> trebuie sa aiba atributul 'open'"
# Textul summary trebuie sa contina 'Importa fisier' (bara slim colapsabila)
assert "Importa fisier" in text, \
"Textul 'Importa fisier' nu a fost gasit in summary-ul sectiunii de import"
def test_wizard_foloseste_scala_tokeni(client):
"""Fragmentele wizard-ului de import folosesc tokeni var(--fs-*) in loc de px hardcodat.
Verifica ca fragmentul de mapare coloane (_mapcoloane.html) si cel de upload
(_upload.html) contin referinte la tokenii de scala --fs-* in inline styles,
nu font-size hardcodat in px sub 12px.
"""
# Fragment upload (/_import/reset) → _upload.html
r_upload = client.get("/_import/reset")
assert r_upload.status_code == 200
upload_text = r_upload.text
# Tokenii trebuie sa apara in inline styles
assert "var(--fs-" in upload_text, \
"Tokenii var(--fs-*) nu au fost gasiti in fragmentul de upload (_upload.html)"
# Fragment mapare coloane → _mapcoloane.html
csv_bytes = _make_csv_bytes(_SAMPLE_ROWS)
r_map = client.post(
"/_import/upload",
files={"file": ("test.csv", csv_bytes, "text/csv")},
)
assert r_map.status_code == 200
map_text = r_map.text
# Mapcoloane trebuie sa contina tokeni
assert "var(--fs-" in map_text, \
"Tokenii var(--fs-*) nu au fost gasiti in fragmentul mapare coloane (_mapcoloane.html)"
# Verifica ca nu exista font-size sub 12px hardcodat in fragmentele wizard
import re
for fragment_text, fragment_name in [(upload_text, "upload"), (map_text, "mapcoloane")]:
for size_str in re.findall(r'font-size:\s*(\d+)px', fragment_text):
size = int(size_str)
assert size >= 12, \
f"font-size:{size}px sub 12px gasit in fragmentul {fragment_name} — trebuie var(--fs-*)"
def test_preview_stari_pill_dot(client):
"""Pill-urile de stare din preview contin un dot consistent cu designul 5.16.
Verifica ca pill-urile din tabelul de preview si din rezumatul de stari contin
un element dot (span cu border-radius:99px ca inline style), consistent cu stripul
slim si cu designul 5.16 (dot + text, nu text gol).
Eticheta umana: din STARI_PREVIEW ('Gata de trimis', 'Cod RAR lipsa' etc.) — nicio
eticheta noua.
"""
_seed_op_mapping(client)
import_id = _upload_and_get_import_id(client)
text = _get_preview_via_mapare(client, import_id)
# Preview trebuie sa fie prezent
assert "confirm-form" in text or "Preview" in text, \
"Fragmentul de preview nu a fost randat"
# Pill-urile de stare trebuie sa contina un dot (span cu border-radius:99px)
assert "border-radius:99px" in text, \
"Dot-ul (border-radius:99px) nu a fost gasit in pill-urile de stare din preview"
# Etichetele umane din STARI_PREVIEW trebuie sa fie prezente (nicio eticheta noua)
# 'Gata de trimis' apare in rezumatul de stari (pill) sau in tabelul de randuri
assert "Gata de trimis" in text or "Cod RAR lipsa" in text or "Verifica valori" in text, \
"Etichetele umane din STARI_PREVIEW nu au fost gasite in preview"