Files
qinglong/packages/ql3-runtime-core/test/localSecurityAuditRetention.test.cjs
T

52 lines
1.7 KiB
JavaScript

const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
InvalidLocalSecurityAuditRetentionValueError,
localSecurityAuditCompactionPayload,
} = require('@qinglong/runtime-core/local-security-audit-retention');
function record(eventId, occurredAtMs) {
return {
eventId,
requestId: `request-${eventId}`,
operationId: 'security.audit.list',
projectId: 'default',
subject: { type: 'user', id: 'owner-user' },
authenticationId: 'local_security_audit:test',
outcome: 'allowed',
reasons: ['instance_authority_security_audit_query'],
fence: { projectVersion: 1, bindingVersion: 1 },
occurredAtMs,
};
}
test('creates a deterministic domain-separated digest over the exact ordered rows', () => {
const first = record('ba000000-0000-4000-8000-000000000001', 1_000);
const second = record('ba000000-0000-4000-8000-000000000002', 2_000);
const payload = localSecurityAuditCompactionPayload([first, second]);
assert.match(payload.recordsDigest, /^[0-9a-f]{64}$/);
assert.equal(payload.payloadBytes > 0, true);
assert.deepEqual(
localSecurityAuditCompactionPayload([first, second]),
payload,
);
assert.notEqual(
localSecurityAuditCompactionPayload([second, first]).recordsDigest,
payload.recordsDigest,
);
});
test('records an explicit empty digest without charging payload bytes', () => {
const payload = localSecurityAuditCompactionPayload([]);
assert.equal(payload.payloadBytes, 0);
assert.match(payload.recordsDigest, /^[0-9a-f]{64}$/);
});
test('rejects malformed records before producing compaction evidence', () => {
assert.throws(
() => localSecurityAuditCompactionPayload([{}]),
InvalidLocalSecurityAuditRetentionValueError,
);
});