8 stories TDD (echipa Sonnet, lead orchestreaza). US-001 scoate hold-ul auto_send din mapare (has_no_auto_send->False, simbol pastrat; cod rezolvat->queued). US-002 scoate bifa auto_send din UI. US-003 preview pas 3 in format .tabel-trimiteri (STARI_PREVIEW + nota_umana_preview, fara repr Python; view-model prez). US-004 filtre layout/stil ca referinta + buton Custom. US-005 navigatie Trimiteri/Mapari sub contoare pe toate paginile. US-006 import <details> nativ colapsabil. US-007 post-commit reveal (OOB _coada/_status + HX-Trigger). US-008 auto-refresh dupa actiuni (nudge eliminat). VERIFY context curat PASS (8/8). /code-review high: 3 buguri reparate (tab nav la self-refresh, pill Custom valori stale, nota_umana_preview precedenta needs_mapping). 934 passed, 1 skipped. Backend trimitere + schema NEATINSE. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
131 lines
4.4 KiB
Python
131 lines
4.4 KiB
Python
"""Teste US-006 (PRD 5.11): Import = container compact colapsabil.
|
|
|
|
TDD — testele sunt scrise INAINTE de implementare (RED), apoi devin GREEN.
|
|
|
|
Verifica:
|
|
- Containerul de import e colapsat implicit cand exista trimiteri (are_trimiteri=True)
|
|
- Containerul de import e deschis la first-run (are_trimiteri=False)
|
|
- Implementare cu <details> nativ (CSS-only disclosure)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import re
|
|
import tempfile
|
|
|
|
import pytest
|
|
|
|
|
|
# ============================================================
|
|
# Fixture
|
|
# ============================================================
|
|
|
|
@pytest.fixture()
|
|
def client(monkeypatch):
|
|
"""Client cu BD izolata; auth dezactivat (cont implicit id=1)."""
|
|
tmp = tempfile.mkdtemp()
|
|
monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "acasa_test.db"))
|
|
monkeypatch.setenv("AUTOPASS_WEB_AUTH_REQUIRED", "false")
|
|
from app.config import get_settings
|
|
get_settings.cache_clear()
|
|
from app.web import ratelimit
|
|
ratelimit._hits.clear()
|
|
from app.main import app
|
|
from fastapi.testclient import TestClient
|
|
|
|
with TestClient(app) as c:
|
|
yield c
|
|
ratelimit._hits.clear()
|
|
get_settings.cache_clear()
|
|
|
|
|
|
# ============================================================
|
|
# Helpere
|
|
# ============================================================
|
|
|
|
def _add_submission(acct_id: int = 1) -> None:
|
|
"""Adauga un submission minimal pentru cont (simuleaza un import efectuat)."""
|
|
from app.db import get_connection
|
|
|
|
conn = get_connection()
|
|
try:
|
|
conn.execute(
|
|
"INSERT INTO submissions (idempotency_key, account_id, status, payload_json) "
|
|
"VALUES (?, ?, 'queued', ?)",
|
|
(f"test_key_us006_{acct_id}", acct_id, json.dumps({"test": True})),
|
|
)
|
|
finally:
|
|
conn.close()
|
|
|
|
|
|
def _detalii_import(html: str) -> re.Match | None:
|
|
"""Returneaza match-ul pentru tagul <details> care contine containerul de import."""
|
|
# Cauta <details cu id="import-details" (sau variante)
|
|
m = re.search(r'<details([^>]*)id=["\']import-details["\']([^>]*)>', html)
|
|
if m:
|
|
return m
|
|
# Fallback: primul <details> care nu e .kebab (e containerul de import)
|
|
m2 = re.search(r'<details(?!.*class=["\'][^"\']*kebab)([^>]*)>', html)
|
|
return m2
|
|
|
|
|
|
# ============================================================
|
|
# test_import_colapsat_cand_are_trimiteri
|
|
# ============================================================
|
|
|
|
def test_import_colapsat_cand_are_trimiteri(client):
|
|
"""Cand contul are deja trimiteri, containerul de import e colapsat (fara atribut open).
|
|
|
|
Serverul NU seteaza atributul `open` pe <details> cand are_trimiteri=True,
|
|
deci browserul il randeaza colapsat implicit.
|
|
"""
|
|
_add_submission(acct_id=1)
|
|
|
|
resp = client.get("/_fragments/acasa")
|
|
assert resp.status_code == 200
|
|
html = resp.text
|
|
|
|
# Containerul de import trebuie sa existe ca element <details>
|
|
m = _detalii_import(html)
|
|
assert m is not None, (
|
|
"Nu s-a gasit un element <details> pentru containerul de import. "
|
|
"Implementati containerul cu <details id='import-details'>."
|
|
)
|
|
|
|
# Atributul `open` NU trebuie sa fie prezent pe <details> cand exista trimiteri
|
|
tag = m.group(0)
|
|
assert "open" not in tag.lower(), (
|
|
f"<details> are atributul 'open' cand sunt trimiteri existente — trebuie colapsat: {tag}"
|
|
)
|
|
|
|
|
|
# ============================================================
|
|
# test_import_deschis_la_first_run
|
|
# ============================================================
|
|
|
|
def test_import_deschis_la_first_run(client):
|
|
"""La first-run (zero trimiteri), containerul de import e deschis (atribut open prezent).
|
|
|
|
Serverul seteaza `open` pe <details> cand are_trimiteri=False, deci importul
|
|
e vizibil imediat fara JS.
|
|
"""
|
|
# Nu adaugam niciun submission — cont proaspat
|
|
resp = client.get("/_fragments/acasa")
|
|
assert resp.status_code == 200
|
|
html = resp.text
|
|
|
|
# Containerul de import trebuie sa existe ca element <details>
|
|
m = _detalii_import(html)
|
|
assert m is not None, (
|
|
"Nu s-a gasit un element <details> pentru containerul de import. "
|
|
"Implementati containerul cu <details id='import-details'>."
|
|
)
|
|
|
|
# Atributul `open` TREBUIE sa fie prezent pe <details> la first-run
|
|
tag = m.group(0)
|
|
assert "open" in tag.lower(), (
|
|
f"<details> NU are atributul 'open' la first-run — trebuie deschis: {tag}"
|
|
)
|