feat: productionize learning engine and classroom
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
validateCourseAgentAnchor,
|
||||
validateCoursePackageDescriptor,
|
||||
} from '../src/index.js';
|
||||
|
||||
const SHA = 'a'.repeat(64);
|
||||
|
||||
describe('course package descriptor', () => {
|
||||
it('accepts immutable unique-course metadata without a product version', () => {
|
||||
const descriptor = {
|
||||
schemaVersion: 1,
|
||||
kind: 'makelore-course-package',
|
||||
courseId: 'course_python_basics',
|
||||
contentHash: SHA,
|
||||
archiveSha256: 'b'.repeat(64),
|
||||
archiveBytes: 1024,
|
||||
formatVersion: 1,
|
||||
minPlayerVersion: '0.1.0',
|
||||
title: 'Python 零基础入门',
|
||||
sceneCount: 10,
|
||||
capabilities: {
|
||||
sceneKinds: ['slide', 'interactive', 'quiz'],
|
||||
hasAudio: false,
|
||||
hasWhiteboard: false,
|
||||
hasAgent: true,
|
||||
},
|
||||
createdAt: '2026-08-16T00:00:00.000Z',
|
||||
};
|
||||
|
||||
expect(validateCoursePackageDescriptor(descriptor)).toEqual({
|
||||
ok: true,
|
||||
value: descriptor,
|
||||
errors: [],
|
||||
});
|
||||
expect(descriptor).not.toHaveProperty('version');
|
||||
});
|
||||
|
||||
it('rejects malformed hashes and zero-byte archives', () => {
|
||||
const result = validateCoursePackageDescriptor({
|
||||
schemaVersion: 1,
|
||||
kind: 'makelore-course-package',
|
||||
courseId: 'course_1',
|
||||
contentHash: 'bad',
|
||||
archiveSha256: SHA,
|
||||
archiveBytes: 0,
|
||||
formatVersion: 1,
|
||||
minPlayerVersion: '0.1.0',
|
||||
title: 'Course',
|
||||
sceneCount: 1,
|
||||
capabilities: {
|
||||
sceneKinds: ['slide'],
|
||||
hasAudio: false,
|
||||
hasWhiteboard: false,
|
||||
hasAgent: false,
|
||||
},
|
||||
createdAt: '2026-08-16T00:00:00.000Z',
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(false);
|
||||
expect(result.errors).toContain('contentHash must be a SHA-256 hex string');
|
||||
expect(result.errors).toContain('archiveBytes must be a positive integer');
|
||||
});
|
||||
});
|
||||
|
||||
describe('agent anchor', () => {
|
||||
it('binds an Agent request to an exact course and playback position', () => {
|
||||
expect(
|
||||
validateCourseAgentAnchor({
|
||||
courseId: 'course_python_basics',
|
||||
contentHash: SHA,
|
||||
sceneOrder: 2,
|
||||
actionIndex: 1,
|
||||
positionMs: 3200,
|
||||
}).ok,
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user