mirror of
https://github.com/Sea-Haven-Industries/sh-mcp.git
synced 2026-09-30 04:13:14 +00:00
39 lines
1.5 KiB
TypeScript
39 lines
1.5 KiB
TypeScript
|
|
import { describe, it, expect, vi } from 'vitest';
|
||
|
|
|
||
|
|
import { isSubDenied } from '../src/deny-list.js';
|
||
|
|
|
||
|
|
function fakeClient(send: () => Promise<unknown>) {
|
||
|
|
return { send: vi.fn(send) } as unknown as Parameters<typeof isSubDenied>[2];
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('isSubDenied', () => {
|
||
|
|
it('returns true when the sub has a deny-list item', async () => {
|
||
|
|
const client = fakeClient(async () => ({ Item: { sub: 'abc' } }));
|
||
|
|
expect(await isSubDenied('sh-mcp-deny-list', 'abc', client)).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('returns false when the sub has no item', async () => {
|
||
|
|
const client = fakeClient(async () => ({}));
|
||
|
|
expect(await isSubDenied('sh-mcp-deny-list', 'abc', client)).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('never denies an absent/empty sub (and does not hit DDB)', async () => {
|
||
|
|
const client = fakeClient(async () => ({ Item: { sub: '' } }));
|
||
|
|
expect(await isSubDenied('sh-mcp-deny-list', undefined, client)).toBe(false);
|
||
|
|
expect((client as unknown as { send: { mock: { calls: unknown[] } } }).send.mock.calls).toEqual(
|
||
|
|
[],
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('FAILS OPEN on a read error: a DDB blip resolves to not-denied (logged)', async () => {
|
||
|
|
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
||
|
|
const client = fakeClient(async () => {
|
||
|
|
throw new Error('throttled');
|
||
|
|
});
|
||
|
|
expect(await isSubDenied('sh-mcp-deny-list', 'abc', client)).toBe(false);
|
||
|
|
expect(warn).toHaveBeenCalledOnce();
|
||
|
|
expect(warn.mock.calls[0]?.[0]).toContain('deny_list_read_failed');
|
||
|
|
warn.mockRestore();
|
||
|
|
});
|
||
|
|
});
|