refactor(core): Move methods from WorkflowHelpers into various workflow services (no-changelog) (#8348)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2024-01-17 10:16:13 +01:00
committed by GitHub
parent ab52aaf7e9
commit 7cdbb424e3
21 changed files with 896 additions and 802 deletions

View File

@@ -1,10 +1,13 @@
import type { User } from '@db/entities/User';
import { Push } from '@/push';
import { createSuccessfulExecution, getAllExecutions } from './shared/db/executions';
import { createOwner } from './shared/db/users';
import { createWorkflow } from './shared/db/workflows';
import * as testDb from './shared/testDb';
import { setupTestServer } from './shared/utils';
import { mockInstance } from '../shared/mocking';
mockInstance(Push);
let testServer = setupTestServer({ endpointGroups: ['executions'] });
let owner: User;

View File

@@ -0,0 +1,78 @@
import type { INode } from 'n8n-workflow';
import { WorkflowEntity } from '@db/entities/WorkflowEntity';
export const FIRST_CREDENTIAL_ID = '1';
export const SECOND_CREDENTIAL_ID = '2';
export const THIRD_CREDENTIAL_ID = '3';
const NODE_WITH_NO_CRED = '0133467b-df4a-473d-9295-fdd9d01fa45a';
const NODE_WITH_ONE_CRED = '4673f869-f2dc-4a33-b053-ca3193bc5226';
const NODE_WITH_TWO_CRED = '9b4208bd-8f10-4a6a-ad3b-da47a326f7da';
const nodeWithNoCredentials: INode = {
id: NODE_WITH_NO_CRED,
name: 'Node with no Credential',
typeVersion: 1,
type: 'n8n-nodes-base.fakeNode',
position: [0, 0],
credentials: {},
parameters: {},
};
const nodeWithOneCredential: INode = {
id: NODE_WITH_ONE_CRED,
name: 'Node with a single credential',
typeVersion: 1,
type: '',
position: [0, 0],
credentials: {
test: {
id: FIRST_CREDENTIAL_ID,
name: 'First fake credential',
},
},
parameters: {},
};
const nodeWithTwoCredentials: INode = {
id: NODE_WITH_TWO_CRED,
name: 'Node with two credentials',
typeVersion: 1,
type: '',
position: [0, 0],
credentials: {
mcTest: {
id: SECOND_CREDENTIAL_ID,
name: 'Second fake credential',
},
mcTest2: {
id: THIRD_CREDENTIAL_ID,
name: 'Third fake credential',
},
},
parameters: {},
};
export function getWorkflow(options?: {
addNodeWithoutCreds?: boolean;
addNodeWithOneCred?: boolean;
addNodeWithTwoCreds?: boolean;
}) {
const workflow = new WorkflowEntity();
workflow.nodes = [];
if (options?.addNodeWithoutCreds) {
workflow.nodes.push(nodeWithNoCredentials);
}
if (options?.addNodeWithOneCred) {
workflow.nodes.push(nodeWithOneCredential);
}
if (options?.addNodeWithTwoCreds) {
workflow.nodes.push(nodeWithTwoCredentials);
}
return workflow;
}

View File

@@ -0,0 +1,180 @@
import Container from 'typedi';
import { mock } from 'jest-mock-extended';
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { Telemetry } from '@/telemetry';
import { EnterpriseWorkflowService } from '@/workflows/workflow.service.ee';
import * as testDb from '../shared/testDb';
import { mockInstance } from '../../shared/mocking';
import {
FIRST_CREDENTIAL_ID,
SECOND_CREDENTIAL_ID,
THIRD_CREDENTIAL_ID,
getWorkflow,
} from '../shared/workflow';
describe('EnterpriseWorkflowService', () => {
let service: EnterpriseWorkflowService;
beforeAll(async () => {
await testDb.init();
mockInstance(Telemetry);
service = new EnterpriseWorkflowService(
mock(),
Container.get(SharedWorkflowRepository),
Container.get(WorkflowRepository),
Container.get(CredentialsRepository),
);
});
afterEach(async () => {
await testDb.truncate(['Workflow']);
jest.restoreAllMocks();
});
afterAll(async () => {
await testDb.terminate();
});
describe('validateWorkflowCredentialUsage', () => {
function generateCredentialEntity(credentialId: string) {
const credentialEntity = new CredentialsEntity();
credentialEntity.id = credentialId;
return credentialEntity;
}
it('Should throw error saving a workflow using credential without access', () => {
const newWorkflowVersion = getWorkflow({ addNodeWithOneCred: true });
const previousWorkflowVersion = getWorkflow();
expect(() => {
service.validateWorkflowCredentialUsage(newWorkflowVersion, previousWorkflowVersion, []);
}).toThrow();
});
it('Should not throw error when saving a workflow using credential with access', () => {
const newWorkflowVersion = getWorkflow({ addNodeWithOneCred: true });
const previousWorkflowVersion = getWorkflow();
expect(() => {
service.validateWorkflowCredentialUsage(newWorkflowVersion, previousWorkflowVersion, [
generateCredentialEntity('1'),
]);
}).not.toThrow();
});
it('Should not throw error when saving a workflow removing node without credential access', () => {
const newWorkflowVersion = getWorkflow();
const previousWorkflowVersion = getWorkflow({ addNodeWithOneCred: true });
expect(() => {
service.validateWorkflowCredentialUsage(newWorkflowVersion, previousWorkflowVersion, [
generateCredentialEntity('1'),
]);
}).not.toThrow();
});
it('Should save fine when not making changes to workflow without access', () => {
const workflowWithOneCredential = getWorkflow({ addNodeWithOneCred: true });
expect(() => {
service.validateWorkflowCredentialUsage(
workflowWithOneCredential,
workflowWithOneCredential,
[],
);
}).not.toThrow();
});
it('Should throw error saving a workflow adding node without credential access', () => {
const newWorkflowVersion = getWorkflow({
addNodeWithOneCred: true,
addNodeWithTwoCreds: true,
});
const previousWorkflowVersion = getWorkflow({ addNodeWithOneCred: true });
expect(() => {
service.validateWorkflowCredentialUsage(newWorkflowVersion, previousWorkflowVersion, []);
}).toThrow();
});
});
describe('getNodesWithInaccessibleCreds', () => {
test('Should return an empty list for a workflow without nodes', () => {
const workflow = getWorkflow();
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, []);
expect(nodesWithInaccessibleCreds).toHaveLength(0);
});
test('Should return an empty list for a workflow with nodes without credentials', () => {
const workflow = getWorkflow({ addNodeWithoutCreds: true });
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, []);
expect(nodesWithInaccessibleCreds).toHaveLength(0);
});
test('Should return an element for a node with a credential without access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true });
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, []);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return an empty list for a node with a credential with access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true });
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, [
FIRST_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(0);
});
test('Should return an element for a node with two credentials and mixed access', () => {
const workflow = getWorkflow({ addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, [
SECOND_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return one node for a workflow with two nodes and two credentials', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true, addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, [
SECOND_CREDENTIAL_ID,
THIRD_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return one element for a workflows with two nodes and one credential', () => {
const workflow = getWorkflow({
addNodeWithoutCreds: true,
addNodeWithOneCred: true,
addNodeWithTwoCreds: true,
});
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, [
FIRST_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return one element for a workflows with two nodes and partial credential access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true, addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, [
FIRST_CREDENTIAL_ID,
SECOND_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return two elements for a workflows with two nodes and partial credential access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true, addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, [
SECOND_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(2);
});
test('Should return two elements for a workflows with two nodes and no credential access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true, addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = service.getNodesWithInaccessibleCreds(workflow, []);
expect(nodesWithInaccessibleCreds).toHaveLength(2);
});
});
});

View File

@@ -1,15 +1,16 @@
import Container from 'typedi';
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
import * as testDb from './shared/testDb';
import { WorkflowService } from '@/workflows/workflow.service';
import { mockInstance } from '../shared/mocking';
import { createOwner } from './shared/db/users';
import { createWorkflow } from './shared/db/workflows';
import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflow.repository';
import { mock } from 'jest-mock-extended';
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import { Telemetry } from '@/telemetry';
import { MultiMainSetup } from '@/services/orchestration/main/MultiMainSetup.ee';
import { WorkflowService } from '@/workflows/workflow.service';
import * as testDb from '../shared/testDb';
import { mockInstance } from '../../shared/mocking';
import { createOwner } from '../shared/db/users';
import { createWorkflow } from '../shared/db/workflows';
let workflowService: WorkflowService;
let activeWorkflowRunner: ActiveWorkflowRunner;
@@ -34,8 +35,6 @@ beforeAll(async () => {
mock(),
multiMainSetup,
mock(),
mock(),
mock(),
activeWorkflowRunner,
);
});

