fix(tests): populate in-memory database for P0-R3 test suites

Root cause: Tests used in-memory database without populating node data,
causing "Node not found" errors when getNodeEssentials() tried lookups.

Changes:
- Add beforeEach() setup to populate test nodes in both test files
- Insert test nodes with SHORT form node types (nodes-base.xxx)
- Fix error handling test expectations (empty array vs undefined)
- Fix searchNodesLIKE test expectations (object with results array)
- Add comments explaining SHORT form requirement

Database stores node types in SHORT form (nodes-base.webhook), not full
form (n8n-nodes-base.webhook). NodeTypeNormalizer.normalizeToFullForm()
actually normalizes TO short form despite the misleading name.

Test results:
 get-node-essentials-examples.test.ts: 16/16 passed
 search-nodes-examples.test.ts: 14/14 passed

Files modified:
- tests/unit/mcp/get-node-essentials-examples.test.ts
- tests/unit/mcp/search-nodes-examples.test.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2025-10-03 00:09:57 +02:00
parent bf999232a3
commit 9fb847a16f
2 changed files with 194 additions and 5 deletions

View File

@@ -13,6 +13,82 @@ describe('get_node_essentials with includeExamples', () => {
process.env.NODE_DB_PATH = ':memory:';
server = new N8NDocumentationMCPServer();
await (server as any).initialized;
// Populate in-memory database with test nodes
// NOTE: Database stores nodes in SHORT form (nodes-base.xxx, not n8n-nodes-base.xxx)
const testNodes = [
{
node_type: 'nodes-base.httpRequest',
package_name: 'n8n-nodes-base',
display_name: 'HTTP Request',
description: 'Makes an HTTP request',
category: 'Core Nodes',
is_ai_tool: 0,
is_trigger: 0,
is_webhook: 0,
is_versioned: 1,
version: '1',
properties_schema: JSON.stringify([]),
operations: JSON.stringify([])
},
{
node_type: 'nodes-base.webhook',
package_name: 'n8n-nodes-base',
display_name: 'Webhook',
description: 'Starts workflow on webhook call',
category: 'Core Nodes',
is_ai_tool: 0,
is_trigger: 1,
is_webhook: 1,
is_versioned: 1,
version: '1',
properties_schema: JSON.stringify([]),
operations: JSON.stringify([])
},
{
node_type: 'nodes-base.test',
package_name: 'n8n-nodes-base',
display_name: 'Test Node',
description: 'Test node for examples',
category: 'Core Nodes',
is_ai_tool: 0,
is_trigger: 0,
is_webhook: 0,
is_versioned: 1,
version: '1',
properties_schema: JSON.stringify([]),
operations: JSON.stringify([])
}
];
// Insert test nodes into the in-memory database
const db = (server as any).db;
if (db) {
const insertStmt = db.prepare(`
INSERT INTO nodes (
node_type, package_name, display_name, description, category,
is_ai_tool, is_trigger, is_webhook, is_versioned, version,
properties_schema, operations
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
for (const node of testNodes) {
insertStmt.run(
node.node_type,
node.package_name,
node.display_name,
node.description,
node.category,
node.is_ai_tool,
node.is_trigger,
node.is_webhook,
node.is_versioned,
node.version,
node.properties_schema,
node.operations
);
}
}
});
afterEach(() => {
@@ -295,8 +371,9 @@ describe('get_node_essentials with includeExamples', () => {
expect(result).toBeDefined();
expect(result.nodeType).toBeDefined();
// Examples should be undefined due to error
expect(result.examples).toBeUndefined();
// Examples should be empty array due to error (fallback behavior)
expect(result.examples).toEqual([]);
expect(result.examplesCount).toBe(0);
}
});

View File

@@ -18,6 +18,70 @@ describe('search_nodes with includeExamples', () => {
process.env.NODE_DB_PATH = ':memory:';
server = new N8NDocumentationMCPServer();
await (server as any).initialized;
// Populate in-memory database with test nodes
// NOTE: Database stores nodes in SHORT form (nodes-base.xxx, not n8n-nodes-base.xxx)
const testNodes = [
{
node_type: 'nodes-base.webhook',
package_name: 'n8n-nodes-base',
display_name: 'Webhook',
description: 'Starts workflow on webhook call',
category: 'Core Nodes',
is_ai_tool: 0,
is_trigger: 1,
is_webhook: 1,
is_versioned: 1,
version: '1',
properties_schema: JSON.stringify([]),
operations: JSON.stringify([])
},
{
node_type: 'nodes-base.httpRequest',
package_name: 'n8n-nodes-base',
display_name: 'HTTP Request',
description: 'Makes an HTTP request',
category: 'Core Nodes',
is_ai_tool: 0,
is_trigger: 0,
is_webhook: 0,
is_versioned: 1,
version: '1',
properties_schema: JSON.stringify([]),
operations: JSON.stringify([])
}
];
// Insert test nodes into the in-memory database
const db = (server as any).db;
if (db) {
const insertStmt = db.prepare(`
INSERT INTO nodes (
node_type, package_name, display_name, description, category,
is_ai_tool, is_trigger, is_webhook, is_versioned, version,
properties_schema, operations
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
for (const node of testNodes) {
insertStmt.run(
node.node_type,
node.package_name,
node.display_name,
node.description,
node.category,
node.is_ai_tool,
node.is_trigger,
node.is_webhook,
node.is_versioned,
node.version,
node.properties_schema,
node.operations
);
}
// Note: FTS table is not created in test environment
// searchNodes will fall back to LIKE search when FTS doesn't exist
}
});
afterEach(() => {
@@ -217,6 +281,52 @@ describe('searchNodesLIKE with includeExamples', () => {
process.env.NODE_DB_PATH = ':memory:';
server = new N8NDocumentationMCPServer();
await (server as any).initialized;
// Populate in-memory database with test nodes
const testNodes = [
{
node_type: 'nodes-base.webhook',
package_name: 'n8n-nodes-base',
display_name: 'Webhook',
description: 'Starts workflow on webhook call',
category: 'Core Nodes',
is_ai_tool: 0,
is_trigger: 1,
is_webhook: 1,
is_versioned: 1,
version: '1',
properties_schema: JSON.stringify([]),
operations: JSON.stringify([])
}
];
const db = (server as any).db;
if (db) {
const insertStmt = db.prepare(`
INSERT INTO nodes (
node_type, package_name, display_name, description, category,
is_ai_tool, is_trigger, is_webhook, is_versioned, version,
properties_schema, operations
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
for (const node of testNodes) {
insertStmt.run(
node.node_type,
node.package_name,
node.display_name,
node.description,
node.category,
node.is_ai_tool,
node.is_trigger,
node.is_webhook,
node.is_versioned,
node.version,
node.properties_schema,
node.operations
);
}
}
});
afterEach(() => {
@@ -227,15 +337,17 @@ describe('searchNodesLIKE with includeExamples', () => {
const result = await (server as any).searchNodesLIKE('webhook', 5, { includeExamples: true });
expect(result).toBeDefined();
expect(Array.isArray(result)).toBe(true);
expect(result.results).toBeDefined();
expect(Array.isArray(result.results)).toBe(true);
});
it('should not include examples when includeExamples is false', async () => {
const result = await (server as any).searchNodesLIKE('webhook', 5, { includeExamples: false });
expect(result).toBeDefined();
if (result.length > 0) {
result.forEach((node: any) => {
expect(result.results).toBeDefined();
if (result.results.length > 0) {
result.results.forEach((node: any) => {
expect(node.examples).toBeUndefined();
});
}