import { describe, expect, it } from 'vitest'; import type { HeaderFieldOut, IssueOut, StatementHeaderOut, StatementOut } from '../../types/api'; import statementV2Json from './__fixtures__/statement-v2.json'; import { headerFields } from './headerFields'; const f = (value: string | null, extra: Partial = {}): HeaderFieldOut => ({ value, original_value: value, confidence: null, verified: null, modified: false, ...extra, }); const header = (over: Partial = {}) => ({ inn: f('3528104476'), report_date: f('2024-12-31'), units: f('тыс. руб.'), organization_name: 'ООО Ромашка', organization_name_modified: false, okei: null, needs_review_fields: [], source: {}, okud: null, okpo: null, okopf: null, okfs: null, address: null, ...over, }) as StatementHeaderOut; const fixtureHeader = (statementV2Json as unknown as StatementOut).header; const fixtureIssue = (statementV2Json as unknown as StatementOut).issues.find((i) => i.id === 'i3') as IssueOut; describe('headerFields — шапка: организация, поля на проверку, подсказки источника', () => { it('четыре поля по порядку', () => { const rows = headerFields(fixtureHeader); expect(rows.map((r) => [r.field, r.label])).toEqual([ ['organization_name', 'Организация'], ['inn', 'ИНН'], ['report_date', 'Дата отчёта'], ['units', 'Единица измерения'], ]); expect(rows[2].text).toBe('30.09.2025'); }); it('внимание только по needs_review_fields', () => { const rows = headerFields(fixtureHeader); expect(rows[2]).toMatchObject({ attention: true, canConfirm: true }); expect(rows[0]).toMatchObject({ attention: false, canConfirm: false }); const low = headerFields(header({ inn: f('312120035', { confidence: '50' }) })); expect(low[1].attention).toBe(false); const empty = headerFields(header({ inn: f(null) })); expect(empty[1]).toMatchObject({ attention: false, text: '—' }); }); it('подтвердить можно только дату с известным значением', () => { const rows = headerFields(header({ needs_review_fields: ['report_date'], report_date: f(null) })); expect(rows[2].canConfirm).toBe(false); }); it('подсказка источника', () => { expect(headerFields(fixtureHeader)[0].tip).toBe('Распознано: «ООО «Ромашкa»» · уверенность 67%'); const h = header({ source: { organization_name: { text: 'ООО Р', confidence: '67.00' } } }); expect(headerFields(h)[0].tip).toBe('Распознано: «ООО Р» · уверенность 67%'); expect(headerFields(header())[0].tip).toBeUndefined(); }); it('уверенность в подсказке округляется, нечисловая — без хвоста, пустой текст — без подсказки', () => { const tip = (confidence: string | null, text = 'ООО Р') => headerFields(header({ source: { organization_name: { text, confidence } } }))[0].tip; expect(tip('61.54')).toBe('Распознано: «ООО Р» · уверенность 62%'); expect(tip('abc')).toBe('Распознано: «ООО Р»'); expect(tip('67', ' ')).toBeUndefined(); }); it('исправленное поле — исходное в подсказке', () => { const rows = headerFields(header({ units: f('руб.', { modified: true, original_value: 'тыс. руб.' }) })); expect(rows[3]).toMatchObject({ modified: true, tip: 'Исходное: тыс. руб.' }); }); it('исправленная организация', () => { const h = header({ organization_name_modified: true, source: { organization_name: { text: 'ООО Р', confidence: '67.00' } }, }); expect(headerFields(h)[0]).toMatchObject({ modified: true, tip: 'Распознано: «ООО Р»' }); }); it('предупреждения поля', () => { const rows = headerFields(fixtureHeader, new Map([['organization_name', [fixtureIssue]]])); expect(rows[0].issues).toEqual([fixtureIssue]); expect(rows[1].issues).toEqual([]); }); });