View File

@@ -3,24 +3,28 @@ import type { SuperAgentTest } from 'supertest';
import { v4 as uuid } from 'uuid';
import type { INode } from 'n8n-workflow';
import * as UserManagementHelpers from '@/UserManagement/UserManagementHelper';
import type { Role } from '@db/entities/Role';
import type { User } from '@db/entities/User';
import { getSharedWorkflowIds } from '@/WorkflowHelpers';
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';
import { makeWorkflow } from './shared/utils/';
import { randomCredentialPayload } from './shared/random';
import { affixRoleToSaveCredential, shareCredentialWithUsers } from './shared/db/credentials';
import { getCredentialOwnerRole, getGlobalMemberRole, getGlobalOwnerRole } from './shared/db/roles';
import { createUser } from './shared/db/users';
import { createWorkflow, getWorkflowSharing, shareWorkflowWithUsers } from './shared/db/workflows';
import type { Role } from '@/databases/entities/Role';
import * as UserManagementHelpers from '@/UserManagement/UserManagementHelper';
import { Push } from '@/push';
import { WorkflowSharingService } from '@/workflows/workflowSharing.service';
import { mockInstance } from '../../shared/mocking';
import * as utils from '../shared/utils/';
import * as testDb from '../shared/testDb';
import type { SaveCredentialFunction } from '../shared/types';
import { makeWorkflow } from '../shared/utils/';
import { randomCredentialPayload } from '../shared/random';
import { affixRoleToSaveCredential, shareCredentialWithUsers } from '../shared/db/credentials';
import {
getCredentialOwnerRole,
getGlobalMemberRole,
getGlobalOwnerRole,
} from '../shared/db/roles';
import { createUser } from '../shared/db/users';
import { createWorkflow, getWorkflowSharing, shareWorkflowWithUsers } from '../shared/db/workflows';
let globalMemberRole: Role;
let owner: User;
@@ -31,7 +35,7 @@ let authMemberAgent: SuperAgentTest;
let authAnotherMemberAgent: SuperAgentTest;
let saveCredential: SaveCredentialFunction;
const activeWorkflowRunnerLike = mockInstance(ActiveWorkflowRunner);
const activeWorkflowRunner = mockInstance(ActiveWorkflowRunner);
mockInstance(Push);
const sharingSpy = jest.spyOn(UserManagementHelpers, 'isSharingEnabled').mockReturnValue(true);
@@ -60,8 +64,8 @@ beforeAll(async () => {
});
beforeEach(async () => {
activeWorkflowRunnerLike.add.mockReset();
activeWorkflowRunnerLike.remove.mockReset();
activeWorkflowRunner.add.mockReset();
activeWorkflowRunner.remove.mockReset();
await testDb.truncate(['Workflow', 'SharedWorkflow', 'WorkflowHistory']);
});
@@ -988,7 +992,8 @@ describe('getSharedWorkflowIds', () => {
owner.globalRole = await getGlobalOwnerRole();
const workflow1 = await createWorkflow({}, member);
const workflow2 = await createWorkflow({}, anotherMember);
const sharedWorkflowIds = await getSharedWorkflowIds(owner);
const sharedWorkflowIds =
await Container.get(WorkflowSharingService).getSharedWorkflowIds(owner);
expect(sharedWorkflowIds).toHaveLength(2);
expect(sharedWorkflowIds).toContain(workflow1.id);
expect(sharedWorkflowIds).toContain(workflow2.id);
@@ -1001,7 +1006,8 @@ describe('getSharedWorkflowIds', () => {
const workflow3 = await createWorkflow({}, anotherMember);
await shareWorkflowWithUsers(workflow1, [member]);
await shareWorkflowWithUsers(workflow3, [member]);
const sharedWorkflowIds = await getSharedWorkflowIds(member);
const sharedWorkflowIds =
await Container.get(WorkflowSharingService).getSharedWorkflowIds(member);
expect(sharedWorkflowIds).toHaveLength(2);
expect(sharedWorkflowIds).toContain(workflow1.id);
expect(sharedWorkflowIds).toContain(workflow3.id);
@@ -1130,7 +1136,7 @@ describe('PATCH /workflows/:id - activate workflow', () => {
const response = await authOwnerAgent.patch(`/workflows/${workflow.id}`).send(payload);
expect(response.statusCode).toBe(200);
expect(activeWorkflowRunnerLike.add).toBeCalled();
expect(activeWorkflowRunner.add).toBeCalled();
const {
data: { id, versionId, active },
@@ -1152,8 +1158,8 @@ describe('PATCH /workflows/:id - activate workflow', () => {
const response = await authOwnerAgent.patch(`/workflows/${workflow.id}`).send(payload);
expect(response.statusCode).toBe(200);
expect(activeWorkflowRunnerLike.add).not.toBeCalled();
expect(activeWorkflowRunnerLike.remove).toBeCalled();
expect(activeWorkflowRunner.add).not.toBeCalled();
expect(activeWorkflowRunner.remove).toBeCalled();
const {
data: { id, versionId, active },

View File

@@ -1,27 +1,28 @@
import Container from 'typedi';
import type { SuperAgentTest } from 'supertest';
import { v4 as uuid } from 'uuid';
import type { INode, IPinData } from 'n8n-workflow';
import * as UserManagementHelpers from '@/UserManagement/UserManagementHelper';
import type { User } from '@db/entities/User';
import { v4 as uuid } from 'uuid';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { RoleService } from '@/services/role.service';
import Container from 'typedi';
import type { ListQuery } from '@/requests';
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/';
import { randomCredentialPayload } from './shared/random';
import { saveCredential } from './shared/db/credentials';
import { createOwner } from './shared/db/users';
import { createWorkflow } from './shared/db/workflows';
import { createTag } from './shared/db/tags';
import { Push } from '@/push';
import { EnterpriseWorkflowService } from '@/workflows/workflow.service.ee';
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
import type { WorkflowEntity } from '@/databases/entities/WorkflowEntity';
import { mockInstance } from '../../shared/mocking';
import * as utils from '../shared/utils/';
import * as testDb from '../shared/testDb';
import { makeWorkflow, MOCK_PINDATA } from '../shared/utils/';
import { randomCredentialPayload } from '../shared/random';
import { saveCredential } from '../shared/db/credentials';
import { createOwner } from '../shared/db/users';
import { createWorkflow } from '../shared/db/workflows';
import { createTag } from '../shared/db/tags';
let owner: User;
let authOwnerAgent: SuperAgentTest;

View File

@@ -1,150 +1,8 @@
import type { INode } from 'n8n-workflow';
import { type Workflow } from 'n8n-workflow';
import { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
import {
getExecutionStartNode,
getNodesWithInaccessibleCreds,
validateWorkflowCredentialUsage,
} from '@/WorkflowHelpers';
import { getExecutionStartNode } from '@/WorkflowHelpers';
import type { IWorkflowExecutionDataProcess } from '@/Interfaces';
const FIRST_CREDENTIAL_ID = '1';
const SECOND_CREDENTIAL_ID = '2';
const THIRD_CREDENTIAL_ID = '3';
const NODE_WITH_NO_CRED = '0133467b-df4a-473d-9295-fdd9d01fa45a';
const NODE_WITH_ONE_CRED = '4673f869-f2dc-4a33-b053-ca3193bc5226';
const NODE_WITH_TWO_CRED = '9b4208bd-8f10-4a6a-ad3b-da47a326f7da';
describe('WorkflowHelpers', () => {
describe('getNodesWithInaccessibleCreds', () => {
test('Should return an empty list for a workflow without nodes', () => {
const workflow = getWorkflow();
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, []);
expect(nodesWithInaccessibleCreds).toHaveLength(0);
});
test('Should return an empty list for a workflow with nodes without credentials', () => {
const workflow = getWorkflow({ addNodeWithoutCreds: true });
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, []);
expect(nodesWithInaccessibleCreds).toHaveLength(0);
});
test('Should return an element for a node with a credential without access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true });
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, []);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return an empty list for a node with a credential with access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true });
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, [
FIRST_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(0);
});
test('Should return an element for a node with two credentials and mixed access', () => {
const workflow = getWorkflow({ addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, [
SECOND_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return one node for a workflow with two nodes and two credentials', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true, addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, [
SECOND_CREDENTIAL_ID,
THIRD_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return one element for a workflows with two nodes and one credential', () => {
const workflow = getWorkflow({
addNodeWithoutCreds: true,
addNodeWithOneCred: true,
addNodeWithTwoCreds: true,
});
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, [
FIRST_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return one element for a workflows with two nodes and partial credential access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true, addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, [
FIRST_CREDENTIAL_ID,
SECOND_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(1);
});
test('Should return two elements for a workflows with two nodes and partial credential access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true, addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, [
SECOND_CREDENTIAL_ID,
]);
expect(nodesWithInaccessibleCreds).toHaveLength(2);
});
test('Should return two elements for a workflows with two nodes and no credential access', () => {
const workflow = getWorkflow({ addNodeWithOneCred: true, addNodeWithTwoCreds: true });
const nodesWithInaccessibleCreds = getNodesWithInaccessibleCreds(workflow, []);
expect(nodesWithInaccessibleCreds).toHaveLength(2);
});
});
describe('validateWorkflowCredentialUsage', () => {
it('Should throw error saving a workflow using credential without access', () => {
const newWorkflowVersion = getWorkflow({ addNodeWithOneCred: true });
const previousWorkflowVersion = getWorkflow();
expect(() => {
validateWorkflowCredentialUsage(newWorkflowVersion, previousWorkflowVersion, []);
}).toThrow();
});
it('Should not throw error when saving a workflow using credential with access', () => {
const newWorkflowVersion = getWorkflow({ addNodeWithOneCred: true });
const previousWorkflowVersion = getWorkflow();
expect(() => {
validateWorkflowCredentialUsage(newWorkflowVersion, previousWorkflowVersion, [
generateCredentialEntity(FIRST_CREDENTIAL_ID),
]);
}).not.toThrow();
});
it('Should not throw error when saving a workflow removing node without credential access', () => {
const newWorkflowVersion = getWorkflow();
const previousWorkflowVersion = getWorkflow({ addNodeWithOneCred: true });
expect(() => {
validateWorkflowCredentialUsage(newWorkflowVersion, previousWorkflowVersion, [
generateCredentialEntity(FIRST_CREDENTIAL_ID),
]);
}).not.toThrow();
});
it('Should save fine when not making changes to workflow without access', () => {
const workflowWithOneCredential = getWorkflow({ addNodeWithOneCred: true });
expect(() => {
validateWorkflowCredentialUsage(workflowWithOneCredential, workflowWithOneCredential, []);
}).not.toThrow();
});
it('Should throw error saving a workflow adding node without credential access', () => {
const newWorkflowVersion = getWorkflow({
addNodeWithOneCred: true,
addNodeWithTwoCreds: true,
});
const previousWorkflowVersion = getWorkflow({ addNodeWithOneCred: true });
expect(() => {
validateWorkflowCredentialUsage(newWorkflowVersion, previousWorkflowVersion, []);
}).toThrow();
});
});
describe('getExecutionStartNode', () => {
it('Should return undefined', () => {
const data = {
@@ -186,77 +44,3 @@ describe('WorkflowHelpers', () => {
});
});
});
function generateCredentialEntity(credentialId: string) {
const credentialEntity = new CredentialsEntity();
credentialEntity.id = credentialId;
return credentialEntity;
}
export function getWorkflow(options?: {
addNodeWithoutCreds?: boolean;
addNodeWithOneCred?: boolean;
addNodeWithTwoCreds?: boolean;
}) {
const workflow = new WorkflowEntity();
workflow.nodes = [];
if (options?.addNodeWithoutCreds) {
workflow.nodes.push(nodeWithNoCredentials);
}
if (options?.addNodeWithOneCred) {
workflow.nodes.push(nodeWithOneCredential);
}
if (options?.addNodeWithTwoCreds) {
workflow.nodes.push(nodeWithTwoCredentials);
}
return workflow;
}
const nodeWithNoCredentials: INode = {
id: NODE_WITH_NO_CRED,
name: 'Node with no Credential',
typeVersion: 1,
type: 'n8n-nodes-base.fakeNode',
position: [0, 0],
credentials: {},
parameters: {},
};
const nodeWithOneCredential: INode = {
id: NODE_WITH_ONE_CRED,
name: 'Node with a single credential',
typeVersion: 1,
type: '',
position: [0, 0],
credentials: {
test: {
id: FIRST_CREDENTIAL_ID,
name: 'First fake credential',
},
},
parameters: {},
};
const nodeWithTwoCredentials: INode = {
id: NODE_WITH_TWO_CRED,
name: 'Node with two credentials',
typeVersion: 1,
type: '',
position: [0, 0],
credentials: {
mcTest: {
id: SECOND_CREDENTIAL_ID,
name: 'Second fake credential',
},
mcTest2: {
id: THIRD_CREDENTIAL_ID,
name: 'Third fake credential',
},
},
parameters: {},
};

View File

@@ -1,11 +1,11 @@
import { mockClear } from 'jest-mock-extended';
import { User } from '@db/entities/User';
import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repository';
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import { WorkflowHistoryService } from '@/workflows/workflowHistory/workflowHistory.service.ee';
import { mockInstance } from '../../shared/mocking';
import { Logger } from '@/Logger';
import { getWorkflow } from '../WorkflowHelpers.test';
import { mockClear } from 'jest-mock-extended';
import { mockInstance } from '../../shared/mocking';
import { getWorkflow } from '../../integration/shared/workflow';
const workflowHistoryRepository = mockInstance(WorkflowHistoryRepository);
const logger = mockInstance(Logger);