import { describe, expect, it } from 'vitest'; import { parseActionsFromStructuredOutput, postProcessInteractiveHtml } from '@openmaic/generation'; describe('action parser', () => { it('repairs malformed structured output and preserves interleaving', () => { const actions = parseActionsFromStructuredOutput( '[{"type":"text","content":"Start"},{"type":"action","name":"widget_setState","params":{}}', 'interactive', ['widget_setState'], ); expect(actions).toEqual([ expect.objectContaining({ type: 'speech', text: 'Start' }), expect.objectContaining({ type: 'widget_setState', state: {} }), ]); }); it('filters slide-only actions from non-slide scenes', () => { expect( parseActionsFromStructuredOutput( '[{"type":"action","name":"spotlight","params":{"elementId":"x"}}]', 'quiz', ), ).toEqual([]); }); }); describe('interactive HTML post-processing', () => { it('converts math, protects scripts, and injects KaTeX once', () => { const source = '
$x+1$'; const once = postProcessInteractiveHtml(source); const twice = postProcessInteractiveHtml(once); expect(once).toContain('\\(x+1\\)'); expect(once).toContain('const price = "$5";'); expect(once).toContain('katex.min.css'); expect(twice.match(/katex\.min\.css/g) ?? []).toHaveLength(1); }); });