feat: complete Epic 1 production foundation
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
const { test, expect } = require('@playwright/test');
|
||||
const { login, localized } = require('./helpers');
|
||||
|
||||
test('logs approval panel renders safe pending approval metadata', async ({ page }) => {
|
||||
await login(page);
|
||||
let approveCalled = false;
|
||||
|
||||
await page.route(/\/api\/admin\/workspaces\/[^/]+\/approvals(?:\?.*)?$/, async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({
|
||||
items: [
|
||||
{
|
||||
approval: {
|
||||
id: 'approval_ui_safe_summary',
|
||||
agent_id: 'agent_sales',
|
||||
operation_id: 'op_charge_customer',
|
||||
operation_version: 3,
|
||||
status: 'pending',
|
||||
risk_level: 'dangerous',
|
||||
request_id: 'req_approval_ui',
|
||||
trace_id: '0af7651916cd43dd8448eb211c80319c',
|
||||
request_payload: {
|
||||
email: 'customer@example.com',
|
||||
api_key: '[REDACTED]',
|
||||
},
|
||||
response_payload: null,
|
||||
created_at: '2026-08-22T10:00:00Z',
|
||||
expires_at: '2026-08-22T10:05:00Z',
|
||||
decided_at: null,
|
||||
decision_note: null,
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
});
|
||||
await page.route(/\/api\/admin\/workspaces\/[^/]+\/approvals\/approval_ui_safe_summary\/approve$/, async (route) => {
|
||||
approveCalled = true;
|
||||
const body = JSON.parse(route.request().postData() || '{}');
|
||||
expect(body).toEqual({ approve: 'yes' });
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({
|
||||
approval: {
|
||||
id: 'approval_ui_safe_summary',
|
||||
agent_id: 'agent_sales',
|
||||
operation_id: 'op_charge_customer',
|
||||
operation_version: 3,
|
||||
status: 'approved',
|
||||
risk_level: 'dangerous',
|
||||
request_id: 'req_approval_ui',
|
||||
trace_id: '0af7651916cd43dd8448eb211c80319c',
|
||||
request_payload: { email: 'customer@example.com', api_key: '[REDACTED]' },
|
||||
response_payload: { approve: 'yes' },
|
||||
created_at: '2026-08-22T10:00:00Z',
|
||||
expires_at: '2026-08-22T10:05:00Z',
|
||||
decided_at: '2026-08-22T10:01:00Z',
|
||||
decision_note: null,
|
||||
},
|
||||
}),
|
||||
});
|
||||
});
|
||||
page.on('dialog', async (dialog) => {
|
||||
expect(dialog.message()).toMatch(localized(
|
||||
'Approve this pending confirmation request?',
|
||||
'Подтвердить эту заявку?',
|
||||
));
|
||||
await dialog.accept();
|
||||
});
|
||||
|
||||
await page.goto('/logs');
|
||||
await expect(page.locator('.approval-panel-title')).toHaveText(
|
||||
localized('Human confirmations', 'Подтверждения человеком'),
|
||||
);
|
||||
await expect(page.locator('#approval-list')).toContainText('approval_ui_safe_summary');
|
||||
await expect(page.locator('#approval-list')).toContainText('op_charge_customer v3');
|
||||
await expect(page.locator('#approval-list')).toContainText('agent_sales');
|
||||
await expect(page.locator('#approval-list')).toContainText('customer@example.com');
|
||||
await expect(page.locator('#approval-list')).toContainText('[REDACTED]');
|
||||
await expect(page.locator('#approval-list')).toContainText('req_approval_ui');
|
||||
await expect(page.locator('#approval-list')).toContainText('0af7651916cd43dd8448eb211c80319c');
|
||||
await expect(page.locator('.approval-approve')).toHaveText(localized('Approve', 'Подтвердить'));
|
||||
await expect(page.locator('.approval-deny')).toHaveText(localized('Deny', 'Отклонить'));
|
||||
await expect(page.locator('#approval-list')).not.toContainText('SECRET_APPROVAL_CANARY');
|
||||
await page.locator('.approval-approve').click();
|
||||
await expect.poll(() => approveCalled).toBe(true);
|
||||
});
|
||||
Reference in New Issue
Block a user