import { describe, expect, it } from 'vitest'; import type { QualityMatrixOut } from '../../types/qualityMetrics'; import { filterByPermission } from '../Sidebar/visibility'; import { buildMatrixRows, buildSourceRows, formatReportDate, formatShare, monthLabel, sourceColumns, sumFixes } from './qualityView'; const matrixFixture: QualityMatrixOut = { counts: { SERVICE_ERROR: 3, OUR_ERROR: 2, CLIENT_DOCUMENT: 1, WITHOUT_PARTICIPATION: 12, AS_IS: 5 }, shares: { SERVICE_ERROR: 0.13, OUR_ERROR: 0.087, CLIENT_DOCUMENT: 0.043, WITHOUT_PARTICIPATION: 0.522, AS_IS: 0.217 }, denominator: 23, removed_before_confirm: 4, removed_after_confirm: 3, deleted_after_confirm_count: 1, superseded_after_confirm_count: 2, in_progress_count: 6, unique_reports_count: 20, technical_failures: { failed_files_count: 1, total_files_count: 30, share: 0.033 }, }; describe('пункт меню по праву', () => { const items = [{ link: '/a' }, { link: '/q', permission: 'QUALITY_METRICS_VIEW' }]; it('скрыт без права', () => { expect(filterByPermission(items, ['USERS_ADMIN']).map((i) => i.link)).toEqual(['/a']); }); it('виден с правом', () => { expect(filterByPermission(items, ['QUALITY_METRICS_VIEW']).map((i) => i.link)).toEqual(['/a', '/q']); }); }); describe('buildMatrixRows', () => { const rows = buildMatrixRows(matrixFixture); it('счётчики из ответа API', () => { expect(rows.find((r) => r.key === 'WITHOUT_PARTICIPATION')?.count).toBe(12); expect(rows.find((r) => r.key === 'REMOVED_BEFORE_CONFIRM')?.count).toBe(4); expect(rows.find((r) => r.key === 'IN_PROGRESS')?.count).toBe(6); }); it('доли только у причин; разбивка удалённых после подтверждения', () => { expect(rows.find((r) => r.key === 'WITHOUT_PARTICIPATION')?.share).toBe('52,2%'); expect(rows.find((r) => r.key === 'IN_PROGRESS')?.share).toBeNull(); expect(rows.find((r) => r.key === 'REMOVED_AFTER_CONFIRM')?.note).toBe('удалено: 1, заменено: 2'); }); }); describe('formatShare', () => { it('нет знаменателя — «нет данных», не 0%', () => { expect(formatShare(0, 0)).toBe('нет данных'); }); }); describe('monthLabel', () => { it('месяц.год', () => { expect(monthLabel('2026-03-01')).toBe('03.2026'); }); }); describe('sourceColumns', () => { it('источник не выбран — PDF, Excel, Всего', () => { expect(sourceColumns(undefined).map((c) => c.key)).toEqual(['image', 'tabular', 'all']); }); it('выбран источник — одна колонка', () => { expect(sourceColumns('tabular').map((c) => c.label)).toEqual(['Excel']); }); }); describe('buildSourceRows', () => { it('счётчики по колонкам источника', () => { const excel = { ...matrixFixture, counts: { ...matrixFixture.counts, AS_IS: 1 } }; const rows = buildSourceRows([ { key: 'image', data: matrixFixture }, { key: 'tabular', data: excel }, ]); const asIs = rows.find((r) => r.key === 'AS_IS'); expect(asIs?.cells.image?.count).toBe(5); expect(asIs?.cells.tabular?.count).toBe(1); }); it('пустой список колонок — нет строк', () => { expect(buildSourceRows([])).toEqual([]); }); }); describe('sumFixes', () => { it('суммирует по сервису и по нашему разбору, правку ОСВ не считает', () => { const fixes = { value_service: 1, value_ours: 2, code_service: 3, code_ours: 4, added_row_service: 5, added_row_ours: 6, header_service: 7, header_ours: 8, osv_period_account: 9, }; expect(sumFixes(fixes)).toEqual({ service: 16, ours: 20 }); }); it('нет правок — null', () => { expect(sumFixes(null)).toBeNull(); }); }); describe('formatReportDate', () => { it('ДД.ММ.ГГГГ', () => { expect(formatReportDate('2026-03-31')).toBe('31.03.2026'); expect(formatReportDate(null)).toBe('—'); }); });