- Fixed NodeJS.Timer → NodeJS.Timeout in scheduler.ts line 13 - Fixed NodeJS.Timer[] → NodeJS.Timeout[] in fixtures.ts line 151 - Resolves TypeScript compile errors from iteration 0 review - All 260 tests passing, build succeeds with no errors
94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
|
|
// Mock parser to avoid LLM calls
|
|
vi.mock('$lib/server/parser', () => ({
|
|
extractRecipe: vi.fn().mockResolvedValue({
|
|
name: 'Test Recipe',
|
|
ingredients: [],
|
|
instructions: 'Test instructions',
|
|
servings: 4
|
|
}),
|
|
detectRecipe: vi.fn().mockResolvedValue(true)
|
|
}));
|
|
|
|
// Mock tandoor to avoid API calls
|
|
vi.mock('$lib/server/tandoor', () => ({
|
|
uploadRecipeWithIngredientsDTO: vi.fn().mockResolvedValue({ id: 123 }),
|
|
uploadRecipeImage: vi.fn().mockResolvedValue(true)
|
|
}));
|
|
|
|
import { queueManager } from '$lib/server/queue/QueueManager';
|
|
import * as extraction from '$lib/server/extraction';
|
|
import { queueProcessor } from '$lib/server/queue/QueueProcessor';
|
|
|
|
describe('QueueProcessor logging', () => {
|
|
|
|
let consoleErrorSpy: any;
|
|
|
|
beforeEach(async () => {
|
|
// Stop processor first
|
|
queueProcessor.stop();
|
|
|
|
// Clear queue
|
|
const items = queueManager.getAll();
|
|
items.forEach(item => queueManager.remove(item.id));
|
|
|
|
// Setup console.error spy
|
|
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
|
|
// Give time for cleanup
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
});
|
|
|
|
afterEach(() => {
|
|
queueProcessor.stop();
|
|
consoleErrorSpy.mockRestore();
|
|
});
|
|
|
|
test('error logs should be properly serialized (no [object Object])', async () => {
|
|
// Create complex error object
|
|
const complexError = new Error('Test extraction error');
|
|
(complexError as any).code = 'ERR_TEST';
|
|
(complexError as any).details = { phase: 'extraction', retries: 3 };
|
|
|
|
// Mock extraction to fail BEFORE starting processor
|
|
const extractSpy = vi.spyOn(extraction, 'extractTextAndThumbnail');
|
|
extractSpy.mockRejectedValueOnce(complexError);
|
|
|
|
const item = queueManager.enqueue('https://instagram.com/p/TEST');
|
|
queueProcessor.start();
|
|
|
|
// Wait for error status
|
|
await vi.waitFor(() => {
|
|
const updated = queueManager.get(item.id);
|
|
return updated?.status === 'error' || updated?.status === 'unhealthy';
|
|
}, { timeout: 5000 });
|
|
|
|
// Stop processor
|
|
queueProcessor.stop();
|
|
|
|
// Wait a bit for all logs to finish
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
// Check that console.error doesn't contain [object Object]
|
|
const allCalls = consoleErrorSpy.mock.calls.map((call: any[]) =>
|
|
call.map(arg => {
|
|
if (arg && typeof arg === 'object' && arg.message) {
|
|
return arg.message; // Handle Error objects
|
|
}
|
|
return String(arg);
|
|
}).join(' ')
|
|
);
|
|
|
|
const hasObjectObject = allCalls.some((msg: string) => msg.includes('[object Object]'));
|
|
expect(hasObjectObject).toBe(false);
|
|
|
|
// Verify QueueProcessor logs are present
|
|
const queueProcessorLogs = allCalls.filter((msg: string) =>
|
|
msg.includes('[QueueProcessor]')
|
|
);
|
|
|
|
expect(queueProcessorLogs.length).toBeGreaterThan(0);
|
|
});
|
|
});
|