chore: establish learning module baseline
This commit is contained in:
65
OpenMAIC/tests/video-export/normalize.test.ts
Normal file
65
OpenMAIC/tests/video-export/normalize.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { normalizeScenes, VideoTimelineCompileError } from '@/lib/video-export';
|
||||
import { act, quiz, slide, speech, spotlight } from './helpers';
|
||||
|
||||
describe('normalizeScenes — ordering', () => {
|
||||
it('orders scenes by `order`, tie-broken by input index (stable)', () => {
|
||||
const scenes = [
|
||||
slide('c', [], { order: 2 }),
|
||||
slide('a', [], { order: 1 }),
|
||||
slide('b', [], { order: 1 }),
|
||||
];
|
||||
const { scenes: out } = normalizeScenes(scenes);
|
||||
expect(out.map((s) => s.id)).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
|
||||
it('falls back to input index when `order` is absent, preserving input order', () => {
|
||||
const scenes = [
|
||||
{ ...slide('x', []), order: undefined },
|
||||
{ ...slide('y', []), order: undefined },
|
||||
];
|
||||
const { scenes: out } = normalizeScenes(scenes as never);
|
||||
expect(out.map((s) => s.id)).toEqual(['x', 'y']);
|
||||
});
|
||||
|
||||
it('throws on an empty scene list', () => {
|
||||
expect(() => normalizeScenes([])).toThrow(VideoTimelineCompileError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('normalizeScenes — action validation', () => {
|
||||
it('drops an unknown action type with an unknown-action diagnostic', () => {
|
||||
const scenes = [slide('s', [act({ id: 'bad', type: 'teleport' }), speech('ok', 'hi')])];
|
||||
const { scenes: out, diagnostics } = normalizeScenes(scenes);
|
||||
expect(out[0].actions).toHaveLength(1);
|
||||
expect(out[0].actions?.[0].id).toBe('ok');
|
||||
expect(diagnostics).toEqual([
|
||||
expect.objectContaining({ code: 'unknown-action', sceneId: 's', actionId: 'bad' }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('drops an action missing a required field with an invalid-action diagnostic', () => {
|
||||
// spotlight without elementId
|
||||
const scenes = [slide('s', [act({ id: 'sp', type: 'spotlight' }), spotlight('good', 'e1')])];
|
||||
const { scenes: out, diagnostics } = normalizeScenes(scenes);
|
||||
expect(out[0].actions?.map((a) => a.id)).toEqual(['good']);
|
||||
expect(diagnostics[0]).toMatchObject({ code: 'invalid-action', actionId: 'sp' });
|
||||
});
|
||||
|
||||
it('keeps an empty-text speech (a legal dwell beat)', () => {
|
||||
const { scenes: out, diagnostics } = normalizeScenes([slide('s', [speech('e', '')])]);
|
||||
expect(out[0].actions).toHaveLength(1);
|
||||
expect(diagnostics).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('does not mutate the input scenes', () => {
|
||||
const scenes = [slide('b', [], { order: 2 }), slide('a', [], { order: 1 })];
|
||||
normalizeScenes(scenes);
|
||||
expect(scenes.map((s) => s.id)).toEqual(['b', 'a']);
|
||||
});
|
||||
|
||||
it('validates quiz scene actions too', () => {
|
||||
const { diagnostics } = normalizeScenes([quiz('q', [act({ id: 'z', type: 'nope' })])]);
|
||||
expect(diagnostics[0].code).toBe('unknown-action');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user