import { describe, expect, test } from 'vitest'; import { buildPrompt, PROMPT_IDS, processConditionalBlocks } from '@/lib/prompts'; function buildOutlinePrompt(flags: { hasSourceImages?: boolean; imageEnabled?: boolean; videoEnabled?: boolean; }) { const imageEnabled = flags.imageEnabled ?? false; const videoEnabled = flags.videoEnabled ?? false; return buildPrompt(PROMPT_IDS.REQUIREMENTS_TO_OUTLINES, { requirement: 'Teach water cycle basics', pdfContent: 'None', availableImages: flags.hasSourceImages ? '- img_1: water cycle diagram' : 'No images available', userProfile: '', researchContext: 'None', teacherContext: '', hasSourceImages: flags.hasSourceImages ?? false, imageEnabled, videoEnabled, mediaEnabled: imageEnabled || videoEnabled, }); } function buildSlidePrompt(flags: { imageElementEnabled?: boolean; generatedImageEnabled?: boolean; generatedVideoEnabled?: boolean; }) { const generatedImageEnabled = flags.generatedImageEnabled ?? false; const generatedVideoEnabled = flags.generatedVideoEnabled ?? false; return buildPrompt(PROMPT_IDS.SLIDE_CONTENT, { title: 'Water Cycle', description: 'Explain evaporation and condensation', keyPoints: '1. Evaporation\\n2. Condensation', assignedImages: flags.imageElementEnabled ? '- img_1: source image' : 'No images available', canvas_width: 1000, canvas_height: 562.5, teacherContext: '', languageDirective: 'Teach in English.', imageElementEnabled: flags.imageElementEnabled ?? false, generatedImageEnabled, generatedVideoEnabled, mediaElementEnabled: generatedImageEnabled || generatedVideoEnabled, }); } function combined(prompt: { system: string; user: string } | null) { expect(prompt).not.toBeNull(); return `${prompt!.system}\n${prompt!.user}`; } describe('conditional blocks', () => { test('processConditionalBlocks includes content only when flag is truthy', () => { expect(processConditionalBlocks('A {{#if enabled}}INCLUDED{{/if}} B', { enabled: true })).toBe( 'A INCLUDED B', ); expect(processConditionalBlocks('A {{#if enabled}}INCLUDED{{/if}} B', { enabled: false })).toBe( 'A B', ); }); }); describe('requirements-to-outlines media prompt conditions', () => { test('omits media generation instructions when image and video generation are disabled', () => { const text = combined(buildOutlinePrompt({ hasSourceImages: false })); expect(text).not.toContain('mediaGenerations'); expect(text).not.toContain('suggestedImageIds'); expect(text).not.toContain('gen_img_'); expect(text).not.toContain('gen_vid_'); expect(text).not.toContain('{{'); }); test('includes image generation instructions without video instructions when only images are enabled', () => { const text = combined(buildOutlinePrompt({ hasSourceImages: true, imageEnabled: true })); expect(text).toContain('suggestedImageIds'); expect(text).toContain('mediaGenerations'); expect(text).toContain('gen_img_1'); expect(text).not.toContain('gen_vid_'); expect(text).not.toContain('{{'); }); test('includes video generation instructions without image generation placeholders when only video is enabled', () => { const text = combined(buildOutlinePrompt({ videoEnabled: true })); expect(text).toContain('mediaGenerations'); expect(text).toContain('gen_vid_1'); expect(text).not.toContain('gen_img_'); expect(text).not.toContain('suggestedImageIds'); expect(text).not.toContain('{{'); }); test('includes both image and video generation instructions when both are enabled', () => { const text = combined( buildOutlinePrompt({ hasSourceImages: true, imageEnabled: true, videoEnabled: true }), ); expect(text).toContain('suggestedImageIds'); expect(text).toContain('mediaGenerations'); expect(text).toContain('gen_img_1'); expect(text).toContain('gen_vid_1'); expect(text).toContain('Content Safety Guidelines'); expect(text).not.toContain('{{'); }); }); describe('slide-content media prompt conditions', () => { test('omits image and video element rules when no media resources are available', () => { const text = combined(buildSlidePrompt({})); expect(text).not.toContain('ImageElement'); expect(text).not.toContain('VideoElement'); expect(text).not.toContain('gen_img_'); expect(text).not.toContain('gen_vid_'); expect(text).not.toContain('{{'); }); test('allows source images without exposing generated image placeholders', () => { const text = combined(buildSlidePrompt({ imageElementEnabled: true })); expect(text).toContain('ImageElement'); expect(text).toContain('img_1'); expect(text).not.toContain('gen_img_'); expect(text).not.toContain('VideoElement'); expect(text).not.toContain('{{'); }); test('allows generated videos without exposing image element rules', () => { const text = combined(buildSlidePrompt({ generatedVideoEnabled: true })); expect(text).toContain('VideoElement'); expect(text).toContain('gen_vid_1'); expect(text).not.toContain('ImageElement'); expect(text).not.toContain('gen_img_'); expect(text).not.toContain('{{'); }); test('is shorter when all media rules are omitted', () => { const noMedia = combined(buildSlidePrompt({})); const allMedia = combined( buildSlidePrompt({ imageElementEnabled: true, generatedImageEnabled: true, generatedVideoEnabled: true, }), ); expect(noMedia.length).toBeLessThan(allMedia.length - 1000); }); });