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

251 lines
5.8 KiB
TypeScript

import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import { Collection, MongoClient } from 'mongodb';
import type { INodeParameters, WorkflowTestData } from 'n8n-workflow';
MongoClient.connect = async function () {
const driverInfo = {
name: 'n8n_crud',
version: '1.2',
};
const client = new MongoClient('mongodb://localhost:27017', { driverInfo });
return client;
};
function buildWorkflow({
parameters,
expectedResult,
}: { parameters: INodeParameters; expectedResult: unknown[] }) {
const test: WorkflowTestData = {
description: 'should pass test',
input: {
workflowData: {
nodes: [
{
parameters: {},
id: '8b7bb389-e4ef-424a-bca1-e7ead60e43eb',
name: 'When clicking "Execute Workflow"',
type: 'n8n-nodes-base.manualTrigger',
typeVersion: 1,
position: [740, 380],
},
{
parameters,
id: '8b7bb389-e4ef-424a-bca1-e7ead60e43ec',
name: 'mongoDb',
type: 'n8n-nodes-base.mongoDb',
typeVersion: 1.2,
position: [1260, 360],
credentials: {
mongoDb: {
id: 'mongodb://localhost:27017',
name: 'Connection String',
},
},
},
],
connections: {
'When clicking "Execute Workflow"': {
main: [
[
{
node: 'mongoDb',
type: 'main',
index: 0,
},
],
],
},
},
},
},
output: {
assertBinaryData: true,
nodeData: {
mongoDb: [expectedResult],
},
},
};
return test;
}
describe('MongoDB CRUD Node', () => {
const testHarness = new NodeTestHarness();
describe('createSearchIndex operation', () => {
const spy: jest.SpyInstance = jest.spyOn(Collection.prototype, 'createSearchIndex');
afterAll(() => jest.restoreAllMocks());
beforeAll(() => {
spy.mockResolvedValueOnce('my-index');
});
testHarness.setupTest(
buildWorkflow({
parameters: {
operation: 'createSearchIndex',
resource: 'searchIndexes',
collection: 'foo',
indexType: 'vectorSearch',
indexDefinition: JSON.stringify({ mappings: {} }),
indexNameRequired: 'my-index',
},
expectedResult: [{ json: { indexName: 'my-index' } }],
}),
);
it('calls the spy with the expected arguments', function () {
expect(spy).toBeCalledWith({
name: 'my-index',
definition: { mappings: {} },
type: 'vectorSearch',
});
});
});
describe('listSearchIndexes operation', () => {
describe('no index name provided', function () {
let spy: jest.SpyInstance;
beforeAll(() => {
spy = jest.spyOn(Collection.prototype, 'listSearchIndexes');
const mockCursor = {
toArray: async () => [],
};
spy.mockReturnValue(mockCursor);
});
afterAll(() => jest.restoreAllMocks());
testHarness.setupTest(
buildWorkflow({
parameters: {
resource: 'searchIndexes',
operation: 'listSearchIndexes',
collection: 'foo',
},
expectedResult: [],
}),
);
it('calls the spy with the expected arguments', function () {
expect(spy).toHaveBeenCalledWith();
});
});
describe('index name provided', function () {
let spy: jest.SpyInstance;
beforeAll(() => {
spy = jest.spyOn(Collection.prototype, 'listSearchIndexes');
const mockCursor = {
toArray: async () => [],
};
spy.mockReturnValue(mockCursor);
});
afterAll(() => jest.restoreAllMocks());
testHarness.setupTest(
buildWorkflow({
parameters: {
resource: 'searchIndexes',
operation: 'listSearchIndexes',
collection: 'foo',
indexName: 'my-index',
},
expectedResult: [],
}),
);
it('calls the spy with the expected arguments', function () {
expect(spy).toHaveBeenCalledWith('my-index');
});
});
describe('return values are transformed into the expected return type', function () {
let spy: jest.SpyInstance;
beforeAll(() => {
spy = jest.spyOn(Collection.prototype, 'listSearchIndexes');
const mockCursor = {
toArray: async () => [{ name: 'my-index' }, { name: 'my-index-2' }],
};
spy.mockReturnValue(mockCursor);
});
afterAll(() => jest.restoreAllMocks());
testHarness.setupTest(
buildWorkflow({
parameters: {
operation: 'listSearchIndexes',
resource: 'searchIndexes',
collection: 'foo',
indexName: 'my-index',
},
expectedResult: [
{
json: { name: 'my-index' },
},
{
json: { name: 'my-index-2' },
},
],
}),
);
});
});
describe('dropSearchIndex operation', () => {
let spy: jest.SpyInstance;
afterAll(() => jest.restoreAllMocks());
beforeAll(() => {
spy = jest.spyOn(Collection.prototype, 'dropSearchIndex');
spy.mockResolvedValueOnce(undefined);
});
testHarness.setupTest(
buildWorkflow({
parameters: {
operation: 'dropSearchIndex',
resource: 'searchIndexes',
collection: 'foo',
indexNameRequired: 'my-index',
},
expectedResult: [{ json: { 'my-index': true } }],
}),
);
it('calls the spy with the expected arguments', function () {
expect(spy).toBeCalledWith('my-index');
});
});
describe('updateSearchIndex operation', () => {
let spy: jest.SpyInstance;
afterAll(() => jest.restoreAllMocks());
beforeAll(() => {
spy = jest.spyOn(Collection.prototype, 'updateSearchIndex');
spy.mockResolvedValueOnce(undefined);
});
testHarness.setupTest(
buildWorkflow({
parameters: {
operation: 'updateSearchIndex',
resource: 'searchIndexes',
collection: 'foo',
indexNameRequired: 'my-index',
indexDefinition: JSON.stringify({
mappings: {
dynamic: true,
},
}),
},
expectedResult: [{ json: { 'my-index': true } }],
}),
);
it('calls the spy with the expected arguments', function () {
expect(spy).toBeCalledWith('my-index', { mappings: { dynamic: true } });
});
});
});