test(service-auto): unit tests multi-tenant + lookup + partener + pc_nr

Acoperire 49 tests offline (fără Oracle real):

test_comanda_helpers (16): _build_pc_nr toate prefixele VFP + fallback,
_build_sir_id_operatii csv + limit 4000 chars, _PREFIX_MAP regression.

test_router_authorization (9): _company_id fallback JWT companies[0],
403 firmă neautorizată, 400 companies[] gol, string→int coercion;
_server_id extragere din request.state.

test_lookup_endpoints (15): cache hit/miss per schema pentru tip_deviz,
masini, asiguratori, inspectori (per-asig), operatii; LIKE escape %/_/\;
min 2 chars short-circuit; server_id propagat la get_connection.

test_partener_create (9): 5 Pydantic validation (denumire min 2,
id_firma ge 1, cui opțional), 4 service mocked (happy path, 409
duplicat CUI, fără CUI, lipsă GRANT → 500 log.critical).

Pattern mock Oracle: fake context managers (async get_connection +
sync cursor), monkeypatch pe lookup_service.get_schema (not _context,
din cauza binding copy la import).

Rulare: pytest backend/modules/service_auto/tests/ -q → 62 passed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-13 20:09:55 +00:00
parent 4397027f36
commit fd64cf3f1e
4 changed files with 743 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
"""
Unit tests pentru helperii din comanda_service (fără DB, fără mocks).
Acoperire:
- _build_pc_nr: toate prefixele VFP (tip_id=1..7) + fallback pe tip_id necunoscut
- _build_sir_id_operatii: None, empty, CSV, limit 4000 chars
"""
import pytest
from fastapi import HTTPException
from backend.modules.service_auto.services.comanda_service import (
_build_pc_nr,
_build_sir_id_operatii,
_MAX_OPERATII_CSV,
_PREFIX_MAP,
)
# ---- _build_pc_nr ----
@pytest.mark.parametrize("tip_id,expected_prefix", [
(1, ""), # POST GARANTIE — fără prefix (VFP default)
(2, "G"), # GARANTIE
(3, "R"), # REGIE
(4, "P"), # PREGATIRE
(6, "PR"), # PRODUCTIE
(7, "C"), # CONSTATARE
])
def test_pc_nr_known_tip_ids_use_vfp_prefix(tip_id, expected_prefix):
"""Toate cele 6 tip_id-uri cu prefix VFP verificat (oproceduri_devize.prg)."""
nrord = _build_pc_nr(tip_id, 123, "B-32-CTL")
assert nrord == f"{expected_prefix}123/B-32-CTL"
def test_pc_nr_tip_5_regie_2_no_vfp_mapping_uses_empty_prefix():
"""tip_id=5 (REGIE 2) nu are mapare VFP → fallback prefix ''."""
assert _build_pc_nr(5, 42, "B-10-ABC") == "42/B-10-ABC"
def test_pc_nr_unknown_tip_id_uses_empty_prefix():
"""tip_id necunoscut (ex: 99) → fallback prefix '' + warning logat."""
assert _build_pc_nr(99, 1, "XYZ") == "1/XYZ"
def test_pc_nr_format_matches_vfp_structure():
"""Format final: <prefix><seq>/<nrinmat> — nu '<prefix>/<seq>/<nrinmat>'."""
nrord = _build_pc_nr(2, 777, "CT-10-EEE")
assert nrord == "G777/CT-10-EEE"
assert "/" in nrord
assert nrord.count("/") == 1 # o singură bară
def test_prefix_map_covers_all_vfp_mappings():
"""Regression guard: _PREFIX_MAP nu trebuie scăpat la refactor."""
assert _PREFIX_MAP == {1: "", 2: "G", 3: "R", 4: "P", 6: "PR", 7: "C"}
# ---- _build_sir_id_operatii ----
def test_sir_operatii_none_returns_none():
"""None → None (nu trimite param la SP)."""
assert _build_sir_id_operatii(None) is None
def test_sir_operatii_empty_list_returns_none():
"""Listă goală → None (echivalent cu 'fără operații')."""
assert _build_sir_id_operatii([]) is None
def test_sir_operatii_single_id():
assert _build_sir_id_operatii([42]) == "42"
def test_sir_operatii_multiple_ids_csv():
assert _build_sir_id_operatii([1, 2, 3]) == "1,2,3"
def test_sir_operatii_below_limit_passes():
"""600 ID-uri cu 2 cifre + virgulă = ~1800 chars, sub limita 4000."""
ids = list(range(10, 110)) # 100 IDs, 3 cifre → ~400 chars
result = _build_sir_id_operatii(ids)
assert result is not None
assert len(result) < _MAX_OPERATII_CSV
def test_sir_operatii_over_limit_raises_422():
"""~1000 IDs cu 6 cifre → peste 4000 chars → HTTPException 422."""
big_ids = list(range(100000, 101000)) # 1000 IDs × 7 chars (6 cifre + virgulă) = 7000 chars
with pytest.raises(HTTPException) as exc_info:
_build_sir_id_operatii(big_ids)
assert exc_info.value.status_code == 422
assert "Prea multe" in exc_info.value.detail