Files
agent-police-department-cla…/tests/detectors.test.js
T
2026-06-14 13:18:56 +00:00

142 lines
4.6 KiB
JavaScript

// tests/detectors.test.js
require('../__mocks__/chrome.js');
const { detectViolations, DETECTOR_NAMES } = require('../lib/detectors.js');
describe('Detectors', () => {
beforeEach(() => {
global.__chromeStore = {};
});
test('DETECTOR_NAMES has 6 detectors', () => {
expect(DETECTOR_NAMES).toHaveLength(6);
expect(DETECTOR_NAMES).toContain('permission_bypass');
expect(DETECTOR_NAMES).toContain('out_of_scope');
expect(DETECTOR_NAMES).toContain('self_permissioning');
expect(DETECTOR_NAMES).toContain('disallowed_tools');
expect(DETECTOR_NAMES).toContain('redundant_operations');
expect(DETECTOR_NAMES).toContain('off_task');
});
test('detects permission bypass for disallowed domain', async () => {
const event = {
id: 'evt-1',
type: 'api_call',
tool: 'fetch',
target: 'https://malicious.com/api',
url: 'https://claude.ai/chat',
timestamp: new Date().toISOString()
};
const policy = {
rules: [
{ id: 'rule_allowed_domains', type: 'allowed_domains', enabled: true, params: { domains: ['github.com', 'claude.ai'] } }
]
};
const violations = await detectViolations(event, policy);
const bypass = violations.find(v => v.detector === 'permission_bypass');
expect(bypass).toBeDefined();
expect(bypass.severity).toBe('high');
expect(bypass.message).toContain('malicious.com');
});
test('allows permitted domain', async () => {
const event = {
id: 'evt-2',
type: 'api_call',
tool: 'fetch',
target: 'https://github.com/api',
url: 'https://claude.ai/chat',
timestamp: new Date().toISOString()
};
const policy = {
rules: [
{ id: 'rule_allowed_domains', type: 'allowed_domains', enabled: true, params: { domains: ['github.com'] } }
]
};
const violations = await detectViolations(event, policy);
const bypass = violations.find(v => v.detector === 'permission_bypass');
expect(bypass).toBeUndefined();
});
test('detects disallowed tools', async () => {
const event = {
id: 'evt-3',
type: 'tool_use',
tool: 'eval',
target: 'some-script.js',
url: 'https://claude.ai/chat',
timestamp: new Date().toISOString()
};
const policy = {
rules: [
{ id: 'rule_disallowed_tools', type: 'disallowed_tools', enabled: true, params: { tools: ['eval', 'exec'] } }
]
};
const violations = await detectViolations(event, policy);
const disallowed = violations.find(v => v.detector === 'disallowed_tools');
expect(disallowed).toBeDefined();
expect(disallowed.severity).toBe('critical');
expect(disallowed.message).toContain('eval');
});
test('detects self-permissioning', async () => {
const event = {
id: 'evt-4',
type: 'tool_use',
tool: 'edit_file',
target: 'permissions.json',
context: 'grant admin access control role privilege',
url: 'https://claude.ai/chat',
timestamp: new Date().toISOString()
};
const policy = {
rules: [
{ id: 'rule_permission_change', type: 'permission_change', enabled: true, params: {} }
]
};
const violations = await detectViolations(event, policy);
const perm = violations.find(v => v.detector === 'self_permissioning');
expect(perm).toBeDefined();
expect(perm.severity).toBe('critical');
});
test('detects out-of-scope operations', async () => {
const event = {
id: 'evt-5',
type: 'api_call',
tool: 'delete',
target: 'https://api.example.com/resource',
url: 'https://claude.ai/chat',
timestamp: new Date().toISOString()
};
const policy = {
rules: [
{ id: 'rule_allowed_operations', type: 'allowed_operations', enabled: true, params: { operations: ['read', 'chat'] } }
]
};
const violations = await detectViolations(event, policy);
const scope = violations.find(v => v.detector === 'out_of_scope');
expect(scope).toBeDefined();
expect(scope.severity).toBe('medium');
});
test('no violations for normal activity', async () => {
const event = {
id: 'evt-6',
type: 'chat',
tool: 'chat',
target: 'conversation',
url: 'https://claude.ai/chat',
timestamp: new Date().toISOString()
};
const policy = {
rules: [
{ id: 'rule_allowed_domains', type: 'allowed_domains', enabled: true, params: { domains: ['claude.ai'] } },
{ id: 'rule_disallowed_tools', type: 'disallowed_tools', enabled: true, params: { tools: ['eval'] } }
]
};
const violations = await detectViolations(event, policy);
expect(violations).toHaveLength(0);
});
});