72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import {
|
|
RECIPE_EXTRACTION_SYSTEM_PROMPT,
|
|
GEMINI_RESPONSE_SCHEMA,
|
|
extractionResponseSchema,
|
|
type ExtractionResponse
|
|
} from '../../src/lib/server/ai/recipe-extraction-prompt';
|
|
|
|
describe('recipe-extraction-prompt', () => {
|
|
it('system prompt is in German and mentions Rezept + Zutaten + Zubereitung', () => {
|
|
const p = RECIPE_EXTRACTION_SYSTEM_PROMPT.toLowerCase();
|
|
expect(p).toContain('rezept');
|
|
expect(p).toContain('zutaten');
|
|
expect(p).toContain('zubereitung');
|
|
});
|
|
|
|
it('Gemini response schema has required top-level keys', () => {
|
|
expect(GEMINI_RESPONSE_SCHEMA.type).toBeDefined();
|
|
expect(Object.keys(GEMINI_RESPONSE_SCHEMA.properties)).toEqual(
|
|
expect.arrayContaining(['title', 'ingredients', 'steps'])
|
|
);
|
|
});
|
|
|
|
it('Zod validator accepts a well-formed response', () => {
|
|
const good: ExtractionResponse = {
|
|
title: 'Testrezept',
|
|
servings_default: 4,
|
|
servings_unit: 'Portionen',
|
|
prep_time_min: 15,
|
|
cook_time_min: 30,
|
|
total_time_min: null,
|
|
ingredients: [{ quantity: 100, unit: 'g', name: 'Mehl', note: null }],
|
|
steps: [{ text: 'Mehl in eine Schüssel geben.' }]
|
|
};
|
|
expect(() => extractionResponseSchema.parse(good)).not.toThrow();
|
|
});
|
|
|
|
it('Zod validator rejects missing title', () => {
|
|
const bad = { servings_default: 4, ingredients: [], steps: [] };
|
|
expect(() => extractionResponseSchema.parse(bad)).toThrow();
|
|
});
|
|
|
|
it('Zod validator accepts quantity=null and unit=null', () => {
|
|
const ok: ExtractionResponse = {
|
|
title: 'Prise-Rezept',
|
|
servings_default: null,
|
|
servings_unit: null,
|
|
prep_time_min: null,
|
|
cook_time_min: null,
|
|
total_time_min: null,
|
|
ingredients: [{ quantity: null, unit: null, name: 'Salz', note: 'nach Geschmack' }],
|
|
steps: [{ text: 'Einfach so.' }]
|
|
};
|
|
expect(() => extractionResponseSchema.parse(ok)).not.toThrow();
|
|
});
|
|
|
|
it('Zod validator rejects unexpected extra top-level keys (strict)', () => {
|
|
const bad = {
|
|
title: 'x',
|
|
servings_default: null,
|
|
servings_unit: null,
|
|
prep_time_min: null,
|
|
cook_time_min: null,
|
|
total_time_min: null,
|
|
ingredients: [],
|
|
steps: [],
|
|
malicious_extra_field: 'pwned'
|
|
};
|
|
expect(() => extractionResponseSchema.parse(bad)).toThrow();
|
|
});
|
|
});
|