Files
insta-recipe/src/tests/tandoor-logging.spec.ts
Giancarmine Salucci 49bccf8f15 simplify
2026-02-18 01:21:44 +01:00

138 lines
3.6 KiB
TypeScript

import { describe, test, expect, vi, beforeEach } from 'vitest';
import { uploadRecipeWithIngredientsDTO, uploadRecipeImage } from '$lib/server/tandoor';
import * as logger from '$lib/server/utils/logger';
vi.mock('$lib/server/tandoor-config', () => ({
tandoorConfig: {
serverUrl: 'http://localhost:8000',
token: 'test-token'
}
}));
describe('tandoor logging', () => {
let logErrorSpy: any;
beforeEach(() => {
vi.clearAllMocks();
logErrorSpy = vi.spyOn(logger, 'logError');
});
test('should use logError on upload failure', async () => {
vi.spyOn(global, 'fetch').mockRejectedValue(new Error('Network error'));
const recipe = {
name: 'Test Recipe',
servings: 4,
description: 'Test description',
ingredients: [{ item: 'Flour', amount: '2', unit: 'cups' }],
steps: ['Mix ingredients']
};
await uploadRecipeWithIngredientsDTO(recipe);
expect(logErrorSpy).toHaveBeenCalledWith('[Tandoor] Fetch error', expect.any(Error));
});
test('should use logError on API error response', async () => {
const errorBody = { detail: 'Invalid token' };
vi.spyOn(global, 'fetch').mockResolvedValue({
ok: false,
status: 401,
statusText: 'Unauthorized',
json: vi.fn().mockResolvedValue(errorBody)
} as any);
const recipe = {
name: 'Test Recipe',
servings: 4,
description: null,
ingredients: null,
steps: null
};
await uploadRecipeWithIngredientsDTO(recipe);
expect(logErrorSpy).toHaveBeenCalledWith(
expect.stringContaining('[Tandoor] API Error'),
errorBody
);
});
test('should use logError on recipe upload exception', async () => {
const error = new Error('Upload failed');
vi.spyOn(global, 'fetch').mockResolvedValue({
ok: true,
json: vi.fn().mockRejectedValue(error)
} as any);
const recipe = {
name: 'Test Recipe',
servings: 4,
description: null,
ingredients: null,
steps: null
};
await uploadRecipeWithIngredientsDTO(recipe);
expect(logErrorSpy).toHaveBeenCalledWith('[Tandoor] Fetch error', expect.any(Error));
});
test('should use logError on image upload failure', async () => {
const error = new Error('Image upload failed');
vi.spyOn(global, 'fetch').mockRejectedValue(error);
const result = await uploadRecipeImage(123, 'https://example.com/image.jpg');
expect(result.success).toBe(false);
expect(logErrorSpy).toHaveBeenCalledWith('[Tandoor Upload] Exception', error);
});
test('should use logError instead of manual error logging', async () => {
const error = new Error('Test error');
vi.spyOn(global, 'fetch').mockRejectedValue(error);
await uploadRecipeWithIngredientsDTO({
name: 'Test',
servings: null,
description: null,
ingredients: null,
steps: null
});
// Verify logError was called (which handles stack trace serialization)
expect(logErrorSpy).toHaveBeenCalledWith('[Tandoor] Fetch error', error);
// logError itself logs stack traces, which is expected behavior
// The key is that tandoor.ts uses logError instead of manual logging
});
test('should serialize complex error objects', async () => {
const complexError = {
code: 'ERR_VALIDATION',
message: 'Invalid recipe data',
details: { field: 'name', reason: 'required' }
};
vi.spyOn(global, 'fetch').mockResolvedValue({
ok: false,
status: 400,
statusText: 'Bad Request',
json: vi.fn().mockResolvedValue(complexError)
} as any);
await uploadRecipeWithIngredientsDTO({
name: 'Test',
servings: null,
description: null,
ingredients: null,
steps: null
});
expect(logErrorSpy).toHaveBeenCalledWith(
expect.stringContaining('[Tandoor] API Error'),
complexError
);
});
});