UNPKG

@accounter/shaam-uniform-format-generator

Version:

Fully typed application that generates, parses, and validates SHAAM uniform format tax reports (INI.TXT and BKMVDATA.TXT).

277 lines (226 loc) • 10.1 kB
import { describe, expect, it } from 'vitest'; import { createDataFile, createFile, createIniFile, createShaamFiles, FileNaming, getFileInfo, readFileAsText, validateShaamFile, } from '../../src/utils/file-helpers.js'; describe('File Helpers', () => { describe('createFile', () => { it('should create a File object with correct content and name', () => { const content = 'Test content'; const filename = 'test.txt'; const file = createFile(content, filename); expect(file).toBeInstanceOf(File); expect(file.name).toBe(filename); expect(file.type).toBe('text/plain'); expect(file.size).toBeGreaterThan(0); }); it('should normalize line endings to CRLF', () => { const contentWithLF = 'Line 1\nLine 2\nLine 3'; const contentWithCRLF = 'Line 1\r\nLine 2\r\nLine 3'; const fileLF = createFile(contentWithLF, 'test1.txt'); const fileCRLF = createFile(contentWithCRLF, 'test2.txt'); expect(fileLF.size).toBe(fileCRLF.size); }); it('should throw error for empty text', () => { expect(() => createFile('', 'test.txt')).toThrow('Text content must be a non-empty string'); expect(() => createFile(null as unknown as string, 'test.txt')).toThrow( 'Text content must be a non-empty string', ); }); it('should throw error for empty filename', () => { expect(() => createFile('content', '')).toThrow('Filename must be a non-empty string'); expect(() => createFile('content', null as unknown as string)).toThrow( 'Filename must be a non-empty string', ); }); it('should accept custom options', () => { const file = createFile('content', 'test.csv', { type: 'text/csv' }); expect(file.type).toBe('text/csv'); }); }); describe('createIniFile', () => { it('should create INI file with correct naming convention', () => { const iniText = 'A000...'; const file = createIniFile(iniText, 'my-report'); expect(file.name).toBe('my-report.INI.TXT'); expect(file.type).toBe('text/plain'); }); it('should use default name when not provided', () => { const iniText = 'A000...'; const file = createIniFile(iniText); expect(file.name).toBe('report.INI.TXT'); }); }); describe('createDataFile', () => { it('should create data file with correct naming convention', () => { const dataText = 'A100...'; const file = createDataFile(dataText, 'my-report'); expect(file.name).toBe('my-report.BKMVDATA.TXT'); expect(file.type).toBe('text/plain'); }); it('should use default name when not provided', () => { const dataText = 'A100...'; const file = createDataFile(dataText); expect(file.name).toBe('report.BKMVDATA.TXT'); }); }); describe('createShaamFiles', () => { it('should create both INI and data files', () => { const iniText = 'A000...'; const dataText = 'A100...'; const { iniFile, dataFile } = createShaamFiles(iniText, dataText, 'test-report'); expect(iniFile.name).toBe('test-report.INI.TXT'); expect(dataFile.name).toBe('test-report.BKMVDATA.TXT'); expect(iniFile.type).toBe('text/plain'); expect(dataFile.type).toBe('text/plain'); }); it('should use default base name when not provided', () => { const iniText = 'A000...'; const dataText = 'A100...'; const { iniFile, dataFile } = createShaamFiles(iniText, dataText); expect(iniFile.name).toBe('report.INI.TXT'); expect(dataFile.name).toBe('report.BKMVDATA.TXT'); }); }); describe('validateShaamFile', () => { it('should validate correct INI file', () => { const iniFile = createIniFile('A000...', 'test'); expect(validateShaamFile(iniFile, 'ini')).toBe(true); }); it('should validate correct data file', () => { const dataFile = createDataFile('A100...', 'test'); expect(validateShaamFile(dataFile, 'data')).toBe(true); }); it('should reject file with wrong extension for INI', () => { const wrongFile = createFile('content', 'test.BKMVDATA.TXT'); expect(validateShaamFile(wrongFile, 'ini')).toBe(false); }); it('should reject file with wrong extension for data', () => { const wrongFile = createFile('content', 'test.INI.TXT'); expect(validateShaamFile(wrongFile, 'data')).toBe(false); }); it('should reject non-File objects', () => { expect(validateShaamFile(null as unknown as File, 'ini')).toBe(false); expect(validateShaamFile({} as unknown as File, 'ini')).toBe(false); expect(validateShaamFile('string' as unknown as File, 'ini')).toBe(false); }); it('should reject files with wrong MIME type', () => { const wrongMimeFile = createFile('content', 'test.INI.TXT', { type: 'application/json' }); expect(validateShaamFile(wrongMimeFile, 'ini')).toBe(false); }); it('should reject empty files', () => { // Create empty file by using empty string (though our createFile prevents this) const emptyFile = new File([''], 'test.INI.TXT', { type: 'text/plain' }); expect(validateShaamFile(emptyFile, 'ini')).toBe(false); }); }); describe('readFileAsText', () => { it('should read file content as text', async () => { const content = 'Test file content'; const file = createFile(content, 'test.txt'); const result = await readFileAsText(file); expect(result).toContain('Test file content'); }); it('should throw error for non-File input', async () => { await expect(readFileAsText(null as unknown as File)).rejects.toThrow( 'Input must be a valid File object', ); await expect(readFileAsText({} as unknown as File)).rejects.toThrow( 'Input must be a valid File object', ); }); }); describe('getFileInfo', () => { it('should return correct file information', () => { const file = createFile('content', 'test.txt'); const info = getFileInfo(file); expect(info).toEqual({ name: 'test.txt', size: expect.any(Number), type: 'text/plain', lastModified: expect.any(Number), }); expect(info.size).toBeGreaterThan(0); }); it('should throw error for non-File input', () => { expect(() => getFileInfo(null as unknown as File)).toThrow( 'Input must be a valid File object', ); expect(() => getFileInfo({} as unknown as File)).toThrow('Input must be a valid File object'); }); }); describe('FileNaming utilities', () => { describe('iniFileName', () => { it('should generate correct INI filename', () => { expect(FileNaming.iniFileName('test')).toBe('test.INI.TXT'); expect(FileNaming.iniFileName()).toBe('report.INI.TXT'); }); }); describe('dataFileName', () => { it('should generate correct data filename', () => { expect(FileNaming.dataFileName('test')).toBe('test.BKMVDATA.TXT'); expect(FileNaming.dataFileName()).toBe('report.BKMVDATA.TXT'); }); }); describe('extractBaseName', () => { it('should extract base name from INI filename', () => { expect(FileNaming.extractBaseName('test.INI.TXT')).toBe('test'); expect(FileNaming.extractBaseName('my-report.INI.TXT')).toBe('my-report'); }); it('should extract base name from data filename', () => { expect(FileNaming.extractBaseName('test.BKMVDATA.TXT')).toBe('test'); expect(FileNaming.extractBaseName('my-report.BKMVDATA.TXT')).toBe('my-report'); }); it('should handle case-insensitive extraction', () => { expect(FileNaming.extractBaseName('test.ini.txt')).toBe('test'); expect(FileNaming.extractBaseName('test.bkmvdata.txt')).toBe('test'); }); it('should return default for invalid filenames', () => { expect(FileNaming.extractBaseName('invalid.txt')).toBe('report'); expect(FileNaming.extractBaseName('')).toBe('report'); }); }); describe('isValidShaamFileName', () => { it('should validate correct SHAAM filenames', () => { expect(FileNaming.isValidShaamFileName('test.INI.TXT')).toBe(true); expect(FileNaming.isValidShaamFileName('test.BKMVDATA.TXT')).toBe(true); expect(FileNaming.isValidShaamFileName('my-report.INI.TXT')).toBe(true); expect(FileNaming.isValidShaamFileName('my-report.BKMVDATA.TXT')).toBe(true); }); it('should handle case-insensitive validation', () => { expect(FileNaming.isValidShaamFileName('test.ini.txt')).toBe(true); expect(FileNaming.isValidShaamFileName('test.bkmvdata.txt')).toBe(true); }); it('should reject invalid filenames', () => { expect(FileNaming.isValidShaamFileName('test.txt')).toBe(false); expect(FileNaming.isValidShaamFileName('test.csv')).toBe(false); expect(FileNaming.isValidShaamFileName('test')).toBe(false); expect(FileNaming.isValidShaamFileName('')).toBe(false); }); }); }); describe('Integration with SHAAM format', () => { it('should work with typical SHAAM file content', () => { const iniContent = 'A000 000000000000000123456789...\r\nA100000000000000001\r\n'; const dataContent = 'A100000000001123456789...\r\nZ900000000008123456789...\r\n'; const { iniFile, dataFile } = createShaamFiles(iniContent, dataContent, 'shaam-report'); expect(validateShaamFile(iniFile, 'ini')).toBe(true); expect(validateShaamFile(dataFile, 'data')).toBe(true); expect(iniFile.name).toBe('shaam-report.INI.TXT'); expect(dataFile.name).toBe('shaam-report.BKMVDATA.TXT'); }); it('should maintain CRLF line endings', async () => { const content = 'Line 1\nLine 2\nLine 3'; const file = createFile(content, 'test.txt'); const result = await readFileAsText(file); expect(result).toContain('\r\n'); expect(result).not.toMatch(/(?<!\r)\n/); // Should not have LF without CR }); }); });