Files
flyer-crawler.projectium.com/src/utils/imageProcessor.test.ts
Torben Sorensen e86e09703e
Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 59s
even even more and more test fixes
2026-01-05 11:27:13 -08:00

98 lines
3.0 KiB
TypeScript

// src/utils/imageProcessor.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import type { Logger } from 'pino';
// --- Hoisted Mocks ---
const mocks = vi.hoisted(() => {
// Create a chainable mock for the sharp library
const toFile = vi.fn().mockResolvedValue({ info: 'mocked' });
const webp = vi.fn(() => ({ toFile }));
const resize = vi.fn(() => ({ webp }));
const sharpInstance = { resize };
// Mock the sharp function and attach static properties required by the implementation
const sharp = vi.fn(() => sharpInstance);
Object.assign(sharp, { fit: { cover: 'cover' } });
return {
sharp: sharp,
resize,
webp,
toFile,
mkdir: vi.fn().mockResolvedValue(undefined),
};
});
// --- Mock Modules ---
vi.mock('sharp', () => ({
__esModule: true,
default: mocks.sharp,
}));
vi.mock('node:fs/promises', () => ({
default: {
mkdir: mocks.mkdir,
},
}));
// Helper to create a type-safe mock logger
const createMockLogger = (): Logger =>
({
info: vi.fn(),
error: vi.fn(),
warn: vi.fn(),
debug: vi.fn(),
fatal: vi.fn(),
trace: vi.fn(),
silent: vi.fn(),
child: vi.fn(() => createMockLogger()), // Return a new mock for child loggers
level: 'info',
}) as unknown as Logger;
const logger = createMockLogger();
vi.mock('../services/logger.server', () => ({ logger }));
// --- Import the function to be tested ---
import { generateFlyerIcon } from './imageProcessor';
describe('generateFlyerIcon', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should process the image and return the correct icon filename', async () => {
const sourceImagePath = '/path/to/flyer image (1).jpg';
const iconsDirectory = '/path/to/icons';
const result = await generateFlyerIcon(sourceImagePath, iconsDirectory, logger);
// Check that the icons directory was created
expect(mocks.mkdir).toHaveBeenCalledWith(iconsDirectory, { recursive: true });
// Check that sharp was called with the correct source
expect(mocks.sharp).toHaveBeenCalledWith(sourceImagePath, { failOn: 'none' });
// Check the processing chain
expect(mocks.resize).toHaveBeenCalledWith({ width: 128, height: 128, fit: 'inside' });
expect(mocks.webp).toHaveBeenCalledWith({ quality: 75 });
expect(mocks.toFile).toHaveBeenCalledWith('/path/to/icons/icon-flyer-image-1.webp');
// Check the returned filename
expect(result).toBe('icon-flyer-image-1.webp');
});
it('should throw an error if sharp fails to process the image', async () => {
const sharpError = new Error('Invalid image buffer');
mocks.toFile.mockRejectedValue(sharpError);
await expect(
generateFlyerIcon('/path/to/bad-image.jpg', '/path/to/icons', logger), // This was a duplicate, fixed.
).rejects.toThrow('Failed to generate icon for /path/to/bad-image.jpg.');
expect(logger.error).toHaveBeenCalledWith(
{ err: sharpError, sourcePath: '/path/to/bad-image.jpg', outputPath: '/path/to/icons/icon-bad-image.webp' },
'An error occurred during icon generation.',
);
});
});