const assert = require("assert"); const fs = require("fs"); const path = require("path"); const root = path.resolve(__dirname, ".."); const read = (file) => fs.readFileSync(path.join(root, file), "utf8"); const auth = read("src/utils/auth.js"); const demoStorage = read("src/utils/studentDemo.js"); const api = read("src/api/studentDemo.js"); const teacherPage = read("src/views/teacherEnd/trainingTask/index.vue"); const demoPage = read("src/views/studentDemo/index.vue"); const navbar = read("src/layout/components/Navbar.vue"); const appMain = read("src/layout/components/AppMain.vue"); assert(auth.includes("getStudentDemoSession") && demoStorage.includes("sessionStorage"), "demo token must use tab-local session storage"); assert(api.includes("/api/teacher/student-demo-sessions"), "teacher ticket API missing"); assert(api.includes("/api/student-demo-sessions/exchange"), "ticket exchange API missing"); assert(teacherPage.includes("学生端讲解"), "teacher entry missing"); assert(teacherPage.includes("window.open("), "teacher entry must open a new window"); assert(teacherPage.includes("STUDENT_DEMO_READY"), "teacher must wait for child readiness"); assert( teacherPage.indexOf('window.addEventListener("message", listener)') < teacherPage.indexOf("createStudentDemoSession("), "teacher must listen for child readiness before requesting the demo ticket" ); assert(demoPage.includes("STUDENT_DEMO_TICKET"), "demo page must receive ticket via postMessage"); assert(demoPage.includes("window.setInterval"), "demo page must retry its readiness notification until it receives the ticket"); assert(demoPage.includes("window.location.origin"), "postMessage must validate origin"); assert(!teacherPage.includes("ticket="), "ticket must not be sent in URL"); assert(navbar.includes("isStudentDemo()"), "demo mode must not request a profile for its temporary user"); assert(appMain.includes("window.close()"), "exiting a demo must close the demo window"); assert(appMain.includes('window.location.replace("/index")'), "blocked close must return to the application home page"); console.log("student demo mode front-end contract passed");