mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-21 00:38:14 +08:00
136 lines
4.1 KiB
JavaScript
136 lines
4.1 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const { test } = require('node:test');
|
|
|
|
const {
|
|
createApprovalRequest,
|
|
decideApprovalRequest,
|
|
} = require('@qinglong/runtime-core/approved-action');
|
|
const {
|
|
MAX_APPROVAL_REQUEST_PAGE_SIZE,
|
|
MAX_APPROVAL_DETAIL_PREVIEW_BYTES,
|
|
InvalidApprovalDiscoveryValueError,
|
|
approvalRequestUpdatedAtMs,
|
|
assertApprovalDiscoveryProjectId,
|
|
assertApprovalDiscoveryRequestId,
|
|
assertApprovalRequestPageSize,
|
|
normalizeApprovalRequestCursor,
|
|
normalizeApprovalDetailPreview,
|
|
} = require('@qinglong/runtime-core/approval-discovery');
|
|
|
|
function pending() {
|
|
return createApprovalRequest({
|
|
id: 'approval-1',
|
|
projectId: 'default',
|
|
action: {
|
|
permission: 'run.start',
|
|
actionType: 'tool.invoke',
|
|
actionRef: 'tool:run.start',
|
|
actionDigest: 'a'.repeat(64),
|
|
previewDigest: 'b'.repeat(64),
|
|
},
|
|
risk: 'medium',
|
|
decisionMode: 'human_confirmation',
|
|
requestedBy: { type: 'agent', id: 'agent-1' },
|
|
requestedAtMs: 10,
|
|
expiresAtMs: 1_000,
|
|
requestFence: { projectVersion: 1, bindingVersion: 1 },
|
|
});
|
|
}
|
|
|
|
test('bounds Approval discovery pages and exact keyset cursors', () => {
|
|
assert.equal(MAX_APPROVAL_REQUEST_PAGE_SIZE, 64);
|
|
assert.doesNotThrow(() => assertApprovalRequestPageSize(1));
|
|
assert.doesNotThrow(() => assertApprovalRequestPageSize(64));
|
|
for (const value of [0, 65, 1.5, Number.NaN]) {
|
|
assert.throws(
|
|
() => assertApprovalRequestPageSize(value),
|
|
InvalidApprovalDiscoveryValueError,
|
|
);
|
|
}
|
|
assert.deepEqual(
|
|
normalizeApprovalRequestCursor({ updatedAtMs: 20, requestId: 'approval-2' }),
|
|
{ updatedAtMs: 20, requestId: 'approval-2' },
|
|
);
|
|
for (const value of [
|
|
null,
|
|
{ updatedAtMs: -1, requestId: 'approval-2' },
|
|
{ updatedAtMs: 20, requestId: '' },
|
|
{ updatedAtMs: 20, requestId: 'approval-2', extra: true },
|
|
]) {
|
|
assert.throws(
|
|
() => normalizeApprovalRequestCursor(value),
|
|
InvalidApprovalDiscoveryValueError,
|
|
);
|
|
}
|
|
});
|
|
|
|
test('accepts bounded Project identifiers and rejects control data', () => {
|
|
assert.doesNotThrow(() => assertApprovalDiscoveryProjectId('default'));
|
|
assert.doesNotThrow(() => assertApprovalDiscoveryRequestId('approval-1'));
|
|
for (const value of ['', 'x'.repeat(129), 'project\nother']) {
|
|
assert.throws(
|
|
() => assertApprovalDiscoveryProjectId(value),
|
|
InvalidApprovalDiscoveryValueError,
|
|
);
|
|
}
|
|
for (const value of ['', 'x'.repeat(129), 'approval/other']) {
|
|
assert.throws(
|
|
() => assertApprovalDiscoveryRequestId(value),
|
|
InvalidApprovalDiscoveryValueError,
|
|
);
|
|
}
|
|
});
|
|
|
|
test('derives the sortable timestamp from the latest durable transition', () => {
|
|
const request = pending();
|
|
assert.equal(approvalRequestUpdatedAtMs(request), 10);
|
|
const approved = decideApprovalRequest(request, {
|
|
expectedVersion: 1,
|
|
decisionId: 'decision-1',
|
|
decision: 'approved',
|
|
reasonCode: 'reviewed',
|
|
principal: {
|
|
subject: { type: 'user', id: 'owner-1' },
|
|
authenticationId: 'auth-owner-1',
|
|
authenticatedAtMs: 15,
|
|
expiresAtMs: 100,
|
|
assurance: 'local_console',
|
|
},
|
|
decidedAtMs: 20,
|
|
authorizationFence: { projectVersion: 1, bindingVersion: 1 },
|
|
});
|
|
assert.equal(approvalRequestUpdatedAtMs(approved), 20);
|
|
});
|
|
|
|
test('normalizes only a bounded document-only Approval preview', () => {
|
|
assert.equal(MAX_APPROVAL_DETAIL_PREVIEW_BYTES, 8 * 1024);
|
|
assert.deepEqual(
|
|
normalizeApprovalDetailPreview({
|
|
title: 'Run task',
|
|
summary: 'Runs one task.',
|
|
fields: [{ kind: 'redacted', label: 'Token', value: null }],
|
|
warnings: ['external_effect'],
|
|
}),
|
|
{
|
|
title: 'Run task',
|
|
summary: 'Runs one task.',
|
|
fields: [{ kind: 'redacted', label: 'Token', value: null }],
|
|
warnings: ['external_effect'],
|
|
},
|
|
);
|
|
assert.throws(
|
|
() =>
|
|
normalizeApprovalDetailPreview({
|
|
title: 'x'.repeat(256),
|
|
summary: 'x'.repeat(2_048),
|
|
fields: Array.from({ length: 16 }, (_, index) => ({
|
|
kind: 'text',
|
|
label: `field-${index}-${'x'.repeat(110)}`,
|
|
value: 'x'.repeat(512),
|
|
})),
|
|
warnings: [],
|
|
}),
|
|
InvalidApprovalDiscoveryValueError,
|
|
);
|
|
});
|