97 lines
3.1 KiB
TypeScript
97 lines
3.1 KiB
TypeScript
// src/utils/fileUtils.test.ts
|
|
import { describe, it, expect, vi, beforeEach, Mocked } from 'vitest';
|
|
import fs from 'node:fs/promises';
|
|
import { logger } from '../services/logger.server';
|
|
import { cleanupUploadedFile, cleanupUploadedFiles } from './fileUtils';
|
|
|
|
// Mock dependencies
|
|
vi.mock('node:fs/promises', () => ({
|
|
default: {
|
|
unlink: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
vi.mock('../services/logger.server', () => ({
|
|
logger: {
|
|
warn: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
// Cast the mocked imports for type safety
|
|
const mockedFs = fs as Mocked<typeof fs>;
|
|
const mockedLogger = logger as Mocked<typeof logger>;
|
|
|
|
describe('fileUtils', () => {
|
|
beforeEach(() => {
|
|
// Clear mock history before each test
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('cleanupUploadedFile', () => {
|
|
it('should call fs.unlink with the correct file path', async () => {
|
|
const mockFile = { path: '/tmp/test-file.jpg' } as Express.Multer.File;
|
|
mockedFs.unlink.mockResolvedValue(undefined);
|
|
|
|
await cleanupUploadedFile(mockFile);
|
|
|
|
expect(mockedFs.unlink).toHaveBeenCalledWith('/tmp/test-file.jpg');
|
|
});
|
|
|
|
it('should not call fs.unlink if the file is undefined', async () => {
|
|
await cleanupUploadedFile(undefined);
|
|
expect(mockedFs.unlink).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should log a warning and not throw if fs.unlink fails', async () => {
|
|
const mockFile = { path: '/tmp/non-existent-file.jpg' } as Express.Multer.File;
|
|
const unlinkError = new Error('ENOENT: no such file or directory');
|
|
mockedFs.unlink.mockRejectedValue(unlinkError);
|
|
|
|
// Use a try-catch to ensure no error is thrown from the function itself
|
|
let didThrow = false;
|
|
try {
|
|
await cleanupUploadedFile(mockFile);
|
|
} catch {
|
|
didThrow = true;
|
|
}
|
|
|
|
expect(didThrow).toBe(false);
|
|
expect(mockedLogger.warn).toHaveBeenCalledWith(
|
|
{ err: unlinkError, filePath: mockFile.path },
|
|
'Failed to clean up uploaded file.',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('cleanupUploadedFiles', () => {
|
|
const mockFiles = [
|
|
{ path: '/tmp/file1.jpg' },
|
|
{ path: '/tmp/file2.png' },
|
|
] as Express.Multer.File[];
|
|
|
|
it('should call fs.unlink for each file in the array', async () => {
|
|
mockedFs.unlink.mockResolvedValue(undefined);
|
|
|
|
await cleanupUploadedFiles(mockFiles);
|
|
|
|
expect(mockedFs.unlink).toHaveBeenCalledTimes(2);
|
|
expect(mockedFs.unlink).toHaveBeenCalledWith('/tmp/file1.jpg');
|
|
expect(mockedFs.unlink).toHaveBeenCalledWith('/tmp/file2.png');
|
|
});
|
|
|
|
it('should not call fs.unlink if the files array is undefined', async () => {
|
|
await cleanupUploadedFiles(undefined);
|
|
expect(mockedFs.unlink).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should not call fs.unlink if the input is not an array', async () => {
|
|
await cleanupUploadedFiles({ not: 'an array' } as unknown as Express.Multer.File[]);
|
|
expect(mockedFs.unlink).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should handle an empty array gracefully', async () => {
|
|
await cleanupUploadedFiles([]);
|
|
expect(mockedFs.unlink).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
}); |