import { describe, expect, it } from 'vitest'; import type { IssueOut, StatementOut } from '../../types/api'; import statementV2Json from './__fixtures__/statement-v2.json'; import { collapseIssues, issueListItems, issuePlaces, worstSeverity } from './issuePlaces'; import { buildStatementGrid, cellKey } from './statementGrid'; const statement = statementV2Json as unknown as StatementOut; const { rows, columns } = buildStatementGrid(statement); const ids = (list: IssueOut[] | undefined) => (list ?? []).map((i) => i.id); const issue = (patch: Partial): IssueOut => ({ id: 'x', kind: 'warning', code: 'X', severity: 'info', message: 'm', line_ids: [], column_id: null, column_index: null, field: null, source: 'service', relation: null, codes: [], expected: null, actual: null, ...patch, }); describe('issuePlaces', () => { it('привязка фикстуры', () => { const p = issuePlaces(statement.issues, rows, columns); expect(ids(p.byRow.get('l-1370a'))).toContain('i1'); expect(ids(p.byRow.get('l-1370b'))).toContain('i1'); for (const k of ['l-1200', 'l-1210', 'l-1230', 'l-1240']) expect(ids(p.byCell.get(cellKey(k, 'c1')))).toEqual(['i6']); expect(ids(p.byColumn.get('c2'))).toEqual(['i2']); expect(ids(p.byField.get('organization_name'))).toEqual(['i3']); expect(ids(p.byField.get('report_date'))).toEqual(['i5']); expect(ids(p.document)).toEqual(['i4']); expect(ids(p.byRow.get('l-1230'))).toEqual(['i7']); }); it('неизвестные строки и поля — у документа', () => { const gone = issue({ id: 'g', line_ids: ['l-gone'] }); const mixed = issue({ id: 'm', line_ids: ['l-gone', 'l-1210'] }); const okpo = issue({ id: 'o', field: 'okpo' }); const p = issuePlaces([gone, mixed, okpo], rows, columns); expect(ids(p.document)).toEqual(['g', 'o']); expect(ids(p.byRow.get('l-1210'))).toEqual(['m']); expect(p.byRow.size).toBe(1); }); }); describe('issueListItems', () => { const p = issuePlaces(statement.issues, rows, columns); const items = issueListItems(statement.issues, p, rows, columns); it('6 пунктов без relation, error первыми', () => { expect(items).toHaveLength(6); expect(items.slice(0, 2).map((i) => i.id)).toEqual(['i2', 'i5']); expect(items.every((i) => i.id !== 'i6')).toBe(true); }); it('места и цели', () => { const by = (id: string) => items.find((i) => i.id === id); expect(by('i4')).toMatchObject({ place: 'столбец 6 вне колонок формы', targetKey: null }); expect(by('i1')).toMatchObject({ place: 'строка 1370', targetKey: 'l-1370a' }); expect(by('i3')?.place).toBe('поле «Организация»'); expect(by('i2')?.place).toMatch(/^колонка «/); }); it('расшифровка', () => { const d = issue({ id: 'd', line_ids: ['l-d13'] }); const list = issueListItems([d], issuePlaces([d], rows, columns), rows, columns); expect(list[0]).toMatchObject({ place: 'расшифровка «справочно»', targetKey: 'l-d13' }); }); it('строка без кода', () => { const u = issue({ id: 'u', line_ids: ['l-u7'] }); const m = issue({ id: 'mm', line_ids: ['l-m8'] }); const list = issueListItems([u, m], issuePlaces([u, m], rows, columns), rows, columns); expect(list.map((i) => i.place)).toEqual(['строка без кода «ИЧ,250»', 'строка без кода']); }); }); describe('worstSeverity', () => { it('уровни', () => { expect(worstSeverity([issue({ severity: 'info' }), issue({ severity: 'error' })])).toBe('error'); expect(worstSeverity([])).toBeNull(); }); }); describe('collapseIssues (T11.11)', () => { const items = Array.from({ length: 6 }, (_, i) => ({ id: String(i) })) as never[]; it('свёрнуто: первые 3, скрыто 3', () => { expect(collapseIssues(items, false, 3)).toEqual({ shown: items.slice(0, 3), hidden: 3 }); }); it('развёрнуто или короткий список: всё', () => { expect(collapseIssues(items, true, 3)).toEqual({ shown: items, hidden: 0 }); expect(collapseIssues(items.slice(0, 3), false, 3)).toEqual({ shown: items.slice(0, 3), hidden: 0 }); }); });