50 lines
2.8 KiB
JavaScript
50 lines
2.8 KiB
JavaScript
import test from 'node:test';
|
|||
|
|
import assert from 'node:assert/strict';
|
||
|
|
import { consentGrantNotice, hasConsent, resolveConsentPolicy } from '../src/components/consent-model.ts';
|
||
|
|
const now = Date.parse('2026-10-05T10:00:00Z');
|
||
|
|
const consent = { type: 'transcript_storage', effective: true, granted_at: '2026-10-01T10:00:00Z' };
|
||
|
|
|
||
|
|
test('consent status rejects withdrawn, expired, future and ineffective grants', () => {
|
||
|
|
assert.equal(hasConsent([consent], 'transcript_storage', now), true);
|
||
|
|
for (const patch of [{ effective: false }, { withdrawn_at: '2026-10-04T10:00:00Z' }, { expires_at: '2026-10-05T10:00:00Z' }, { granted_at: '2026-10-06T10:00:00Z' }]) {
|
||
|
|
assert.equal(hasConsent([{ ...consent, ...patch }], 'transcript_storage', now), false);
|
||
|
|
}
|
||
|
|
assert.equal(hasConsent([{ ...consent, expires_at: '2026-10-05T10:00:01Z' }], 'transcript_storage', now), true);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('historical withdrawal does not hide a later valid grant or grant a different purpose', () => {
|
||
|
|
const withdrawn = { ...consent, withdrawn_at: '2026-10-04T10:00:00Z' };
|
||
|
|
assert.equal(hasConsent([withdrawn, consent], 'transcript_storage', now), true);
|
||
|
|
assert.equal(hasConsent([withdrawn, consent], 'raw_audio_storage', now), false);
|
||
|
|
assert.equal(hasConsent([], 'transcript_storage', now), false);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a policy version alone never counts as a readable policy', () => {
|
||
|
|
for (const version of ['', 'local-v1', 'published-v2']) {
|
||
|
|
assert.equal(resolveConsentPolicy(version).state, 'blocked');
|
||
|
|
assert.equal(consentGrantNotice('personalized_memory', '测试对象', version), undefined);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
test('blank or mismatched policy documents block confirmation', () => {
|
||
|
|
for (const document of [
|
||
|
|
{ version: 'v1', title: '测试文档', content: ' ' },
|
||
|
|
{ version: 'v1', title: '', content: '仅供自动化测试的内容' },
|
||
|
|
{ version: 'v0', title: '测试文档', content: '仅供自动化测试的内容' },
|
||
|
|
]) {
|
||
|
|
assert.equal(resolveConsentPolicy('v1', document).state, 'blocked');
|
||
|
|
assert.equal(consentGrantNotice('personalized_memory', '测试对象', 'v1', document), undefined);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
test('grant evidence includes the displayed document and exact purpose', () => {
|
||
|
|
const document = { version: 'v1', title: '测试文档', content: '仅供自动化测试的内容\n保留换行' };
|
||
|
|
assert.equal(resolveConsentPolicy('v1', document).state, 'ready');
|
||
|
|
const notice = consentGrantNotice('personalized_memory', '测试对象', 'v1', document);
|
||
|
|
assert.ok(notice.includes(document.content));
|
||
|
|
assert.ok(notice.includes('测试对象'));
|
||
|
|
assert.ok(notice.includes('个性化记忆'));
|
||
|
|
assert.notEqual(notice, consentGrantNotice('personalized_memory', '测试对象', 'v1', { ...document, content: `${document.content}\n已修订` }));
|
||
|
|
assert.notEqual(notice, consentGrantNotice('raw_audio_storage', '测试对象', 'v1', document));
|
||
|
|
});
|