feat: integrate learning module
Some checks failed
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled

This commit is contained in:
inman
2026-08-16 20:52:16 +08:00
parent 26b52d76e3
commit 01bee3188b
107 changed files with 6318 additions and 12063 deletions

View File

@@ -0,0 +1,35 @@
import { describe, expect, it } from 'vitest';
import { sanitizeLearningRuntimeAnchor } from '@/lib/learning-runtime-anchor';
import { matchesLearningCloudProgress } from '@/pages/Learning/CoursePlayer';
describe('Learning CoursePlayer runtime boundary', () => {
it('copies only sceneId and sceneOrder from the untrusted iframe anchor', () => {
expect(sanitizeLearningRuntimeAnchor({
sceneId: 'scene-3',
sceneOrder: 3,
courseId: 'iframe-course',
contentHash: 'iframe-hash',
moduleId: 'iframe-module',
moduleContentHash: 'iframe-module-hash',
actionIndex: 8,
})).toEqual({ sceneId: 'scene-3', sceneOrder: 3 });
});
it('drops invalid or empty anchors instead of forwarding arbitrary context', () => {
expect(sanitizeLearningRuntimeAnchor({ sceneId: '', sceneOrder: -1, arbitrary: true })).toBeUndefined();
expect(sanitizeLearningRuntimeAnchor(['scene-1'])).toBeUndefined();
});
it('restores single-course cloud progress stored under the server main module', () => {
expect(matchesLearningCloudProgress(
{ courseId: 'course-1', contentHash: 'a'.repeat(64), moduleId: 'main' },
'course-1',
{ courseContentHash: 'a'.repeat(64), moduleId: null, modules: [{}] },
)).toBe(true);
expect(matchesLearningCloudProgress(
{ courseId: 'course-1', contentHash: 'a'.repeat(64), moduleId: 'other' },
'course-1',
{ courseContentHash: 'a'.repeat(64), moduleId: null, modules: [{}] },
)).toBe(false);
});
});