mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 19:29:13 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
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,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user