test(phase6b): add ROOT curriculum acceptance coverage + real-Lab rehearsal
e2e-phase6b.js (24 checks): hierarchy for the 13 new modules across ROOT 05-10/12/Capstone, prerequisite chains through the newly-inserted front-door modules, lesson/knowledge-check completion in brand-new modules, a newly-wired scenario (job-task) completing correctly, the optional-vs-required (is_required) completion rule, persistence/ isolation/RBAC/draft-hiding proven against the new content, and the capstone server-side unlock fix in both directions (a direct bypass attempt rejected with blocking_stage_ids, an ordinary exam unaffected, a legitimately unlocked attempt still accepted and its completion reflected in the course content model). test-phase6b-root-course-rehearsal.js + wrapper (11 checks, real k3s): one continuous student narrative through a brand-new module (ROOT 07 Services & Service Discovery, not the Phase 6A gold module) — real Lab launch, the Lab's own setup_commands, a real 'kubectl expose' against the live cluster, real validate, logout/login/Resume Learning, Lab destroy/recreate with academic progress intact — plus an instructor narrative proving Curriculum view, Prepare Labs, and classroom/learning tooling all still work against the expanded curriculum. e2e-phase6a.js updated for two of this phase's own intentional, documented behavior changes (not defects): resume now points at root-05's new mental-model module instead of the old bare-lab bank, and root-10's gold module now unlocks the new troubleshooting-framework module rather than the bare-lab bank directly. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -128,8 +128,10 @@ async function main() {
|
||||
await test('resume points at the first activity of the first unlocked course', async () => {
|
||||
const { body } = await casey.request('GET', `/api/student/programs/${enrollmentId}/courses`);
|
||||
assert.equal(body.resume.course_id, 'root-05-kubernetes-foundations');
|
||||
assert.equal(body.resume.module_id, 'root-05-m01-pods-and-kubectl-basics');
|
||||
assert.equal(body.resume.activity_id, 'root-05-m01-pods-and-kubectl-basics-a01-pod-basics-mcq');
|
||||
// Phase 6B added root-05-m00 (the mental-model module) as the new front door, sequenced
|
||||
// before the pre-existing bare-lab bank — see docs/PHASE6B_ROOT_CURRICULUM_EXPANSION.md.
|
||||
assert.equal(body.resume.module_id, 'root-05-m00-kubernetes-mental-model');
|
||||
assert.equal(body.resume.activity_id, 'root-05-m00-a01-lesson-mental-model');
|
||||
});
|
||||
|
||||
await test('a student cannot mark a lab activity complete manually — only real scenario completion counts', async () => {
|
||||
@@ -138,8 +140,15 @@ async function main() {
|
||||
assert.equal(body.error, 'not_manually_completable');
|
||||
});
|
||||
|
||||
await test('completing root-05\'s 20 real scenarios marks the course complete and unlocks root-06', async () => {
|
||||
await test('completing root-05\'s 20 real scenarios + the Phase 6B mental-model module marks the course complete and unlocks root-06', async () => {
|
||||
for (const sid of FOUNDATION) await completeScenario(casey, sid);
|
||||
// Phase 6B's root-05-m00 has its own manual-marker activities (lesson/demonstration/
|
||||
// knowledge_check/guided_exercise/reflection) that scenario completion alone never
|
||||
// satisfies — root-05 the COURSE isn't complete until these are marked too.
|
||||
for (const suffix of ['a01-lesson-mental-model', 'a02-demonstration-desired-state', 'a03-knowledge-check', 'a04-guided-exercise-namespaces', 'a06-reflection']) {
|
||||
const { status } = await casey.request('POST', `/api/student/activities/root-05-m00-${suffix}/complete`);
|
||||
assert.equal(status, 200);
|
||||
}
|
||||
const { body } = await casey.request('GET', `/api/student/programs/${enrollmentId}/courses`);
|
||||
const root05 = courseById(body.courses, 'root-05-kubernetes-foundations');
|
||||
assert.equal(root05.complete, true);
|
||||
@@ -180,8 +189,11 @@ async function main() {
|
||||
const goldModule = moduleById(body.courses, 'root-10-m01-health-probes-and-troubleshooting');
|
||||
assert.equal(goldModule.complete, true);
|
||||
assert.equal(goldModule.percent_complete, 100);
|
||||
const nextModule = moduleById(body.courses, 'root-10-m02-general-troubleshooting');
|
||||
assert.equal(nextModule.locked, false, 'root-10-m02 must unlock once the gold module is complete');
|
||||
// Phase 6B inserted root-10-m03 (the troubleshooting framework module) between the gold
|
||||
// module and the pre-existing bare-lab bank — m02's prerequisite is now m03, not m01
|
||||
// directly. See docs/PHASE6B_ROOT_CURRICULUM_EXPANSION.md.
|
||||
const frameworkModule = moduleById(body.courses, 'root-10-m03-troubleshooting-framework');
|
||||
assert.equal(frameworkModule.locked, false, 'root-10-m03 must unlock once the gold module is complete');
|
||||
});
|
||||
|
||||
// ── Assessment/capstone-derived completion (auto_assessment) ────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user