first commit
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
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
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
/* eslint-disable n8n-nodes-base/node-param-display-name-miscased */
|
||||
import mysql2 from 'mysql2/promise';
|
||||
import type { ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow';
|
||||
|
||||
import { searchTables } from '../../v1/GenericFunctions';
|
||||
|
||||
jest.mock('mysql2/promise');
|
||||
|
||||
describe('MySQL / v1 / Generic Functions', () => {
|
||||
let mockLoadOptionsFunctions: ILoadOptionsFunctions;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
mockLoadOptionsFunctions = {
|
||||
getCredentials: jest.fn().mockResolvedValue({
|
||||
database: 'test_db',
|
||||
}),
|
||||
} as unknown as ILoadOptionsFunctions;
|
||||
});
|
||||
|
||||
describe('searchTables', () => {
|
||||
it('should return matching tables', async () => {
|
||||
const mockRows = [{ table_name: 'users' }, { table_name: 'products' }];
|
||||
|
||||
const mockQuery = jest.fn().mockResolvedValue([mockRows]);
|
||||
const mockEnd = jest.fn().mockResolvedValue(undefined);
|
||||
|
||||
(mysql2.createConnection as jest.Mock).mockResolvedValue({
|
||||
query: mockQuery,
|
||||
end: mockEnd,
|
||||
});
|
||||
|
||||
const result: INodeListSearchResult = await searchTables.call(
|
||||
mockLoadOptionsFunctions,
|
||||
'user',
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
results: [
|
||||
{ name: 'users', value: 'users' },
|
||||
{ name: 'products', value: 'products' },
|
||||
],
|
||||
});
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(
|
||||
`SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = ?
|
||||
AND table_name LIKE ?
|
||||
ORDER BY table_name`,
|
||||
['test_db', '%user%'],
|
||||
);
|
||||
|
||||
expect(mockEnd).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle empty search query', async () => {
|
||||
const mockRows: any[] = [];
|
||||
|
||||
const mockQuery = jest.fn().mockResolvedValue([mockRows]);
|
||||
const mockEnd = jest.fn().mockResolvedValue(undefined);
|
||||
|
||||
(mysql2.createConnection as jest.Mock).mockResolvedValue({
|
||||
query: mockQuery,
|
||||
end: mockEnd,
|
||||
});
|
||||
|
||||
const result = await searchTables.call(mockLoadOptionsFunctions);
|
||||
|
||||
expect(result).toEqual({ results: [] });
|
||||
expect(mockQuery).toHaveBeenCalledWith(
|
||||
`SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = ?
|
||||
AND table_name LIKE ?
|
||||
ORDER BY table_name`,
|
||||
['test_db', '%%'],
|
||||
);
|
||||
|
||||
expect(mockEnd).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle database errors', async () => {
|
||||
const mockError = new Error('Database connection failed');
|
||||
|
||||
(mysql2.createConnection as jest.Mock).mockRejectedValue(mockError);
|
||||
|
||||
await expect(searchTables.call(mockLoadOptionsFunctions)).rejects.toThrow(
|
||||
'Database connection failed',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { Connection, QueryResult } from 'mysql2/promise';
|
||||
|
||||
const mockConnection = mock<Connection>();
|
||||
const createConnection = jest.fn().mockReturnValue(mockConnection);
|
||||
jest.mock('mysql2/promise', () => ({ createConnection }));
|
||||
|
||||
describe('Test MySqlV1, executeQuery', () => {
|
||||
mockConnection.query.mockResolvedValue([{ success: true } as unknown as QueryResult, []]);
|
||||
|
||||
new NodeTestHarness().setupTests({
|
||||
workflowFiles: ['executeQuery.workflow.json'],
|
||||
customAssertions() {
|
||||
expect(mockConnection.query).toHaveBeenCalledTimes(1);
|
||||
expect(mockConnection.query).toHaveBeenCalledWith(
|
||||
"select * from family_parents where (parent_email = 'parent1@mail.com' or parent_email = 'parent2@mail.com') and parent_email <> '';",
|
||||
);
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"name": "mysql v1 resolve expression copy",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "d6d9fbcc-d8bc-4f79-8e00-3acf8ffb12de",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
460,
|
||||
460
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "select * from family_parents where (parent_email = {{ \"'\" + $json['Parent 1 email'] + \"'\" }} or parent_email = {{ \"'\" + $json['Parent 2 email'] + \"'\"}}) and parent_email <> '';\n"
|
||||
},
|
||||
"id": "faefc24c-91b4-4b10-85a6-b3cecbceee08",
|
||||
"name": "Get matching families",
|
||||
"type": "n8n-nodes-base.mySql",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
900,
|
||||
460
|
||||
],
|
||||
"credentials": {
|
||||
"mySql": {
|
||||
"id": "93",
|
||||
"name": "MySQL account"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "29c30f6e-9f5f-4b3a-80c4-2da762e96bd9",
|
||||
"name": "No Operation, do nothing1",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
1120,
|
||||
460
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"fields": {
|
||||
"values": [
|
||||
{
|
||||
"name": "Parent 1 email",
|
||||
"stringValue": "parent1@mail.com"
|
||||
},
|
||||
{
|
||||
"name": "Parent 2 email",
|
||||
"stringValue": "parent2@mail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": "none",
|
||||
"options": {}
|
||||
},
|
||||
"id": "54c7bbf9-dabc-421b-85b2-7c3006f5ee61",
|
||||
"name": "Edit Fields",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 3.2,
|
||||
"position": [
|
||||
680,
|
||||
460
|
||||
]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"No Operation, do nothing1": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Edit Fields",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Get matching families": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "No Operation, do nothing1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Edit Fields": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Get matching families",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "aeb01d24-c117-405a-875f-909ea8ccdc16",
|
||||
"id": "GlTwlHZfQwNjbeqv",
|
||||
"meta": {
|
||||
"instanceId": "b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
Reference in New Issue
Block a user