const assert = require("assert"); const fs = require("fs"); const path = require("path"); const root = path.resolve(__dirname, ".."); const teacherPage = fs.readFileSync(path.join(root, "src/views/teacherEnd/trainingTask/index.vue"), "utf8"); const studentPage = fs.readFileSync(path.join(root, "src/views/training/GenericTrainingPage.vue"), "utf8"); const newProductSurveyPage = fs.readFileSync(path.join(root, "src/views/foundation/new-product-survey.vue"), "utf8"); const productDevelopmentFactorsPage = fs.readFileSync(path.join(root, "src/views/foundation/product-development-factors.vue"), "utf8"); const trainingIntro = fs.readFileSync(path.join(root, "src/views/components/TrainingIntro.vue"), "utf8"); const materialButton = fs.readFileSync(path.join(root, "src/views/components/TrainingMaterialButton.vue"), "utf8"); const directStudentBriefFiles = [ "src/views/demand/index.vue", "src/views/demand/environment.vue", "src/views/demand/people.vue", "src/views/demand/consumer-behavior.vue", "src/views/demand/consumer-scenario.vue", "src/views/demand/feature-conversion.vue", "src/views/product/index.vue", "src/views/product/differentiation.vue", ]; const directStudentBriefPages = directStudentBriefFiles.map((file) => fs.readFileSync(path.join(root, file), "utf8")); const trainingTaskBrief = fs.existsSync(path.join(root, "src/views/components/TrainingTaskBrief.vue")) ? fs.readFileSync(path.join(root, "src/views/components/TrainingTaskBrief.vue"), "utf8") : ""; assert( /uploadTrainingTaskMaterial/.test(teacherPage), "teacher training task editor should use the common upload API for case materials" ); assert( /async function handleMaterialChange/.test(teacherPage) && /taskForm\.materialUrl\s*=\s*res\?\.(url|fileName)/.test(teacherPage), "teacher case material upload should persist the returned materialUrl" ); assert( /class="material-download"/.test(studentPage) && /@click="handleMaterialDownload"/.test(studentPage), "student task page should always render the current route task material button" ); assert( /function handleMaterialDownload/.test(studentPage) && /暂无案例文档/.test(studentPage), "student task material button should report empty state when no case material exists" ); assert( /TrainingMaterialButton/.test(newProductSurveyPage), "new product survey page should render the case material button" ); assert( /TrainingMaterialButton/.test(productDevelopmentFactorsPage), "product development factors page should render the case material button" ); assert.match( materialButton, /function normalizeMaterialUrl\(rawUrl\)/, "case material downloads must normalize legacy absolute URLs" ); assert.ok( materialButton.includes('["localhost", "127.0.0.1", "::1"]'), "localhost case material URLs must not be sent to each student's own browser port" ); assert.match( materialButton, /url: normalizeMaterialUrl\(url\)/, "the download button must use the normalized material URL" ); assert.match( materialButton, /async function handleDownload\(\)/, "case material downloads must validate the file response before opening a download" ); assert.match( materialButton, /await fetch\(material\.value\.url\)/, "case material downloads must request the configured file URL" ); assert.match( materialButton, /案例资料文件不存在或暂不可下载/, "a missing case material file must show a clear recovery message" ); const studentBriefPages = [studentPage, newProductSurveyPage, productDevelopmentFactorsPage, trainingIntro, ...directStudentBriefPages]; assert(/实训背景/.test(trainingTaskBrief) && /实训目标/.test(trainingTaskBrief) && /实训要求/.test(trainingTaskBrief), "common TrainingTaskBrief component should render the three student brief sections"); for (const page of studentBriefPages) { assert(/TrainingTaskBrief/.test(page), "student training pages should use the shared TrainingTaskBrief component"); assert(!/任务分析|相关知识|remoteTask\?\.knowledge|taskConfig\.value\?\.knowledge|page\.knowledge/.test(page), "student training brief should not expose related knowledge/task analysis"); } assert(!/label="任务分析|v-model="taskForm\.knowledge"|knowledge:\s*taskForm\.knowledge/.test(teacherPage), "teacher task editor should not edit or submit related knowledge");