diff --git a/api/tests/test_mapping_golden.py b/api/tests/test_mapping_golden.py index 399c874..7b6915e 100644 --- a/api/tests/test_mapping_golden.py +++ b/api/tests/test_mapping_golden.py @@ -29,13 +29,14 @@ from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from src.contract.result import RecognitionResult +from src.contract.result_v2 import RecognitionResultV2 from src.domain.osv_mapping import normalize_account_code from src.models.accounting import ChartOfAccount from src.models.enums import DocumentType, FileStatus, RecognitionStatus from src.models.files import Document, StoredFile from src.models.osv import OsvEntry from src.repositories.counterparties import CounterpartyIndex -from src.services.result_mapping import map_file +from src.services.result_mapping import _osv_documents, _split_duplicates, map_file from tests.factories import make_legal_entity, make_stored_file from tests.fixtures_helpers import golden_result @@ -141,7 +142,7 @@ async def _form_problems(session: AsyncSession, file_id: uuid.UUID, raw: dict[st ] -async def test_all_golden_snapshots_mapped(seeded: AsyncSession, fixtures_dir: Path) -> None: # noqa: PLR0914 +async def test_all_golden_snapshots_mapped(seeded: AsyncSession, fixtures_dir: Path) -> None: # noqa: PLR0914, PLR0915 """«Все golden-снимки парсера» (не меньше 113) маппятся в БД, инварианты спеки на каждом документе, ≤ 60 с.""" session = seeded snapshots = _snapshots(fixtures_dir) @@ -155,7 +156,7 @@ async def test_all_golden_snapshots_mapped(seeded: AsyncSession, fixtures_dir: P assert chart, "план счетов seed пуст — сверка account_id ничего не проверит" index = await CounterpartyIndex.load(session) - mapped: list[tuple[Path, uuid.UUID, RecognitionResult]] = [] + mapped: list[tuple[Path, uuid.UUID, RecognitionResult | RecognitionResultV2]] = [] mapping_seconds = 0.0 for path in snapshots: file, job = await make_stored_file( @@ -174,7 +175,7 @@ async def test_all_golden_snapshots_mapped(seeded: AsyncSession, fixtures_dir: P problems: list[str] = [] missing_codes: set[str] = set() documents_total = entries_total = with_account = with_kind = 0 - for path, file_id, _ in mapped: + for path, file_id, result in mapped: name = str(path.relative_to(fixtures_dir / GOLDEN_DIR)) raw = json.loads(path.read_text("utf-8")) documents = { @@ -189,7 +190,14 @@ async def test_all_golden_snapshots_mapped(seeded: AsyncSession, fixtures_dir: P ).scalars() } problems.extend(await _form_problems(session, file_id, raw, name)) - sheets = [sheet for sheet in raw["documents"] if sheet["document_type"] == "OSV"] + # D-7: повтор счёта/периода в одном файле не становится отдельным документом + # (services/result_mapping._split_duplicates) — синтетика s48/s49/s50/s53 (tp#81, AURORA-1717/1732) намеренно + # кладёт несколько листов под один счёт в одном файле, проверяя распознавание разных названий ведомости. + kept, _duplicate_warnings, _warnings = _split_duplicates(_osv_documents(result)) + kept_locators = {sheet.locator for sheet in kept} + sheets = [ + sheet for sheet in raw["documents"] if sheet["document_type"] == "OSV" and sheet["locator"] in kept_locators + ] if set(documents) != {sheet["locator"] for sheet in sheets}: problems.append(f"{name}: документы {sorted(documents)} не совпадают с листами снимка") continue