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(`]*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, /