Files

77 lines
4.5 KiB
JavaScript
Raw Permalink Normal View History

const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const Module = require('node:module');
const ts = require('typescript');
const React = require('react');
const { renderToStaticMarkup } = require('react-dom/server');
// Render the actual consent components without a browser or network connection.
// Ant Design's portal is replaced with a visible dialog for server rendering.
const originalLoad = Module._load;
Module._load = function(request, parent, isMain) {
if (request.endsWith('.css')) return {};
if (request === '@phosphor-icons/react') return new Proxy({}, { get: () => () => null });
if (request === '../api/client') return {
APIRequestError: class extends Error {},
platformApi: new Proxy({}, { get() { return () => { throw new Error('Unexpected API request'); }; } }),
};
if (request === 'antd') return {
Modal: ({ children, okButtonProps, okText }) => React.createElement('div', null, children, React.createElement('button', { disabled: okButtonProps.disabled }, okText)),
Alert: ({ title }) => React.createElement('p', null, title),
Checkbox: ({ children, ...props }) => React.createElement('label', null, React.createElement('input', { type: 'checkbox', ...props }), children),
};
return originalLoad.call(this, request, parent, isMain);
};
for (const extension of ['.ts', '.tsx']) {
require.extensions[extension] = (module, file) => module._compile(ts.transpileModule(fs.readFileSync(file, 'utf8'), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, jsx: ts.JsxEmit.ReactJSX }, fileName: file,
}).outputText, file);
}
const { SubjectConsentDialog } = require('../src/components/SubjectConsentDialog.tsx');
const { CreationConsentDialog } = require('../src/components/CreationConsentDialog.tsx');
const { ConsentGrantDialog } = require('../src/components/ConsentGuidance.tsx');
const noop = () => {};
const render = (component, props) => renderToStaticMarkup(React.createElement(component, props));
const status = { state: 'ready', items: [], refresh: noop };
const common = { subjectID: 'subject-test', subjectName: '测试对象', accessToken: '', policyVersion: 'local-v1', status, onClose: noop };
const inputFor = (html, label) => html.match(new RegExp(`<input[^>]*aria-label="${label}"[^>]*>`))?.[0];
test('existing-subject authorization is blocked by a version-only policy, but active consent can be unchecked', () => {
const html = render(SubjectConsentDialog, { ...common, canManage: true, onSaved: noop,
status: { ...status, items: [{ type: 'transcript_storage', effective: true, granted_at: '2020-01-01T00:00:00Z' }] },
});
assert.match(html, /政策正文不可用/);
assert.match(html, /local-v1/);
assert.match(inputFor(html, '个性化记忆'), /disabled/);
assert.doesNotMatch(inputFor(html, '保存聊天文字'), /disabled/);
assert.match(inputFor(html, '保存聊天文字'), /checked/);
assert.doesNotMatch(html, /我已阅读/);
});
test('creation without policy text keeps optional authorization blocked and allows creating without it', () => {
const html = render(CreationConsentDialog, { name: '测试对象', selected: [], policyVersion: 'local-v1', onChange: noop, onBack: noop, onClose: noop, onConfirm: noop });
assert.match(html, /<fieldset[^>]*disabled/);
assert.match(html, /<button[^>]*disabled[^>]*>同意所选并创建/);
const skip = html.match(/<button[^>]*>暂不开通,完成创建<\/button>/)?.[0];
assert.ok(skip);
assert.doesNotMatch(skip, /disabled/);
assert.doesNotMatch(html, /checked=""/);
});
test('quick grant cannot confirm merely because local-v1 is present', () => {
const html = render(ConsentGrantDialog, { ...common, type: 'personalized_memory', canGrant: true, onGranted: noop });
assert.match(html, /尚未提供可阅读的正式政策正文/);
assert.match(html, /<input[^>]*disabled/);
assert.match(html, /<button[^>]*disabled[^>]*>确认授权/);
assert.doesNotMatch(html, /checked=""/);
});
test('an available matching document is readable and never preconfirms a grant', () => {
const document = { version: 'v2', title: '测试文档', content: '仅供自动化测试的正文' };
const html = render(CreationConsentDialog, { name: '测试对象', selected: ['personalized_memory'], policyVersion: 'v2', policyDocument: document, onChange: noop, onBack: noop, onClose: noop, onConfirm: noop });
assert.match(html, /隐私与授权政策正文/);
assert.match(html, /仅供自动化测试的正文/);
assert.match(html, /<button[^>]*disabled[^>]*>同意所选并创建/);
});