n8n/packages/@n8n/fs-proxy/src/logger.test.ts
oleg 629826ca1d
feat: Instance AI and local gateway modules (no-changelog) (#27206)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
Co-authored-by: Albert Alises <albert.alises@gmail.com>
Co-authored-by: Jaakko Husso <jaakko@n8n.io>
Co-authored-by: Dimitri Lavrenük <20122620+dlavrenuek@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Tuukka Kantola <Tuukkaa@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com>
Co-authored-by: Raúl Gómez Morales <raul00gm@gmail.com>
Co-authored-by: Elias Meire <elias@meire.dev>
Co-authored-by: Dimitri Lavrenük <dimitri.lavrenuek@n8n.io>
Co-authored-by: Tomi Turtiainen <10324676+tomi@users.noreply.github.com>
Co-authored-by: Mutasem Aldmour <mutasem@n8n.io>
2026-04-01 21:33:38 +03:00

197 lines
6.8 KiB
TypeScript

import type { GatewayConfig } from './config';
import { logger, printModuleStatus } from './logger';
const BASE_CONFIG: GatewayConfig = {
logLevel: 'info',
port: 7655,
allowedOrigins: [],
filesystem: { dir: '/test' },
computer: { shell: { timeout: 30_000 } },
browser: {
defaultBrowser: 'chrome',
},
permissions: {},
};
/** Find the message logged for a specific module by inspecting the meta argument. */
function messageFor(spy: jest.SpyInstance, module: string): string {
const call: [string, Record<string, unknown>] | undefined = (
spy.mock.calls as Array<[string, Record<string, unknown>]>
).find(([, meta]) => meta?.module === module);
return call?.[0] ?? '';
}
describe('printModuleStatus', () => {
let infoSpy: jest.SpyInstance;
beforeEach(() => {
infoSpy = jest.spyOn(logger, 'info').mockImplementation(() => {});
});
afterEach(() => {
infoSpy.mockRestore();
});
// ---------------------------------------------------------------------------
// Filesystem read
// ---------------------------------------------------------------------------
describe('Filesystem read', () => {
it('shows ✓ and directory path when allow', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { filesystemRead: 'allow' } });
const msg = messageFor(infoSpy, 'FilesystemRead');
expect(msg).toContain('✓');
expect(msg).toContain('/test');
expect(msg).not.toContain('(disabled)');
});
it('shows ? and directory path when ask', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { filesystemRead: 'ask' } });
const msg = messageFor(infoSpy, 'FilesystemRead');
expect(msg).toContain('?');
expect(msg).toContain('/test');
expect(msg).not.toContain('(disabled)');
});
it('shows ✗ and (disabled) when deny', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { filesystemRead: 'deny' } });
const msg = messageFor(infoSpy, 'FilesystemRead');
expect(msg).toContain('✗');
expect(msg).toContain('(disabled)');
});
it('defaults to deny when not specified', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: {} });
const msg = messageFor(infoSpy, 'FilesystemRead');
expect(msg).toContain('✗');
expect(msg).toContain('(disabled)');
});
});
// ---------------------------------------------------------------------------
// Filesystem write
// ---------------------------------------------------------------------------
describe('Filesystem write', () => {
it('shows ✓ and directory path when allow', () => {
printModuleStatus({
...BASE_CONFIG,
permissions: { filesystemRead: 'allow', filesystemWrite: 'allow' },
});
const msg = messageFor(infoSpy, 'FilesystemWrite');
expect(msg).toContain('✓');
expect(msg).toContain('/test');
expect(msg).not.toContain('(disabled)');
});
it('shows ? and directory path when ask', () => {
printModuleStatus({
...BASE_CONFIG,
permissions: { filesystemRead: 'allow', filesystemWrite: 'ask' },
});
const msg = messageFor(infoSpy, 'FilesystemWrite');
expect(msg).toContain('?');
expect(msg).toContain('/test');
});
it('shows ✗ and (disabled) when deny', () => {
printModuleStatus({
...BASE_CONFIG,
permissions: { filesystemRead: 'allow', filesystemWrite: 'deny' },
});
const msg = messageFor(infoSpy, 'FilesystemWrite');
expect(msg).toContain('✗');
expect(msg).toContain('(disabled)');
});
it('is forced to deny when filesystemRead is deny, regardless of filesystemWrite setting', () => {
printModuleStatus({
...BASE_CONFIG,
permissions: { filesystemRead: 'deny', filesystemWrite: 'allow' },
});
const msg = messageFor(infoSpy, 'FilesystemWrite');
expect(msg).toContain('✗');
expect(msg).toContain('(disabled)');
});
});
// ---------------------------------------------------------------------------
// Shell
// ---------------------------------------------------------------------------
describe('Shell', () => {
it('shows ✓ and timeout when allow', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { shell: 'allow' } });
const msg = messageFor(infoSpy, 'Shell');
expect(msg).toContain('✓');
expect(msg).toContain('timeout: 30s');
});
it('shows ? and timeout when ask', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { shell: 'ask' } });
const msg = messageFor(infoSpy, 'Shell');
expect(msg).toContain('?');
expect(msg).toContain('timeout: 30s');
});
it('shows ✗ and (disabled) when deny', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { shell: 'deny' } });
const msg = messageFor(infoSpy, 'Shell');
expect(msg).toContain('✗');
expect(msg).toContain('(disabled)');
});
});
// ---------------------------------------------------------------------------
// Computer (Screenshot + Mouse/keyboard share the same permission group)
// ---------------------------------------------------------------------------
describe('Computer (screenshot + mouse/keyboard)', () => {
it('shows ✓ on both Screenshot and Mouse/keyboard lines when allow', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { computer: 'allow' } });
expect(messageFor(infoSpy, 'Screenshot')).toContain('✓');
expect(messageFor(infoSpy, 'MouseKeyboard')).toContain('✓');
});
it('shows ? on both lines when ask', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { computer: 'ask' } });
expect(messageFor(infoSpy, 'Screenshot')).toContain('?');
expect(messageFor(infoSpy, 'MouseKeyboard')).toContain('?');
});
it('shows ✗ and (disabled) on both lines when deny', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { computer: 'deny' } });
expect(messageFor(infoSpy, 'Screenshot')).toContain('✗');
expect(messageFor(infoSpy, 'Screenshot')).toContain('(disabled)');
expect(messageFor(infoSpy, 'MouseKeyboard')).toContain('✗');
expect(messageFor(infoSpy, 'MouseKeyboard')).toContain('(disabled)');
});
});
// ---------------------------------------------------------------------------
// Browser
// ---------------------------------------------------------------------------
describe('Browser', () => {
it('shows ✓ and browser name when allow', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { browser: 'allow' } });
const msg = messageFor(infoSpy, 'Browser');
expect(msg).toContain('✓');
expect(msg).toContain('chrome');
});
it('shows ? and browser name when ask', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { browser: 'ask' } });
const msg = messageFor(infoSpy, 'Browser');
expect(msg).toContain('?');
expect(msg).toContain('chrome');
});
it('shows ✗ and (disabled) when deny', () => {
printModuleStatus({ ...BASE_CONFIG, permissions: { browser: 'deny' } });
const msg = messageFor(infoSpy, 'Browser');
expect(msg).toContain('✗');
expect(msg).toContain('(disabled)');
});
});
});