"""TDD 5.18 US-007 — Badge sursa sugestie in editorul de mapare (_mapari.html). Chip mic langa sugestia sistemului care arata DE UNDE vine codul propus: - "confirmat" -> GOLD partajat (validat de om, shared_mappings) - "similar" -> SILVER exact-match / k-NN embeddings (exemplu deja vazut) - "non-operatie" -> pre-filtru NUL determinist (ITP/plata/discount...) Toate suggestion-only (#13): badge-ul e doar indiciu vizual, nu schimba enqueue. Render real prin GET /_fragments/mapari (fragmentul HTMX scoped pe cont). """ from __future__ import annotations import json import os import tempfile import pytest @pytest.fixture() def env(monkeypatch): """DB temporara cu schema, auth web dezactivata (mod dev -> cont id=1).""" tmp = tempfile.mkdtemp() monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "badge_sursa_test.db")) monkeypatch.setenv("AUTOPASS_WEB_AUTH_REQUIRED", "false") from app.config import get_settings get_settings.cache_clear() from app.db import init_db init_db() yield monkeypatch get_settings.cache_clear() @pytest.fixture() def client(env): from app.main import app from fastapi.testclient import TestClient with TestClient(app) as c: yield c def _seed_nomenclator(conn): conn.executemany( "INSERT OR IGNORE INTO nomenclator_rar (cod_prestatie, nume_prestatie) VALUES (?, ?)", [("OE-1", "REPARATIE"), ("OE-3", "REVIZIE PERIODICA")], ) def _insert_needs_mapping(conn, *, op: str, denumire: str, key: str): conn.execute( "INSERT INTO submissions (account_id, status, payload_json, idempotency_key) " "VALUES (1, 'needs_mapping', ?, ?)", (json.dumps({ "vin": "WVWZZZ1KZAW001111", "prestatii": [{"cod_op_service": op, "denumire": denumire}], }), key), ) def test_badge_gold_confirmat(env, client): """O operatie cu match in GOLD partajat -> chip 'confirmat' in coloana Sugestii.""" from app.db import get_connection from app.shared_store import record_human_validation conn = get_connection() try: _seed_nomenclator(conn) record_human_validation(conn, "Revizie anuala", "OE-3") _insert_needs_mapping(conn, op="OP-REV", denumire="Revizie anuala", key="badge-gold-1") conn.commit() finally: conn.close() resp = client.get("/_fragments/mapari") assert resp.status_code == 200, resp.text html = resp.text assert "sugg-sursa--confirmat" in html assert ">confirmat<" in html def test_badge_similar_silver(env, client): """O operatie cu match in SILVER (mapping_suggestions) -> chip 'similar'.""" from app.db import get_connection from app.shared_store import seed_suggestions conn = get_connection() try: _seed_nomenclator(conn) seed_suggestions(conn, [ {"denumire": "Reparatie motor", "cod_prestatie": "OE-1", "source": "llm", "confidence": 0.9}, ]) _insert_needs_mapping(conn, op="OP-REP", denumire="Reparatie motor", key="badge-similar-1") conn.commit() finally: conn.close() resp = client.get("/_fragments/mapari") assert resp.status_code == 200, resp.text html = resp.text assert "sugg-sursa--similar" in html assert ">similar<" in html # NU trebuie sa fie marcat confirmat (sursa e SILVER, nu GOLD). assert "sugg-sursa--confirmat" not in html def test_badge_nul_non_operatie(env, client): """O operatie prinsa de pre-filtrul NUL (ITP) -> chip 'non-operatie', fara cod sugerat.""" from app.db import get_connection conn = get_connection() try: _seed_nomenclator(conn) _insert_needs_mapping(conn, op="OP-ITP", denumire="ITP CT 12 ABC", key="badge-nul-1") conn.commit() finally: conn.close() resp = client.get("/_fragments/mapari") assert resp.status_code == 200, resp.text html = resp.text assert "sugg-sursa--nul" in html assert ">non-operatie<" in html def test_fara_sursa_fara_badge(env, client): """O operatie fara nicio sursa (necunoscuta) NU primeste chip de sursa.""" from app.db import get_connection conn = get_connection() try: _seed_nomenclator(conn) _insert_needs_mapping(conn, op="OP-NISA", denumire="Operatie complet necunoscuta xyz", key="badge-none-1") conn.commit() finally: conn.close() resp = client.get("/_fragments/mapari") assert resp.status_code == 200, resp.text assert "sugg-sursa" not in resp.text