fix: resolve TypeScript and linting errors in test infrastructure

- Add @types/better-sqlite3 dependency
- Remove duplicate database mock file
- Fix property spread order in workflow builder to prevent overwrites
- All 75 tests now pass with no linting errors

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2025-07-28 13:26:00 +02:00
parent 17013d8a25
commit 45b271c860
4 changed files with 13 additions and 150 deletions

11
package-lock.json generated
View File

@@ -26,6 +26,7 @@
"devDependencies": {
"@faker-js/faker": "^9.9.0",
"@testing-library/jest-dom": "^6.6.4",
"@types/better-sqlite3": "^7.6.13",
"@types/express": "^5.0.3",
"@types/node": "^22.15.30",
"@types/ws": "^8.18.1",
@@ -13679,6 +13680,16 @@
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/better-sqlite3": {
"version": "7.6.13",
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz",
"integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/body-parser": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",

View File

@@ -92,6 +92,7 @@
"devDependencies": {
"@faker-js/faker": "^9.9.0",
"@testing-library/jest-dom": "^6.6.4",
"@types/better-sqlite3": "^7.6.13",
"@types/express": "^5.0.3",
"@types/node": "^22.15.30",
"@types/ws": "^8.18.1",

View File

@@ -1,149 +0,0 @@
import { vi } from 'vitest';
import type { Database } from 'better-sqlite3';
export interface MockDatabase extends Partial<Database> {
prepare: ReturnType<typeof vi.fn>;
exec: ReturnType<typeof vi.fn>;
close: ReturnType<typeof vi.fn>;
transaction: ReturnType<typeof vi.fn>;
pragma: ReturnType<typeof vi.fn>;
backup: ReturnType<typeof vi.fn>;
serialize: ReturnType<typeof vi.fn>;
function: ReturnType<typeof vi.fn>;
aggregate: ReturnType<typeof vi.fn>;
table: ReturnType<typeof vi.fn>;
loadExtension: ReturnType<typeof vi.fn>;
defaultSafeIntegers: ReturnType<typeof vi.fn>;
unsafeMode: ReturnType<typeof vi.fn>;
}
export interface MockStatement {
run: ReturnType<typeof vi.fn>;
get: ReturnType<typeof vi.fn>;
all: ReturnType<typeof vi.fn>;
iterate: ReturnType<typeof vi.fn>;
pluck: ReturnType<typeof vi.fn>;
expand: ReturnType<typeof vi.fn>;
raw: ReturnType<typeof vi.fn>;
columns: ReturnType<typeof vi.fn>;
bind: ReturnType<typeof vi.fn>;
safeIntegers: ReturnType<typeof vi.fn>;
}
export function createMockDatabase(): MockDatabase {
const mockDb: MockDatabase = {
prepare: vi.fn(),
exec: vi.fn(),
close: vi.fn(),
transaction: vi.fn(),
pragma: vi.fn(),
backup: vi.fn(),
serialize: vi.fn(),
function: vi.fn(),
aggregate: vi.fn(),
table: vi.fn(),
loadExtension: vi.fn(),
defaultSafeIntegers: vi.fn(),
unsafeMode: vi.fn(),
memory: false,
readonly: false,
name: ':memory:',
open: true,
inTransaction: false,
};
// Setup default behavior
mockDb.transaction.mockImplementation((fn: Function) => {
return (...args: any[]) => fn(...args);
});
mockDb.pragma.mockReturnValue(undefined);
return mockDb;
}
export function createMockStatement(defaultResults: any = []): MockStatement {
const mockStmt: MockStatement = {
run: vi.fn().mockReturnValue({ changes: 1, lastInsertRowid: 1 }),
get: vi.fn().mockReturnValue(defaultResults[0] || undefined),
all: vi.fn().mockReturnValue(defaultResults),
iterate: vi.fn().mockReturnValue(defaultResults[Symbol.iterator]()),
pluck: vi.fn().mockReturnThis(),
expand: vi.fn().mockReturnThis(),
raw: vi.fn().mockReturnThis(),
columns: vi.fn().mockReturnValue([]),
bind: vi.fn().mockReturnThis(),
safeIntegers: vi.fn().mockReturnThis(),
};
return mockStmt;
}
export function setupDatabaseMock(mockDb: MockDatabase, queryResults: Record<string, any> = {}) {
mockDb.prepare.mockImplementation((query: string) => {
// Match queries to results
for (const [pattern, result] of Object.entries(queryResults)) {
if (query.includes(pattern)) {
return createMockStatement(Array.isArray(result) ? result : [result]);
}
}
// Default mock statement
return createMockStatement();
});
}
// Helper to create a mock node repository
export function createMockNodeRepository() {
return {
getNodeByType: vi.fn(),
searchNodes: vi.fn(),
listNodes: vi.fn(),
getNodeEssentials: vi.fn(),
getNodeDocumentation: vi.fn(),
getNodeInfo: vi.fn(),
searchNodeProperties: vi.fn(),
listAITools: vi.fn(),
getNodeForTask: vi.fn(),
listTasks: vi.fn(),
getDatabaseStatistics: vi.fn(),
close: vi.fn(),
};
}
// Helper to create mock node data
export function createMockNode(overrides: any = {}) {
return {
id: 1,
package_name: 'n8n-nodes-base',
node_type: 'n8n-nodes-base.webhook',
display_name: 'Webhook',
description: 'Starts the workflow when a webhook is called',
version: 2,
defaults: JSON.stringify({ name: 'Webhook' }),
properties: JSON.stringify([]),
credentials: JSON.stringify([]),
inputs: JSON.stringify(['main']),
outputs: JSON.stringify(['main']),
type_version: 2,
is_trigger: 1,
is_regular: 0,
is_webhook: 1,
webhook_path: '/webhook',
full_metadata: JSON.stringify({}),
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
...overrides,
};
}
// Helper to create mock query results
export function createMockQueryResults() {
return {
'SELECT * FROM nodes WHERE node_type = ?': createMockNode(),
'SELECT COUNT(*) as count FROM nodes': { count: 525 },
'SELECT * FROM nodes WHERE display_name LIKE ?': [
createMockNode({ node_type: 'n8n-nodes-base.slack', display_name: 'Slack' }),
createMockNode({ node_type: 'n8n-nodes-base.webhook', display_name: 'Webhook' }),
],
};
}

View File

@@ -114,13 +114,13 @@ export class WorkflowBuilder {
const nodeName = node.name || `${node.type} ${++this.nodeCounter}`;
const fullNode: INode = {
...node, // Spread first to allow overrides
id: nodeId,
name: nodeName,
type: node.type,
typeVersion: node.typeVersion,
position: node.position || this.getNextPosition(),
parameters: node.parameters || {},
...node,
};
this.workflow.nodes.push(fullNode);