- Клиент API: ApiError.body, apiFetchBlob для бинарных ответов с автоматическим разбором ошибок - Деньги: formatAmount (строка Decimal → форматированная с пробелами), parseAmountInput (ввод → нормализация) - Подписи: documentTypeLabel, documentStatusLabel, fileStatusLabel, periodLabel для UI - Dev-proxy: /api → localhost:8000 (CORS-free, Content-Disposition читается) - Типы: Quarter, DocumentType, DocumentStatus, FileStatus в src/types/api.ts - Удалён smoke.test.ts Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EAKRDNzXtRrwmWz9z6PZu3
25 lines
1.1 KiB
TypeScript
25 lines
1.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
||
import { exportFilename, filenameFromContentDisposition } from './download';
|
||
|
||
describe('filenameFromContentDisposition', () => {
|
||
it('RFC 5987 filename*', () => {
|
||
expect(filenameFromContentDisposition("attachment; filename*=UTF-8''%D0%A1%D0%B2%D0%BE%D0%B4.xlsx")).toBe('Свод.xlsx');
|
||
});
|
||
it('filename в кавычках', () => {
|
||
expect(filenameFromContentDisposition('attachment; filename="osv.xlsx"')).toBe('osv.xlsx');
|
||
});
|
||
it('filename* важнее filename', () => {
|
||
expect(filenameFromContentDisposition('attachment; filename="a.xlsx"; filename*=UTF-8\'\'b.xlsx')).toBe('b.xlsx');
|
||
});
|
||
it('нет заголовка или имени', () => {
|
||
expect(filenameFromContentDisposition(null)).toBeNull();
|
||
expect(filenameFromContentDisposition('inline')).toBeNull();
|
||
});
|
||
});
|
||
|
||
describe('exportFilename', () => {
|
||
it('безопасное имя', () => {
|
||
expect(exportFilename('ГК «Русский бисквит»/Север', 2024, 'Q3')).toBe('Сводная_ОСВ_ГК_«Русский_бисквит»_Север_2024_Q3.xlsx');
|
||
});
|
||
});
|