"""Teste T5: import DBF -> SQLite (dry-run/raport + commit idempotent). `mapare_prestatii.DBF` real e gol, deci pentru maparile reale scriem fixturi DBF dBASE III minimale. Nomenclatorul real (`prestatii_rar.DBF`, 20 randuri) e citit direct pentru un test de read pe date reale. """ from __future__ import annotations import os import struct import tempfile from pathlib import Path import pytest from app.config import ROOT # --------------------------------------------------------------------------- # # Helper: scriitor dBASE III minimal pentru fixturi # # --------------------------------------------------------------------------- # def write_dbf(path: Path, fields: list[tuple[str, str, int]], records: list[dict]) -> None: """Scrie un DBF dBASE III. fields = [(nume, tip C/L, lungime)].""" header = bytearray(32) header[0] = 0x03 # dBASE III, fara memo header[1:4] = bytes((25, 1, 1)) # data ultimei actualizari (fictiva) n_fields = len(fields) header_len = 32 + 32 * n_fields + 1 record_len = 1 + sum(length for _, _, length in fields) struct.pack_into(" tuple[Path, Path]: mp = dirpath / "mapare.DBF" np_ = dirpath / "prest.DBF" write_dbf( np_, PREST_FIELDS, [{"COD_PREST": "OE-1", "NUME_PREST": "REPARATIE"}, {"COD_PREST": "R-ODO", "NUME_PREST": "REPARATIE ODOMETRU"}], ) write_dbf( mp, MAPARE_FIELDS, [ {"COD_OP": "OP1", "DESCR_OP": "Reparatie", "COD_RAR": "OE-1", "AUTO_SEND": True}, {"COD_OP": "OP2", "DESCR_OP": "Operatie necunoscuta", "COD_RAR": "XYZ", "AUTO_SEND": False}, # orfan ], ) return mp, np_ def test_dry_run_does_not_write(env): from tools.import_dbf import run from app.db import get_connection mp, np_ = _fixtures(env) res = run(commit=False, mapare_path=mp, prest_path=np_) assert res["written"] == {"nomenclator": 0, "mapari": 0} assert len(res["orphans"]) == 1 assert res["orphans"][0]["cod_op_service"] == "OP2" conn = get_connection() try: n = conn.execute("SELECT COUNT(*) AS n FROM operations_mapping").fetchone()["n"] assert n == 0 finally: conn.close() def test_commit_writes_and_is_idempotent(env): from tools.import_dbf import run from app.db import get_connection mp, np_ = _fixtures(env) res1 = run(commit=True, mapare_path=mp, prest_path=np_) assert res1["written"] == {"nomenclator": 2, "mapari": 2} conn = get_connection() try: maps = conn.execute( "SELECT cod_op_service, cod_prestatie, auto_send FROM operations_mapping ORDER BY cod_op_service" ).fetchall() assert [(m["cod_op_service"], m["cod_prestatie"], m["auto_send"]) for m in maps] == [ ("OP1", "OE-1", 1), ("OP2", "XYZ", 0), ] nom = conn.execute("SELECT COUNT(*) AS n FROM nomenclator_rar").fetchone()["n"] finally: conn.close() # A doua rulare nu duplica (upsert pe cheile UNIQUE). run(commit=True, mapare_path=mp, prest_path=np_) conn = get_connection() try: assert conn.execute("SELECT COUNT(*) AS n FROM operations_mapping").fetchone()["n"] == 2 assert conn.execute("SELECT COUNT(*) AS n FROM nomenclator_rar").fetchone()["n"] == nom finally: conn.close() def test_missing_dbf_raises(env): from tools.import_dbf import run with pytest.raises(FileNotFoundError): run(commit=False, mapare_path=env / "nope.DBF", prest_path=env / "nope2.DBF")