| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- import test from 'node:test';
- import assert from 'node:assert/strict';
- import fs from 'node:fs';
- import { COURSE_ASSESSMENT_COLUMNS, courseAssessmentRows } from '../skills/ksf-workshop-runtime/scripts/course-assessment.mjs';
- import { renderReportHtml } from '../skills/ksf-workshop-runtime/scripts/render-report-html.mjs';
- import { saveAndVerifyReport } from '../skills/ksf-workshop-runtime/scripts/save-report.mjs';
- import { DELIVERY_SCHEMA } from '../skills/ksf-workshop-runtime/scripts/report-contract.mjs';
- const section = rows => ({ id: 'course-priority', kind: 'table', data: { cols: [...COURSE_ASSESSMENT_COLUMNS], rows } });
- const valid = () => section([
- ['测试候选A', 3, 2, 2, '证据为隔离样例;工艺条件仅测试;商业价值需本组复核', '第1'],
- ['测试候选B', 2, 1, 2, '测试可做性1分,保持不进入前三', '不进入前三'],
- ['测试候选C', 2, null, 2, '工艺资料缺失,列未知项;不是低分', '先补证'],
- ]);
- const task = table => ({ artifactType: 'assessment_report', stageCode: 'S4', version: 1, title: '隔离样例:课程排序',
- report: { delivery: { schema: DELIVERY_SCHEMA, moduleId: 'D2-05', kind: 'validation', contentStatus: 'ready', outputs: ['validation'] },
- chapters: [{ id: 'opportunity-validation', title: '三维评分', sections: [table] }] } });
- test('课程三维分别为1–3,未知保持未知,资格不是自动前三或总分', () => {
- const rows = courseAssessmentRows(valid());
- assert.deepEqual(rows.map(row => row.status), ['可参与排序', '不进入前三', '未知项待补']);
- assert.deepEqual(rows[2].scores, [2, null, 2]);
- assert.equal(Object.hasOwn(rows[0], 'total'), false);
- const displayTable = valid(); displayTable.data.cols[0] = '机\u2009会';
- assert.equal(courseAssessmentRows(displayTable).length, 3);
- });
- test('一维1分或未知时不能按样卡进入前三,越界分值和缺依据不通过', () => {
- for (const scores of [[2, 1, 2], [2, null, 2], [0, 2, 2], [4, 2, 2], [2.5, 2, 2]]) {
- assert.throws(() => courseAssessmentRows(section([['测试', ...scores, '测试依据', '第3']])), { code: 'COURSE_ASSESSMENT_INVALID' });
- }
- assert.throws(() => courseAssessmentRows(section([['测试', 2, 2, 2, '', '第1']])), { code: 'COURSE_ASSESSMENT_INVALID' });
- assert.equal(courseAssessmentRows({ kind: 'table', data: { rows: [['旧表']] } }), null);
- });
- test('独立HTML从同一评分表展示三维、未知及说明,不生成百分制总分', () => {
- const html = renderReportHtml(task(valid()));
- assert.match(html, /data-course-assessment/);assert.match(html, /待确认/);assert.match(html, /不进入前三/);
- assert.match(html, /商业价值需本组复核/);assert.doesNotMatch(html, /总分<\/th>/);
- const escaped = valid(); escaped.data.rows[0][0] = '<img src=x onerror=alert(1)>';
- assert.doesNotMatch(renderReportHtml(task(escaped)), /<img src=x/);
- });
- test('课程非法排序在任何远程调用前停止保存', async () => {
- let calls = 0;
- const bad = task(section([['测试', 2, 1, 2, '可做性为1', '第3']]));
- await assert.rejects(saveAndVerifyReport(bad, { requestId: 'invalid-course', invoke: () => { calls++; } }), { code: 'COURSE_ASSESSMENT_INVALID' });
- assert.equal(calls, 0);
- });
- test('final操作手册采用v3全文,13段提示词原样,页内锚点不被远程base改写', () => {
- const source = fs.readFileSync(new URL('../docs/workshop-v3-alignment-20261112/source-manual-v3.html', import.meta.url), 'utf8');
- const final = fs.readFileSync(new URL('../docs/workshop-quality-r13-20261110/final-康师傅工作坊操作手册.html', import.meta.url), 'utf8');
- assert.equal(final.replace(/<script id="ksf-v3-responsive-tables">[\s\S]*?<\/script>\n/, '')
- .replaceAll('href="https://s3.fmode.cn/user/K0xKEZANOG/kangshifu/overview/index.html"', 'href="../overview/index.html"'), source);
- assert.doesNotMatch(final, /<base\s/i);
- const saved = JSON.parse(fs.readFileSync(new URL('../docs/workshop-quality-r13-20261110/manual/workshop-dialogue-prompts.json', import.meta.url)));
- const original = JSON.parse(fs.readFileSync(new URL('../docs/workshop-v3-alignment-20261112/source-prompts-v3.json', import.meta.url)));
- assert.deepEqual(saved.prompts, original.prompts);assert.equal(Object.keys(saved.prompts).length, 13);
- });
|