Files
alighasami 3d5eaf9445
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
first commit
2026-03-17 16:22:57 +03:30

128 lines
3.3 KiB
TypeScript

import { describe, test, expect, beforeAll, afterAll } from 'vitest';
import { createServiceStack, type N8NStack } from 'n8n-containers';
import { constructExecutionMetaData } from 'n8n-core';
import type { IDataObject, IExecuteFunctions, INode } from 'n8n-workflow';
import { router } from '../../v2/actions/router';
import type { MysqlNodeCredentials } from '../../v2/helpers/interfaces';
let stack: N8NStack;
let credentials: MysqlNodeCredentials;
beforeAll(async () => {
stack = await createServiceStack({ services: ['mysql'] });
const meta = stack.serviceResults.mysql!.meta as {
externalHost: string;
externalPort: number;
database: string;
username: string;
password: string;
};
credentials = {
host: meta.externalHost,
port: meta.externalPort,
database: meta.database,
user: meta.username,
password: meta.password,
connectTimeout: 10000,
ssl: false,
sshTunnel: false,
};
});
afterAll(async () => {
await stack?.stop();
});
const node: INode = {
id: '1',
name: 'MySQL',
typeVersion: 2.5,
type: 'n8n-nodes-base.mySql',
position: [0, 0],
parameters: {},
};
function mockExecuteFunctions(
params: IDataObject,
creds: MysqlNodeCredentials,
continueOnFail = false,
): IExecuteFunctions {
return {
getNodeParameter: (name: string, _i: number, fallback?: unknown) => params[name] ?? fallback,
getNode: () => node,
getInputData: () => [{ json: {} }],
continueOnFail: () => continueOnFail,
getCredentials: async () => creds,
helpers: {
constructExecutionMetaData,
getSSHClient: () => {
throw new Error('No SSH');
},
},
} as unknown as IExecuteFunctions;
}
const badCreds: MysqlNodeCredentials = {
host: 'invalid.host',
port: 3306,
database: 'x',
user: 'x',
password: 'x',
connectTimeout: 1000,
ssl: false,
sshTunnel: false,
};
describe('MySQL Integration - NODE-4174', () => {
test('happy path: SELECT against real MySQL', async () => {
const params = {
resource: 'database',
operation: 'executeQuery',
query: 'SELECT 1 as result',
options: { queryBatching: 'single', nodeVersion: 2.5 },
};
const result = await router.call(mockExecuteFunctions(params, credentials));
expect(result[0][0].json).toEqual({ result: 1 });
});
test('bad path: query error returns error item with continueOnFail', async () => {
const params = {
resource: 'database',
operation: 'executeQuery',
query: 'SELECT * FROM table_that_does_not_exist',
options: { queryBatching: 'single', nodeVersion: 2.5 },
};
const result = await router.call(mockExecuteFunctions(params, credentials, true));
expect(result[0][0].json).toHaveProperty('message');
});
test('connection error should return error item with continueOnFail', async () => {
const params = {
resource: 'database',
operation: 'executeQuery',
query: 'SELECT 1',
options: { queryBatching: 'single', nodeVersion: 2.5, connectTimeout: 1000 },
};
const result = await router.call(mockExecuteFunctions(params, badCreds, true));
expect(result[0][0].json).toHaveProperty('error');
});
test('connection error throws when continueOnFail is false', async () => {
const params = {
resource: 'database',
operation: 'executeQuery',
query: 'SELECT 1',
options: { queryBatching: 'single', nodeVersion: 2.5, connectTimeout: 1000 },
};
await expect(router.call(mockExecuteFunctions(params, badCreds, false))).rejects.toThrow();
});
});