mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
refactor(core): Refactor cli command tests (no-changelog) (#9731)
This commit is contained in:
parent
fb73ec3994
commit
2d02c73fbd
|
@ -14,7 +14,7 @@ import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData'
|
|||
import config from '@/config';
|
||||
import type { Job, JobId, JobResponse, WebhookResponse } from '@/Queue';
|
||||
import { Queue } from '@/Queue';
|
||||
import { N8N_VERSION } from '@/constants';
|
||||
import { N8N_VERSION, inTest } from '@/constants';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import type { ICredentialsOverwrite } from '@/Interfaces';
|
||||
|
@ -498,7 +498,7 @@ export class Worker extends BaseCommand {
|
|||
}
|
||||
|
||||
// Make sure that the process does not close
|
||||
await new Promise(() => {});
|
||||
if (!inTest) await new Promise(() => {});
|
||||
}
|
||||
|
||||
async catch(error: Error) {
|
||||
|
|
|
@ -1,39 +1,24 @@
|
|||
import { Config } from '@oclif/core';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { ImportCredentialsCommand } from '@/commands/import/credentials';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
|
||||
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
||||
import { mockInstance } from '../../shared/mocking';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { getAllCredentials, getAllSharedCredentials } from '../shared/db/credentials';
|
||||
import { createMember, createOwner } from '../shared/db/users';
|
||||
import { getPersonalProject } from '../shared/db/projects';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
const oclifConfig = new Config({ root: __dirname });
|
||||
|
||||
async function importCredential(argv: string[]) {
|
||||
const importer = new ImportCredentialsCommand(argv, oclifConfig);
|
||||
await importer.init();
|
||||
await importer.run();
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
await testDb.init();
|
||||
await oclifConfig.load();
|
||||
});
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
const command = setupTestCommand(ImportCredentialsCommand);
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Credentials', 'SharedCredentials', 'User']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('import:credentials should import a credential', async () => {
|
||||
//
|
||||
// ARRANGE
|
||||
|
@ -44,9 +29,7 @@ test('import:credentials should import a credential', async () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await importCredential([
|
||||
'--input=./test/integration/commands/importCredentials/credentials.json',
|
||||
]);
|
||||
await command.run(['--input=./test/integration/commands/importCredentials/credentials.json']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -78,7 +61,7 @@ test('import:credentials should import a credential from separated files', async
|
|||
// ACT
|
||||
//
|
||||
// import credential the first time, assigning it to the owner
|
||||
await importCredential([
|
||||
await command.run([
|
||||
'--separate',
|
||||
'--input=./test/integration/commands/importCredentials/separate',
|
||||
]);
|
||||
|
@ -117,7 +100,7 @@ test('`import:credentials --userId ...` should fail if the credential exists alr
|
|||
const member = await createMember();
|
||||
|
||||
// import credential the first time, assigning it to the owner
|
||||
await importCredential([
|
||||
await command.run([
|
||||
'--input=./test/integration/commands/importCredentials/credentials.json',
|
||||
`--userId=${owner.id}`,
|
||||
]);
|
||||
|
@ -145,7 +128,7 @@ test('`import:credentials --userId ...` should fail if the credential exists alr
|
|||
// Import again while updating the name we try to assign the
|
||||
// credential to another user.
|
||||
await expect(
|
||||
importCredential([
|
||||
command.run([
|
||||
'--input=./test/integration/commands/importCredentials/credentials-updated.json',
|
||||
`--userId=${member.id}`,
|
||||
]),
|
||||
|
@ -188,7 +171,7 @@ test("only update credential, don't create or update owner if neither `--userId`
|
|||
const memberProject = await getPersonalProject(member);
|
||||
|
||||
// import credential the first time, assigning it to a member
|
||||
await importCredential([
|
||||
await command.run([
|
||||
'--input=./test/integration/commands/importCredentials/credentials.json',
|
||||
`--userId=${member.id}`,
|
||||
]);
|
||||
|
@ -213,7 +196,7 @@ test("only update credential, don't create or update owner if neither `--userId`
|
|||
// ACT
|
||||
//
|
||||
// Import again only updating the name and omitting `--userId`
|
||||
await importCredential([
|
||||
await command.run([
|
||||
'--input=./test/integration/commands/importCredentials/credentials-updated.json',
|
||||
]);
|
||||
|
||||
|
@ -253,7 +236,7 @@ test('`import:credential --projectId ...` should fail if the credential already
|
|||
const memberProject = await getPersonalProject(member);
|
||||
|
||||
// import credential the first time, assigning it to the owner
|
||||
await importCredential([
|
||||
await command.run([
|
||||
'--input=./test/integration/commands/importCredentials/credentials.json',
|
||||
`--userId=${owner.id}`,
|
||||
]);
|
||||
|
@ -281,7 +264,7 @@ test('`import:credential --projectId ...` should fail if the credential already
|
|||
// Import again while updating the name we try to assign the
|
||||
// credential to another user.
|
||||
await expect(
|
||||
importCredential([
|
||||
command.run([
|
||||
'--input=./test/integration/commands/importCredentials/credentials-updated.json',
|
||||
`--projectId=${memberProject.id}`,
|
||||
]),
|
||||
|
@ -317,7 +300,7 @@ test('`import:credential --projectId ...` should fail if the credential already
|
|||
|
||||
test('`import:credential --projectId ... --userId ...` fails explaining that only one of the options can be used at a time', async () => {
|
||||
await expect(
|
||||
importCredential([
|
||||
command.run([
|
||||
'--input=./test/integration/commands/importCredentials/credentials-updated.json',
|
||||
`--projectId=${nanoid()}`,
|
||||
`--userId=${nanoid()}`,
|
||||
|
|
|
@ -1,39 +1,24 @@
|
|||
import { Config } from '@oclif/core';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { ImportWorkflowsCommand } from '@/commands/import/workflow';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
|
||||
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
||||
import { mockInstance } from '../../shared/mocking';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { getAllSharedWorkflows, getAllWorkflows } from '../shared/db/workflows';
|
||||
import { createMember, createOwner } from '../shared/db/users';
|
||||
import { getPersonalProject } from '../shared/db/projects';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
const oclifConfig = new Config({ root: __dirname });
|
||||
|
||||
async function importWorkflow(argv: string[]) {
|
||||
const importer = new ImportWorkflowsCommand(argv, oclifConfig);
|
||||
await importer.init();
|
||||
await importer.run();
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
await testDb.init();
|
||||
await oclifConfig.load();
|
||||
});
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
const command = setupTestCommand(ImportWorkflowsCommand);
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Workflow', 'SharedWorkflow', 'User']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('import:workflow should import active workflow and deactivate it', async () => {
|
||||
//
|
||||
// ARRANGE
|
||||
|
@ -44,10 +29,7 @@ test('import:workflow should import active workflow and deactivate it', async ()
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await importWorkflow([
|
||||
'--separate',
|
||||
'--input=./test/integration/commands/importWorkflows/separate',
|
||||
]);
|
||||
await command.run(['--separate', '--input=./test/integration/commands/importWorkflows/separate']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -86,9 +68,7 @@ test('import:workflow should import active workflow from combined file and deact
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await importWorkflow([
|
||||
'--input=./test/integration/commands/importWorkflows/combined/combined.json',
|
||||
]);
|
||||
await command.run(['--input=./test/integration/commands/importWorkflows/combined/combined.json']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -126,7 +106,7 @@ test('`import:workflow --userId ...` should fail if the workflow exists already
|
|||
const member = await createMember();
|
||||
|
||||
// Import workflow the first time, assigning it to a member.
|
||||
await importWorkflow([
|
||||
await command.run([
|
||||
'--input=./test/integration/commands/importWorkflows/combined-with-update/original.json',
|
||||
`--userId=${owner.id}`,
|
||||
]);
|
||||
|
@ -153,7 +133,7 @@ test('`import:workflow --userId ...` should fail if the workflow exists already
|
|||
// Import the same workflow again, with another name but the same ID, and try
|
||||
// to assign it to the member.
|
||||
await expect(
|
||||
importWorkflow([
|
||||
command.run([
|
||||
'--input=./test/integration/commands/importWorkflows/combined-with-update/updated.json',
|
||||
`--userId=${member.id}`,
|
||||
]),
|
||||
|
@ -190,7 +170,7 @@ test("only update the workflow, don't create or update the owner if `--userId` i
|
|||
const memberProject = await getPersonalProject(member);
|
||||
|
||||
// Import workflow the first time, assigning it to a member.
|
||||
await importWorkflow([
|
||||
await command.run([
|
||||
'--input=./test/integration/commands/importWorkflows/combined-with-update/original.json',
|
||||
`--userId=${member.id}`,
|
||||
]);
|
||||
|
@ -215,7 +195,7 @@ test("only update the workflow, don't create or update the owner if `--userId` i
|
|||
// ACT
|
||||
//
|
||||
// Import the same workflow again, with another name but the same ID.
|
||||
await importWorkflow([
|
||||
await command.run([
|
||||
'--input=./test/integration/commands/importWorkflows/combined-with-update/updated.json',
|
||||
]);
|
||||
|
||||
|
@ -249,7 +229,7 @@ test('`import:workflow --projectId ...` should fail if the credential already ex
|
|||
const memberProject = await getPersonalProject(member);
|
||||
|
||||
// Import workflow the first time, assigning it to a member.
|
||||
await importWorkflow([
|
||||
await command.run([
|
||||
'--input=./test/integration/commands/importWorkflows/combined-with-update/original.json',
|
||||
`--userId=${owner.id}`,
|
||||
]);
|
||||
|
@ -276,7 +256,7 @@ test('`import:workflow --projectId ...` should fail if the credential already ex
|
|||
// Import the same workflow again, with another name but the same ID, and try
|
||||
// to assign it to the member.
|
||||
await expect(
|
||||
importWorkflow([
|
||||
command.run([
|
||||
'--input=./test/integration/commands/importWorkflows/combined-with-update/updated.json',
|
||||
`--projectId=${memberProject.id}`,
|
||||
]),
|
||||
|
@ -306,7 +286,7 @@ test('`import:workflow --projectId ...` should fail if the credential already ex
|
|||
|
||||
test('`import:workflow --projectId ... --userId ...` fails explaining that only one of the options can be used at a time', async () => {
|
||||
await expect(
|
||||
importWorkflow([
|
||||
command.run([
|
||||
'--input=./test/integration/commands/importWorkflows/combined-with-update/updated.json',
|
||||
`--userId=${nanoid()}`,
|
||||
`--projectId=${nanoid()}`,
|
||||
|
|
|
@ -1,57 +1,37 @@
|
|||
import { Reset } from '@/commands/ldap/reset';
|
||||
import { Config } from '@oclif/core';
|
||||
import { Container } from 'typedi';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { EntityNotFoundError } from '@n8n/typeorm';
|
||||
|
||||
import * as testDb from '../../shared/testDb';
|
||||
import { Reset } from '@/commands/ldap/reset';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { mockInstance } from '../../../shared/mocking';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import { getLdapSynchronizations, saveLdapSynchronization } from '@/Ldap/helpers';
|
||||
import { LdapService } from '@/Ldap/ldap.service';
|
||||
import { Push } from '@/push';
|
||||
import { Telemetry } from '@/telemetry';
|
||||
|
||||
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
||||
import { mockInstance } from '../../../shared/mocking';
|
||||
import { createLdapUser, createMember, getUserById } from '../../shared/db/users';
|
||||
import { createWorkflow } from '../../shared/db/workflows';
|
||||
import { randomCredentialPayload } from '../../shared/random';
|
||||
import { saveCredential } from '../../shared/db/credentials';
|
||||
import Container from 'typedi';
|
||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { CredentialsRepository } from '@/databases/repositories/credentials.repository';
|
||||
import { EntityNotFoundError } from '@n8n/typeorm';
|
||||
import { Push } from '@/push';
|
||||
import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflow.repository';
|
||||
import { SharedCredentialsRepository } from '@/databases/repositories/sharedCredentials.repository';
|
||||
import { createTeamProject, findProject, getPersonalProject } from '../../shared/db/projects';
|
||||
import { getLdapSynchronizations, saveLdapSynchronization } from '@/Ldap/helpers';
|
||||
import { createLdapConfig } from '../../shared/ldap';
|
||||
import { LdapService } from '@/Ldap/ldap.service';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { Telemetry } from '@/telemetry';
|
||||
import { createTeamProject, findProject, getPersonalProject } from '../../shared/db/projects';
|
||||
|
||||
mockInstance(Telemetry);
|
||||
|
||||
const oclifConfig = new Config({ root: __dirname });
|
||||
|
||||
async function resetLDAP(argv: string[]) {
|
||||
const cmd = new Reset(argv, oclifConfig);
|
||||
try {
|
||||
await cmd.init();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
await cmd.run();
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
mockInstance(Push);
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
await testDb.init();
|
||||
await oclifConfig.load();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
});
|
||||
mockInstance(Push);
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
const command = setupTestCommand(Reset);
|
||||
|
||||
test('fails if neither `--userId` nor `--projectId` nor `--deleteWorkflowsAndCredentials` is passed', async () => {
|
||||
await expect(resetLDAP([])).rejects.toThrowError(
|
||||
await expect(command.run()).rejects.toThrowError(
|
||||
'You must use exactly one of `--userId`, `--projectId` or `--deleteWorkflowsAndCredentials`.',
|
||||
);
|
||||
});
|
||||
|
@ -66,7 +46,7 @@ test.each([
|
|||
])(
|
||||
'fails if more than one of `--userId`, `--projectId`, `--deleteWorkflowsAndCredentials` are passed',
|
||||
async (...argv) => {
|
||||
await expect(resetLDAP(argv)).rejects.toThrowError(
|
||||
await expect(command.run(argv)).rejects.toThrowError(
|
||||
'You must use exactly one of `--userId`, `--projectId` or `--deleteWorkflowsAndCredentials`.',
|
||||
);
|
||||
},
|
||||
|
@ -95,7 +75,7 @@ describe('--deleteWorkflowsAndCredentials', () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await resetLDAP(['--deleteWorkflowsAndCredentials']);
|
||||
await command.run(['--deleteWorkflowsAndCredentials']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -139,7 +119,7 @@ describe('--deleteWorkflowsAndCredentials', () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await resetLDAP(['--deleteWorkflowsAndCredentials']);
|
||||
await command.run(['--deleteWorkflowsAndCredentials']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -159,7 +139,7 @@ describe('--deleteWorkflowsAndCredentials', () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await resetLDAP(['--deleteWorkflowsAndCredentials']);
|
||||
await command.run(['--deleteWorkflowsAndCredentials']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -173,7 +153,7 @@ describe('--deleteWorkflowsAndCredentials', () => {
|
|||
describe('--userId', () => {
|
||||
test('fails if the user does not exist', async () => {
|
||||
const userId = uuid();
|
||||
await expect(resetLDAP([`--userId=${userId}`])).rejects.toThrowError(
|
||||
await expect(command.run([`--userId=${userId}`])).rejects.toThrowError(
|
||||
`Could not find the user with the ID ${userId} or their personalProject.`,
|
||||
);
|
||||
});
|
||||
|
@ -184,7 +164,7 @@ describe('--userId', () => {
|
|||
//
|
||||
const member = await createLdapUser({ role: 'global:member' }, uuid());
|
||||
|
||||
await expect(resetLDAP([`--userId=${member.id}`])).rejects.toThrowError(
|
||||
await expect(command.run([`--userId=${member.id}`])).rejects.toThrowError(
|
||||
`Can't migrate workflows and credentials to the user with the ID ${member.id}. That user was created via LDAP and will be deleted as well.`,
|
||||
);
|
||||
});
|
||||
|
@ -212,7 +192,7 @@ describe('--userId', () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await resetLDAP([`--userId=${normalMember.id}`]);
|
||||
await command.run([`--userId=${normalMember.id}`]);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -249,7 +229,7 @@ describe('--userId', () => {
|
|||
describe('--projectId', () => {
|
||||
test('fails if the project does not exist', async () => {
|
||||
const projectId = uuid();
|
||||
await expect(resetLDAP([`--projectId=${projectId}`])).rejects.toThrowError(
|
||||
await expect(command.run([`--projectId=${projectId}`])).rejects.toThrowError(
|
||||
`Could not find the project with the ID ${projectId}.`,
|
||||
);
|
||||
});
|
||||
|
@ -261,7 +241,7 @@ describe('--projectId', () => {
|
|||
const member = await createLdapUser({ role: 'global:member' }, uuid());
|
||||
const memberProject = await getPersonalProject(member);
|
||||
|
||||
await expect(resetLDAP([`--projectId=${memberProject.id}`])).rejects.toThrowError(
|
||||
await expect(command.run([`--projectId=${memberProject.id}`])).rejects.toThrowError(
|
||||
`Can't migrate workflows and credentials to the project with the ID ${memberProject.id}. That project is a personal project belonging to a user that was created via LDAP and will be deleted as well.`,
|
||||
);
|
||||
});
|
||||
|
@ -289,7 +269,7 @@ describe('--projectId', () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await resetLDAP([`--projectId=${normalMemberProject.id}`]);
|
||||
await command.run([`--projectId=${normalMemberProject.id}`]);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -346,7 +326,7 @@ describe('--projectId', () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await resetLDAP([`--projectId=${teamProject.id}`]);
|
||||
await command.run([`--projectId=${teamProject.id}`]);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
|
|
@ -2,27 +2,18 @@ import { InternalHooks } from '@/InternalHooks';
|
|||
import { License } from '@/License';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { ClearLicenseCommand } from '@/commands/license/clear';
|
||||
import { Config } from '@oclif/core';
|
||||
|
||||
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
||||
import { mockInstance } from '../../shared/mocking';
|
||||
|
||||
const oclifConfig = new Config({ root: __dirname });
|
||||
|
||||
beforeAll(async () => {
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
await oclifConfig.load();
|
||||
});
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
const license = mockInstance(License);
|
||||
const command = setupTestCommand(ClearLicenseCommand);
|
||||
|
||||
test('license:clear invokes shutdown() to release any floating entitlements', async () => {
|
||||
const cmd = new ClearLicenseCommand([], oclifConfig);
|
||||
await cmd.init();
|
||||
|
||||
const license = mockInstance(License);
|
||||
|
||||
await cmd.run();
|
||||
await command.run();
|
||||
|
||||
expect(license.init).toHaveBeenCalledTimes(1);
|
||||
expect(license.shutdown).toHaveBeenCalledTimes(1);
|
||||
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
|
|
@ -1,38 +1,34 @@
|
|||
import { Container } from 'typedi';
|
||||
|
||||
import { Reset } from '@/commands/user-management/reset';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { NodeTypes } from '@/NodeTypes';
|
||||
import Container from 'typedi';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
||||
import { mockInstance } from '../../shared/mocking';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { createMember, createUser } from '../shared/db/users';
|
||||
import { createWorkflow } from '../shared/db/workflows';
|
||||
import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflow.repository';
|
||||
import { getPersonalProject } from '../shared/db/projects';
|
||||
import { encryptCredentialData, saveCredential } from '../shared/db/credentials';
|
||||
import { randomCredentialPayload } from '../shared/random';
|
||||
import { SharedCredentialsRepository } from '@/databases/repositories/sharedCredentials.repository';
|
||||
import { CredentialsRepository } from '@/databases/repositories/credentials.repository';
|
||||
import { CredentialsEntity } from '@/databases/entities/CredentialsEntity';
|
||||
import { SettingsRepository } from '@/databases/repositories/settings.repository';
|
||||
|
||||
beforeAll(async () => {
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
mockInstance(NodeTypes);
|
||||
await testDb.init();
|
||||
});
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
mockInstance(NodeTypes);
|
||||
const command = setupTestCommand(Reset);
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
// eslint-disable-next-line n8n-local-rules/no-skipped-tests
|
||||
test('user-management:reset should reset DB to default user state', async () => {
|
||||
//
|
||||
|
@ -65,7 +61,7 @@ test('user-management:reset should reset DB to default user state', async () =>
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
await Reset.run();
|
||||
await command.run();
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import { Config } from '@oclif/core';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { UpdateWorkflowCommand } from '@/commands/update/workflow';
|
||||
|
||||
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
||||
import * as testDb from '../../shared/testDb';
|
||||
import { createWorkflowWithTrigger, getAllWorkflows } from '../../shared/db/workflows';
|
||||
import { mockInstance } from '../../../shared/mocking';
|
||||
|
||||
const oclifConfig = new Config({ root: __dirname });
|
||||
|
||||
beforeAll(async () => {
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
await testDb.init();
|
||||
await oclifConfig.load();
|
||||
});
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
const command = setupTestCommand(UpdateWorkflowCommand);
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Workflow']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('update:workflow can activate all workflows', async () => {
|
||||
//
|
||||
// ARRANGE
|
||||
|
@ -37,9 +28,7 @@ test('update:workflow can activate all workflows', async () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
const updater = new UpdateWorkflowCommand(['--all', '--active=true'], oclifConfig);
|
||||
await updater.init();
|
||||
await updater.run();
|
||||
await command.run(['--all', '--active=true']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -61,9 +50,7 @@ test('update:workflow can deactivate all workflows', async () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
const updater = new UpdateWorkflowCommand(['--all', '--active=false'], oclifConfig);
|
||||
await updater.init();
|
||||
await updater.run();
|
||||
await command.run(['--all', '--active=false']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -87,12 +74,7 @@ test('update:workflow can activate a specific workflow', async () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
const updater = new UpdateWorkflowCommand(
|
||||
[`--id=${workflows[0].id}`, '--active=true'],
|
||||
oclifConfig,
|
||||
);
|
||||
await updater.init();
|
||||
await updater.run();
|
||||
await command.run([`--id=${workflows[0].id}`, '--active=true']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
@ -116,12 +98,7 @@ test('update:workflow can deactivate a specific workflow', async () => {
|
|||
//
|
||||
// ACT
|
||||
//
|
||||
const updater = new UpdateWorkflowCommand(
|
||||
[`--id=${workflows[0].id}`, '--active=false'],
|
||||
oclifConfig,
|
||||
);
|
||||
await updater.init();
|
||||
await updater.run();
|
||||
await command.run([`--id=${workflows[0].id}`, '--active=false']);
|
||||
|
||||
//
|
||||
// ASSERT
|
||||
|
|
|
@ -1,85 +1,51 @@
|
|||
import { Config } from '@oclif/core';
|
||||
import { BinaryDataService } from 'n8n-core';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
|
||||
import { Worker } from '@/commands/worker';
|
||||
import config from '@/config';
|
||||
import { Telemetry } from '@/telemetry';
|
||||
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
|
||||
import { BinaryDataService } from 'n8n-core';
|
||||
import { CacheService } from '@/services/cache/cache.service';
|
||||
import { RedisServicePubSubPublisher } from '@/services/redis/RedisServicePubSubPublisher';
|
||||
import { RedisServicePubSubSubscriber } from '@/services/redis/RedisServicePubSubSubscriber';
|
||||
import { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { CredentialTypes } from '@/CredentialTypes';
|
||||
import { NodeTypes } from '@/NodeTypes';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { PostHogClient } from '@/posthog';
|
||||
import { RedisService } from '@/services/redis.service';
|
||||
import { OrchestrationHandlerWorkerService } from '@/services/orchestration/worker/orchestration.handler.worker.service';
|
||||
import { OrchestrationService } from '@/services/orchestration.service';
|
||||
import { OrchestrationWorkerService } from '@/services/orchestration/worker/orchestration.worker.service';
|
||||
import { License } from '@/License';
|
||||
import { ExternalHooks } from '@/ExternalHooks';
|
||||
import { type JobQueue, Queue } from '@/Queue';
|
||||
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { setupTestCommand } from '@test-integration/utils/testCommand';
|
||||
import { mockInstance } from '../../shared/mocking';
|
||||
|
||||
const oclifConfig = new Config({ root: __dirname });
|
||||
config.set('executions.mode', 'queue');
|
||||
config.set('binaryDataManager.availableModes', 'filesystem');
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
const binaryDataService = mockInstance(BinaryDataService);
|
||||
const externalHooks = mockInstance(ExternalHooks);
|
||||
const externalSecretsManager = mockInstance(ExternalSecretsManager);
|
||||
const license = mockInstance(License);
|
||||
const messageEventBus = mockInstance(MessageEventBus);
|
||||
const orchestrationHandlerWorkerService = mockInstance(OrchestrationHandlerWorkerService);
|
||||
const queue = mockInstance(Queue);
|
||||
const orchestrationWorkerService = mockInstance(OrchestrationWorkerService);
|
||||
const command = setupTestCommand(Worker);
|
||||
|
||||
let eventBus: MessageEventBus;
|
||||
|
||||
beforeAll(async () => {
|
||||
config.set('executions.mode', 'queue');
|
||||
config.set('binaryDataManager.availableModes', 'filesystem');
|
||||
mockInstance(Telemetry);
|
||||
mockInstance(PostHogClient);
|
||||
mockInstance(InternalHooks);
|
||||
mockInstance(CacheService);
|
||||
mockInstance(ExternalSecretsManager);
|
||||
mockInstance(BinaryDataService);
|
||||
eventBus = mockInstance(MessageEventBus);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
mockInstance(CredentialTypes);
|
||||
mockInstance(NodeTypes);
|
||||
mockInstance(RedisService);
|
||||
mockInstance(RedisServicePubSubPublisher);
|
||||
mockInstance(RedisServicePubSubSubscriber);
|
||||
mockInstance(OrchestrationService);
|
||||
await testDb.init();
|
||||
await oclifConfig.load();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
});
|
||||
queue.getBullObjectInstance.mockReturnValue(mock<JobQueue>({ on: jest.fn() }));
|
||||
|
||||
test('worker initializes all its components', async () => {
|
||||
const worker = new Worker([], oclifConfig);
|
||||
|
||||
jest.spyOn(worker, 'init');
|
||||
jest.spyOn(worker, 'initLicense').mockImplementation(async () => {});
|
||||
jest.spyOn(worker, 'initBinaryDataService').mockImplementation(async () => {});
|
||||
jest.spyOn(worker, 'initExternalHooks').mockImplementation(async () => {});
|
||||
jest.spyOn(worker, 'initExternalSecrets').mockImplementation(async () => {});
|
||||
jest.spyOn(worker, 'initEventBus').mockImplementation(async () => {});
|
||||
jest.spyOn(worker, 'initOrchestration');
|
||||
// jest.spyOn(MessageEventBus.prototype, 'send').mockImplementation(async () => {});
|
||||
jest
|
||||
.spyOn(OrchestrationHandlerWorkerService.prototype, 'initSubscriber')
|
||||
.mockImplementation(async () => {});
|
||||
jest.spyOn(RedisServicePubSubPublisher.prototype, 'init').mockImplementation(async () => {});
|
||||
jest.spyOn(worker, 'initQueue').mockImplementation(async () => {});
|
||||
|
||||
await worker.init();
|
||||
const worker = await command.run();
|
||||
|
||||
expect(worker.queueModeId).toBeDefined();
|
||||
expect(worker.queueModeId).toContain('worker');
|
||||
expect(worker.queueModeId.length).toBeGreaterThan(15);
|
||||
expect(worker.initLicense).toHaveBeenCalledTimes(1);
|
||||
expect(worker.initBinaryDataService).toHaveBeenCalledTimes(1);
|
||||
expect(worker.initExternalHooks).toHaveBeenCalledTimes(1);
|
||||
expect(worker.initExternalSecrets).toHaveBeenCalledTimes(1);
|
||||
expect(worker.initEventBus).toHaveBeenCalledTimes(1);
|
||||
expect(worker.initOrchestration).toHaveBeenCalledTimes(1);
|
||||
expect(OrchestrationHandlerWorkerService.prototype.initSubscriber).toHaveBeenCalledTimes(1);
|
||||
expect(eventBus.send).toHaveBeenCalledTimes(1);
|
||||
expect(worker.initQueue).toHaveBeenCalledTimes(1);
|
||||
|
||||
jest.restoreAllMocks();
|
||||
expect(license.init).toHaveBeenCalledTimes(1);
|
||||
expect(binaryDataService.init).toHaveBeenCalledTimes(1);
|
||||
expect(externalHooks.init).toHaveBeenCalledTimes(1);
|
||||
expect(externalSecretsManager.init).toHaveBeenCalledTimes(1);
|
||||
expect(messageEventBus.initialize).toHaveBeenCalledTimes(1);
|
||||
expect(queue.init).toHaveBeenCalledTimes(1);
|
||||
expect(queue.process).toHaveBeenCalledTimes(1);
|
||||
expect(orchestrationWorkerService.init).toHaveBeenCalledTimes(1);
|
||||
expect(orchestrationHandlerWorkerService.initWithOptions).toHaveBeenCalledTimes(1);
|
||||
expect(messageEventBus.send).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
|
37
packages/cli/test/integration/shared/utils/testCommand.ts
Normal file
37
packages/cli/test/integration/shared/utils/testCommand.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import type { Config } from '@oclif/core';
|
||||
import type { Class } from 'n8n-core';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
|
||||
import type { BaseCommand } from '@/commands/BaseCommand';
|
||||
import * as testDb from '../testDb';
|
||||
|
||||
export const setupTestCommand = <T extends BaseCommand>(Command: Class<T>) => {
|
||||
const config = mock<Config>();
|
||||
config.runHook.mockResolvedValue({ successes: [], failures: [] });
|
||||
|
||||
// mock SIGINT/SIGTERM registration
|
||||
process.once = jest.fn();
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate();
|
||||
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
const run = async (argv: string[] = []) => {
|
||||
const command = new Command(argv, config);
|
||||
await command.init();
|
||||
await command.run();
|
||||
return command;
|
||||
};
|
||||
|
||||
return { run };
|
||||
};
|
Loading…
Reference in a new issue