ci(core): Reduce memory usage in tests (part-2) (no-changelog) (#7671)

This also gets rid of `Db.collection`, which was another source of
circular dependencies.
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-11-10 15:04:26 +01:00
committed by GitHub
parent 37dd658dc5
commit 000e76e3b4
174 changed files with 892 additions and 808 deletions

View File

@@ -14,14 +14,15 @@ import { WebhookService } from '@/services/webhook.service';
import * as WebhookHelpers from '@/WebhookHelpers';
import * as AdditionalData from '@/WorkflowExecuteAdditionalData';
import { WorkflowRunner } from '@/WorkflowRunner';
import { mockInstance, setSchedulerAsLoadedNode } from './shared/utils';
import * as testDb from './shared/testDb';
import type { User } from '@/databases/entities/User';
import type { WebhookEntity } from '@/databases/entities/WebhookEntity';
import type { User } from '@db/entities/User';
import type { WebhookEntity } from '@db/entities/WebhookEntity';
import { NodeTypes } from '@/NodeTypes';
import { chooseRandomly } from './shared/random';
import { MultiMainInstancePublisher } from '@/services/orchestration/main/MultiMainInstance.publisher.ee';
import { mockInstance } from '../shared/mocking';
import { chooseRandomly } from './shared/random';
import { setSchedulerAsLoadedNode } from './shared/utils';
import * as testDb from './shared/testDb';
import { createOwner } from './shared/db/users';
import { createWorkflow } from './shared/db/workflows';

View File

@@ -1,36 +1,38 @@
import type { SuperAgentTest } from 'supertest';
import { License } from '@/License';
import * as utils from '../shared/utils/';
import type { ExternalSecretsSettings, SecretsProviderState } from '@/Interfaces';
import { Cipher } from 'n8n-core';
import { SettingsRepository } from '@/databases/repositories/settings.repository';
import { SettingsRepository } from '@db/repositories/settings.repository';
import { Container } from 'typedi';
import { ExternalSecretsProviders } from '@/ExternalSecrets/ExternalSecretsProviders.ee';
import config from '@/config';
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
import { CREDENTIAL_BLANKING_VALUE } from '@/constants';
import { jsonParse, type IDataObject } from 'n8n-workflow';
import { mock } from 'jest-mock-extended';
import { mockInstance } from '../../shared/mocking';
import { setupTestServer } from '../shared/utils';
import { createOwner, createUser } from '../shared/db/users';
import {
DummyProvider,
FailedProvider,
MockProviders,
TestFailProvider,
} from '../../shared/ExternalSecrets/utils';
import config from '@/config';
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
import { CREDENTIAL_BLANKING_VALUE } from '@/constants';
import { jsonParse, type IDataObject } from 'n8n-workflow';
import { mock } from 'jest-mock-extended';
import { createOwner, createUser } from '../shared/db/users';
let authOwnerAgent: SuperAgentTest;
let authMemberAgent: SuperAgentTest;
const licenseLike = utils.mockInstance(License, {
const licenseLike = mockInstance(License, {
isExternalSecretsEnabled: jest.fn().mockReturnValue(true),
isWithinUsersLimit: jest.fn().mockReturnValue(true),
});
const mockProvidersInstance = new MockProviders();
utils.mockInstance(ExternalSecretsProviders, mockProvidersInstance);
mockInstance(ExternalSecretsProviders, mockProvidersInstance);
const testServer = utils.setupTestServer({ endpointGroups: ['externalSecrets'] });
const testServer = setupTestServer({ endpointGroups: ['externalSecrets'] });
const connectedDate = '2023-08-01T12:32:29.000Z';

View File

@@ -1,11 +1,15 @@
import { v4 as uuid } from 'uuid';
import * as Db from '@/Db';
import config from '@/config';
import { audit } from '@/audit';
import { CREDENTIALS_REPORT } from '@/audit/constants';
import { getRiskSection } from './utils';
import * as testDb from '../shared/testDb';
import { generateNanoId } from '@db/utils/generators';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { ExecutionRepository } from '@db/repositories/execution.repository';
import { ExecutionDataRepository } from '@db/repositories/executionData.repository';
beforeAll(async () => {
await testDb.init();
@@ -46,8 +50,8 @@ test('should report credentials not in any use', async () => {
};
await Promise.all([
Db.collections.Credentials.save(credentialDetails),
Db.collections.Workflow.save(workflowDetails),
Container.get(CredentialsRepository).save(credentialDetails),
Container.get(WorkflowRepository).save(workflowDetails),
]);
const testAudit = await audit(['credentials']);
@@ -74,7 +78,7 @@ test('should report credentials not in active use', async () => {
nodesAccess: [{ nodeType: 'n8n-nodes-base.slack', date: '2022-12-21T11:23:00.561Z' }],
};
const credential = await Db.collections.Credentials.save(credentialDetails);
const credential = await Container.get(CredentialsRepository).save(credentialDetails);
const workflowDetails = {
id: generateNanoId(),
@@ -93,7 +97,7 @@ test('should report credentials not in active use', async () => {
],
};
await Db.collections.Workflow.save(workflowDetails);
await Container.get(WorkflowRepository).save(workflowDetails);
const testAudit = await audit(['credentials']);
@@ -119,7 +123,7 @@ test('should report credential in not recently executed workflow', async () => {
nodesAccess: [{ nodeType: 'n8n-nodes-base.slack', date: '2022-12-21T11:23:00.561Z' }],
};
const credential = await Db.collections.Credentials.save(credentialDetails);
const credential = await Container.get(CredentialsRepository).save(credentialDetails);
const workflowDetails = {
id: generateNanoId(),
@@ -144,12 +148,12 @@ test('should report credential in not recently executed workflow', async () => {
],
};
const workflow = await Db.collections.Workflow.save(workflowDetails);
const workflow = await Container.get(WorkflowRepository).save(workflowDetails);
const date = new Date();
date.setDate(date.getDate() - config.getEnv('security.audit.daysAbandonedWorkflow') - 1);
const savedExecution = await Db.collections.Execution.save({
const savedExecution = await Container.get(ExecutionRepository).save({
finished: true,
mode: 'manual',
startedAt: date,
@@ -157,7 +161,7 @@ test('should report credential in not recently executed workflow', async () => {
workflowId: workflow.id,
waitTill: null,
});
await Db.collections.ExecutionData.save({
await Container.get(ExecutionDataRepository).save({
execution: savedExecution,
data: '[]',
workflowData: workflow,
@@ -187,7 +191,7 @@ test('should not report credentials in recently executed workflow', async () =>
nodesAccess: [{ nodeType: 'n8n-nodes-base.slack', date: '2022-12-21T11:23:00.561Z' }],
};
const credential = await Db.collections.Credentials.save(credentialDetails);
const credential = await Container.get(CredentialsRepository).save(credentialDetails);
const workflowDetails = {
id: generateNanoId(),
@@ -212,12 +216,12 @@ test('should not report credentials in recently executed workflow', async () =>
],
};
const workflow = await Db.collections.Workflow.save(workflowDetails);
const workflow = await Container.get(WorkflowRepository).save(workflowDetails);
const date = new Date();
date.setDate(date.getDate() - config.getEnv('security.audit.daysAbandonedWorkflow') + 1);
const savedExecution = await Db.collections.Execution.save({
const savedExecution = await Container.get(ExecutionRepository).save({
finished: true,
mode: 'manual',
startedAt: date,
@@ -226,7 +230,7 @@ test('should not report credentials in recently executed workflow', async () =>
waitTill: null,
});
await Db.collections.ExecutionData.save({
await Container.get(ExecutionDataRepository).save({
execution: savedExecution,
data: '[]',
workflowData: workflow,

View File

@@ -1,5 +1,4 @@
import { v4 as uuid } from 'uuid';
import * as Db from '@/Db';
import { audit } from '@/audit';
import {
DATABASE_REPORT,
@@ -9,6 +8,8 @@ import {
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
import * as testDb from '../shared/testDb';
import { generateNanoId } from '@db/utils/generators';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi';
beforeAll(async () => {
await testDb.init();
@@ -50,7 +51,7 @@ test('should report expressions in queries', async () => {
],
};
return Db.collections.Workflow.save(details);
return Container.get(WorkflowRepository).save(details);
});
await Promise.all(promises);
@@ -105,7 +106,7 @@ test('should report expressions in query params', async () => {
],
};
return Db.collections.Workflow.save(details);
return Container.get(WorkflowRepository).save(details);
});
await Promise.all(promises);
@@ -157,7 +158,7 @@ test('should report unused query params', async () => {
],
};
return Db.collections.Workflow.save(details);
return Container.get(WorkflowRepository).save(details);
});
await Promise.all(promises);

View File

@@ -1,9 +1,10 @@
import { v4 as uuid } from 'uuid';
import * as Db from '@/Db';
import { audit } from '@/audit';
import { FILESYSTEM_INTERACTION_NODE_TYPES, FILESYSTEM_REPORT } from '@/audit/constants';
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
import * as testDb from '../shared/testDb';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi';
beforeAll(async () => {
await testDb.init();
@@ -26,7 +27,7 @@ test('should report filesystem interaction nodes', async () => {
);
const promises = Object.entries(map).map(async ([nodeType, nodeId]) => {
const details = Db.collections.Workflow.create({
const details = Container.get(WorkflowRepository).create({
name: 'My Test Workflow',
active: false,
connections: {},
@@ -42,7 +43,7 @@ test('should report filesystem interaction nodes', async () => {
],
});
return Db.collections.Workflow.save(details);
return Container.get(WorkflowRepository).save(details);
});
await Promise.all(promises);

View File

@@ -1,5 +1,4 @@
import { v4 as uuid } from 'uuid';
import * as Db from '@/Db';
import { audit } from '@/audit';
import { INSTANCE_REPORT, WEBHOOK_VALIDATOR_NODE_TYPES } from '@/audit/constants';
import {
@@ -13,6 +12,8 @@ import * as testDb from '../shared/testDb';
import { toReportTitle } from '@/audit/utils';
import config from '@/config';
import { generateNanoId } from '@db/utils/generators';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi';
beforeAll(async () => {
await testDb.init();
@@ -53,7 +54,7 @@ test('should report webhook lacking authentication', async () => {
],
};
await Db.collections.Workflow.save(details);
await Container.get(WorkflowRepository).save(details);
const testAudit = await audit(['instance']);
@@ -97,7 +98,7 @@ test('should not report webhooks having basic or header auth', async () => {
],
};
return Db.collections.Workflow.save(details);
return Container.get(WorkflowRepository).save(details);
});
await Promise.all(promises);
@@ -158,7 +159,7 @@ test('should not report webhooks validated by direct children', async () => {
},
};
return Db.collections.Workflow.save(details);
return Container.get(WorkflowRepository).save(details);
});
await Promise.all(promises);

View File

@@ -1,15 +1,16 @@
import { v4 as uuid } from 'uuid';
import { Container } from 'typedi';
import * as Db from '@/Db';
import { audit } from '@/audit';
import { OFFICIAL_RISKY_NODE_TYPES, NODES_REPORT } from '@/audit/constants';
import { getRiskSection, MOCK_PACKAGE, saveManualTriggerWorkflow } from './utils';
import * as testDb from '../shared/testDb';
import { toReportTitle } from '@/audit/utils';
import { mockInstance } from '../shared/utils/';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { NodeTypes } from '@/NodeTypes';
import { CommunityPackagesService } from '@/services/communityPackages.service';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { mockInstance } from '../../shared/mocking';
import { getRiskSection, MOCK_PACKAGE, saveManualTriggerWorkflow } from './utils';
import * as testDb from '../shared/testDb';
const nodesAndCredentials = mockInstance(LoadNodesAndCredentials);
nodesAndCredentials.getCustomDirectories.mockReturnValue([]);
@@ -37,7 +38,7 @@ test('should report risky official nodes', async () => {
}, {});
const promises = Object.entries(map).map(async ([nodeType, nodeId]) => {
const details = Db.collections.Workflow.create({
const details = Container.get(WorkflowRepository).create({
name: 'My Test Workflow',
active: false,
connections: {},
@@ -53,7 +54,7 @@ test('should report risky official nodes', async () => {
],
});
return Db.collections.Workflow.save(details);
return Container.get(WorkflowRepository).save(details);
});
await Promise.all(promises);

View File

@@ -1,12 +1,13 @@
import nock from 'nock';
import config from '@/config';
import { v4 as uuid } from 'uuid';
import * as Db from '@/Db';
import { toReportTitle } from '@/audit/utils';
import * as constants from '@/constants';
import type { Risk } from '@/audit/types';
import type { InstalledNodes } from '@db/entities/InstalledNodes';
import type { InstalledPackages } from '@db/entities/InstalledPackages';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi';
type GetSectionKind<C extends Risk.Category> = C extends 'instance'
? Risk.InstanceSection
@@ -52,7 +53,7 @@ export async function saveManualTriggerWorkflow() {
],
};
return Db.collections.Workflow.save(details);
return Container.get(WorkflowRepository).save(details);
}
export const MOCK_09990_N8N_VERSION = {

View File

@@ -3,7 +3,6 @@ import { Container } from 'typedi';
import { License } from '@/License';
import validator from 'validator';
import config from '@/config';
import * as Db from '@/Db';
import { AUTH_COOKIE_NAME } from '@/constants';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
@@ -13,6 +12,7 @@ import * as testDb from './shared/testDb';
import * as utils from './shared/utils/';
import { getGlobalMemberRole, getGlobalOwnerRole } from './shared/db/roles';
import { createUser, createUserShell } from './shared/db/users';
import { UserRepository } from '@db/repositories/user.repository';
let globalOwnerRole: Role;
let globalMemberRole: Role;
@@ -292,7 +292,7 @@ describe('GET /resolve-signup-token', () => {
.query({ inviteeId });
// cause inconsistent DB state
await Db.collections.User.update(owner.id, { email: '' });
await Container.get(UserRepository).update(owner.id, { email: '' });
const fifth = await authOwnerAgent
.get('/resolve-signup-token')
.query({ inviterId: owner.id })

View File

@@ -1,8 +1,10 @@
import fsp from 'node:fs/promises';
import { Readable } from 'node:stream';
import { BinaryDataService, FileNotFoundError } from 'n8n-core';
import { mockInstance, setupTestServer } from './shared/utils';
import type { SuperAgentTest } from 'supertest';
import { mockInstance } from '../shared/mocking';
import { setupTestServer } from './shared/utils';
import { createOwner } from './shared/db/users';
jest.mock('fs/promises');

View File

@@ -3,8 +3,9 @@ import * as Config from '@oclif/config';
import { InternalHooks } from '@/InternalHooks';
import { ImportCredentialsCommand } from '@/commands/import/credentials';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { mockInstance } from '../../shared/mocking';
import * as testDb from '../shared/testDb';
import { mockInstance } from '../shared/utils';
import { getAllCredentials } from '../shared/db/credentials';
beforeAll(async () => {

View File

@@ -3,8 +3,9 @@ import * as Config from '@oclif/config';
import { InternalHooks } from '@/InternalHooks';
import { ImportWorkflowsCommand } from '@/commands/import/workflow';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { mockInstance } from '../../shared/mocking';
import * as testDb from '../shared/testDb';
import { mockInstance } from '../shared/utils/';
import { getAllWorkflows } from '../shared/db/workflows';
beforeAll(async () => {

View File

@@ -1,11 +1,13 @@
import * as Db from '@/Db';
import { Reset } from '@/commands/user-management/reset';
import type { Role } from '@db/entities/Role';
import * as testDb from '../shared/testDb';
import { mockInstance } from '../shared/utils/';
import { InternalHooks } from '@/InternalHooks';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { NodeTypes } from '@/NodeTypes';
import Container from 'typedi';
import { UserRepository } from '@db/repositories/user.repository';
import { mockInstance } from '../../shared/mocking';
import * as testDb from '../shared/testDb';
import { getGlobalOwnerRole } from '../shared/db/roles';
import { createUser } from '../shared/db/users';
@@ -34,7 +36,7 @@ test.skip('user-management:reset should reset DB to default user state', async (
await Reset.run();
const user = await Db.collections.User.findOneBy({ globalRoleId: globalOwnerRole.id });
const user = await Container.get(UserRepository).findOneBy({ globalRoleId: globalOwnerRole.id });
if (!user) {
fail('No owner found after DB reset to default user state');

View File

@@ -1,12 +1,10 @@
import * as Config from '@oclif/config';
import { mockInstance } from '../shared/utils';
import { DataSource } from 'typeorm';
import { Start } from '@/commands/start';
import { BaseCommand } from '@/commands/BaseCommand';
import config from '@/config';
import { License } from '@/License';
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
import { MultiMainInstancePublisher } from '@/services/orchestration/main/MultiMainInstance.publisher.ee';
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
@@ -16,9 +14,12 @@ import { RedisServicePubSubPublisher } from '@/services/redis/RedisServicePubSub
import { RedisServicePubSubSubscriber } from '@/services/redis/RedisServicePubSubSubscriber';
import { OrchestrationHandlerMainService } from '@/services/orchestration/main/orchestration.handler.main.service';
import { mockInstance } from '../../shared/mocking';
const oclifConfig: Config.IConfig = new Config.Config({ root: __dirname });
beforeAll(() => {
mockInstance(DataSource);
mockInstance(ExternalSecretsManager);
mockInstance(ActiveWorkflowRunner);
mockInstance(WorkflowHistoryManager);

View File

@@ -1,4 +1,3 @@
import { mockInstance } from '../shared/utils/';
import { Worker } from '@/commands/worker';
import * as Config from '@oclif/config';
import config from '@/config';
@@ -18,6 +17,8 @@ import { RedisService } from '@/services/redis.service';
import { OrchestrationHandlerWorkerService } from '@/services/orchestration/worker/orchestration.handler.worker.service';
import { OrchestrationWorkerService } from '@/services/orchestration/worker/orchestration.worker.service';
import { mockInstance } from '../../shared/mocking';
const oclifConfig: Config.IConfig = new Config.Config({ root: __dirname });
beforeAll(async () => {

View File

@@ -7,14 +7,9 @@ import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { Push } from '@/push';
import { CommunityPackagesService } from '@/services/communityPackages.service';
import { mockInstance } from '../shared/mocking';
import { COMMUNITY_PACKAGE_VERSION } from './shared/constants';
import {
mockInstance,
setupTestServer,
mockPackage,
mockNode,
mockPackageName,
} from './shared/utils';
import { setupTestServer, mockPackage, mockNode, mockPackageName } from './shared/utils';
import { createOwner } from './shared/db/users';
const communityPackagesService = mockInstance(CommunityPackagesService, {

View File

@@ -2,7 +2,6 @@ import type { SuperAgentTest } from 'supertest';
import { In } from 'typeorm';
import type { IUser } from 'n8n-workflow';
import * as Db from '@/Db';
import type { Credentials } from '@/requests';
import * as UserManagementHelpers from '@/UserManagement/UserManagementHelper';
import type { Role } from '@db/entities/Role';
@@ -15,6 +14,8 @@ import * as utils from './shared/utils/';
import { affixRoleToSaveCredential, shareCredentialWithUsers } from './shared/db/credentials';
import { getCredentialOwnerRole, getGlobalMemberRole, getGlobalOwnerRole } from './shared/db/roles';
import { createManyUsers, createUser, createUserShell } from './shared/db/users';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import Container from 'typedi';
const sharingSpy = jest.spyOn(UserManagementHelpers, 'isSharingEnabled').mockReturnValue(true);
const testServer = utils.setupTestServer({ endpointGroups: ['credentials'] });
@@ -340,7 +341,7 @@ describe('PUT /credentials/:id/share', () => {
expect(response.statusCode).toBe(200);
expect(response.body.data).toBeUndefined();
const sharedCredentials = await Db.collections.SharedCredentials.find({
const sharedCredentials = await Container.get(SharedCredentialsRepository).find({
relations: ['role'],
where: { credentialsId: savedCredential.id },
});
@@ -375,7 +376,7 @@ describe('PUT /credentials/:id/share', () => {
expect(response.body.data).toBeUndefined();
// check that sharings got correctly set in DB
const sharedCredentials = await Db.collections.SharedCredentials.find({
const sharedCredentials = await Container.get(SharedCredentialsRepository).find({
relations: ['role'],
where: { credentialsId: savedCredential.id, userId: In([...memberIds]) },
});
@@ -388,7 +389,7 @@ describe('PUT /credentials/:id/share', () => {
});
// check that owner still exists
const ownerSharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
const ownerSharedCredential = await Container.get(SharedCredentialsRepository).findOneOrFail({
relations: ['role'],
where: { credentialsId: savedCredential.id, userId: owner.id },
});
@@ -425,7 +426,7 @@ describe('PUT /credentials/:id/share', () => {
expect(response.statusCode).toBe(200);
const sharedCredentials = await Db.collections.SharedCredentials.find({
const sharedCredentials = await Container.get(SharedCredentialsRepository).find({
where: { credentialsId: savedCredential.id },
});
@@ -442,7 +443,7 @@ describe('PUT /credentials/:id/share', () => {
expect(response.statusCode).toBe(200);
const sharedCredentials = await Db.collections.SharedCredentials.find({
const sharedCredentials = await Container.get(SharedCredentialsRepository).find({
where: { credentialsId: savedCredential.id },
});
@@ -475,7 +476,7 @@ describe('PUT /credentials/:id/share', () => {
expect(response.statusCode).toBe(200);
const sharedCredentials = await Db.collections.SharedCredentials.find({
const sharedCredentials = await Container.get(SharedCredentialsRepository).find({
where: { credentialsId: savedCredential.id },
});

View File

@@ -1,6 +1,5 @@
import type { SuperAgentTest } from 'supertest';
import * as Db from '@/Db';
import config from '@/config';
import * as UserManagementHelpers from '@/UserManagement/UserManagementHelper';
import type { Credentials } from '@/requests';
@@ -14,6 +13,9 @@ import * as utils from './shared/utils/';
import { affixRoleToSaveCredential } from './shared/db/credentials';
import { getCredentialOwnerRole, getGlobalMemberRole, getGlobalOwnerRole } from './shared/db/roles';
import { createManyUsers, createUser } from './shared/db/users';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import Container from 'typedi';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
// mock that credentialsSharing is not enabled
jest.spyOn(UserManagementHelpers, 'isSharingEnabled').mockReturnValue(false);
@@ -109,14 +111,14 @@ describe('POST /credentials', () => {
expect(nodesAccess[0].nodeType).toBe(payload.nodesAccess[0].nodeType);
expect(encryptedData).not.toBe(payload.data);
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
const credential = await Container.get(CredentialsRepository).findOneByOrFail({ id });
expect(credential.name).toBe(payload.name);
expect(credential.type).toBe(payload.type);
expect(credential.nodesAccess[0].nodeType).toBe(payload.nodesAccess[0].nodeType);
expect(credential.data).not.toBe(payload.data);
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
const sharedCredential = await Container.get(SharedCredentialsRepository).findOneOrFail({
relations: ['user', 'credentials'],
where: { credentialsId: credential.id },
});
@@ -156,13 +158,13 @@ describe('DELETE /credentials/:id', () => {
expect(response.statusCode).toBe(200);
expect(response.body).toEqual({ data: true });
const deletedCredential = await Db.collections.Credentials.findOneBy({
const deletedCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(deletedCredential).toBeNull(); // deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOneBy({});
expect(deletedSharedCredential).toBeNull(); // deleted
});
@@ -175,13 +177,13 @@ describe('DELETE /credentials/:id', () => {
expect(response.statusCode).toBe(200);
expect(response.body).toEqual({ data: true });
const deletedCredential = await Db.collections.Credentials.findOneBy({
const deletedCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(deletedCredential).toBeNull(); // deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOneBy({});
expect(deletedSharedCredential).toBeNull(); // deleted
});
@@ -194,13 +196,13 @@ describe('DELETE /credentials/:id', () => {
expect(response.statusCode).toBe(200);
expect(response.body).toEqual({ data: true });
const deletedCredential = await Db.collections.Credentials.findOneBy({
const deletedCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(deletedCredential).toBeNull(); // deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOneBy({});
expect(deletedSharedCredential).toBeNull(); // deleted
});
@@ -212,11 +214,13 @@ describe('DELETE /credentials/:id', () => {
expect(response.statusCode).toBe(404);
const shellCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
const shellCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(shellCredential).toBeDefined(); // not deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOneBy({});
expect(deletedSharedCredential).toBeDefined(); // not deleted
});
@@ -250,14 +254,14 @@ describe('PATCH /credentials/:id', () => {
expect(encryptedData).not.toBe(patchPayload.data);
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
const credential = await Container.get(CredentialsRepository).findOneByOrFail({ id });
expect(credential.name).toBe(patchPayload.name);
expect(credential.type).toBe(patchPayload.type);
expect(credential.nodesAccess[0].nodeType).toBe(patchPayload.nodesAccess[0].nodeType);
expect(credential.data).not.toBe(patchPayload.data);
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
const sharedCredential = await Container.get(SharedCredentialsRepository).findOneOrFail({
relations: ['credentials'],
where: { credentialsId: credential.id },
});
@@ -287,14 +291,14 @@ describe('PATCH /credentials/:id', () => {
expect(encryptedData).not.toBe(patchPayload.data);
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
const credential = await Container.get(CredentialsRepository).findOneByOrFail({ id });
expect(credential.name).toBe(patchPayload.name);
expect(credential.type).toBe(patchPayload.type);
expect(credential.nodesAccess[0].nodeType).toBe(patchPayload.nodesAccess[0].nodeType);
expect(credential.data).not.toBe(patchPayload.data);
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
const sharedCredential = await Container.get(SharedCredentialsRepository).findOneOrFail({
relations: ['credentials'],
where: { credentialsId: credential.id },
});
@@ -324,14 +328,14 @@ describe('PATCH /credentials/:id', () => {
expect(encryptedData).not.toBe(patchPayload.data);
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
const credential = await Container.get(CredentialsRepository).findOneByOrFail({ id });
expect(credential.name).toBe(patchPayload.name);
expect(credential.type).toBe(patchPayload.type);
expect(credential.nodesAccess[0].nodeType).toBe(patchPayload.nodesAccess[0].nodeType);
expect(credential.data).not.toBe(patchPayload.data);
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
const sharedCredential = await Container.get(SharedCredentialsRepository).findOneOrFail({
relations: ['credentials'],
where: { credentialsId: credential.id },
});
@@ -349,7 +353,7 @@ describe('PATCH /credentials/:id', () => {
expect(response.statusCode).toBe(404);
const shellCredential = await Db.collections.Credentials.findOneByOrFail({
const shellCredential = await Container.get(CredentialsRepository).findOneByOrFail({
id: savedCredential.id,
});

View File

@@ -1,4 +1,4 @@
import type { User } from '@/databases/entities/User';
import type { User } from '@db/entities/User';
import { createSuccessfulExecution, getAllExecutions } from './shared/db/executions';
import { createOwner } from './shared/db/users';
import { createWorkflow } from './shared/db/workflows';

View File

@@ -4,7 +4,6 @@ import { Not } from 'typeorm';
import { jsonParse } from 'n8n-workflow';
import config from '@/config';
import * as Db from '@/Db';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
import { LDAP_DEFAULT_CONFIGURATION, LDAP_FEATURE_NAME } from '@/Ldap/constants';
@@ -21,6 +20,9 @@ import Container from 'typedi';
import { Cipher } from 'n8n-core';
import { getGlobalMemberRole, getGlobalOwnerRole } from '../shared/db/roles';
import { createLdapUser, createUser, getAllUsers, getLdapIdentities } from '../shared/db/users';
import { UserRepository } from '@db/repositories/user.repository';
import { SettingsRepository } from '@db/repositories/settings.repository';
import { AuthProviderSyncHistoryRepository } from '@db/repositories/authProviderSyncHistory.repository';
jest.mock('@/telemetry');
@@ -73,7 +75,7 @@ beforeEach(async () => {
'Workflow',
]);
await Db.collections.User.delete({ id: Not(owner.id) });
await Container.get(UserRepository).delete({ id: Not(owner.id) });
jest.mock('@/telemetry');
@@ -83,7 +85,7 @@ beforeEach(async () => {
});
const createLdapConfig = async (attributes: Partial<LdapConfig> = {}): Promise<LdapConfig> => {
const { value: ldapConfig } = await Db.collections.Settings.save({
const { value: ldapConfig } = await Container.get(SettingsRepository).save({
key: LDAP_FEATURE_NAME,
value: JSON.stringify({
...defaultLdapConfig,
@@ -174,7 +176,7 @@ describe('PUT /ldap/config', () => {
// disable the login, so the strategy is applied
await authOwnerAgent.put('/ldap/config').send({ ...configuration, loginEnabled: false });
const emailUser = await Db.collections.User.findOneByOrFail({ id: member.id });
const emailUser = await Container.get(UserRepository).findOneByOrFail({ id: member.id });
const localLdapIdentities = await getLdapIdentities();
expect(getCurrentAuthenticationMethod()).toBe('email');
@@ -237,7 +239,9 @@ describe('POST /ldap/sync', () => {
await authOwnerAgent.post('/ldap/sync').send({ type: 'dry' }).expect(200);
const synchronization = await Db.collections.AuthProviderSyncHistory.findOneByOrFail({});
const synchronization = await Container.get(
AuthProviderSyncHistoryRepository,
).findOneByOrFail({});
expect(synchronization.id).toBeDefined();
expect(synchronization.startedAt).toBeDefined();
@@ -268,7 +272,7 @@ describe('POST /ldap/sync', () => {
expect(synchronization.created).toBe(1);
// Make sure only the instance owner is on the DB
const localDbUsers = await Db.collections.User.find();
const localDbUsers = await Container.get(UserRepository).find();
expect(localDbUsers.length).toBe(1);
expect(localDbUsers[0].id).toBe(owner.id);
});
@@ -330,7 +334,9 @@ describe('POST /ldap/sync', () => {
await authOwnerAgent.post('/ldap/sync').send({ type: 'live' }).expect(200);
const synchronization = await Db.collections.AuthProviderSyncHistory.findOneByOrFail({});
const synchronization = await Container.get(
AuthProviderSyncHistoryRepository,
).findOneByOrFail({});
expect(synchronization.id).toBeDefined();
expect(synchronization.startedAt).toBeDefined();

View File

@@ -1,7 +1,6 @@
import type { SuperAgentTest } from 'supertest';
import { IsNull } from 'typeorm';
import validator from 'validator';
import * as Db from '@/Db';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
import { SUCCESS_RESPONSE_BODY } from './shared/constants';
@@ -16,6 +15,8 @@ import * as testDb from './shared/testDb';
import * as utils from './shared/utils/';
import { getGlobalMemberRole, getGlobalOwnerRole } from './shared/db/roles';
import { addApiKey, createUser, createUserShell } from './shared/db/users';
import Container from 'typedi';
import { UserRepository } from '@db/repositories/user.repository';
const testServer = utils.setupTestServer({ endpointGroups: ['me'] });
@@ -70,7 +71,7 @@ describe('Owner shell', () => {
expect(globalRole.scope).toBe('global');
expect(apiKey).toBeUndefined();
const storedOwnerShell = await Db.collections.User.findOneByOrFail({ id });
const storedOwnerShell = await Container.get(UserRepository).findOneByOrFail({ id });
expect(storedOwnerShell.email).toBe(validPayload.email.toLowerCase());
expect(storedOwnerShell.firstName).toBe(validPayload.firstName);
@@ -83,7 +84,7 @@ describe('Owner shell', () => {
const response = await authOwnerShellAgent.patch('/me').send(invalidPayload);
expect(response.statusCode).toBe(400);
const storedOwnerShell = await Db.collections.User.findOneByOrFail({});
const storedOwnerShell = await Container.get(UserRepository).findOneByOrFail({});
expect(storedOwnerShell.email).toBeNull();
expect(storedOwnerShell.firstName).toBeNull();
expect(storedOwnerShell.lastName).toBeNull();
@@ -102,7 +103,7 @@ describe('Owner shell', () => {
const response = await authOwnerShellAgent.patch('/me/password').send(payload);
expect([400, 500].includes(response.statusCode)).toBe(true);
const storedMember = await Db.collections.User.findOneByOrFail({});
const storedMember = await Container.get(UserRepository).findOneByOrFail({});
if (payload.newPassword) {
expect(storedMember.password).not.toBe(payload.newPassword);
@@ -113,7 +114,7 @@ describe('Owner shell', () => {
}
}
const storedOwnerShell = await Db.collections.User.findOneByOrFail({});
const storedOwnerShell = await Container.get(UserRepository).findOneByOrFail({});
expect(storedOwnerShell.password).toBeNull();
});
@@ -126,7 +127,7 @@ describe('Owner shell', () => {
expect(response.statusCode).toBe(200);
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);
const storedShellOwner = await Db.collections.User.findOneOrFail({
const storedShellOwner = await Container.get(UserRepository).findOneOrFail({
where: { email: IsNull() },
});
@@ -141,7 +142,7 @@ describe('Owner shell', () => {
expect(response.body.data.apiKey).toBeDefined();
expect(response.body.data.apiKey).not.toBeNull();
const storedShellOwner = await Db.collections.User.findOneOrFail({
const storedShellOwner = await Container.get(UserRepository).findOneOrFail({
where: { email: IsNull() },
});
@@ -160,7 +161,7 @@ describe('Owner shell', () => {
expect(response.statusCode).toBe(200);
const storedShellOwner = await Db.collections.User.findOneOrFail({
const storedShellOwner = await Container.get(UserRepository).findOneOrFail({
where: { email: IsNull() },
});
@@ -213,7 +214,7 @@ describe('Member', () => {
expect(globalRole.scope).toBe('global');
expect(apiKey).toBeUndefined();
const storedMember = await Db.collections.User.findOneByOrFail({ id });
const storedMember = await Container.get(UserRepository).findOneByOrFail({ id });
expect(storedMember.email).toBe(validPayload.email.toLowerCase());
expect(storedMember.firstName).toBe(validPayload.firstName);
@@ -226,7 +227,7 @@ describe('Member', () => {
const response = await authMemberAgent.patch('/me').send(invalidPayload);
expect(response.statusCode).toBe(400);
const storedMember = await Db.collections.User.findOneByOrFail({});
const storedMember = await Container.get(UserRepository).findOneByOrFail({});
expect(storedMember.email).toBe(member.email);
expect(storedMember.firstName).toBe(member.firstName);
expect(storedMember.lastName).toBe(member.lastName);
@@ -243,7 +244,7 @@ describe('Member', () => {
expect(response.statusCode).toBe(200);
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);
const storedMember = await Db.collections.User.findOneByOrFail({});
const storedMember = await Container.get(UserRepository).findOneByOrFail({});
expect(storedMember.password).not.toBe(member.password);
expect(storedMember.password).not.toBe(validPayload.newPassword);
});
@@ -253,7 +254,7 @@ describe('Member', () => {
const response = await authMemberAgent.patch('/me/password').send(payload);
expect([400, 500].includes(response.statusCode)).toBe(true);
const storedMember = await Db.collections.User.findOneByOrFail({});
const storedMember = await Container.get(UserRepository).findOneByOrFail({});
if (payload.newPassword) {
expect(storedMember.password).not.toBe(payload.newPassword);
@@ -272,9 +273,9 @@ describe('Member', () => {
expect(response.statusCode).toBe(200);
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);
const { personalizationAnswers: storedAnswers } = await Db.collections.User.findOneByOrFail(
{},
);
const { personalizationAnswers: storedAnswers } = await Container.get(
UserRepository,
).findOneByOrFail({});
expect(storedAnswers).toEqual(validPayload);
}
@@ -287,7 +288,7 @@ describe('Member', () => {
expect(response.body.data.apiKey).toBeDefined();
expect(response.body.data.apiKey).not.toBeNull();
const storedMember = await Db.collections.User.findOneByOrFail({ id: member.id });
const storedMember = await Container.get(UserRepository).findOneByOrFail({ id: member.id });
expect(storedMember.apiKey).toEqual(response.body.data.apiKey);
});
@@ -304,7 +305,7 @@ describe('Member', () => {
expect(response.statusCode).toBe(200);
const storedMember = await Db.collections.User.findOneByOrFail({ id: member.id });
const storedMember = await Container.get(UserRepository).findOneByOrFail({ id: member.id });
expect(storedMember.apiKey).toBeNull();
});
@@ -347,7 +348,7 @@ describe('Owner', () => {
expect(globalRole.scope).toBe('global');
expect(apiKey).toBeUndefined();
const storedOwner = await Db.collections.User.findOneByOrFail({ id });
const storedOwner = await Container.get(UserRepository).findOneByOrFail({ id });
expect(storedOwner.email).toBe(validPayload.email.toLowerCase());
expect(storedOwner.firstName).toBe(validPayload.firstName);

View File

@@ -1,6 +1,5 @@
import Container from 'typedi';
import config from '@/config';
import * as Db from '@/Db';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
import { randomPassword } from '@/Ldap/helpers';
@@ -10,6 +9,7 @@ import { randomDigit, randomString, randomValidPassword, uniqueId } from '../sha
import * as testDb from '../shared/testDb';
import * as utils from '../shared/utils';
import { createUser, createUserWithMfaEnabled } from '../shared/db/users';
import { UserRepository } from '@db/repositories/user.repository';
jest.mock('@/telemetry');
@@ -161,7 +161,7 @@ describe('Enable MFA setup', () => {
expect(statusCode).toBe(200);
const user = await Db.collections.User.findOneOrFail({
const user = await Container.get(UserRepository).findOneOrFail({
where: {},
select: ['mfaEnabled', 'mfaRecoveryCodes', 'mfaSecret'],
});
@@ -181,7 +181,7 @@ describe('Disable MFA setup', () => {
expect(response.statusCode).toBe(200);
const dbUser = await Db.collections.User.findOneOrFail({
const dbUser = await Container.get(UserRepository).findOneOrFail({
where: { id: user.id },
select: ['mfaEnabled', 'mfaRecoveryCodes', 'mfaSecret'],
});
@@ -375,7 +375,7 @@ describe('Login', () => {
expect(data.mfaEnabled).toBe(true);
expect(data.hasRecoveryCodesLeft).toBe(true);
const dbUser = await Db.collections.User.findOneOrFail({
const dbUser = await Container.get(UserRepository).findOneOrFail({
where: { id: user.id },
select: ['mfaEnabled', 'mfaRecoveryCodes', 'mfaSecret'],
});

View File

@@ -2,7 +2,6 @@ import validator from 'validator';
import type { SuperAgentTest } from 'supertest';
import config from '@/config';
import * as Db from '@/Db';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
import {
@@ -15,6 +14,8 @@ import * as testDb from './shared/testDb';
import * as utils from './shared/utils/';
import { getGlobalOwnerRole } from './shared/db/roles';
import { createUserShell } from './shared/db/users';
import { UserRepository } from '@db/repositories/user.repository';
import Container from 'typedi';
const testServer = utils.setupTestServer({ endpointGroups: ['owner'] });
@@ -72,7 +73,7 @@ describe('POST /owner/setup', () => {
expect(globalRole.scope).toBe('global');
expect(apiKey).toBeUndefined();
const storedOwner = await Db.collections.User.findOneByOrFail({ id });
const storedOwner = await Container.get(UserRepository).findOneByOrFail({ id });
expect(storedOwner.password).not.toBe(newOwnerData.password);
expect(storedOwner.email).toBe(newOwnerData.email);
expect(storedOwner.firstName).toBe(newOwnerData.firstName);
@@ -102,7 +103,7 @@ describe('POST /owner/setup', () => {
expect(id).toBe(ownerShell.id);
expect(email).toBe(newOwnerData.email.toLowerCase());
const storedOwner = await Db.collections.User.findOneByOrFail({ id });
const storedOwner = await Container.get(UserRepository).findOneByOrFail({ id });
expect(storedOwner.email).toBe(newOwnerData.email.toLowerCase());
});

View File

@@ -4,7 +4,6 @@ import { Container } from 'typedi';
import { mock } from 'jest-mock-extended';
import { License } from '@/License';
import * as Db from '@/Db';
import config from '@/config';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
@@ -13,8 +12,10 @@ import { ExternalHooks } from '@/ExternalHooks';
import { JwtService } from '@/services/jwt.service';
import { UserService } from '@/services/user.service';
import { UserManagementMailer } from '@/UserManagement/email';
import { UserRepository } from '@db/repositories/user.repository';
import * as utils from './shared/utils/';
import { mockInstance } from '../shared/mocking';
import { getAuthToken, setupTestServer } from './shared/utils/';
import {
randomEmail,
randomInvalidPassword,
@@ -33,9 +34,9 @@ let globalMemberRole: Role;
let owner: User;
let member: User;
const externalHooks = utils.mockInstance(ExternalHooks);
const mailer = utils.mockInstance(UserManagementMailer, { isEmailSetUp: true });
const testServer = utils.setupTestServer({ endpointGroups: ['passwordReset'] });
const externalHooks = mockInstance(ExternalHooks);
const mailer = mockInstance(UserManagementMailer, { isEmailSetUp: true });
const testServer = setupTestServer({ endpointGroups: ['passwordReset'] });
const jwtService = Container.get(JwtService);
let userService: UserService;
@@ -199,10 +200,10 @@ describe('POST /change-password', () => {
expect(response.statusCode).toBe(200);
const authToken = utils.getAuthToken(response);
const authToken = getAuthToken(response);
expect(authToken).toBeDefined();
const { password: storedPassword } = await Db.collections.User.findOneByOrFail({
const { password: storedPassword } = await Container.get(UserRepository).findOneByOrFail({
id: owner.id,
});
@@ -243,7 +244,7 @@ describe('POST /change-password', () => {
.post('/change-password')
.query(invalidPayload);
expect(response.statusCode).toBe(400);
const { password: storedPassword } = await Db.collections.User.findOneByOrFail({
const { password: storedPassword } = await Container.get(UserRepository).findOneByOrFail({
id: owner.id,
});
expect(owner.password).toBe(storedPassword);
@@ -276,10 +277,10 @@ describe('POST /change-password', () => {
expect(response.statusCode).toBe(200);
const authToken = utils.getAuthToken(response);
const authToken = getAuthToken(response);
expect(authToken).toBeDefined();
const { password: storedPassword } = await Db.collections.User.findOneByOrFail({
const { password: storedPassword } = await Container.get(UserRepository).findOneByOrFail({
id: owner.id,
});

View File

@@ -1,15 +1,17 @@
import config from '@/config';
import * as Db from '@/Db';
import { BinaryDataService } from 'n8n-core';
import type { ExecutionStatus } from 'n8n-workflow';
import Container from 'typedi';
import * as testDb from './shared/testDb';
import type { ExecutionEntity } from '@db/entities/ExecutionEntity';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { ExecutionRepository } from '@db/repositories/execution.repository';
import { TIME } from '@/constants';
import { PruningService } from '@/services/pruning.service';
import { Logger } from '@/Logger';
import { mockInstance } from './shared/utils';
import { mockInstance } from '../shared/mocking';
import { createWorkflow } from './shared/db/workflows';
import { createExecution, createSuccessfulExecution } from './shared/db/executions';
@@ -25,7 +27,7 @@ describe('softDeleteOnPruningCycle()', () => {
pruningService = new PruningService(
mockInstance(Logger),
Db.collections.Execution,
Container.get(ExecutionRepository),
mockInstance(BinaryDataService),
);
@@ -45,7 +47,7 @@ describe('softDeleteOnPruningCycle()', () => {
});
async function findAllExecutions() {
return Db.collections.Execution.find({
return Container.get(ExecutionRepository).find({
order: { id: 'asc' },
withDeleted: true,
});

View File

@@ -1,5 +1,4 @@
import type { SuperAgentTest } from 'supertest';
import * as Db from '@/Db';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
@@ -10,6 +9,9 @@ import * as testDb from '../shared/testDb';
import { affixRoleToSaveCredential } from '../shared/db/credentials';
import { getAllRoles } from '../shared/db/roles';
import { addApiKey, createUser, createUserShell } from '../shared/db/users';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import Container from 'typedi';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
let globalMemberRole: Role;
let credentialOwnerRole: Role;
@@ -64,13 +66,13 @@ describe('POST /credentials', () => {
expect(name).toBe(payload.name);
expect(type).toBe(payload.type);
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
const credential = await Container.get(CredentialsRepository).findOneByOrFail({ id });
expect(credential.name).toBe(payload.name);
expect(credential.type).toBe(payload.type);
expect(credential.data).not.toBe(payload.data);
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
const sharedCredential = await Container.get(SharedCredentialsRepository).findOneOrFail({
relations: ['user', 'credentials', 'role'],
where: { credentialsId: credential.id, userId: owner.id },
});
@@ -100,13 +102,13 @@ describe('DELETE /credentials/:id', () => {
expect(name).toBe(savedCredential.name);
expect(type).toBe(savedCredential.type);
const deletedCredential = await Db.collections.Credentials.findOneBy({
const deletedCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(deletedCredential).toBeNull(); // deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOneBy({});
expect(deletedSharedCredential).toBeNull(); // deleted
});
@@ -118,13 +120,13 @@ describe('DELETE /credentials/:id', () => {
expect(response.statusCode).toBe(200);
const deletedCredential = await Db.collections.Credentials.findOneBy({
const deletedCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(deletedCredential).toBeNull(); // deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOneBy({});
expect(deletedSharedCredential).toBeNull(); // deleted
});
@@ -141,13 +143,13 @@ describe('DELETE /credentials/:id', () => {
expect(name).toBe(savedCredential.name);
expect(type).toBe(savedCredential.type);
const deletedCredential = await Db.collections.Credentials.findOneBy({
const deletedCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(deletedCredential).toBeNull(); // deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOneBy({});
expect(deletedSharedCredential).toBeNull(); // deleted
});
@@ -173,13 +175,13 @@ describe('DELETE /credentials/:id', () => {
expect(name).toBe(savedCredential.name);
expect(type).toBe(savedCredential.type);
const deletedCredential = await Db.collections.Credentials.findOneBy({
const deletedCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(deletedCredential).toBeNull(); // deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOne({
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOne({
where: {
credentialsId: savedCredential.id,
},
@@ -189,13 +191,13 @@ describe('DELETE /credentials/:id', () => {
await Promise.all(
[notToBeChangedCredential, notToBeChangedCredential2].map(async (credential) => {
const untouchedCredential = await Db.collections.Credentials.findOneBy({
const untouchedCredential = await Container.get(CredentialsRepository).findOneBy({
id: credential.id,
});
expect(untouchedCredential).toEqual(credential); // not deleted
const untouchedSharedCredential = await Db.collections.SharedCredentials.findOne({
const untouchedSharedCredential = await Container.get(SharedCredentialsRepository).findOne({
where: {
credentialsId: credential.id,
},
@@ -213,13 +215,13 @@ describe('DELETE /credentials/:id', () => {
expect(response.statusCode).toBe(404);
const shellCredential = await Db.collections.Credentials.findOneBy({
const shellCredential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(shellCredential).toBeDefined(); // not deleted
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
const deletedSharedCredential = await Container.get(SharedCredentialsRepository).findOneBy({});
expect(deletedSharedCredential).toBeDefined(); // not deleted
});

View File

@@ -5,13 +5,14 @@ import { v4 as uuid } from 'uuid';
import type { Role } from '@db/entities/Role';
import { License } from '@/License';
import { mockInstance } from '../../shared/mocking';
import { randomApiKey } from '../shared/random';
import * as utils from '../shared/utils/';
import * as testDb from '../shared/testDb';
import { getGlobalMemberRole, getGlobalOwnerRole } from '../shared/db/roles';
import { createUser, createUserShell } from '../shared/db/users';
utils.mockInstance(License, {
mockInstance(License, {
getUsersLimit: jest.fn().mockReturnValue(-1),
});
@@ -216,7 +217,7 @@ describe('With license without quota:users', () => {
let authOwnerAgent: SuperAgentTest;
beforeEach(async () => {
utils.mockInstance(License, { getUsersLimit: jest.fn().mockReturnValue(null) });
mockInstance(License, { getUsersLimit: jest.fn().mockReturnValue(null) });
const owner = await createUser({
globalRole: globalOwnerRole,

View File

@@ -1,18 +1,19 @@
import type { SuperAgentTest } from 'supertest';
import * as Db from '@/Db';
import type { Role } from '@db/entities/Role';
import type { TagEntity } from '@db/entities/TagEntity';
import type { User } from '@db/entities/User';
import type { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
import { randomApiKey } from '../shared/random';
import * as utils from '../shared/utils/';
import * as testDb from '../shared/testDb';
import Container from 'typedi';
import type { INode } from 'n8n-workflow';
import { STARTING_NODES } from '@/constants';
import { License } from '@/License';
import { WorkflowHistoryRepository } from '@/databases/repositories';
import Container from 'typedi';
import type { Role } from '@db/entities/Role';
import type { TagEntity } from '@db/entities/TagEntity';
import type { User } from '@db/entities/User';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repository';
import type { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
import { mockInstance } from '../../shared/mocking';
import { randomApiKey } from '../shared/random';
import * as utils from '../shared/utils/';
import * as testDb from '../shared/testDb';
import { getAllRoles } from '../shared/db/roles';
import { createUser } from '../shared/db/users';
import { createWorkflow, createWorkflowWithTrigger } from '../shared/db/workflows';
@@ -27,7 +28,7 @@ let workflowRunner: ActiveWorkflowRunner;
const testServer = utils.setupTestServer({ endpointGroups: ['publicApi'] });
const licenseLike = utils.mockInstance(License, {
const licenseLike = mockInstance(License, {
isWorkflowHistoryLicensed: jest.fn().mockReturnValue(false),
isWithinUsersLimit: jest.fn().mockReturnValue(true),
});
@@ -58,7 +59,7 @@ beforeEach(async () => {
'Tag',
'Workflow',
'Credentials',
WorkflowHistoryRepository,
'WorkflowHistory',
]);
authOwnerAgent = testServer.publicApiAgentFor(owner);
@@ -397,7 +398,7 @@ describe('DELETE /workflows/:id', () => {
expect(updatedAt).toEqual(workflow.updatedAt.toISOString());
// make sure the workflow actually deleted from the db
const sharedWorkflow = await Db.collections.SharedWorkflow.findOneBy({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOneBy({
workflowId: workflow.id,
});
@@ -426,7 +427,7 @@ describe('DELETE /workflows/:id', () => {
expect(updatedAt).toEqual(workflow.updatedAt.toISOString());
// make sure the workflow actually deleted from the db
const sharedWorkflow = await Db.collections.SharedWorkflow.findOneBy({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOneBy({
workflowId: workflow.id,
});
@@ -474,7 +475,7 @@ describe('POST /workflows/:id/activate', () => {
expect(updatedAt).toEqual(workflow.updatedAt.toISOString());
// check whether the workflow is on the database
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: member.id,
workflowId: workflow.id,
@@ -509,7 +510,7 @@ describe('POST /workflows/:id/activate', () => {
expect(updatedAt).toEqual(workflow.updatedAt.toISOString());
// check whether the workflow is on the database
const sharedOwnerWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedOwnerWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: owner.id,
workflowId: workflow.id,
@@ -518,7 +519,7 @@ describe('POST /workflows/:id/activate', () => {
expect(sharedOwnerWorkflow).toBeNull();
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: member.id,
workflowId: workflow.id,
@@ -572,7 +573,7 @@ describe('POST /workflows/:id/deactivate', () => {
expect(updatedAt).toBeDefined();
// get the workflow after it was deactivated
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: member.id,
workflowId: workflow.id,
@@ -609,7 +610,7 @@ describe('POST /workflows/:id/deactivate', () => {
expect(updatedAt).toBeDefined();
// check whether the workflow is deactivated in the database
const sharedOwnerWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedOwnerWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: owner.id,
workflowId: workflow.id,
@@ -618,7 +619,7 @@ describe('POST /workflows/:id/deactivate', () => {
expect(sharedOwnerWorkflow).toBeNull();
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: member.id,
workflowId: workflow.id,
@@ -685,7 +686,7 @@ describe('POST /workflows', () => {
expect(updatedAt).toEqual(createdAt);
// check if created workflow in DB
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: member.id,
workflowId: response.body.id,
@@ -924,7 +925,7 @@ describe('PUT /workflows/:id', () => {
expect(updatedAt).not.toBe(workflow.updatedAt.toISOString());
// check updated workflow in DB
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: member.id,
workflowId: response.body.id,
@@ -1093,7 +1094,7 @@ describe('PUT /workflows/:id', () => {
expect(updatedAt).not.toBe(workflow.updatedAt.toISOString());
// check updated workflow in DB
const sharedOwnerWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedOwnerWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: owner.id,
workflowId: response.body.id,
@@ -1102,7 +1103,7 @@ describe('PUT /workflows/:id', () => {
expect(sharedOwnerWorkflow).toBeNull();
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
where: {
userId: member.id,
workflowId: response.body.id,

View File

@@ -5,7 +5,8 @@ import type { ICredentialsDb } from '@/Interfaces';
import { RoleService } from '@/services/role.service';
import type { CredentialPayload } from '../types';
import Container from 'typedi';
import { CredentialsRepository, SharedCredentialsRepository } from '@/databases/repositories';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
async function encryptCredentialData(credential: CredentialsEntity) {
const { createCredentialsFromCredentialsEntity } = await import('@/CredentialsHelper');

View File

@@ -2,7 +2,8 @@ import Container from 'typedi';
import type { ExecutionData } from '@db/entities/ExecutionData';
import type { ExecutionEntity } from '@db/entities/ExecutionEntity';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { ExecutionDataRepository, ExecutionRepository } from '@db/repositories';
import { ExecutionRepository } from '@db/repositories/execution.repository';
import { ExecutionDataRepository } from '@db/repositories/executionData.repository';
export async function createManyExecutions(
amount: number,

View File

@@ -1,7 +1,8 @@
import Container from 'typedi';
import type { TagEntity } from '@db/entities/TagEntity';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { TagRepository, WorkflowTagMappingRepository } from '@db/repositories';
import { TagRepository } from '@db/repositories/tag.repository';
import { WorkflowTagMappingRepository } from '@db/repositories/workflowTagMapping.repository';
import { generateNanoId } from '@db/utils/generators';
import { randomName } from '../random';

View File

@@ -3,7 +3,8 @@ import { hash } from 'bcryptjs';
import { AuthIdentity } from '@db/entities/AuthIdentity';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
import { AuthIdentityRepository, UserRepository } from '@db/repositories';
import { AuthIdentityRepository } from '@db/repositories/authIdentity.repository';
import { UserRepository } from '@db/repositories/user.repository';
import { TOTPService } from '@/Mfa/totp.service';
import { MfaService } from '@/Mfa/mfa.service';

View File

@@ -1,7 +1,7 @@
import Container from 'typedi';
import { v4 as uuid } from 'uuid';
import type { WorkflowHistory } from '@db/entities/WorkflowHistory';
import { WorkflowHistoryRepository } from '@db/repositories';
import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repository';
export async function createWorkflowHistoryItem(
workflowId: string,

View File

@@ -2,7 +2,8 @@ import Container from 'typedi';
import { v4 as uuid } from 'uuid';
import type { User } from '@db/entities/User';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { SharedWorkflowRepository, WorkflowRepository } from '@db/repositories';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { getWorkflowEditorRole, getWorkflowOwnerRole } from './roles';
export async function createManyWorkflows(

View File

@@ -8,12 +8,10 @@ import { entities } from '@db/entities';
import { mysqlMigrations } from '@db/migrations/mysqldb';
import { postgresMigrations } from '@db/migrations/postgresdb';
import { sqliteMigrations } from '@db/migrations/sqlite';
import { TagRepository, WorkflowTagMappingRepository } from '@/databases/repositories';
import { DB_INITIALIZATION_TIMEOUT } from './constants';
import { randomString } from './random';
import type { CollectionName, PostgresSchemaSection } from './types';
import { separate } from '@/utils';
import type { PostgresSchemaSection } from './types';
export type TestDBType = 'postgres' | 'mysql';
@@ -88,23 +86,40 @@ export async function terminate() {
await Db.close();
}
// Can't use `Object.keys(entities)` here because some entities have a `Entity` suffix, while the repositories don't
const repositories = [
'AuthIdentity',
'AuthProviderSyncHistory',
'Credentials',
'EventDestinations',
'ExecutionData',
'ExecutionMetadata',
'Execution',
'InstalledNodes',
'InstalledPackages',
'Role',
'Settings',
'SharedCredentials',
'SharedWorkflow',
'Tag',
'User',
'Variables',
'Webhook',
'Workflow',
'WorkflowHistory',
'WorkflowStatistics',
'WorkflowTagMapping',
] as const;
/**
* Truncate specific DB tables in a test DB.
*/
export async function truncate(collections: CollectionName[]) {
const [tag, rest] = separate(collections, (c) => c === 'Tag');
if (tag.length) {
await Container.get(TagRepository).delete({});
await Container.get(WorkflowTagMappingRepository).delete({});
}
for (const collection of rest) {
if (typeof collection === 'string') {
await Db.collections[collection].delete({});
} else {
await Container.get(collection as { new (): Repository<any> }).delete({});
}
export async function truncate(names: Array<(typeof repositories)[number]>) {
for (const name of names) {
const RepositoryClass: { new (): Repository<any> } = (
await import(`@db/repositories/${name.charAt(0).toLowerCase() + name.slice(1)}.repository`)
)[`${name}Repository`];
await Container.get(RepositoryClass).delete({});
}
}

View File

@@ -5,12 +5,7 @@ import type { Server } from 'http';
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
import type { User } from '@db/entities/User';
import type { BooleanLicenseFeature, ICredentialsDb, IDatabaseCollections } from '@/Interfaces';
import type { DataSource, Repository } from 'typeorm';
export type CollectionName =
| keyof IDatabaseCollections
| { new (dataSource: DataSource): Repository<any> };
import type { BooleanLicenseFeature, ICredentialsDb } from '@/Interfaces';
type EndpointGroup =
| 'me'

View File

@@ -3,7 +3,8 @@ import { InstalledPackages } from '@db/entities/InstalledPackages';
import { randomName } from '../random';
import { COMMUNITY_NODE_VERSION, COMMUNITY_PACKAGE_VERSION } from '../constants';
import { InstalledNodesRepository, InstalledPackagesRepository } from '@/databases/repositories';
import { InstalledNodesRepository } from '@db/repositories/installedNodes.repository';
import { InstalledPackagesRepository } from '@db/repositories/installedPackages.repository';
import Container from 'typedi';
export const mockPackageName = () => NODE_PACKAGE_PREFIX + randomName();

View File

@@ -10,15 +10,14 @@ import type request from 'supertest';
import { v4 as uuid } from 'uuid';
import config from '@/config';
import * as Db from '@/Db';
import { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { AUTH_COOKIE_NAME } from '@/constants';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { mockInstance } from './mocking';
import { SettingsRepository } from '@db/repositories/settings.repository';
import { mockNodeTypesData } from '../../../unit/Helpers';
import { mockInstance } from '../../../shared/mocking';
export { mockInstance } from './mocking';
export { setupTestServer } from './testServer';
// ----------------------------------
@@ -108,7 +107,7 @@ export function getAuthToken(response: request.Response, authCookieName = AUTH_C
// ----------------------------------
export async function isInstanceOwnerSetUp() {
const { value } = await Db.collections.Settings.findOneByOrFail({
const { value } = await Container.get(SettingsRepository).findOneByOrFail({
key: 'userManagement.isInstanceOwnerSetUp',
});
@@ -118,7 +117,7 @@ export async function isInstanceOwnerSetUp() {
export const setInstanceOwnerSetUp = async (value: boolean) => {
config.set('userManagement.isInstanceOwnerSetUp', value);
await Db.collections.Settings.update(
await Container.get(SettingsRepository).update(
{ key: 'userManagement.isInstanceOwnerSetUp' },
{ value: JSON.stringify(value) },
);

View File

@@ -14,18 +14,12 @@ import { rawBodyReader, bodyParser, setupAuthMiddlewares } from '@/middlewares';
import { InternalHooks } from '@/InternalHooks';
import { PostHogClient } from '@/posthog';
import { License } from '@/License';
import {
SettingsRepository,
SharedCredentialsRepository,
SharedWorkflowRepository,
} from '@/databases/repositories';
import { Logger } from '@/Logger';
import { mockInstance } from '../../../shared/mocking';
import * as testDb from '../../shared/testDb';
import { AUTHLESS_ENDPOINTS, PUBLIC_API_REST_PATH_SEGMENT, REST_PATH_SEGMENT } from '../constants';
import type { SetupProps, TestServer } from '../types';
import { mockInstance } from './mocking';
/**
* Plugin to prefix a path segment into a request URL pathname.
@@ -217,6 +211,7 @@ export const setupTestServer = ({
case 'owner':
const { UserService } = await import('@/services/user.service');
const { SettingsRepository } = await import('@db/repositories/settings.repository');
const { OwnerController } = await import('@/controllers/owner.controller');
registerController(
app,
@@ -232,6 +227,12 @@ export const setupTestServer = ({
break;
case 'users':
const { SharedCredentialsRepository } = await import(
'@db/repositories/sharedCredentials.repository'
);
const { SharedWorkflowRepository } = await import(
'@db/repositories/sharedWorkflow.repository'
);
const { ActiveWorkflowRunner } = await import('@/ActiveWorkflowRunner');
const { ExternalHooks } = await import('@/ExternalHooks');
const { JwtService } = await import('@/services/jwt.service');

View File

@@ -1,7 +1,7 @@
import * as utils from './shared/utils/';
import * as testDb from './shared/testDb';
import type { SuperAgentTest } from 'supertest';
import { TagRepository } from '@/databases/repositories';
import { TagRepository } from '@db/repositories/tag.repository';
import Container from 'typedi';
import { getGlobalOwnerRole } from './shared/db/roles';
import { createUserShell } from './shared/db/users';

View File

@@ -2,7 +2,6 @@ import validator from 'validator';
import { Not } from 'typeorm';
import type { SuperAgentTest } from 'supertest';
import * as Db from '@/Db';
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
@@ -10,6 +9,14 @@ import { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { compareHash } from '@/UserManagement/UserManagementHelper';
import { UserManagementMailer } from '@/UserManagement/email/UserManagementMailer';
import Container from 'typedi';
import { UserRepository } from '@db/repositories/user.repository';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import { mockInstance } from '../shared/mocking';
import { SUCCESS_RESPONSE_BODY } from './shared/constants';
import {
randomCredentialPayload,
@@ -31,7 +38,7 @@ let credentialOwnerRole: Role;
let owner: User;
let authOwnerAgent: SuperAgentTest;
const mailer = utils.mockInstance(UserManagementMailer, { isEmailSetUp: true });
const mailer = mockInstance(UserManagementMailer, { isEmailSetUp: true });
const testServer = utils.setupTestServer({ endpointGroups: ['users'] });
@@ -54,7 +61,7 @@ beforeAll(async () => {
beforeEach(async () => {
await testDb.truncate(['SharedCredentials', 'SharedWorkflow', 'Workflow', 'Credentials']);
await Db.collections.User.delete({ id: Not(owner.id) });
await Container.get(UserRepository).delete({ id: Not(owner.id) });
mailer.invite.mockResolvedValue({ emailSent: true });
});
@@ -72,9 +79,9 @@ describe('DELETE /users/:id', () => {
nodes: [],
});
const savedWorkflow = await Db.collections.Workflow.save(newWorkflow);
const savedWorkflow = await Container.get(WorkflowRepository).save(newWorkflow);
await Db.collections.SharedWorkflow.save({
await Container.get(SharedWorkflowRepository).save({
role: workflowOwnerRole,
user: userToDelete,
workflow: savedWorkflow,
@@ -89,9 +96,9 @@ describe('DELETE /users/:id', () => {
nodesAccess: [],
});
const savedCredential = await Db.collections.Credentials.save(newCredential);
const savedCredential = await Container.get(CredentialsRepository).save(newCredential);
await Db.collections.SharedCredentials.save({
await Container.get(SharedCredentialsRepository).save({
role: credentialOwnerRole,
user: userToDelete,
credentials: savedCredential,
@@ -102,27 +109,29 @@ describe('DELETE /users/:id', () => {
expect(response.statusCode).toBe(200);
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);
const user = await Db.collections.User.findOneBy({ id: userToDelete.id });
const user = await Container.get(UserRepository).findOneBy({ id: userToDelete.id });
expect(user).toBeNull(); // deleted
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
relations: ['user'],
where: { userId: userToDelete.id, roleId: workflowOwnerRole.id },
});
expect(sharedWorkflow).toBeNull(); // deleted
const sharedCredential = await Db.collections.SharedCredentials.findOne({
const sharedCredential = await Container.get(SharedCredentialsRepository).findOne({
relations: ['user'],
where: { userId: userToDelete.id, roleId: credentialOwnerRole.id },
});
expect(sharedCredential).toBeNull(); // deleted
const workflow = await Db.collections.Workflow.findOneBy({ id: savedWorkflow.id });
const workflow = await Container.get(WorkflowRepository).findOneBy({ id: savedWorkflow.id });
expect(workflow).toBeNull(); // deleted
// TODO: Include active workflow and check whether webhook has been removed
const credential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
const credential = await Container.get(CredentialsRepository).findOneBy({
id: savedCredential.id,
});
expect(credential).toBeNull(); // deleted
});
@@ -131,7 +140,7 @@ describe('DELETE /users/:id', () => {
expect(response.statusCode).toBe(400);
const user = await Db.collections.User.findOneBy({ id: owner.id });
const user = await Container.get(UserRepository).findOneBy({ id: owner.id });
expect(user).toBeDefined();
});
@@ -144,7 +153,7 @@ describe('DELETE /users/:id', () => {
expect(response.statusCode).toBe(400);
const user = await Db.collections.User.findOneBy({ id: idToDelete });
const user = await Container.get(UserRepository).findOneBy({ id: idToDelete });
expect(user).toBeDefined();
});
@@ -164,7 +173,7 @@ describe('DELETE /users/:id', () => {
expect(response.statusCode).toBe(200);
const sharedWorkflow = await Db.collections.SharedWorkflow.findOneOrFail({
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOneOrFail({
relations: ['workflow'],
where: { userId: owner.id },
});
@@ -172,7 +181,7 @@ describe('DELETE /users/:id', () => {
expect(sharedWorkflow.workflow).toBeDefined();
expect(sharedWorkflow.workflow.id).toBe(savedWorkflow.id);
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
const sharedCredential = await Container.get(SharedCredentialsRepository).findOneOrFail({
relations: ['credentials'],
where: { userId: owner.id },
});
@@ -180,7 +189,7 @@ describe('DELETE /users/:id', () => {
expect(sharedCredential.credentials).toBeDefined();
expect(sharedCredential.credentials.id).toBe(savedCredential.id);
const deletedUser = await Db.collections.User.findOneBy({ id: userToDelete.id });
const deletedUser = await Container.get(UserRepository).findOneBy({ id: userToDelete.id });
expect(deletedUser).toBeNull();
});
@@ -226,7 +235,7 @@ describe('POST /users/:id', () => {
const authToken = utils.getAuthToken(response);
expect(authToken).toBeDefined();
const member = await Db.collections.User.findOneByOrFail({ id: memberShell.id });
const member = await Container.get(UserRepository).findOneByOrFail({ id: memberShell.id });
expect(member.firstName).toBe(memberData.firstName);
expect(member.lastName).toBe(memberData.lastName);
expect(member.password).not.toBe(memberData.password);
@@ -235,7 +244,7 @@ describe('POST /users/:id', () => {
test('should fail with invalid inputs', async () => {
const memberShellEmail = randomEmail();
const memberShell = await Db.collections.User.save({
const memberShell = await Container.get(UserRepository).save({
email: memberShellEmail,
globalRole: globalMemberRole,
});
@@ -275,7 +284,7 @@ describe('POST /users/:id', () => {
.send(invalidPayload);
expect(response.statusCode).toBe(400);
const storedUser = await Db.collections.User.findOneOrFail({
const storedUser = await Container.get(UserRepository).findOneOrFail({
where: { email: memberShellEmail },
});
@@ -299,7 +308,7 @@ describe('POST /users/:id', () => {
expect(response.statusCode).toBe(400);
const storedMember = await Db.collections.User.findOneOrFail({
const storedMember = await Container.get(UserRepository).findOneOrFail({
where: { email: member.email },
});
expect(storedMember.firstName).not.toBe(newMemberData.firstName);
@@ -353,7 +362,7 @@ describe('POST /users', () => {
expect(error).toBe('Email could not be sent');
}
const storedUser = await Db.collections.User.findOneByOrFail({ id });
const storedUser = await Container.get(UserRepository).findOneByOrFail({ id });
const { firstName, lastName, personalizationAnswers, password } = storedUser;
expect(firstName).toBeNull();
@@ -377,7 +386,7 @@ describe('POST /users', () => {
const response = await authOwnerAgent.post('/users').send(invalidPayload);
expect(response.statusCode).toBe(400);
const users = await Db.collections.User.find();
const users = await Container.get(UserRepository).find();
expect(users.length).toBe(1); // DB unaffected
}),
);
@@ -392,7 +401,7 @@ describe('POST /users', () => {
expect(Array.isArray(data)).toBe(true);
expect(data.length).toBe(0);
const users = await Db.collections.User.find();
const users = await Container.get(UserRepository).find();
expect(users.length).toBe(1);
});
});

View File

@@ -1,7 +1,7 @@
import { createMember, createOwner } from './shared/db/users';
import * as testDb from './shared/testDb';
import { setupTestServer } from './shared/utils/';
import type { User } from '@/databases/entities/User';
import type { User } from '@db/entities/User';
import type { PublicUser } from '@/Interfaces';
const { any } = expect;

View File

@@ -1,10 +1,12 @@
import Container from 'typedi';
import type { SuperAgentTest } from 'supertest';
import type { Variables } from '@db/entities/Variables';
import { VariablesRepository } from '@db/repositories';
import { VariablesRepository } from '@db/repositories/variables.repository';
import { generateNanoId } from '@db/utils/generators';
import { License } from '@/License';
import { VariablesService } from '@/environments/variables/variables.service';
import { mockInstance } from '../shared/mocking';
import * as testDb from './shared/testDb';
import * as utils from './shared/utils/';
import { createOwner, createUser } from './shared/db/users';
@@ -47,7 +49,7 @@ async function getVariableById(id: string) {
}
beforeAll(async () => {
utils.mockInstance(License, licenseLike);
mockInstance(License, licenseLike);
const owner = await createOwner();
authOwnerAgent = testServer.authAgentFor(owner);

View File

@@ -10,7 +10,8 @@ import { NodeTypes } from '@/NodeTypes';
import { Push } from '@/push';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { mockInstance, initActiveWorkflowRunner } from './shared/utils';
import { mockInstance } from '../shared/mocking';
import { initActiveWorkflowRunner } from './shared/utils';
import * as testDb from './shared/testDb';
import { createUser } from './shared/db/users';
import { createWorkflow } from './shared/db/workflows';

View File

@@ -1,9 +1,10 @@
import type { SuperAgentTest } from 'supertest';
import { License } from '@/License';
import type { User } from '@db/entities/User';
import { mockInstance } from '../shared/mocking';
import * as testDb from './shared/testDb';
import * as utils from './shared/utils/';
import type { User } from '@/databases/entities/User';
import { WorkflowHistoryRepository } from '@/databases/repositories';
import { createOwner, createUser } from './shared/db/users';
import { createWorkflow } from './shared/db/workflows';
import { createWorkflowHistoryItem } from './shared/db/workflowHistory';
@@ -13,7 +14,7 @@ let authOwnerAgent: SuperAgentTest;
let member: User;
let authMemberAgent: SuperAgentTest;
const licenseLike = utils.mockInstance(License, {
const licenseLike = mockInstance(License, {
isWorkflowHistoryLicensed: jest.fn().mockReturnValue(true),
isWithinUsersLimit: jest.fn().mockReturnValue(true),
});
@@ -32,7 +33,7 @@ beforeEach(() => {
});
afterEach(async () => {
await testDb.truncate(['Workflow', 'SharedWorkflow', WorkflowHistoryRepository]);
await testDb.truncate(['Workflow', 'SharedWorkflow', 'WorkflowHistory']);
});
describe('GET /workflow-history/:workflowId', () => {

View File

@@ -3,12 +3,12 @@ import { In } from 'typeorm';
import { DateTime } from 'luxon';
import config from '@/config';
import { WorkflowHistoryRepository } from '@/databases/repositories';
import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repository';
import { License } from '@/License';
import { WorkflowHistoryManager } from '@/workflows/workflowHistory/workflowHistoryManager.ee';
import { mockInstance } from '../shared/mocking';
import * as testDb from './shared/testDb';
import { mockInstance } from './shared/utils';
import { createWorkflow } from './shared/db/workflows';
import { createManyWorkflowHistoryItems } from './shared/db/workflowHistory';

View File

@@ -7,9 +7,10 @@ import * as UserManagementHelpers from '@/UserManagement/UserManagementHelper';
import type { User } from '@db/entities/User';
import { getSharedWorkflowIds } from '@/WorkflowHelpers';
import { License } from '@/License';
import { WorkflowHistoryRepository } from '@/databases/repositories';
import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repository';
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
import { mockInstance } from '../shared/mocking';
import * as utils from './shared/utils/';
import * as testDb from './shared/testDb';
import type { SaveCredentialFunction } from './shared/types';
@@ -28,11 +29,11 @@ let authMemberAgent: SuperAgentTest;
let authAnotherMemberAgent: SuperAgentTest;
let saveCredential: SaveCredentialFunction;
const licenseLike = utils.mockInstance(License, {
const licenseLike = mockInstance(License, {
isWorkflowHistoryLicensed: jest.fn().mockReturnValue(false),
isWithinUsersLimit: jest.fn().mockReturnValue(true),
});
const activeWorkflowRunnerLike = utils.mockInstance(ActiveWorkflowRunner);
const activeWorkflowRunnerLike = mockInstance(ActiveWorkflowRunner);
const sharingSpy = jest.spyOn(UserManagementHelpers, 'isSharingEnabled').mockReturnValue(true);
const testServer = utils.setupTestServer({
@@ -62,7 +63,7 @@ beforeEach(async () => {
activeWorkflowRunnerLike.add.mockReset();
activeWorkflowRunnerLike.remove.mockReset();
await testDb.truncate(['Workflow', 'SharedWorkflow', WorkflowHistoryRepository]);
await testDb.truncate(['Workflow', 'SharedWorkflow', 'WorkflowHistory']);
licenseLike.isWorkflowHistoryLicensed.mockReturnValue(false);
});

View File

@@ -1,15 +1,16 @@
import type { SuperAgentTest } from 'supertest';
import type { INode, IPinData } from 'n8n-workflow';
import * as UserManagementHelpers from '@/UserManagement/UserManagementHelper';
import type { User } from '@/databases/entities/User';
import type { User } from '@db/entities/User';
import { v4 as uuid } from 'uuid';
import { RoleService } from '@/services/role.service';
import Container from 'typedi';
import type { ListQuery } from '@/requests';
import { License } from '@/License';
import { WorkflowHistoryRepository } from '@/databases/repositories';
import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repository';
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
import { mockInstance } from '../shared/mocking';
import * as utils from './shared/utils/';
import * as testDb from './shared/testDb';
import { makeWorkflow, MOCK_PINDATA } from './shared/utils/';
@@ -27,12 +28,12 @@ const testServer = utils.setupTestServer({ endpointGroups: ['workflows'] });
const { objectContaining, arrayContaining, any } = expect;
const licenseLike = utils.mockInstance(License, {
const licenseLike = mockInstance(License, {
isWorkflowHistoryLicensed: jest.fn().mockReturnValue(false),
isWithinUsersLimit: jest.fn().mockReturnValue(true),
});
const activeWorkflowRunnerLike = utils.mockInstance(ActiveWorkflowRunner);
const activeWorkflowRunnerLike = mockInstance(ActiveWorkflowRunner);
beforeAll(async () => {
owner = await createOwner();
@@ -41,7 +42,7 @@ beforeAll(async () => {
beforeEach(async () => {
jest.resetAllMocks();
await testDb.truncate(['Workflow', 'SharedWorkflow', 'Tag', WorkflowHistoryRepository]);
await testDb.truncate(['Workflow', 'SharedWorkflow', 'Tag', 'WorkflowHistory']);
licenseLike.isWorkflowHistoryLicensed.mockReturnValue(false);
});

View File

@@ -5,7 +5,7 @@ import { Container } from 'typedi';
import type { IExecuteResponsePromiseData, IRun } from 'n8n-workflow';
import { createDeferredPromise } from 'n8n-workflow';
import type { IWorkflowExecutionDataProcess } from '@/Interfaces';
import { ExecutionRepository } from '@db/repositories';
import { ExecutionRepository } from '@db/repositories/execution.repository';
import { mock } from 'jest-mock-extended';
const FAKE_EXECUTION_ID = '15';

View File

@@ -1,7 +1,7 @@
import { CredentialTypes } from '@/CredentialTypes';
import { Container } from 'typedi';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { mockInstance } from '../integration/shared/utils';
import { mockInstance } from '../shared/mocking';
describe('CredentialTypes', () => {
const mockNodesAndCredentials = mockInstance(LoadNodesAndCredentials, {

View File

@@ -1,3 +1,4 @@
import Container from 'typedi';
import type {
IAuthenticateGeneric,
ICredentialDataDecryptedObject,
@@ -11,10 +12,13 @@ import { Workflow } from 'n8n-workflow';
import { CredentialsHelper } from '@/CredentialsHelper';
import { NodeTypes } from '@/NodeTypes';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { mockInstance } from '../integration/shared/utils';
import Container from 'typedi';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { mockInstance } from '../shared/mocking';
describe('CredentialsHelper', () => {
mockInstance(CredentialsRepository);
mockInstance(SharedCredentialsRepository);
const mockNodesAndCredentials = mockInstance(LoadNodesAndCredentials, {
loadedNodes: {
'test.set': {

View File

@@ -1,12 +1,12 @@
import { Container } from 'typedi';
import { Cipher } from 'n8n-core';
import { SettingsRepository } from '@/databases/repositories';
import { SettingsRepository } from '@db/repositories/settings.repository';
import type { ExternalSecretsSettings } from '@/Interfaces';
import { License } from '@/License';
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
import { ExternalSecretsProviders } from '@/ExternalSecrets/ExternalSecretsProviders.ee';
import { InternalHooks } from '@/InternalHooks';
import { mockInstance } from '../../integration/shared/utils';
import { mockInstance } from '../../shared/mocking';
import {
DummyProvider,
ErrorProvider,

View File

@@ -1,6 +1,6 @@
import { Telemetry } from '@/telemetry';
import { InternalHooks } from '@/InternalHooks';
import { mockInstance } from '../integration/shared/utils';
import { mockInstance } from '../shared/mocking';
import type { IDiagnosticInfo } from '@/Interfaces';
import { mock } from 'jest-mock-extended';

View File

@@ -1,10 +1,11 @@
import { LicenseManager } from '@n8n_io/license-sdk';
import { InstanceSettings } from 'n8n-core';
import { mock } from 'jest-mock-extended';
import config from '@/config';
import { License } from '@/License';
import { Logger } from '@/Logger';
import { N8N_VERSION } from '@/constants';
import { mockInstance } from '../integration/shared/utils';
import { mockInstance } from '../shared/mocking';
jest.mock('@n8n_io/license-sdk');
@@ -28,7 +29,7 @@ describe('License', () => {
const instanceSettings = mockInstance(InstanceSettings, { instanceId: MOCK_INSTANCE_ID });
beforeEach(async () => {
license = new License(logger, instanceSettings);
license = new License(logger, instanceSettings, mock(), mock());
await license.init();
});
@@ -51,7 +52,7 @@ describe('License', () => {
});
test('initializes license manager for worker', async () => {
license = new License(logger, instanceSettings);
license = new License(logger, instanceSettings, mock(), mock());
await license.init('worker');
expect(LicenseManager).toHaveBeenCalledWith({
autoRenewEnabled: false,

View File

@@ -4,7 +4,6 @@ import type { INodeTypes } from 'n8n-workflow';
import { SubworkflowOperationError, Workflow } from 'n8n-workflow';
import config from '@/config';
import * as Db from '@/Db';
import { Role } from '@db/entities/Role';
import { User } from '@db/entities/User';
import { SharedWorkflow } from '@db/entities/SharedWorkflow';
@@ -14,7 +13,7 @@ import { PermissionChecker } from '@/UserManagement/PermissionChecker';
import * as UserManagementHelper from '@/UserManagement/UserManagementHelper';
import { OwnershipService } from '@/services/ownership.service';
import { mockInstance } from '../integration/shared/utils/';
import { mockInstance } from '../shared/mocking';
import {
randomCredentialPayload as randomCred,
randomPositiveDigit,
@@ -25,6 +24,8 @@ import { mockNodeTypesData } from './Helpers';
import { affixRoleToSaveCredential } from '../integration/shared/db/credentials';
import { getCredentialOwnerRole, getWorkflowOwnerRole } from '../integration/shared/db/roles';
import { createOwner, createUser } from '../integration/shared/db/users';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
let mockNodeTypes: INodeTypes;
let credentialOwnerRole: Role;
@@ -199,9 +200,9 @@ describe('PermissionChecker.check()', () => {
],
};
const workflowEntity = await Db.collections.Workflow.save(workflowDetails);
const workflowEntity = await Container.get(WorkflowRepository).save(workflowDetails);
await Db.collections.SharedWorkflow.save({
await Container.get(SharedWorkflowRepository).save({
workflow: workflowEntity,
user: member,
role: workflowOwnerRole,

View File

@@ -2,7 +2,7 @@ import { PostHog } from 'posthog-node';
import { InstanceSettings } from 'n8n-core';
import { PostHogClient } from '@/posthog';
import config from '@/config';
import { mockInstance } from '../integration/shared/utils';
import { mockInstance } from '../shared/mocking';
jest.mock('posthog-node');

View File

@@ -18,6 +18,7 @@ import {
import { constants as fsConstants, accessSync } from 'fs';
import type { SourceControlledFile } from '@/environments/sourceControl/types/sourceControlledFile';
import type { SourceControlPreferences } from '@/environments/sourceControl/types/sourceControlPreferences';
import { mockInstance } from '../shared/mocking';
const pushResult: SourceControlledFile[] = [
{
@@ -149,8 +150,11 @@ const pullResult: SourceControlledFile[] = [
},
];
const license = mockInstance(License);
beforeAll(async () => {
Container.get(License).isSourceControlLicensed = () => true;
jest.resetAllMocks();
license.isSourceControlLicensed.mockReturnValue(true);
Container.get(SourceControlPreferencesService).getPreferences = () => ({
branchName: 'main',
connected: true,
@@ -205,10 +209,6 @@ describe('Source Control', () => {
expect(accessSync(gitFolder, fsConstants.F_OK)).toBeUndefined();
});
it('should check if source control is licensed', async () => {
expect(Container.get(License).isSourceControlLicensed()).toBe(true);
});
it('should get repo type from url', async () => {
expect(getRepoType('git@github.com:n8ntest/n8n_testrepo.git')).toBe('github');
expect(getRepoType('git@gitlab.com:n8ntest/n8n_testrepo.git')).toBe('gitlab');

View File

@@ -4,8 +4,8 @@ import config from '@/config';
import { flushPromises } from './Helpers';
import { PostHogClient } from '@/posthog';
import { mock } from 'jest-mock-extended';
import { mockInstance } from '../integration/shared/utils';
import { InstanceSettings } from 'n8n-core';
import { mockInstance } from '../shared/mocking';
jest.unmock('@/telemetry');
jest.mock('@/license/License.service', () => {

View File

@@ -1,43 +1,36 @@
import { mocked } from 'jest-mock';
import type { INode, IWorkflowCredentials } from 'n8n-workflow';
import * as Db from '@/Db';
import type { FindOptionsWhere } from 'typeorm';
import type { INode } from 'n8n-workflow';
import { WorkflowCredentials } from '@/WorkflowCredentials';
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { mockInstance } from '../shared/mocking';
// Define a function used to mock the findOneBy function
async function mockFind({
id,
type,
}: {
id: string;
type: string;
}): Promise<IWorkflowCredentials | null> {
// Simple statement that maps a return value based on the `id` parameter
if (id === notFoundNode.credentials!.test.id) {
return null;
}
// Otherwise just build some kind of credential object and return it
return {
[type]: {
[id]: {
id,
name: type,
type,
nodesAccess: [],
data: '',
},
},
};
}
const credentialsRepository = mockInstance(CredentialsRepository);
credentialsRepository.findOneBy.mockImplementation(
async (where: FindOptionsWhere<CredentialsEntity>) => {
const { id, type } = where as {
id: string;
type: string;
};
// Simple statement that maps a return value based on the `id` parameter
if (id === notFoundNode.credentials!.test.id) {
return null;
}
jest.mock('@/Db', () => {
return {
collections: {
Credentials: {
findOneBy: jest.fn(mockFind),
// Otherwise just build some kind of credential object and return it
return {
[type]: {
[id]: {
id,
name: type,
type,
nodesAccess: [],
data: '',
},
},
},
};
});
} as unknown as CredentialsEntity;
},
);
// Create an array of Nodes with info that pass or fail the checks as required.
// DB returns an object of type { [id: string]: ICredentialsEncrypted } but as it isn't checked
@@ -54,7 +47,7 @@ describe('WorkflowCredentials', () => {
`Credentials with name "${credentials.name}" for type "test" miss an ID.`,
);
await expect(WorkflowCredentials([noIdNode])).rejects.toEqual(expectedError);
expect(mocked(Db.collections.Credentials.findOneBy)).toHaveBeenCalledTimes(0);
expect(credentialsRepository.findOneBy).toHaveBeenCalledTimes(0);
});
test('Should return an error if credentials cannot be found in the DB', async () => {
@@ -63,7 +56,7 @@ describe('WorkflowCredentials', () => {
`Could not find credentials for type "test" with ID "${credentials.id}".`,
);
await expect(WorkflowCredentials([notFoundNode])).rejects.toEqual(expectedError);
expect(mocked(Db.collections.Credentials.findOneBy)).toHaveBeenCalledTimes(1);
expect(credentialsRepository.findOneBy).toHaveBeenCalledTimes(1);
});
test('Should ignore duplicates', async () => {

View File

@@ -1,7 +1,7 @@
import { Container } from 'typedi';
import { ExecutionMetadataRepository } from '@db/repositories';
import { ExecutionMetadataRepository } from '@db/repositories/executionMetadata.repository';
import { ExecutionMetadataService } from '@/services/executionMetadata.service';
import { mockInstance } from '../integration/shared/utils';
import { mockInstance } from '../shared/mocking';
describe('WorkflowExecuteAdditionalData', () => {
const repository = mockInstance(ExecutionMetadataRepository);

View File

@@ -1,12 +1,13 @@
import type { User } from '@db/entities/User';
import * as testDb from '../integration/shared/testDb';
import * as utils from '../integration/shared/utils/';
import { WorkflowRunner } from '@/WorkflowRunner';
import { WorkflowHooks, type ExecutionError, type IWorkflowExecuteHooks } from 'n8n-workflow';
import { Push } from '@/push';
import { mockInstance } from '../integration/shared/utils';
import Container from 'typedi';
import config from '@/config';
import { mockInstance } from '../shared/mocking';
import * as testDb from '../integration/shared/testDb';
import { setupTestServer } from '../integration/shared/utils';
import { getGlobalOwnerRole } from '../integration/shared/db/roles';
import { createUser } from '../integration/shared/db/users';
import { createWorkflow } from '../integration/shared/db/workflows';
@@ -15,7 +16,7 @@ import { createExecution } from '../integration/shared/db/executions';
let owner: User;
let runner: WorkflowRunner;
let hookFunctions: IWorkflowExecuteHooks;
utils.setupTestServer({ endpointGroups: [] });
setupTestServer({ endpointGroups: [] });
class Watchers {
workflowExecuteAfter = jest.fn();

View File

@@ -1,6 +1,6 @@
import { CollaborationService } from '@/collaboration/collaboration.service';
import type { Logger } from '@/Logger';
import type { User } from '@/databases/entities/User';
import type { User } from '@db/entities/User';
import type { UserService } from '@/services/user.service';
import { CollaborationState } from '@/collaboration/collaboration.state';
import type { Push } from '@/push';

View File

@@ -11,13 +11,15 @@ import type { AuthenticatedRequest, MeRequest } from '@/requests';
import { UserService } from '@/services/user.service';
import { ExternalHooks } from '@/ExternalHooks';
import { InternalHooks } from '@/InternalHooks';
import { License } from '@/License';
import { badPasswords } from '../shared/testData';
import { mockInstance } from '../../integration/shared/utils';
import { mockInstance } from '../../shared/mocking';
describe('MeController', () => {
const externalHooks = mockInstance(ExternalHooks);
const internalHooks = mockInstance(InternalHooks);
const userService = mockInstance(UserService);
mockInstance(License).isWithinUsersLimit.mockReturnValue(true);
const controller = Container.get(MeController);
describe('updateCurrentUser', () => {

View File

@@ -8,14 +8,15 @@ import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
import type { User } from '@db/entities/User';
import type { OAuthRequest } from '@/requests';
import { BadRequestError, NotFoundError } from '@/ResponseHelper';
import { CredentialsRepository, SharedCredentialsRepository } from '@/databases/repositories';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { ExternalHooks } from '@/ExternalHooks';
import { Logger } from '@/Logger';
import { VariablesService } from '@/environments/variables/variables.service';
import { SecretsHelper } from '@/SecretsHelpers';
import { CredentialsHelper } from '@/CredentialsHelper';
import { mockInstance } from '../../integration/shared/utils';
import { mockInstance } from '../../shared/mocking';
describe('OAuth1CredentialController', () => {
mockInstance(Logger);

View File

@@ -10,14 +10,15 @@ import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
import type { User } from '@db/entities/User';
import type { OAuthRequest } from '@/requests';
import { BadRequestError, NotFoundError } from '@/ResponseHelper';
import { CredentialsRepository, SharedCredentialsRepository } from '@/databases/repositories';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { ExternalHooks } from '@/ExternalHooks';
import { Logger } from '@/Logger';
import { VariablesService } from '@/environments/variables/variables.service';
import { SecretsHelper } from '@/SecretsHelpers';
import { CredentialsHelper } from '@/CredentialsHelper';
import { mockInstance } from '../../integration/shared/utils';
import { mockInstance } from '../../shared/mocking';
describe('OAuth2CredentialController', () => {
mockInstance(Logger);

View File

@@ -3,21 +3,24 @@ import { anyObject, captor, mock } from 'jest-mock-extended';
import jwt from 'jsonwebtoken';
import type { IInternalHooksClass } from '@/Interfaces';
import type { User } from '@db/entities/User';
import type { SettingsRepository } from '@db/repositories';
import type { SettingsRepository } from '@db/repositories/settings.repository';
import type { Config } from '@/config';
import { BadRequestError } from '@/ResponseHelper';
import type { OwnerRequest } from '@/requests';
import { OwnerController } from '@/controllers/owner.controller';
import { badPasswords } from '../shared/testData';
import { AUTH_COOKIE_NAME } from '@/constants';
import { UserService } from '@/services/user.service';
import { mockInstance } from '../../integration/shared/utils';
import { License } from '@/License';
import { mockInstance } from '../../shared/mocking';
import { badPasswords } from '../shared/testData';
describe('OwnerController', () => {
const config = mock<Config>();
const internalHooks = mock<IInternalHooksClass>();
const userService = mockInstance(UserService);
const settingsRepository = mock<SettingsRepository>();
mockInstance(License).isWithinUsersLimit.mockReturnValue(true);
const controller = new OwnerController(
config,
mock(),

View File

@@ -1,6 +1,6 @@
import { restoreBinaryDataId } from '@/executionLifecycleHooks/restoreBinaryDataId';
import { BinaryDataService } from 'n8n-core';
import { mockInstance } from '../integration/shared/utils/mocking';
import { mockInstance } from '../shared/mocking';
import { toSaveSettings } from '@/executionLifecycleHooks/toSaveSettings';
import type { IRun } from 'n8n-workflow';
import config from '@/config';

View File

@@ -3,9 +3,9 @@ import { EventEmitter } from 'events';
import type WebSocket from 'ws';
import { WebSocketPush } from '@/push/websocket.push';
import { Logger } from '@/Logger';
import type { User } from '@/databases/entities/User';
import type { User } from '@db/entities/User';
import type { PushDataExecutionRecovered } from '@/Interfaces';
import { mockInstance } from '../../integration/shared/utils';
import { mockInstance } from '../../shared/mocking';
jest.useFakeTimers();

View File

@@ -4,7 +4,7 @@ import { mock } from 'jest-mock-extended';
import type { RoleNames, RoleScopes } from '@db/entities/Role';
import { Role } from '@db/entities/Role';
import { RoleRepository } from '@db/repositories/role.repository';
import { mockInstance } from '../../integration/shared/utils/';
import { mockInstance } from '../../shared/mocking';
import { randomInteger } from '../../integration/shared/random';
describe('RoleRepository', () => {

View File

@@ -5,7 +5,7 @@ import type { User } from '@db/entities/User';
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
import { SharedCredentials } from '@db/entities/SharedCredentials';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { mockInstance } from '../../integration/shared/utils/';
import { mockInstance } from '../../shared/mocking';
describe('SharedCredentialsRepository', () => {
const entityManager = mockInstance(EntityManager);

View File

@@ -15,16 +15,18 @@ import config from '@/config';
import { InstalledPackages } from '@db/entities/InstalledPackages';
import type { CommunityPackages } from '@/Interfaces';
import { CommunityPackagesService } from '@/services/communityPackages.service';
import { InstalledNodesRepository, InstalledPackagesRepository } from '@/databases/repositories';
import { InstalledNodes } from '@/databases/entities/InstalledNodes';
import { InstalledNodesRepository } from '@db/repositories/installedNodes.repository';
import { InstalledPackagesRepository } from '@db/repositories/installedPackages.repository';
import { InstalledNodes } from '@db/entities/InstalledNodes';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { mockInstance } from '../../shared/mocking';
import {
COMMUNITY_NODE_VERSION,
COMMUNITY_PACKAGE_VERSION,
} from '../../integration/shared/constants';
import { randomName } from '../../integration/shared/random';
import { mockInstance, mockPackageName, mockPackagePair } from '../../integration/shared/utils';
import { mockPackageName, mockPackagePair } from '../../integration/shared/utils';
jest.mock('fs/promises');
jest.mock('child_process');

View File

@@ -11,11 +11,11 @@ import { mock } from 'jest-mock-extended';
import config from '@/config';
import type { User } from '@db/entities/User';
import type { WorkflowStatistics } from '@db/entities/WorkflowStatistics';
import { WorkflowStatisticsRepository } from '@db/repositories';
import { WorkflowStatisticsRepository } from '@db/repositories/workflowStatistics.repository';
import { EventsService } from '@/services/events.service';
import { UserService } from '@/services/user.service';
import { OwnershipService } from '@/services/ownership.service';
import { mockInstance } from '../../integration/shared/utils';
import { mockInstance } from '../../shared/mocking';
jest.mock('@/UserManagement/UserManagementHelper', () => ({ getWorkflowOwner: jest.fn() }));

View File

@@ -4,13 +4,13 @@ import { SingleMainInstancePublisher } from '@/services/orchestration/main/Singl
import type { RedisServiceWorkerResponseObject } from '@/services/redis/RedisServiceCommands';
import { eventBus } from '@/eventbus';
import { RedisService } from '@/services/redis.service';
import { mockInstance } from '../../integration/shared/utils';
import { handleWorkerResponseMessageMain } from '@/services/orchestration/main/handleWorkerResponseMessageMain';
import { handleCommandMessageMain } from '@/services/orchestration/main/handleCommandMessageMain';
import { OrchestrationHandlerMainService } from '@/services/orchestration/main/orchestration.handler.main.service';
import * as helpers from '@/services/orchestration/helpers';
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
import { Logger } from '@/Logger';
import { mockInstance } from '../../shared/mocking';
const os = Container.get(SingleMainInstancePublisher);
const handler = Container.get(OrchestrationHandlerMainService);

View File

@@ -1,20 +1,20 @@
import { OwnershipService } from '@/services/ownership.service';
import { SharedWorkflowRepository } from '@/databases/repositories';
import { mockInstance } from '../../integration/shared/utils';
import { Role } from '@/databases/entities/Role';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import { Role } from '@db/entities/Role';
import { SharedWorkflow } from '@db/entities/SharedWorkflow';
import { CacheService } from '@/services/cache.service';
import { User } from '@db/entities/User';
import { RoleService } from '@/services/role.service';
import { UserService } from '@/services/user.service';
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
import type { SharedCredentials } from '@db/entities/SharedCredentials';
import { mockInstance } from '../../shared/mocking';
import {
randomCredentialPayload,
randomEmail,
randomInteger,
randomName,
} from '../../integration/shared/random';
import { SharedWorkflow } from '@/databases/entities/SharedWorkflow';
import { CacheService } from '@/services/cache.service';
import { User } from '@/databases/entities/User';
import { RoleService } from '@/services/role.service';
import { UserService } from '@/services/user.service';
import { CredentialsEntity } from '@/databases/entities/CredentialsEntity';
import type { SharedCredentials } from '@/databases/entities/SharedCredentials';
const wfOwnerRole = () =>
Object.assign(new Role(), {

View File

@@ -2,7 +2,7 @@ import Container from 'typedi';
import { Logger } from '@/Logger';
import config from '@/config';
import { RedisService } from '@/services/redis.service';
import { mockInstance } from '../../integration/shared/utils';
import { mockInstance } from '../../shared/mocking';
mockInstance(Logger);
const redisService = Container.get(RedisService);

View File

@@ -1,11 +1,11 @@
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import type { RoleNames, RoleScopes } from '@db/entities/Role';
import { Role } from '@db/entities/Role';
import { mockInstance } from '../../integration/shared/utils/';
import { RoleService } from '@/services/role.service';
import { RoleRepository } from '@/databases/repositories';
import { RoleRepository } from '@db/repositories/role.repository';
import { CacheService } from '@/services/cache.service';
import { SharedWorkflow } from '@/databases/entities/SharedWorkflow';
import { SharedWorkflow } from '@db/entities/SharedWorkflow';
import { mockInstance } from '../../shared/mocking';
import { chooseRandomly } from '../../integration/shared/random';
import config from '@/config';

View File

@@ -3,9 +3,9 @@ import jwt from 'jsonwebtoken';
import { Logger } from '@/Logger';
import config from '@/config';
import { User } from '@db/entities/User';
import { UserRepository } from '@db/repositories';
import { UserRepository } from '@db/repositories/user.repository';
import { UserService } from '@/services/user.service';
import { mockInstance } from '../../integration/shared/utils';
import { mockInstance } from '../../shared/mocking';
describe('UserService', () => {
config.set('userManagement.jwtSecret', 'random-secret');

View File

@@ -1,10 +1,10 @@
import { v4 as uuid } from 'uuid';
import config from '@/config';
import { mockInstance } from '../../integration/shared/utils/';
import { WebhookRepository } from '@/databases/repositories';
import { WebhookRepository } from '@db/repositories/webhook.repository';
import { CacheService } from '@/services/cache.service';
import { WebhookService } from '@/services/webhook.service';
import { WebhookEntity } from '@/databases/entities/WebhookEntity';
import { WebhookEntity } from '@db/entities/WebhookEntity';
import { mockInstance } from '../../shared/mocking';
const createWebhook = (method: string, path: string, webhookId?: string, pathSegments?: number) =>
Object.assign(new WebhookEntity(), {

View File

@@ -11,7 +11,7 @@ import { TestWebhooks } from '@/TestWebhooks';
import { WaitingWebhooks } from '@/WaitingWebhooks';
import type { IResponseCallbackData } from '@/Interfaces';
import { mockInstance } from '../integration/shared/utils';
import { mockInstance } from '../shared/mocking';
let agent: SuperAgentTest;

View File

@@ -1,7 +1,7 @@
import { License } from '@/License';
import { mockInstance } from '../integration/shared/utils';
import config from '@/config';
import { getWorkflowHistoryPruneTime } from '@/workflows/workflowHistory/workflowHistoryHelper.ee';
import { mockInstance } from '../shared/mocking';
let licenseMock: License;
let licensePruneTime = -1;