"""Teste US-009 (PRD 5.20) — Import web: selector mediu RAR conditionat de disponibilitate. Verifica: - La 0 medii: banner avertisment non-blocant (upload functioneaza, commit foloseste ancora globala). - La 1 mediu: eticheta statica, fara selector; submissions primesc acel mediu. - La 2 medii: selector vizibil pre-bifat pe default-ul contului. - La commit: toate submission-urile lotului primesc rar_env ales (sau fallback ancora globala). """ from __future__ import annotations import csv import io import os import re import tempfile import pytest from fastapi.testclient import TestClient # --------------------------------------------------------------------------- # # Fixture client cu DB izolat # # --------------------------------------------------------------------------- # @pytest.fixture() def client(monkeypatch): tmp = tempfile.mkdtemp() monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "rar_env_test.db")) monkeypatch.setenv("AUTOPASS_WEB_AUTH_REQUIRED", "false") monkeypatch.setenv("AUTOPASS_RAR_ENV", "test") # ancora globala = test from app.config import get_settings get_settings.cache_clear() from app.crypto import reset_cache reset_cache() from app.main import app with TestClient(app) as c: yield c get_settings.cache_clear() reset_cache() # --------------------------------------------------------------------------- # # Utilitare # # --------------------------------------------------------------------------- # def _csv_bytes(rows: list[dict], sep: str = ";") -> bytes: buf = io.StringIO() writer = csv.DictWriter(buf, fieldnames=list(rows[0].keys()), delimiter=sep) writer.writeheader() writer.writerows(rows) return buf.getvalue().encode("utf-8") def _seed_nomenclator_si_mapare(client: TestClient) -> None: """Semeaza nomenclatorul si o mapare pentru randuri ok.""" 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,?,?,1)", ("OP-FRANE", "R-FRANE"), ) conn.commit() finally: conn.close() def _configureaza_un_mediu(client: TestClient, env: str = "test") -> None: """Activeaza un singur mediu RAR pe contul 1 (simulate creds disponibile).""" from app.db import get_connection from app.crypto import encrypt_creds conn = get_connection() try: fake_creds = encrypt_creds({"email": "test@rar.ro", "password": "pass"}) if env == "test": conn.execute( "UPDATE accounts SET rar_test_enabled=1, rar_creds_test_enc=?, " "rar_prod_enabled=0, rar_creds_prod_enc=NULL, rar_env_default='test' WHERE id=1", (fake_creds,), ) else: conn.execute( "UPDATE accounts SET rar_prod_enabled=1, rar_creds_prod_enc=?, " "rar_test_enabled=0, rar_creds_test_enc=NULL, rar_env_default='prod' WHERE id=1", (fake_creds,), ) conn.commit() finally: conn.close() def _configureaza_doua_medii(client: TestClient, default_env: str = "test") -> None: """Activeaza ambele medii RAR pe contul 1.""" from app.db import get_connection from app.crypto import encrypt_creds conn = get_connection() try: fake_test = encrypt_creds({"email": "test@rar.ro", "password": "pass_test"}) fake_prod = encrypt_creds({"email": "prod@rar.ro", "password": "pass_prod"}) conn.execute( "UPDATE accounts SET " "rar_test_enabled=1, rar_creds_test_enc=?, " "rar_prod_enabled=1, rar_creds_prod_enc=?, " "rar_env_default=? WHERE id=1", (fake_test, fake_prod, default_env), ) conn.commit() finally: conn.close() _ROWS_OK = [ { "VIN": "WVWZZZ1KZAW009001", "Nr": "B009TST", "Data": "2026-06-15", "KM": "77000", "Operatie": "OP-FRANE", }, ] def _upload_si_mapare(client: TestClient, rows: list[dict]) -> int: """Upload CSV si seteaza mapare coloane. Intoarce import_id.""" data = _csv_bytes(rows) r = client.post( "/_import/upload", files={"file": ("test.csv", io.BytesIO(data), "text/csv")}, ) assert r.status_code == 200, r.text m = re.search(r"/_import/(\d+)/", r.text) assert m, f"import_id negasit in raspunsul de upload: {r.text[:400]}" iid = int(m.group(1)) # Seteaza maparea daca nu e deja if f"/_import/{iid}/mapare-coloane" in r.text or "mapare-coloane" in r.text.lower(): r2 = client.post( f"/_import/{iid}/mapare-coloane", data={ "colname": ["VIN", "Nr", "Data", "KM", "Operatie"], "canon": ["vin", "nr_inmatriculare", "data_prestatie", "odometru_final", "operatie"], "format_data": "YYYY-MM-DD", }, ) assert r2.status_code == 200, r2.text return iid def _get_preview(client: TestClient, iid: int) -> str: rp = client.get(f"/_import/{iid}/preview") assert rp.status_code == 200, rp.text return rp.text def _commit(client: TestClient, iid: int, n_ok: int, rar_env: str | None = None) -> object: data = { "csrf_token": "", "n_confirmat": str(n_ok), "confirmed_by": "test@us009.ro", } if rar_env: data["rar_env"] = rar_env return client.post(f"/_import/{iid}/confirma", data=data) # --------------------------------------------------------------------------- # # Tests # # --------------------------------------------------------------------------- # def test_selector_ascuns_la_un_mediu(client): """La 1 mediu disponibil: nu apare selector; apare eticheta statica cu mediul.""" _seed_nomenclator_si_mapare(client) _configureaza_un_mediu(client, env="test") # GET fragment/import: verifica ca nu exista selector si apare eticheta r = client.get("/_fragments/import") assert r.status_code == 200, r.text html = r.text # Eticheta statica "Testare" trebuie sa fie prezenta assert "Testare" in html, "Eticheta mediu 'Testare' lipseste la 1 mediu disponibil" # Selectorul nu trebuie sa apara (input cu name=rar_env hidden, dar fara