Merge pull request 'Issue #211: golden-тест учитывает D-7 для синтетики s48/49/50/53' (#212) from fix/211-golden-dup-check into main

This commit is contained in:
aep 2026-11-02 19:33:39 +03:00
commit fcd57311bd

View File

@ -29,13 +29,14 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.contract.result import RecognitionResult from src.contract.result import RecognitionResult
from src.contract.result_v2 import RecognitionResultV2
from src.domain.osv_mapping import normalize_account_code from src.domain.osv_mapping import normalize_account_code
from src.models.accounting import ChartOfAccount from src.models.accounting import ChartOfAccount
from src.models.enums import DocumentType, FileStatus, RecognitionStatus from src.models.enums import DocumentType, FileStatus, RecognitionStatus
from src.models.files import Document, StoredFile from src.models.files import Document, StoredFile
from src.models.osv import OsvEntry from src.models.osv import OsvEntry
from src.repositories.counterparties import CounterpartyIndex 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.factories import make_legal_entity, make_stored_file
from tests.fixtures_helpers import golden_result 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 с.""" """«Все golden-снимки парсера» (не меньше 113) маппятся в БД, инварианты спеки на каждом документе, ≤ 60 с."""
session = seeded session = seeded
snapshots = _snapshots(fixtures_dir) 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 ничего не проверит" assert chart, "план счетов seed пуст — сверка account_id ничего не проверит"
index = await CounterpartyIndex.load(session) index = await CounterpartyIndex.load(session)
mapped: list[tuple[Path, uuid.UUID, RecognitionResult]] = [] mapped: list[tuple[Path, uuid.UUID, RecognitionResult | RecognitionResultV2]] = []
mapping_seconds = 0.0 mapping_seconds = 0.0
for path in snapshots: for path in snapshots:
file, job = await make_stored_file( 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] = [] problems: list[str] = []
missing_codes: set[str] = set() missing_codes: set[str] = set()
documents_total = entries_total = with_account = with_kind = 0 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)) name = str(path.relative_to(fixtures_dir / GOLDEN_DIR))
raw = json.loads(path.read_text("utf-8")) raw = json.loads(path.read_text("utf-8"))
documents = { documents = {
@ -189,7 +190,14 @@ async def test_all_golden_snapshots_mapped(seeded: AsyncSession, fixtures_dir: P
).scalars() ).scalars()
} }
problems.extend(await _form_problems(session, file_id, raw, name)) 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}: if set(documents) != {sheet["locator"] for sheet in sheets}:
problems.append(f"{name}: документы {sorted(documents)} не совпадают с листами снимка") problems.append(f"{name}: документы {sorted(documents)} не совпадают с листами снимка")
continue continue