ci / verify (push) Canceled after 0s
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
77 lines
4.5 KiB
JavaScript
77 lines
4.5 KiB
JavaScript
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[^>]*>同意所选并创建/);
|
|
});
|