import { OnFileCallback, traverseDirectoryTreeWrapper, } from '@/functions/fileReader'; describe('fileReader', () => { it('should process a single file', async () => { const mockFileCallback: OnFileCallback = vi.fn(); const mockFile = new File(['content'], 'mockFile.txt', { type: 'text/plain', }); // Mock FileSystemFileEntry const mockFileEntry = { isFile: true, isDirectory: false, file: vi.fn((callback: (file: File) => void) => callback(mockFile)), } as unknown as FileSystemFileEntry; // Mock DataTransferItem const mockEntry = { webkitGetAsEntry: vi.fn(() => mockFileEntry), } as unknown as DataTransferItem; // Mock DataTransferItemList const mockDataTransferItemList = [ mockEntry, ] as unknown as DataTransferItemList; // Call the wrapper function await traverseDirectoryTreeWrapper( mockDataTransferItemList, mockFileCallback, ); // Assertions expect(mockFileCallback).toHaveBeenCalledWith(mockFile, ''); expect(mockFileCallback).toHaveBeenCalledTimes(1); }); it('should process a nested directory with files', async () => { const mockFileCallback: OnFileCallback = vi.fn(); const mockFile = new File(['content'], 'nestedFile.txt', { type: 'text/plain', }); // Mock FileSystemFileEntry const mockFileEntry = { isFile: true, isDirectory: false, file: vi.fn((callback: (file: File) => void) => callback(mockFile)), } as unknown as FileSystemFileEntry; // Mock nested FileSystemDirectoryReader const mockNestedDirectoryReader = { readEntries: vi .fn() .mockImplementationOnce( (success: (entries: Array) => void) => { success([mockFileEntry]); // First call returns the file entry }, ) .mockImplementationOnce( (success: (entries: Array) => void) => { success([]); // Second call returns no entries, ending recursion }, ), } as unknown as FileSystemDirectoryReader; // Mock nested FileSystemDirectoryEntry const mockNestedDirectoryEntry = { isFile: false, isDirectory: true, name: 'nestedDirectory', createReader: vi.fn(() => mockNestedDirectoryReader), } as unknown as FileSystemDirectoryEntry; // Mock top-level FileSystemDirectoryReader const mockDirectoryReader = { readEntries: vi .fn() .mockImplementationOnce( (success: (entries: Array) => void) => { success([mockNestedDirectoryEntry]); // First call returns the nested directory }, ) .mockImplementationOnce( (success: (entries: Array) => void) => { success([]); // Second call returns no entries, ending recursion }, ), } as unknown as FileSystemDirectoryReader; // Mock top-level FileSystemDirectoryEntry const mockDirectoryEntry = { isFile: false, isDirectory: true, name: 'mockDirectory', createReader: vi.fn(() => mockDirectoryReader), } as unknown as FileSystemDirectoryEntry; // Mock DataTransferItem const mockEntry = { webkitGetAsEntry: vi.fn(() => mockDirectoryEntry), } as unknown as DataTransferItem; // Mock DataTransferItemList const mockDataTransferItemList = [ mockEntry, ] as unknown as DataTransferItemList; // Call the wrapper function await traverseDirectoryTreeWrapper( mockDataTransferItemList, mockFileCallback, ); // Assertions expect(mockFileCallback).toHaveBeenCalledWith( mockFile, 'mockDirectory/nestedDirectory/', ); expect(mockFileCallback).toHaveBeenCalledTimes(1); }); it('should handle an empty directory gracefully', async () => { const mockFileCallback: OnFileCallback = vi.fn(); // Mock FileSystemDirectoryReader const mockDirectoryReader = { readEntries: vi.fn( (success: (entries: Array) => void) => { success([]); // Immediately return no entries }, ), } as unknown as FileSystemDirectoryReader; // Mock FileSystemDirectoryEntry const mockDirectoryEntry = { isFile: false, isDirectory: true, name: 'emptyDirectory', createReader: vi.fn(() => mockDirectoryReader), } as unknown as FileSystemDirectoryEntry; // Mock DataTransferItem const mockEntry = { webkitGetAsEntry: vi.fn(() => mockDirectoryEntry), } as unknown as DataTransferItem; // Mock DataTransferItemList const mockDataTransferItemList = [ mockEntry, ] as unknown as DataTransferItemList; // Call the wrapper function await traverseDirectoryTreeWrapper( mockDataTransferItemList, mockFileCallback, ); // Assertions expect(mockFileCallback).not.toHaveBeenCalled(); // Callback should not be invoked }); });