55 lines
3.0 KiB
TypeScript
55 lines
3.0 KiB
TypeScript
import { mkdtemp, rm } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import JSZip from 'jszip';
|
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
import {
|
|
packageUniqueMakeloreCourse,
|
|
persistUniqueMakeloreCourse,
|
|
readUniqueMakeloreCoursePackage,
|
|
} from '@/lib/makelore-course/package';
|
|
import { loadMakeloreCourse } from '@/lib/makelore-runtime/course-store';
|
|
import { validateCoursePackageDescriptor } from '../../../packages/@makelore/learning-contracts/src/index';
|
|
import type { Scene, Stage } from '@/lib/types/stage';
|
|
|
|
describe('unique Makelore course package', () => {
|
|
let root = '';
|
|
const previousPackageRoot = process.env.MAKELORE_COURSE_PACKAGE_DIR;
|
|
const previousStoreRoot = process.env.MAKELORE_COURSE_STORE_DIR;
|
|
|
|
afterEach(async () => {
|
|
if (root) await rm(root, { recursive: true, force: true });
|
|
if (previousPackageRoot === undefined) delete process.env.MAKELORE_COURSE_PACKAGE_DIR;
|
|
else process.env.MAKELORE_COURSE_PACKAGE_DIR = previousPackageRoot;
|
|
if (previousStoreRoot === undefined) delete process.env.MAKELORE_COURSE_STORE_DIR;
|
|
else process.env.MAKELORE_COURSE_STORE_DIR = previousStoreRoot;
|
|
});
|
|
|
|
it('freezes classroom, quiz and knowledge without a product version', async () => {
|
|
const stage = {
|
|
id: 'stage-1', name: '变量入门', createdAt: Date.now(), updatedAt: Date.now(),
|
|
generatedAgentConfigs: [{ id: 'teacher-1', name: 'AI Teacher', role: 'teacher', persona: '耐心讲解', avatar: '/avatars/teacher.png', color: '#3b82f6', priority: 10 }],
|
|
} as Stage;
|
|
const scenes = [{
|
|
id: 'scene-1', stageId: stage.id, title: '变量是什么', order: 1, type: 'interactive',
|
|
content: { type: 'interactive', html: '<!doctype html><html><head></head><body><button>试一试</button><script>document.querySelector("button").onclick=()=>document.body.dataset.clicked="1"</script></body></html>' },
|
|
createdAt: Date.now(), updatedAt: Date.now(),
|
|
}] as Scene[];
|
|
const course = await packageUniqueMakeloreCourse({ courseId: 'course-1', stage, scenes });
|
|
const zip = await JSZip.loadAsync(course.bytes);
|
|
const descriptor = JSON.parse(await zip.file('descriptor.json')!.async('string'));
|
|
expect(descriptor).toMatchObject({ courseId: 'course-1', formatVersion: 1, sceneCount: 1 });
|
|
expect(validateCoursePackageDescriptor(descriptor)).toMatchObject({ ok: true, errors: [] });
|
|
expect(descriptor).not.toHaveProperty('version');
|
|
expect(zip.file('classroom.json')).not.toBeNull();
|
|
expect(zip.file('knowledge/knowledge.json')).not.toBeNull();
|
|
|
|
root = await mkdtemp(join(tmpdir(), 'makelore-course-package-'));
|
|
process.env.MAKELORE_COURSE_PACKAGE_DIR = join(root, 'packages');
|
|
process.env.MAKELORE_COURSE_STORE_DIR = join(root, 'courses');
|
|
await persistUniqueMakeloreCourse('course-1', course);
|
|
await expect(readUniqueMakeloreCoursePackage('course-1')).resolves.toEqual(course.bytes);
|
|
await expect(loadMakeloreCourse('course-1', course.contentHash)).resolves.toMatchObject({ title: '变量入门' });
|
|
});
|
|
});
|