45 lines
2.2 KiB
JavaScript
45 lines
2.2 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { readFile } from 'node:fs/promises';
|
|
import test from 'node:test';
|
|
|
|
const [app, index] = await Promise.all([
|
|
readFile(new URL('./app.js', import.meta.url), 'utf8'),
|
|
readFile(new URL('./index.html', import.meta.url), 'utf8')
|
|
]);
|
|
|
|
test('workbench exposes one XLS/XLSX roster attachment without turning it into persistent state', () => {
|
|
assert.match(index, /id="rosterAttachment"[^>]+type="file"/);
|
|
assert.match(index, /accept="\.xls,\.xlsx,application\/vnd\.ms-excel,application\/vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet"/);
|
|
assert.doesNotMatch(index, /id="rosterAttachment"[^>]+multiple/);
|
|
assert.match(index, /id="rosterAttachmentStatus"[^>]+role="status"/);
|
|
assert.doesNotMatch(app, /sessionStorage\.(?:setItem|getItem)\([^\n]*(?:attachment|base64|file)/i);
|
|
assert.doesNotMatch(app, /console\.(?:log|info|warn|error)\([^\n]*(?:attachment|base64|file)/i);
|
|
});
|
|
|
|
test('new and awaiting roster tasks send a single in-memory base64 JSON attachment', () => {
|
|
assert.match(app, /async function encodeRosterAttachment\(file\)/);
|
|
assert.match(app, /reader\.readAsDataURL\(file\)/);
|
|
assert.match(app, /content_base64:/);
|
|
assert.match(app, /attachments: rosterAttachment \? \[rosterAttachment\] : undefined/);
|
|
assert.match(app, /async function sendTaskAttachment/);
|
|
assert.match(app, /message: ''/);
|
|
assert.match(app, /attachments: \[attachment\]/);
|
|
assert.match(app, /taskAttachmentDrafts/);
|
|
});
|
|
|
|
test('awaiting_attachment has a dedicated attachment-only continuation UI', () => {
|
|
assert.match(app, /function isAwaitingAttachment\(task\)/);
|
|
assert.match(app, /status === 'awaiting_attachment'/);
|
|
assert.match(app, /kind === 'awaiting_attachment'/);
|
|
assert.match(app, /renderTaskAttachmentForm\(task\)/);
|
|
assert.match(index, /option value="awaiting_attachment">等待名单附件<\/option>/);
|
|
});
|
|
|
|
test('parser routing visibly locks Program-only routes and keeps emergency wording accurate', () => {
|
|
assert.match(app, /route\.mode_locked/);
|
|
assert.match(app, /route\.allowed_modes/);
|
|
assert.match(app, /Program-only/);
|
|
assert.match(app, /名单导入仍保持 Program/);
|
|
assert.match(index, /可配置业务全部切回 AI/);
|
|
});
|