- Remove Jest and all related packages - Install Vitest with coverage support - Create vitest.config.ts with path aliases - Set up global test configuration - Migrate all 6 test files to Vitest syntax - Update TypeScript configuration for better Vitest support - Create separate tsconfig.build.json for clean builds - Fix all import/module issues in tests - All 68 tests passing successfully - Current coverage baseline: 2.45% Phase 1 of testing suite improvement complete. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
174 lines
4.9 KiB
TypeScript
174 lines
4.9 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { N8NMCPBridge } from '../src/utils/bridge';
|
|
|
|
describe('N8NMCPBridge', () => {
|
|
describe('n8nToMCPToolArgs', () => {
|
|
it('should extract json from n8n data object', () => {
|
|
const n8nData = { json: { foo: 'bar' } };
|
|
const result = N8NMCPBridge.n8nToMCPToolArgs(n8nData);
|
|
expect(result).toEqual({ foo: 'bar' });
|
|
});
|
|
|
|
it('should remove n8n metadata', () => {
|
|
const n8nData = { foo: 'bar', pairedItem: 0 };
|
|
const result = N8NMCPBridge.n8nToMCPToolArgs(n8nData);
|
|
expect(result).toEqual({ foo: 'bar' });
|
|
});
|
|
});
|
|
|
|
describe('mcpToN8NExecutionData', () => {
|
|
it('should convert MCP content array to n8n format', () => {
|
|
const mcpResponse = {
|
|
content: [{ type: 'text', text: '{"result": "success"}' }],
|
|
};
|
|
const result = N8NMCPBridge.mcpToN8NExecutionData(mcpResponse, 1);
|
|
expect(result).toEqual({
|
|
json: { result: 'success' },
|
|
pairedItem: 1,
|
|
});
|
|
});
|
|
|
|
it('should handle non-JSON text content', () => {
|
|
const mcpResponse = {
|
|
content: [{ type: 'text', text: 'plain text response' }],
|
|
};
|
|
const result = N8NMCPBridge.mcpToN8NExecutionData(mcpResponse);
|
|
expect(result).toEqual({
|
|
json: { result: 'plain text response' },
|
|
pairedItem: 0,
|
|
});
|
|
});
|
|
|
|
it('should handle direct object response', () => {
|
|
const mcpResponse = { foo: 'bar' };
|
|
const result = N8NMCPBridge.mcpToN8NExecutionData(mcpResponse);
|
|
expect(result).toEqual({
|
|
json: { foo: 'bar' },
|
|
pairedItem: 0,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('n8nWorkflowToMCP', () => {
|
|
it('should convert n8n workflow to MCP format', () => {
|
|
const n8nWorkflow = {
|
|
id: '123',
|
|
name: 'Test Workflow',
|
|
nodes: [
|
|
{
|
|
id: 'node1',
|
|
type: 'n8n-nodes-base.start',
|
|
name: 'Start',
|
|
parameters: {},
|
|
position: [100, 100],
|
|
},
|
|
],
|
|
connections: {},
|
|
settings: { executionOrder: 'v1' },
|
|
active: true,
|
|
createdAt: '2024-01-01T00:00:00Z',
|
|
updatedAt: '2024-01-02T00:00:00Z',
|
|
};
|
|
|
|
const result = N8NMCPBridge.n8nWorkflowToMCP(n8nWorkflow);
|
|
|
|
expect(result).toEqual({
|
|
id: '123',
|
|
name: 'Test Workflow',
|
|
description: '',
|
|
nodes: [
|
|
{
|
|
id: 'node1',
|
|
type: 'n8n-nodes-base.start',
|
|
name: 'Start',
|
|
parameters: {},
|
|
position: [100, 100],
|
|
},
|
|
],
|
|
connections: {},
|
|
settings: { executionOrder: 'v1' },
|
|
metadata: {
|
|
createdAt: '2024-01-01T00:00:00Z',
|
|
updatedAt: '2024-01-02T00:00:00Z',
|
|
active: true,
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('mcpToN8NWorkflow', () => {
|
|
it('should convert MCP workflow to n8n format', () => {
|
|
const mcpWorkflow = {
|
|
name: 'Test Workflow',
|
|
nodes: [{ id: 'node1', type: 'n8n-nodes-base.start' }],
|
|
connections: { node1: { main: [[]] } },
|
|
};
|
|
|
|
const result = N8NMCPBridge.mcpToN8NWorkflow(mcpWorkflow);
|
|
|
|
expect(result).toEqual({
|
|
name: 'Test Workflow',
|
|
nodes: [{ id: 'node1', type: 'n8n-nodes-base.start' }],
|
|
connections: { node1: { main: [[]] } },
|
|
settings: { executionOrder: 'v1' },
|
|
staticData: null,
|
|
pinData: {},
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('sanitizeData', () => {
|
|
it('should handle null and undefined', () => {
|
|
expect(N8NMCPBridge.sanitizeData(null)).toEqual({});
|
|
expect(N8NMCPBridge.sanitizeData(undefined)).toEqual({});
|
|
});
|
|
|
|
it('should wrap non-objects', () => {
|
|
expect(N8NMCPBridge.sanitizeData('string')).toEqual({ value: 'string' });
|
|
expect(N8NMCPBridge.sanitizeData(123)).toEqual({ value: 123 });
|
|
});
|
|
|
|
it('should handle circular references', () => {
|
|
const obj: any = { a: 1 };
|
|
obj.circular = obj;
|
|
|
|
const result = N8NMCPBridge.sanitizeData(obj);
|
|
expect(result).toEqual({ a: 1, circular: '[Circular]' });
|
|
});
|
|
});
|
|
|
|
describe('formatError', () => {
|
|
it('should format standard errors', () => {
|
|
const error = new Error('Test error');
|
|
error.stack = 'stack trace';
|
|
|
|
const result = N8NMCPBridge.formatError(error);
|
|
|
|
expect(result).toEqual({
|
|
message: 'Test error',
|
|
type: 'Error',
|
|
stack: 'stack trace',
|
|
details: {
|
|
code: undefined,
|
|
statusCode: undefined,
|
|
data: undefined,
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should include additional error properties', () => {
|
|
const error: any = new Error('API error');
|
|
error.code = 'ERR_API';
|
|
error.statusCode = 404;
|
|
error.data = { field: 'value' };
|
|
|
|
const result = N8NMCPBridge.formatError(error);
|
|
|
|
expect(result.details).toEqual({
|
|
code: 'ERR_API',
|
|
statusCode: 404,
|
|
data: { field: 'value' },
|
|
});
|
|
});
|
|
});
|
|
}); |