Files
rar-autopass/tests/test_web_preview_motive.py
Claude Agent d7ba1195d4 feat(web): dashboard compact — import pe Acasa, status cu bife, Trimiteri lizibile, Mapari complete (3.5)
Acasa = ecran de import (tab Import scos, ?tab=import->Acasa). Bara status
compacta pe 2 randuri cu bife accesibile (glife + text) + data formatata.
'Coada'->'Trimiteri': coloane RO, stare umana, detaliu la click in panou
dedicat. Mapari pe 3 sectiuni (de rezolvat / op salvate / formate coloane),
Cont doar cheie+creds. Filtrare Trimiteri, corectie inline needs_data cu
re-enqueue + detectie coliziune idempotency, badge contoare pe tab-uri.
Helper pur partajat payload_view.py (web + GET /v1/prezentari).
Backend trimitere (worker/idempotenta/mapping/schema) neatins. 483 teste.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 08:56:45 +00:00

89 lines
3.1 KiB
Python

"""Teste US-008 (PRD 3.5): preview-ul de import arata MOTIVUL randurilor respinse.
Un rand needs_data (ex. lipsa odometru) trebuie sa apara cu motivul explicit
(mesajul de validare), nu doar numarat la "blocate".
"""
from __future__ import annotations
import csv
import io
import os
import re
import tempfile
import pytest
@pytest.fixture()
def client(monkeypatch):
tmp = tempfile.mkdtemp()
monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "prev.db"))
monkeypatch.setenv("AUTOPASS_WEB_AUTH_REQUIRED", "false")
from app.config import get_settings
get_settings.cache_clear()
from app.main import app
from fastapi.testclient import TestClient
with TestClient(app) as c:
yield c
get_settings.cache_clear()
def _csv_bytes(rows: list[dict]) -> bytes:
buf = io.StringIO()
writer = csv.DictWriter(buf, fieldnames=list(rows[0].keys()), delimiter=";")
writer.writeheader()
writer.writerows(rows)
return buf.getvalue().encode("utf-8")
def _seed_mapping_op1() -> None:
"""Mapeaza OP-1 -> R-FRANE (cont dev id=1) ca randurile sa nu fie needs_mapping."""
from app.db import get_connection
conn = get_connection()
try:
conn.execute("INSERT OR REPLACE INTO nomenclator_rar (cod_prestatie, nume_prestatie) VALUES ('R-FRANE','Reparatie frane')")
conn.execute(
"INSERT OR IGNORE INTO operations_mapping (account_id, cod_op_service, cod_prestatie, auto_send) "
"VALUES (1, 'OP-1', 'R-FRANE', 1)"
)
conn.commit()
finally:
conn.close()
def test_preview_arata_motiv_needs_data(client):
"""Un rand fara odometru apare in preview cu motivul, nu doar numarat la blocate."""
_seed_mapping_op1()
rows = [
# rand valid
{"VIN": "WVWZZZ1KZAW000123", "Nr inmatriculare": "B001TST",
"Data prestatie": "15.06.2026", "Odometru final": "123456", "Operatie": "OP-1"},
# rand fara odometru -> needs_data
{"VIN": "WVWZZZ1KZAW000456", "Nr inmatriculare": "B002TST",
"Data prestatie": "15.06.2026", "Odometru final": "", "Operatie": "OP-1"},
]
data = _csv_bytes(rows)
# Upload -> formular mapare
r = client.post("/_import/upload", files={"file": ("test.csv", data, "text/csv")})
assert r.status_code == 200
m = re.search(r"/_import/(\d+)/mapare-coloane", r.text)
assert m, "Nu am gasit import_id in formularul de mapare"
import_id = int(m.group(1))
# Salveaza maparea -> preview
r = client.post(f"/_import/{import_id}/mapare-coloane", data={
"colname": ["VIN", "Nr inmatriculare", "Data prestatie", "Odometru final", "Operatie"],
"canon": ["vin", "nr_inmatriculare", "data_prestatie", "odometru_final", "operatie"],
"format_data": "DD.MM.YYYY",
})
assert r.status_code == 200
html = r.text
# Trebuie sa apara starea needs_data si MOTIVUL (mesajul de validare odometru)
assert "needs_data" in html, "Randul fara odometru trebuia marcat needs_data"
assert "odometruFinal" in html, (
"Preview-ul nu arata motivul (mesajul de validare) pentru randul fara odometru"
)