feat(errors): erori pe 3 niveluri (problema+cauza+fix) pe API si UI (PRD 5.4)
Catalog central pur app/errors.py ca sursa unica cod->{problema,fix},
consumat de API+UI+worker. Aditiv (field/message pastrate la octet) +
rar_error stocat superset. Scope: fluxul de declarare; login/signup/CSRF
neatinse. labels.parse_erori degradeaza gratios; UI progresiv AA light+dark.
631 teste.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -161,3 +161,89 @@ def test_op_mapat_declanseaza_regula_odometru(client):
|
||||
def test_item_fara_cod_si_fara_op_e_422(client):
|
||||
r = client.post("/v1/prezentari", json=_body([{"denumire": "doar text"}]))
|
||||
assert r.status_code == 422
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# US-003: 3 niveluri in classify_prezentare (needs_mapping) #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
def test_unmapped_are_3niveluri(client):
|
||||
"""cod_op_service necunoscut -> needs_mapping; rar_error are cheie 'unmapped'
|
||||
PASTRATA + campurile COD_NEMAPAT (cod/problema/cauza/fix)."""
|
||||
import json
|
||||
from app.mapping import classify_prezentare
|
||||
|
||||
content = {
|
||||
"vin": "WVWZZZ1KZAW000123",
|
||||
"nr_inmatriculare": "B999TST",
|
||||
"data_prestatie": "2026-06-15",
|
||||
"odometru_final": "123456",
|
||||
"prestatii": [{"cod_op_service": "OP_NECUNOSCUT", "denumire": "Reparatie necunoscuta"}],
|
||||
}
|
||||
mapping = {}
|
||||
mapping_meta = {}
|
||||
res = classify_prezentare(content, mapping, mapping_meta)
|
||||
assert res["status"] == "needs_mapping"
|
||||
err = json.loads(res["rar_error"])
|
||||
# Cheia originala pastrata
|
||||
assert "unmapped" in err
|
||||
assert len(err["unmapped"]) == 1
|
||||
assert err["unmapped"][0]["cod_op_service"] == "OP_NECUNOSCUT"
|
||||
# 3 niveluri prezente
|
||||
assert err["cod"] == "COD_NEMAPAT"
|
||||
assert err["problema"]
|
||||
assert err["cauza"]
|
||||
assert err["fix"]
|
||||
|
||||
|
||||
def test_auto_send_oprit_3niveluri(client):
|
||||
"""Mapare cu auto_send=0 -> needs_mapping; rar_error are cheie 'auto_send'
|
||||
PASTRATA + campurile AUTO_SEND_OPRIT (cod/problema/cauza/fix)."""
|
||||
import json
|
||||
from app.mapping import classify_prezentare
|
||||
|
||||
content = {
|
||||
"vin": "WVWZZZ1KZAW000123",
|
||||
"nr_inmatriculare": "B999TST",
|
||||
"data_prestatie": "2026-06-15",
|
||||
"odometru_final": "123456",
|
||||
"prestatii": [{"cod_op_service": "OP_REVIEW", "denumire": "Operatie cu review"}],
|
||||
}
|
||||
mapping = {"OP_REVIEW": "OE-1"}
|
||||
mapping_meta = {"OP_REVIEW": {"cod_prestatie": "OE-1", "auto_send": False}}
|
||||
res = classify_prezentare(content, mapping, mapping_meta)
|
||||
assert res["status"] == "needs_mapping"
|
||||
err = json.loads(res["rar_error"])
|
||||
# Cheia originala pastrata
|
||||
assert "auto_send" in err
|
||||
# 3 niveluri prezente
|
||||
assert err["cod"] == "AUTO_SEND_OPRIT"
|
||||
assert err["problema"]
|
||||
assert err["cauza"]
|
||||
assert err["fix"]
|
||||
|
||||
|
||||
def test_needs_data_pass_through(client):
|
||||
"""VIN invalid -> needs_data; rar_error = array cu erori care au cod/problema/fix (US-002)."""
|
||||
import json
|
||||
from app.mapping import classify_prezentare
|
||||
|
||||
content = {
|
||||
"vin": "VIN_INVALID_XXXXXXXXX", # nu trece regex
|
||||
"nr_inmatriculare": "B999TST",
|
||||
"data_prestatie": "2026-06-15",
|
||||
"odometru_final": "123456",
|
||||
"prestatii": [{"cod_prestatie": "OE-1"}],
|
||||
}
|
||||
mapping = {}
|
||||
mapping_meta = {}
|
||||
res = classify_prezentare(content, mapping, mapping_meta)
|
||||
assert res["status"] == "needs_data"
|
||||
erori = json.loads(res["rar_error"])
|
||||
assert isinstance(erori, list)
|
||||
assert len(erori) >= 1
|
||||
# Fiecare eroare are cele 3 niveluri (pass-through US-002)
|
||||
for e in erori:
|
||||
assert "cod" in e, f"lipseste 'cod' in {e}"
|
||||
assert "problema" in e, f"lipseste 'problema' in {e}"
|
||||
assert "fix" in e, f"lipseste 'fix' in {e}"
|
||||
|
||||
Reference in New Issue
Block a user