mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 21:07:28 -08:00
refactor(core): Delete unused code, and fix typings in tests (no-changelog) (#8142)
This commit is contained in:
parent
5778b3bac8
commit
4007163651
|
@ -1,51 +0,0 @@
|
|||
import Container from 'typedi';
|
||||
import { ApplicationError, type INode, type IWorkflowCredentials } from 'n8n-workflow';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export async function WorkflowCredentials(nodes: INode[]): Promise<IWorkflowCredentials> {
|
||||
// Go through all nodes to find which credentials are needed to execute the workflow
|
||||
const returnCredentials: IWorkflowCredentials = {};
|
||||
|
||||
let node;
|
||||
let type;
|
||||
let nodeCredentials;
|
||||
let foundCredentials;
|
||||
|
||||
for (node of nodes) {
|
||||
if (node.disabled === true || !node.credentials) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (type of Object.keys(node.credentials)) {
|
||||
if (!returnCredentials[type]) {
|
||||
returnCredentials[type] = {};
|
||||
}
|
||||
nodeCredentials = node.credentials[type];
|
||||
|
||||
if (!nodeCredentials.id) {
|
||||
throw new ApplicationError(
|
||||
`Credentials with name "${nodeCredentials.name}" for type "${type}" miss an ID.`,
|
||||
{ extra: { credentialName: nodeCredentials.name }, tags: { credentialType: type } },
|
||||
);
|
||||
}
|
||||
|
||||
if (!returnCredentials[type][nodeCredentials.id]) {
|
||||
foundCredentials = await Container.get(CredentialsRepository).findOneBy({
|
||||
id: nodeCredentials.id,
|
||||
type,
|
||||
});
|
||||
if (!foundCredentials) {
|
||||
throw new ApplicationError('Could not find credential.', {
|
||||
tags: { credentialType: type },
|
||||
extra: { credentialId: nodeCredentials.id },
|
||||
});
|
||||
}
|
||||
|
||||
returnCredentials[type][nodeCredentials.id] = foundCredentials;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnCredentials;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import type { Credentials } from '@/requests';
|
||||
import type { ListQuery } from '@/requests';
|
||||
import type { User } from '@db/entities/User';
|
||||
import * as testDb from './shared/testDb';
|
||||
import { setupTestServer } from './shared/utils/';
|
||||
|
@ -21,7 +21,7 @@ beforeEach(async () => {
|
|||
member = await createMember();
|
||||
});
|
||||
|
||||
type GetAllResponse = { body: { data: Credentials.WithOwnedByAndSharedWith[] } };
|
||||
type GetAllResponse = { body: { data: ListQuery.Credentials.WithOwnedByAndSharedWith[] } };
|
||||
|
||||
describe('GET /credentials', () => {
|
||||
describe('should return', () => {
|
||||
|
@ -278,7 +278,7 @@ describe('GET /credentials', () => {
|
|||
});
|
||||
});
|
||||
|
||||
function validateCredential(credential: Credentials.WithOwnedByAndSharedWith) {
|
||||
function validateCredential(credential: ListQuery.Credentials.WithOwnedByAndSharedWith) {
|
||||
const { name, type, nodesAccess, sharedWith, ownedBy } = credential;
|
||||
|
||||
expect(typeof name).toBe('string');
|
||||
|
|
|
@ -24,6 +24,7 @@ describe('ExecutionRepository', () => {
|
|||
const executionId = await executionRepo.createNewExecution({
|
||||
workflowId: workflow.id,
|
||||
data: {
|
||||
//@ts-expect-error This is not needed for tests
|
||||
resultData: {},
|
||||
},
|
||||
workflowData: workflow,
|
||||
|
|
|
@ -271,6 +271,7 @@ describe('CredentialsHelper', () => {
|
|||
|
||||
for (const testData of tests) {
|
||||
test(testData.description, async () => {
|
||||
//@ts-expect-error `loadedCredentials` is a getter and we are replacing it here with a property
|
||||
mockNodesAndCredentials.loadedCredentials = {
|
||||
[testData.input.credentialType.name]: {
|
||||
type: testData.input.credentialType,
|
||||
|
|
|
@ -41,6 +41,7 @@ describe('InternalHooks', () => {
|
|||
licensePlanName,
|
||||
licenseTenantId,
|
||||
binary_data_s3: false,
|
||||
multi_main_setup_enabled: false,
|
||||
};
|
||||
|
||||
const parameters = {
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('Telemetry', () => {
|
|||
const postHog = new PostHogClient(instanceSettings);
|
||||
await postHog.init();
|
||||
|
||||
telemetry = new Telemetry(mock(), postHog, mock(), instanceSettings);
|
||||
telemetry = new Telemetry(mock(), postHog, mock(), instanceSettings, mock());
|
||||
(telemetry as any).rudderStack = mockRudderStack;
|
||||
});
|
||||
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
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';
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
// All the mock will need to return is some form of Object when successful
|
||||
|
||||
describe('WorkflowCredentials', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('Should return an error if any node has no credential ID', async () => {
|
||||
const credentials = noIdNode.credentials!.test;
|
||||
const expectedError = new Error(
|
||||
`Credentials with name "${credentials.name}" for type "test" miss an ID.`,
|
||||
);
|
||||
await expect(WorkflowCredentials([noIdNode])).rejects.toEqual(expectedError);
|
||||
expect(credentialsRepository.findOneBy).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('Should return an error if credentials cannot be found in the DB', async () => {
|
||||
const expectedError = new Error('Could not find credential.');
|
||||
await expect(WorkflowCredentials([notFoundNode])).rejects.toEqual(expectedError);
|
||||
expect(credentialsRepository.findOneBy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Should ignore duplicates', async () => {
|
||||
const response = await WorkflowCredentials([validNode, validNode, validNode]);
|
||||
expect(Object.keys(response)).toEqual(['test']);
|
||||
});
|
||||
|
||||
test('Should ignore Nodes with no credentials set', async () => {
|
||||
const response = await WorkflowCredentials([validNode, noCredentialsNode]);
|
||||
expect(Object.keys(response)).toEqual(['test']);
|
||||
});
|
||||
|
||||
test('Should work for Nodes with multiple credentials', async () => {
|
||||
const response = await WorkflowCredentials([multiCredNode]);
|
||||
expect(Object.keys(response)).toEqual(['mcTest', 'mcTest2']);
|
||||
});
|
||||
});
|
||||
|
||||
const validNode: INode = {
|
||||
id: '1',
|
||||
name: 'Node with Valid Credentials',
|
||||
typeVersion: 1,
|
||||
type: '',
|
||||
position: [0, 0],
|
||||
credentials: {
|
||||
test: {
|
||||
id: 'cred#1',
|
||||
name: 'Test Credentials',
|
||||
},
|
||||
},
|
||||
parameters: {},
|
||||
};
|
||||
|
||||
const noIdNode: INode = {
|
||||
id: '2',
|
||||
name: 'Node with no Credential ID',
|
||||
typeVersion: 1,
|
||||
type: '',
|
||||
position: [0, 0],
|
||||
credentials: {
|
||||
test: {
|
||||
id: null,
|
||||
name: 'NOFIND',
|
||||
},
|
||||
},
|
||||
parameters: {},
|
||||
};
|
||||
|
||||
const notFoundNode: INode = {
|
||||
id: '3',
|
||||
name: 'Node that will not be found in the DB',
|
||||
typeVersion: 1,
|
||||
type: '',
|
||||
position: [0, 0],
|
||||
credentials: {
|
||||
test: {
|
||||
id: 'noDB',
|
||||
name: 'Not in Database',
|
||||
},
|
||||
},
|
||||
parameters: {},
|
||||
};
|
||||
|
||||
const noCredentialsNode: INode = {
|
||||
id: '4',
|
||||
name: 'Node that has no credentials',
|
||||
typeVersion: 1,
|
||||
type: '',
|
||||
position: [0, 0],
|
||||
parameters: {},
|
||||
};
|
||||
|
||||
// Reference this as a DataObject so I can provide a null credential for testing
|
||||
const multiCredNode: INode = {
|
||||
id: '5',
|
||||
name: 'Node that has mutliple credential elements',
|
||||
typeVersion: 1,
|
||||
type: '',
|
||||
position: [0, 0],
|
||||
credentials: {
|
||||
mcTest: {
|
||||
id: 'multicred#1',
|
||||
name: 'First of Multiple Credentials',
|
||||
},
|
||||
mcTest2: {
|
||||
id: 'multicred#2',
|
||||
name: 'Second of Multiple Credentials',
|
||||
},
|
||||
},
|
||||
parameters: {},
|
||||
};
|
Loading…
Reference in a new issue