test(core): Move unit tests closer to testable components (no-changelog) (#10287)

This commit is contained in:
Tomi Turtiainen 2024-08-05 12:12:25 +03:00 committed by GitHub
parent 8131d66f8c
commit afa43e75f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
80 changed files with 95 additions and 105 deletions

View file

@ -40,13 +40,13 @@ module.exports = {
overrides: [ overrides: [
{ {
files: ['./src/databases/**/*.ts', './test/**/*.ts'], files: ['./src/databases/**/*.ts', './test/**/*.ts', './src/**/__tests__/**/*.ts'],
rules: { rules: {
'n8n-local-rules/misplaced-n8n-typeorm-import': 'off', 'n8n-local-rules/misplaced-n8n-typeorm-import': 'off',
}, },
}, },
{ {
files: ['./test/**/*.ts'], files: ['./test/**/*.ts', './src/**/__tests__/**/*.ts'],
rules: { rules: {
'n8n-local-rules/no-type-unsafe-event-emitter': 'off', 'n8n-local-rules/no-type-unsafe-event-emitter': 'off',
}, },

View file

@ -72,11 +72,9 @@ export class ActiveWebhooks implements IWebhookManager {
const pathElements = path.split('/').slice(1); const pathElements = path.split('/').slice(1);
// extracting params from path // extracting params from path
// @ts-ignore
webhook.webhookPath.split('/').forEach((ele, index) => { webhook.webhookPath.split('/').forEach((ele, index) => {
if (ele.startsWith(':')) { if (ele.startsWith(':')) {
// write params to req.params // write params to req.params
// @ts-ignore
request.params[ele.slice(1)] = pathElements[index]; request.params[ele.slice(1)] = pathElements[index];
} }
}); });

View file

@ -6,13 +6,13 @@ import { License } from '@/License';
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee'; import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
import { ExternalSecretsProviders } from '@/ExternalSecrets/ExternalSecretsProviders.ee'; import { ExternalSecretsProviders } from '@/ExternalSecrets/ExternalSecretsProviders.ee';
import { InternalHooks } from '@/InternalHooks'; import { InternalHooks } from '@/InternalHooks';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { import {
DummyProvider, DummyProvider,
ErrorProvider, ErrorProvider,
FailedProvider, FailedProvider,
MockProviders, MockProviders,
} from '../../shared/ExternalSecrets/utils'; } from '@test/ExternalSecrets/utils';
import { mock } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended';
describe('External Secrets Manager', () => { describe('External Secrets Manager', () => {

View file

@ -1,5 +1,5 @@
import { UserRepository } from '@/databases/repositories/user.repository'; import { UserRepository } from '@/databases/repositories/user.repository';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import * as helpers from '@/Ldap/helpers.ee'; import * as helpers from '@/Ldap/helpers.ee';
import { AuthIdentity } from '@/databases/entities/AuthIdentity'; import { AuthIdentity } from '@/databases/entities/AuthIdentity';
import { User } from '@/databases/entities/User'; import { User } from '@/databases/entities/User';

View file

@ -717,7 +717,6 @@ export async function getRunData(
const runData: IWorkflowExecutionDataProcess = { const runData: IWorkflowExecutionDataProcess = {
executionMode: mode, executionMode: mode,
executionData: runExecutionData, executionData: runExecutionData,
// @ts-ignore
workflowData, workflowData,
}; };

View file

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

View file

@ -14,7 +14,7 @@ import { NodeTypes } from '@/NodeTypes';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials'; import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { CredentialsRepository } from '@db/repositories/credentials.repository'; import { CredentialsRepository } from '@db/repositories/credentials.repository';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository'; import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { mockInstance } from '../shared/mocking'; import { mockInstance } from '@test/mocking';
describe('CredentialsHelper', () => { describe('CredentialsHelper', () => {
mockInstance(CredentialsRepository); mockInstance(CredentialsRepository);

View file

@ -5,7 +5,7 @@ import config from '@/config';
import { License } from '@/License'; import { License } from '@/License';
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';
import { N8N_VERSION } from '@/constants'; import { N8N_VERSION } from '@/constants';
import { mockInstance } from '../shared/mocking'; import { mockInstance } from '@test/mocking';
import { OrchestrationService } from '@/services/orchestration.service'; import { OrchestrationService } from '@/services/orchestration.service';
jest.mock('@n8n_io/license-sdk'); jest.mock('@n8n_io/license-sdk');

View file

@ -1,5 +1,5 @@
import { VariablesService } from '@/environments/variables/variables.service.ee'; import { VariablesService } from '@/environments/variables/variables.service.ee';
import { mockInstance } from '../shared/mocking'; import { mockInstance } from '@test/mocking';
import { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus'; import { MessageEventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
import { getBase } from '@/WorkflowExecuteAdditionalData'; import { getBase } from '@/WorkflowExecuteAdditionalData';
import Container from 'typedi'; import Container from 'typedi';

View file

@ -4,11 +4,11 @@ import type { User } from '@db/entities/User';
import { WorkflowRunner } from '@/WorkflowRunner'; import { WorkflowRunner } from '@/WorkflowRunner';
import config from '@/config'; import config from '@/config';
import * as testDb from '../integration/shared/testDb'; import * as testDb from '@test-integration/testDb';
import { setupTestServer } from '../integration/shared/utils'; import { setupTestServer } from '@test-integration/utils';
import { createUser } from '../integration/shared/db/users'; import { createUser } from '@test-integration/db/users';
import { createWorkflow } from '../integration/shared/db/workflows'; import { createWorkflow } from '@test-integration/db/workflows';
import { createExecution } from '../integration/shared/db/executions'; import { createExecution } from '@test-integration/db/executions';
import { mockInstance } from '@test/mocking'; import { mockInstance } from '@test/mocking';
import { Telemetry } from '@/telemetry'; import { Telemetry } from '@/telemetry';

View file

@ -1,5 +1,5 @@
import { main } from '@/commands/db/revert'; import { main } from '@/commands/db/revert';
import { mockInstance } from '../../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';
import type { IrreversibleMigration, ReversibleMigration } from '@/databases/types'; import type { IrreversibleMigration, ReversibleMigration } from '@/databases/types';
import type { Migration, MigrationExecutor } from '@n8n/typeorm'; import type { Migration, MigrationExecutor } from '@n8n/typeorm';

View file

@ -13,8 +13,8 @@ import { InternalHooks } from '@/InternalHooks';
import { License } from '@/License'; import { License } from '@/License';
import { BadRequestError } from '@/errors/response-errors/bad-request.error'; import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { UserRepository } from '@/databases/repositories/user.repository'; import { UserRepository } from '@/databases/repositories/user.repository';
import { badPasswords } from '../shared/testData'; import { badPasswords } from '@test/testData';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
const browserId = 'test-browser-id'; const browserId = 'test-browser-id';

View file

@ -16,8 +16,8 @@ import type { OwnerRequest } from '@/requests';
import type { UserService } from '@/services/user.service'; import type { UserService } from '@/services/user.service';
import { PasswordUtility } from '@/services/password.utility'; import { PasswordUtility } from '@/services/password.utility';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { badPasswords } from '../shared/testData'; import { badPasswords } from '@test/testData';
describe('OwnerController', () => { describe('OwnerController', () => {
const configGetSpy = jest.spyOn(config, 'getEnv'); const configGetSpy = jest.spyOn(config, 'getEnv');

View file

@ -60,7 +60,7 @@ describe('UserSettingsController', () => {
[], [],
], ],
[ [
'updates user settings, reseting to waiting state', 'updates user settings, resetting to waiting state',
{ {
waitingForResponse: true, waitingForResponse: true,
ignoredCount: 0, ignoredCount: 0,
@ -137,7 +137,7 @@ describe('UserSettingsController', () => {
'is waitingForResponse but missing ignoredCount', 'is waitingForResponse but missing ignoredCount',
{ lastShownAt: 123, waitingForResponse: true }, { lastShownAt: 123, waitingForResponse: true },
], ],
])('thows error when request payload is %s', async (_, payload) => { ])('throws error when request payload is %s', async (_, payload) => {
const req = mock<NpsSurveyRequest.NpsSurveyUpdate>(); const req = mock<NpsSurveyRequest.NpsSurveyUpdate>();
req.user.id = '1'; req.user.id = '1';
req.body = payload; req.body = payload;

View file

@ -19,7 +19,7 @@ import { CredentialsHelper } from '@/CredentialsHelper';
import { BadRequestError } from '@/errors/response-errors/bad-request.error'; import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { NotFoundError } from '@/errors/response-errors/not-found.error'; import { NotFoundError } from '@/errors/response-errors/not-found.error';
import { mockInstance } from '../../../shared/mocking'; import { mockInstance } from '@test/mocking';
describe('OAuth1CredentialController', () => { describe('OAuth1CredentialController', () => {
mockInstance(Logger); mockInstance(Logger);

View file

@ -19,7 +19,7 @@ import { CredentialsHelper } from '@/CredentialsHelper';
import { BadRequestError } from '@/errors/response-errors/bad-request.error'; import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { NotFoundError } from '@/errors/response-errors/not-found.error'; import { NotFoundError } from '@/errors/response-errors/not-found.error';
import { mockInstance } from '../../../shared/mocking'; import { mockInstance } from '@test/mocking';
describe('OAuth2CredentialController', () => { describe('OAuth2CredentialController', () => {
mockInstance(Logger); mockInstance(Logger);

View file

@ -3,7 +3,7 @@ import { mock } from 'jest-mock-extended';
import { CREDENTIAL_BLANKING_VALUE } from '@/constants'; import { CREDENTIAL_BLANKING_VALUE } from '@/constants';
import type { CredentialsEntity } from '@db/entities/CredentialsEntity'; import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
import type { CredentialTypes } from '@/CredentialTypes'; import type { CredentialTypes } from '@/CredentialTypes';
import { CredentialsService } from '../credentials.service'; import { CredentialsService } from '@/credentials/credentials.service';
describe('CredentialsService', () => { describe('CredentialsService', () => {
const credType = mock<ICredentialType>({ const credType = mock<ICredentialType>({

View file

@ -8,8 +8,7 @@ import { mock } from 'jest-mock-extended';
import { ExecutionEntity } from '@db/entities/ExecutionEntity'; import { ExecutionEntity } from '@db/entities/ExecutionEntity';
import { ExecutionRepository } from '@db/repositories/execution.repository'; import { ExecutionRepository } from '@db/repositories/execution.repository';
import { mockEntityManager } from '../../shared/mocking'; import { mockInstance, mockEntityManager } from '@test/mocking';
import { mockInstance } from '../../shared/mocking';
describe('ExecutionRepository', () => { describe('ExecutionRepository', () => {
const entityManager = mockEntityManager(ExecutionEntity); const entityManager = mockEntityManager(ExecutionEntity);

View file

@ -8,7 +8,7 @@ import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
import { SharedCredentials } from '@db/entities/SharedCredentials'; import { SharedCredentials } from '@db/entities/SharedCredentials';
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository'; import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
import { GLOBAL_MEMBER_SCOPES, GLOBAL_OWNER_SCOPES } from '@/permissions/global-roles'; import { GLOBAL_MEMBER_SCOPES, GLOBAL_OWNER_SCOPES } from '@/permissions/global-roles';
import { mockEntityManager } from '../../shared/mocking'; import { mockEntityManager } from '@test/mocking';
describe('SharedCredentialsRepository', () => { describe('SharedCredentialsRepository', () => {
const entityManager = mockEntityManager(SharedCredentials); const entityManager = mockEntityManager(SharedCredentials);

View file

@ -5,7 +5,7 @@ import { mock, mockClear } from 'jest-mock-extended';
import { StatisticsNames, WorkflowStatistics } from '@db/entities/WorkflowStatistics'; import { StatisticsNames, WorkflowStatistics } from '@db/entities/WorkflowStatistics';
import { WorkflowStatisticsRepository } from '@db/repositories/workflowStatistics.repository'; import { WorkflowStatisticsRepository } from '@db/repositories/workflowStatistics.repository';
import { mockEntityManager } from '../../shared/mocking'; import { mockEntityManager } from '@test/mocking';
describe('insertWorkflowStatistics', () => { describe('insertWorkflowStatistics', () => {
const entityManager = mockEntityManager(WorkflowStatistics); const entityManager = mockEntityManager(WorkflowStatistics);

View file

@ -18,7 +18,7 @@ import {
import { constants as fsConstants, accessSync } from 'fs'; import { constants as fsConstants, accessSync } from 'fs';
import type { SourceControlledFile } from '@/environments/sourceControl/types/sourceControlledFile'; import type { SourceControlledFile } from '@/environments/sourceControl/types/sourceControlledFile';
import type { SourceControlPreferences } from '@/environments/sourceControl/types/sourceControlPreferences'; import type { SourceControlPreferences } from '@/environments/sourceControl/types/sourceControlPreferences';
import { mockInstance } from '../shared/mocking'; import { mockInstance } from '@test/mocking';
const pushResult: SourceControlledFile[] = [ const pushResult: SourceControlledFile[] = [
{ {

View file

@ -1,6 +1,6 @@
import { restoreBinaryDataId } from '@/executionLifecycleHooks/restoreBinaryDataId'; import { restoreBinaryDataId } from '@/executionLifecycleHooks/restoreBinaryDataId';
import { BinaryDataService } from 'n8n-core'; import { BinaryDataService } from 'n8n-core';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import type { IRun } from 'n8n-workflow'; import type { IRun } from 'n8n-workflow';
import config from '@/config'; import config from '@/config';
@ -24,7 +24,7 @@ function toIRun(item?: object) {
} }
function getDataId(run: IRun, kind: 'binary' | 'json') { function getDataId(run: IRun, kind: 'binary' | 'json') {
// @ts-ignore // @ts-expect-error The type doesn't have the correct structure
return run.data.resultData.runData.myNode[0].data.main[0][0][kind].data.id; return run.data.resultData.runData.myNode[0].data.main[0][0][kind].data.id;
} }

View file

@ -1,5 +1,5 @@
import { ExecutionRepository } from '@/databases/repositories/execution.repository'; import { ExecutionRepository } from '@/databases/repositories/execution.repository';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';
import { saveExecutionProgress } from '@/executionLifecycleHooks/saveExecutionProgress'; import { saveExecutionProgress } from '@/executionLifecycleHooks/saveExecutionProgress';
import * as fnModule from '@/executionLifecycleHooks/toSaveSettings'; import * as fnModule from '@/executionLifecycleHooks/toSaveSettings';

View file

@ -35,7 +35,7 @@ describe('failed production executions', () => {
}); });
}); });
describe('sucessful production executions', () => { describe('successful production executions', () => {
it('should favor workflow settings over defaults', () => { it('should favor workflow settings over defaults', () => {
config.set('executions.saveDataOnSuccess', 'none'); config.set('executions.saveDataOnSuccess', 'none');

View file

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

View file

@ -9,7 +9,7 @@ import { WebSocketPush } from '@/push/websocket.push';
import type { WebSocketPushRequest, SSEPushRequest } from '@/push/types'; import type { WebSocketPushRequest, SSEPushRequest } from '@/push/types';
import { BadRequestError } from '@/errors/response-errors/bad-request.error'; import { BadRequestError } from '@/errors/response-errors/bad-request.error';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
jest.unmock('@/push'); jest.unmock('@/push');

View file

@ -6,7 +6,7 @@ import { WebSocketPush } from '@/push/websocket.push';
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';
import type { PushDataExecutionRecovered } from '@/Interfaces'; import type { PushDataExecutionRecovered } from '@/Interfaces';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
jest.useFakeTimers(); jest.useFakeTimers();

View file

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

View file

@ -20,13 +20,10 @@ import { InstalledPackagesRepository } from '@db/repositories/installedPackages.
import { InstalledNodes } from '@db/entities/InstalledNodes'; import { InstalledNodes } from '@db/entities/InstalledNodes';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials'; import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { import { COMMUNITY_NODE_VERSION, COMMUNITY_PACKAGE_VERSION } from '@test-integration/constants';
COMMUNITY_NODE_VERSION, import { randomName } from '@test-integration/random';
COMMUNITY_PACKAGE_VERSION, import { mockPackageName, mockPackagePair } from '@test-integration/utils';
} from '../../integration/shared/constants';
import { randomName } from '../../integration/shared/random';
import { mockPackageName, mockPackagePair } from '../../integration/shared/utils';
import { InstanceSettings, PackageDirectoryLoader } from 'n8n-core'; import { InstanceSettings, PackageDirectoryLoader } from 'n8n-core';
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';

View file

@ -1,6 +1,6 @@
import { WorkflowRepository } from '@/databases/repositories/workflow.repository'; import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
import { CredentialsRepository } from '@/databases/repositories/credentials.repository'; import { CredentialsRepository } from '@/databases/repositories/credentials.repository';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { NamingService } from '@/services/naming.service'; import { NamingService } from '@/services/naming.service';
import type { WorkflowEntity } from '@/databases/entities/WorkflowEntity'; import type { WorkflowEntity } from '@/databases/entities/WorkflowEntity';
import type { CredentialsEntity } from '@/databases/entities/CredentialsEntity'; import type { CredentialsEntity } from '@/databases/entities/CredentialsEntity';

View file

@ -17,7 +17,7 @@ import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';
import { Push } from '@/push'; import { Push } from '@/push';
import { ActiveWorkflowManager } from '@/ActiveWorkflowManager'; import { ActiveWorkflowManager } from '@/ActiveWorkflowManager';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { RedisClientService } from '@/services/redis/redis-client.service'; import { RedisClientService } from '@/services/redis/redis-client.service';
const instanceSettings = Container.get(InstanceSettings); const instanceSettings = Container.get(InstanceSettings);

View file

@ -3,14 +3,14 @@ import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.reposi
import { SharedWorkflow } from '@db/entities/SharedWorkflow'; import { SharedWorkflow } from '@db/entities/SharedWorkflow';
import { User } from '@db/entities/User'; import { User } from '@db/entities/User';
import type { SharedCredentials } from '@db/entities/SharedCredentials'; import type { SharedCredentials } from '@db/entities/SharedCredentials';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { WorkflowEntity } from '@/databases/entities/WorkflowEntity'; import { WorkflowEntity } from '@/databases/entities/WorkflowEntity';
import { UserRepository } from '@/databases/repositories/user.repository'; import { UserRepository } from '@/databases/repositories/user.repository';
import { mock } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended';
import { Project } from '@/databases/entities/Project'; import { Project } from '@/databases/entities/Project';
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository'; import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
import { ProjectRelation } from '@/databases/entities/ProjectRelation'; import { ProjectRelation } from '@/databases/entities/ProjectRelation';
import { mockCredential, mockProject } from '../shared/mockObjects'; import { mockCredential, mockProject } from '@test/mockObjects';
describe('OwnershipService', () => { describe('OwnershipService', () => {
const userRepository = mockInstance(UserRepository); const userRepository = mockInstance(UserRepository);

View file

@ -2,7 +2,7 @@ import Container from 'typedi';
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';
import config from '@/config'; import config from '@/config';
import { RedisService } from '@/services/redis.service'; import { RedisService } from '@/services/redis.service';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
jest.mock('ioredis', () => { jest.mock('ioredis', () => {
const Redis = require('ioredis-mock'); const Redis = require('ioredis-mock');
@ -14,7 +14,7 @@ jest.mock('ioredis', () => {
}; };
} }
// second mock for our code // second mock for our code
return function (...args: any) { return function (...args: unknown[]) {
return new Redis(args); return new Redis(args);
}; };
}); });

View file

@ -4,7 +4,7 @@ import { v4 as uuid } from 'uuid';
import { User } from '@db/entities/User'; import { User } from '@db/entities/User';
import { UserService } from '@/services/user.service'; import { UserService } from '@/services/user.service';
import { UrlService } from '@/services/url.service'; import { UrlService } from '@/services/url.service';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { UserRepository } from '@/databases/repositories/user.repository'; import { UserRepository } from '@/databases/repositories/user.repository';
import { GlobalConfig } from '@n8n/config'; import { GlobalConfig } from '@n8n/config';

View file

@ -4,7 +4,7 @@ import { WebhookRepository } from '@db/repositories/webhook.repository';
import { CacheService } from '@/services/cache/cache.service'; import { CacheService } from '@/services/cache/cache.service';
import { WebhookService } from '@/services/webhook.service'; import { WebhookService } from '@/services/webhook.service';
import { WebhookEntity } from '@db/entities/WebhookEntity'; import { WebhookEntity } from '@db/entities/WebhookEntity';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
const createWebhook = (method: string, path: string, webhookId?: string, pathSegments?: number) => const createWebhook = (method: string, path: string, webhookId?: string, pathSegments?: number) =>
Object.assign(new WebhookEntity(), { Object.assign(new WebhookEntity(), {

View file

@ -17,7 +17,7 @@ import { WorkflowStatisticsRepository } from '@db/repositories/workflowStatistic
import { WorkflowStatisticsService } from '@/services/workflow-statistics.service'; import { WorkflowStatisticsService } from '@/services/workflow-statistics.service';
import { UserService } from '@/services/user.service'; import { UserService } from '@/services/user.service';
import { OwnershipService } from '@/services/ownership.service'; import { OwnershipService } from '@/services/ownership.service';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import type { Project } from '@/databases/entities/Project'; import type { Project } from '@/databases/entities/Project';
describe('WorkflowStatisticsService', () => { describe('WorkflowStatisticsService', () => {

View file

@ -1,7 +1,7 @@
import { mock } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended';
import type express from 'express'; import type express from 'express';
import { SamlService } from '@/sso/saml/saml.service.ee'; import { SamlService } from '@/sso/saml/saml.service.ee';
import { mockInstance } from '../../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { UrlService } from '@/services/url.service'; import { UrlService } from '@/services/url.service';
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';
import type { IdentityProviderInstance, ServiceProviderInstance } from 'samlify'; import type { IdentityProviderInstance, ServiceProviderInstance } from 'samlify';

View file

@ -2,7 +2,7 @@ import { User } from '@/databases/entities/User';
import { generateNanoId } from '@/databases/utils/generators'; import { generateNanoId } from '@/databases/utils/generators';
import * as helpers from '@/sso/saml/samlHelpers'; import * as helpers from '@/sso/saml/samlHelpers';
import type { SamlUserAttributes } from '@/sso/saml/types/samlUserAttributes'; import type { SamlUserAttributes } from '@/sso/saml/types/samlUserAttributes';
import { mockInstance } from '../../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { UserRepository } from '@/databases/repositories/user.repository'; import { UserRepository } from '@/databases/repositories/user.repository';
import type { AuthIdentity } from '@/databases/entities/AuthIdentity'; import type { AuthIdentity } from '@/databases/entities/AuthIdentity';
import { AuthIdentityRepository } from '@/databases/repositories/authIdentity.repository'; import { AuthIdentityRepository } from '@/databases/repositories/authIdentity.repository';

View file

@ -1,11 +1,11 @@
import type RudderStack from '@rudderstack/rudder-sdk-node'; import type RudderStack from '@rudderstack/rudder-sdk-node';
import { Telemetry } from '@/telemetry'; import { Telemetry } from '@/telemetry';
import config from '@/config'; import config from '@/config';
import { flushPromises } from './Helpers'; import { flushPromises } from '@test/flushPromises';
import { PostHogClient } from '@/posthog'; import { PostHogClient } from '@/posthog';
import { mock } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended';
import { InstanceSettings } from 'n8n-core'; import { InstanceSettings } from 'n8n-core';
import { mockInstance } from '../shared/mocking'; import { mockInstance } from '@test/mocking';
jest.unmock('@/telemetry'); jest.unmock('@/telemetry');
jest.mock('@/posthog'); jest.mock('@/posthog');

View file

@ -4,8 +4,8 @@ import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repo
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository'; import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
import { WorkflowHistoryService } from '@/workflows/workflowHistory/workflowHistory.service.ee'; import { WorkflowHistoryService } from '@/workflows/workflowHistory/workflowHistory.service.ee';
import { Logger } from '@/Logger'; import { Logger } from '@/Logger';
import { mockInstance } from '../../shared/mocking'; import { mockInstance } from '@test/mocking';
import { getWorkflow } from '../../integration/shared/workflow'; import { getWorkflow } from '@test-integration/workflow';
const workflowHistoryRepository = mockInstance(WorkflowHistoryRepository); const workflowHistoryRepository = mockInstance(WorkflowHistoryRepository);
const logger = mockInstance(Logger); const logger = mockInstance(Logger);

View file

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

View file

@ -1,6 +1,6 @@
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { Container } from 'typedi'; import { Container } from 'typedi';
import type { INode } from 'n8n-workflow'; import type { INode, INodeTypeData } from 'n8n-workflow';
import { randomInt } from 'n8n-workflow'; import { randomInt } from 'n8n-workflow';
import type { User } from '@db/entities/User'; import type { User } from '@db/entities/User';
import { WorkflowRepository } from '@db/repositories/workflow.repository'; import { WorkflowRepository } from '@db/repositories/workflow.repository';
@ -14,7 +14,6 @@ import { mockInstance } from '../shared/mocking';
import { randomCredentialPayload as randomCred } from '../integration/shared/random'; import { randomCredentialPayload as randomCred } from '../integration/shared/random';
import * as testDb from '../integration/shared/testDb'; import * as testDb from '../integration/shared/testDb';
import type { SaveCredentialFunction } from '../integration/shared/types'; import type { SaveCredentialFunction } from '../integration/shared/types';
import { mockNodeTypesData } from '../unit/Helpers';
import { affixRoleToSaveCredential } from '../integration/shared/db/credentials'; import { affixRoleToSaveCredential } from '../integration/shared/db/credentials';
import { createOwner, createUser } from '../integration/shared/db/users'; import { createOwner, createUser } from '../integration/shared/db/users';
import { SharedCredentialsRepository } from '@/databases/repositories/sharedCredentials.repository'; import { SharedCredentialsRepository } from '@/databases/repositories/sharedCredentials.repository';
@ -25,6 +24,36 @@ import { ProjectRepository } from '@/databases/repositories/project.repository';
const ownershipService = mockInstance(OwnershipService); const ownershipService = mockInstance(OwnershipService);
function mockNodeTypesData(
nodeNames: string[],
options?: {
addTrigger?: boolean;
},
) {
return nodeNames.reduce<INodeTypeData>((acc, nodeName) => {
return (
(acc[`n8n-nodes-base.${nodeName}`] = {
sourcePath: '',
type: {
description: {
displayName: nodeName,
name: nodeName,
group: [],
description: '',
version: 1,
defaults: {},
inputs: [],
outputs: [],
properties: [],
},
trigger: options?.addTrigger ? async () => undefined : undefined,
},
}),
acc
);
}, {});
}
const createWorkflow = async (nodes: INode[], workflowOwner?: User): Promise<WorkflowEntity> => { const createWorkflow = async (nodes: INode[], workflowOwner?: User): Promise<WorkflowEntity> => {
const workflowDetails = { const workflowDetails = {
id: randomInt(1, 10).toString(), id: randomInt(1, 10).toString(),

View file

@ -11,7 +11,7 @@ import { WaitingWebhooks } from '@/WaitingWebhooks';
import { WaitingForms } from '@/WaitingForms'; import { WaitingForms } from '@/WaitingForms';
import type { IResponseCallbackData } from '@/Interfaces'; import type { IResponseCallbackData } from '@/Interfaces';
import { mockInstance } from '../shared/mocking'; import { mockInstance } from '@test/mocking';
import { GlobalConfig } from '@n8n/config'; import { GlobalConfig } from '@n8n/config';
import Container from 'typedi'; import Container from 'typedi';

View file

@ -0,0 +1,6 @@
/**
* Ensure all pending promises settle. The promise's `resolve` is placed in
* the macrotask queue and so called at the next iteration of the event loop
* after all promises in the microtask queue have settled first.
*/
export const flushPromises = async () => await new Promise(setImmediate);

View file

@ -8,7 +8,7 @@ import {
randomEmail, randomEmail,
randomName, randomName,
uniqueId, uniqueId,
} from '../../integration/shared/random'; } from '../integration/shared/random';
export const mockCredential = (): CredentialsEntity => export const mockCredential = (): CredentialsEntity =>
Object.assign(new CredentialsEntity(), randomCredentialPayload()); Object.assign(new CredentialsEntity(), randomCredentialPayload());

View file

@ -1,38 +0,0 @@
import type { INodeTypeData } from 'n8n-workflow';
/**
* Ensure all pending promises settle. The promise's `resolve` is placed in
* the macrotask queue and so called at the next iteration of the event loop
* after all promises in the microtask queue have settled first.
*/
export const flushPromises = async () => await new Promise(setImmediate);
export function mockNodeTypesData(
nodeNames: string[],
options?: {
addTrigger?: boolean;
},
) {
return nodeNames.reduce<INodeTypeData>((acc, nodeName) => {
return (
(acc[`n8n-nodes-base.${nodeName}`] = {
sourcePath: '',
type: {
description: {
displayName: nodeName,
name: nodeName,
group: [],
description: '',
version: 1,
defaults: {},
inputs: [],
outputs: [],
properties: [],
},
trigger: options?.addTrigger ? async () => undefined : undefined,
},
}),
acc
);
}, {});
}