OpenMAIC-React / tests /classroom /complete-summary.test.ts
muthuk1's picture
Add missing files: LICENSE, Dockerfile, .github, tests, e2e, eval, scripts, configs
a0ebf39 verified
import { describe, it, expect } from 'vitest';
import { summarizeScenes } from '@/lib/classroom/complete-summary';
import type { Scene, QuizQuestion } from '@/lib/types/stage';
function slide(id: string, order: number): Scene {
return {
id,
stageId: 's1',
type: 'slide',
title: id,
order,
content: { type: 'slide', canvas: {} as never },
};
}
function quizScene(id: string, order: number, questions: QuizQuestion[]): Scene {
return {
id,
stageId: 's1',
type: 'quiz',
title: id,
order,
content: { type: 'quiz', questions },
};
}
function interactive(id: string, order: number): Scene {
return {
id,
stageId: 's1',
type: 'interactive',
title: id,
order,
content: { type: 'interactive', url: 'about:blank' },
};
}
const choiceQ = (id: string, answer: string[]): QuizQuestion => ({
id,
type: 'single',
question: id,
options: [
{ value: 'a', label: 'A' },
{ value: 'b', label: 'B' },
],
answer,
hasAnswer: true,
points: 1,
});
describe('summarizeScenes', () => {
it('counts scenes by type and omits zeros', () => {
const scenes = [slide('s1', 0), slide('s2', 1), interactive('i1', 2)];
const result = summarizeScenes(scenes, () => ({}));
expect(result.countsByType).toEqual({ slide: 2, interactive: 1 });
expect(result.quiz).toBeNull();
});
it('returns null quiz when no quiz scenes exist', () => {
const result = summarizeScenes([slide('s1', 0)], () => ({}));
expect(result.quiz).toBeNull();
});
it('aggregates quiz answers across multiple quiz scenes', () => {
const scenes = [
quizScene('q1', 0, [choiceQ('qa', ['a']), choiceQ('qb', ['b'])]),
quizScene('q2', 1, [choiceQ('qc', ['a'])]),
];
const answers: Record<string, Record<string, string | string[]>> = {
q1: { qa: 'a', qb: 'a' },
q2: { qc: 'a' },
};
const result = summarizeScenes(scenes, (sceneId) => answers[sceneId] ?? {});
expect(result.quiz).toEqual({ correct: 2, total: 3, pct: Math.round((2 / 3) * 100) });
expect(result.countsByType.quiz).toBe(2);
});
it('returns null quiz when quiz scenes exist but have no gradeable questions', () => {
const saOnly = quizScene('q1', 0, [
{
id: 'sa',
type: 'short_answer',
question: 'x',
answer: [],
hasAnswer: false,
},
]);
const result = summarizeScenes([saOnly], () => ({}));
expect(result.quiz).toBeNull();
expect(result.countsByType.quiz).toBe(1);
});
it('treats missing answers as incorrect (not skipped)', () => {
const scenes = [quizScene('q1', 0, [choiceQ('qa', ['a']), choiceQ('qb', ['b'])])];
const result = summarizeScenes(scenes, () => ({}));
expect(result.quiz).toEqual({ correct: 0, total: 2, pct: 0 });
});
});