diff --git a/packages/@n8n_io/eslint-config/base.js b/packages/@n8n_io/eslint-config/base.js index 0958755fc..700bc8c77 100644 --- a/packages/@n8n_io/eslint-config/base.js +++ b/packages/@n8n_io/eslint-config/base.js @@ -459,7 +459,6 @@ const config = (module.exports = { '@typescript-eslint/naming-convention': 'off', '@typescript-eslint/no-duplicate-imports': 'off', '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-floating-promises': 'off', '@typescript-eslint/no-loop-func': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-shadow': 'off', diff --git a/packages/cli/src/ActiveWorkflowRunner.ts b/packages/cli/src/ActiveWorkflowRunner.ts index 1de34856d..58a08fba8 100644 --- a/packages/cli/src/ActiveWorkflowRunner.ts +++ b/packages/cli/src/ActiveWorkflowRunner.ts @@ -3,7 +3,6 @@ /* eslint-disable no-param-reassign */ /* eslint-disable no-await-in-loop */ /* eslint-disable no-restricted-syntax */ -/* eslint-disable @typescript-eslint/no-floating-promises */ /* eslint-disable @typescript-eslint/no-shadow */ /* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ @@ -306,8 +305,7 @@ export class ActiveWorkflowRunner { return new Promise((resolve, reject) => { const executionMode = 'webhook'; - // @ts-ignore - WebhookHelpers.executeWebhook( + void WebhookHelpers.executeWebhook( workflow, webhookData, workflowData, @@ -627,7 +625,7 @@ export class ActiveWorkflowRunner { ): void => { // eslint-disable-next-line @typescript-eslint/restrict-template-expressions Logger.debug(`Received event to trigger execution for workflow "${workflow.name}"`); - WorkflowHelpers.saveStaticData(workflow); + void WorkflowHelpers.saveStaticData(workflow); const executePromise = this.runWorkflow( workflowData, node, @@ -638,14 +636,14 @@ export class ActiveWorkflowRunner { ); if (donePromise) { - executePromise.then((executionId) => { + void executePromise.then((executionId) => { this.activeExecutions .getPostExecutePromise(executionId) .then(donePromise.resolve) .catch(donePromise.reject); }); } else { - executePromise.catch(Logger.error); + void executePromise.catch(Logger.error); } }; @@ -684,7 +682,7 @@ export class ActiveWorkflowRunner { ): void => { // eslint-disable-next-line @typescript-eslint/restrict-template-expressions Logger.debug(`Received trigger for workflow "${workflow.name}"`); - WorkflowHelpers.saveStaticData(workflow); + void WorkflowHelpers.saveStaticData(workflow); // eslint-disable-next-line id-denylist const executePromise = this.runWorkflow( workflowData, @@ -696,7 +694,7 @@ export class ActiveWorkflowRunner { ); if (donePromise) { - executePromise.then((executionId) => { + void executePromise.then((executionId) => { this.activeExecutions .getPostExecutePromise(executionId) .then(donePromise.resolve) diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index 6ad8ac7da..da4535ba4 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -552,12 +552,12 @@ export class Server extends AbstractServer { // Check for basic auth credentials if activated if (config.getEnv('security.basicAuth.active')) { - await setupBasicAuth(this.app, config, authIgnoreRegex); + setupBasicAuth(this.app, config, authIgnoreRegex); } // Check for and validate JWT if configured if (config.getEnv('security.jwtAuth.active')) { - await setupExternalJWTAuth(this.app, config, authIgnoreRegex); + setupExternalJWTAuth(this.app, config, authIgnoreRegex); } // ---------------------------------------- diff --git a/packages/cli/src/TestWebhooks.ts b/packages/cli/src/TestWebhooks.ts index d509a1c03..c9a36e9f2 100644 --- a/packages/cli/src/TestWebhooks.ts +++ b/packages/cli/src/TestWebhooks.ts @@ -272,8 +272,7 @@ export class TestWebhooks { if (!foundWebhook) { // As it removes all webhooks of the workflow execute only once - // eslint-disable-next-line @typescript-eslint/no-floating-promises - activeWebhooks.removeWorkflow(workflow); + void activeWebhooks.removeWorkflow(workflow); } foundWebhook = true; diff --git a/packages/cli/src/WaitTracker.ts b/packages/cli/src/WaitTracker.ts index e04daee12..91e1051b3 100644 --- a/packages/cli/src/WaitTracker.ts +++ b/packages/cli/src/WaitTracker.ts @@ -3,8 +3,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/restrict-template-expressions */ -/* eslint-disable @typescript-eslint/no-floating-promises */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars import { ErrorReporterProxy as ErrorReporter, LoggerProxy as Logger, @@ -40,10 +38,10 @@ export class WaitTracker { constructor() { // Poll every 60 seconds a list of upcoming executions this.mainTimer = setInterval(() => { - this.getWaitingExecutions(); + void this.getWaitingExecutions(); }, 60000); - this.getWaitingExecutions(); + void this.getWaitingExecutions(); } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types diff --git a/packages/cli/src/WaitingWebhooks.ts b/packages/cli/src/WaitingWebhooks.ts index f5e9ac634..e5f8497b4 100644 --- a/packages/cli/src/WaitingWebhooks.ts +++ b/packages/cli/src/WaitingWebhooks.ts @@ -130,8 +130,7 @@ export class WaitingWebhooks { return new Promise((resolve, reject) => { const executionMode = 'webhook'; - // eslint-disable-next-line @typescript-eslint/no-floating-promises - WebhookHelpers.executeWebhook( + void WebhookHelpers.executeWebhook( workflow, webhookData, workflowData as IWorkflowDb, diff --git a/packages/cli/src/WorkflowRunner.ts b/packages/cli/src/WorkflowRunner.ts index c785a2fa2..58390f495 100644 --- a/packages/cli/src/WorkflowRunner.ts +++ b/packages/cli/src/WorkflowRunner.ts @@ -5,7 +5,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/no-shadow */ -/* eslint-disable @typescript-eslint/no-floating-promises */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/prefer-optional-chain */ /* eslint-disable no-param-reassign */ @@ -75,8 +74,7 @@ export class WorkflowRunner { * The process did send a hook message so execute the appropriate hook */ processHookMessage(workflowHooks: WorkflowHooks, hookData: IProcessMessageDataHook) { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - workflowHooks.executeHookFunctions(hookData.hook, hookData.parameters); + void workflowHooks.executeHookFunctions(hookData.hook, hookData.parameters); } /** @@ -305,11 +303,8 @@ export class WorkflowRunner { error, error.node, ); - additionalData.hooks - .executeHookFunctions('workflowExecuteAfter', [failedExecution]) - .then(() => { - this.activeExecutions.remove(executionId, failedExecution); - }); + await additionalData.hooks.executeHookFunctions('workflowExecuteAfter', [failedExecution]); + this.activeExecutions.remove(executionId, failedExecution); return executionId; } @@ -382,7 +377,7 @@ export class WorkflowRunner { if (workflowTimeout > 0) { const timeout = Math.min(workflowTimeout, config.getEnv('executions.maxTimeout')) * 1000; // as seconds executionTimeout = setTimeout(() => { - this.activeExecutions.stopExecution(executionId, 'timeout'); + void this.activeExecutions.stopExecution(executionId, 'timeout'); }, timeout); } @@ -395,15 +390,15 @@ export class WorkflowRunner { fullRunData.status = this.activeExecutions.getStatus(executionId); this.activeExecutions.remove(executionId, fullRunData); }) - .catch((error) => { + .catch(async (error) => this.processError( error, new Date(), data.executionMode, executionId, additionalData.hooks, - ); - }); + ), + ); } catch (error) { await this.processError( error, @@ -467,7 +462,7 @@ export class WorkflowRunner { // Normally also workflow should be supplied here but as it only used for sending // data to editor-UI is not needed. - hooks.executeHookFunctions('workflowExecuteBefore', []); + await hooks.executeHookFunctions('workflowExecuteBefore', []); } catch (error) { // We use "getWorkflowHooksWorkerExecuter" as "getWorkflowHooksWorkerMain" does not contain the // "workflowExecuteAfter" which we require. @@ -585,7 +580,7 @@ export class WorkflowRunner { this.activeExecutions.remove(executionId, runData); // Normally also static data should be supplied here but as it only used for sending // data to editor-UI is not needed. - hooks.executeHookFunctions('workflowExecuteAfter', [runData]); + await hooks.executeHookFunctions('workflowExecuteAfter', [runData]); try { // Check if this execution data has to be removed from database // based on workflow settings. @@ -668,7 +663,7 @@ export class WorkflowRunner { let workflowTimeout = workflowSettings.executionTimeout ?? config.getEnv('executions.timeout'); // initialize with default const processTimeoutFunction = (timeout: number) => { - this.activeExecutions.stopExecution(executionId, 'timeout'); + void this.activeExecutions.stopExecution(executionId, 'timeout'); executionTimeout = setTimeout(() => subprocess.kill(), Math.max(timeout * 0.2, 5000)); // minimum 5 seconds }; @@ -732,7 +727,7 @@ export class WorkflowRunner { const timeoutError = new WorkflowOperationError('Workflow execution timed out!'); // No need to add hook here as the subprocess takes care of calling the hooks - this.processError(timeoutError, startedAt, data.executionMode, executionId); + await this.processError(timeoutError, startedAt, data.executionMode, executionId); } else if (message.type === 'startExecution') { const executionId = await this.activeExecutions.add(message.data.runData); childExecutionIds.push(executionId); diff --git a/packages/cli/src/WorkflowRunnerProcess.ts b/packages/cli/src/WorkflowRunnerProcess.ts index 0e4bb0813..6beba9bcd 100644 --- a/packages/cli/src/WorkflowRunnerProcess.ts +++ b/packages/cli/src/WorkflowRunnerProcess.ts @@ -497,8 +497,7 @@ process.on('message', async (message: IProcessMessage) => { status: 'canceled', }; - // eslint-disable-next-line @typescript-eslint/no-floating-promises - workflowRunner.sendHookToParentProcess('workflowExecuteAfter', [runData]); + await workflowRunner.sendHookToParentProcess('workflowExecuteAfter', [runData]); } await sendToParentProcess(message.type === 'timeout' ? message.type : 'end', { diff --git a/packages/cli/src/commands/start.ts b/packages/cli/src/commands/start.ts index 82640335c..30f76cf72 100644 --- a/packages/cli/src/commands/start.ts +++ b/packages/cli/src/commands/start.ts @@ -282,7 +282,6 @@ export class Start extends BaseCommand { if (dbType === 'sqlite') { const shouldRunVacuum = config.getEnv('database.sqlite.executeVacuumOnStartup'); if (shouldRunVacuum) { - // eslint-disable-next-line @typescript-eslint/no-floating-promises await Db.collections.Execution.query('VACUUM;'); } } @@ -360,8 +359,7 @@ export class Start extends BaseCommand { this.openBrowser(); } else if (key.charCodeAt(0) === 3) { // Ctrl + c got pressed - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.stopProcess(); + void this.stopProcess(); } else { // When anything else got pressed, record it and send it on enter into the child process // eslint-disable-next-line no-lonely-if diff --git a/packages/cli/src/commands/worker.ts b/packages/cli/src/commands/worker.ts index 5463eca9f..e51619e13 100644 --- a/packages/cli/src/commands/worker.ts +++ b/packages/cli/src/commands/worker.ts @@ -51,8 +51,7 @@ export class Worker extends BaseCommand { LoggerProxy.info('Stopping n8n...'); // Stop accepting new jobs - // eslint-disable-next-line @typescript-eslint/no-floating-promises - Worker.jobQueue.pause(true); + await Worker.jobQueue.pause(true); try { await this.externalHooks.run('n8n.stop', []); @@ -239,8 +238,9 @@ export class Worker extends BaseCommand { const queue = Container.get(Queue); await queue.init(); Worker.jobQueue = queue.getBullObjectInstance(); - // eslint-disable-next-line @typescript-eslint/no-floating-promises - Worker.jobQueue.process(flags.concurrency, async (job) => this.runJob(job, this.nodeTypes)); + void Worker.jobQueue.process(flags.concurrency, async (job) => + this.runJob(job, this.nodeTypes), + ); this.logger.info('\nn8n worker is now ready'); this.logger.info(` * Version: ${N8N_VERSION}`); diff --git a/packages/cli/src/middlewares/basicAuth.ts b/packages/cli/src/middlewares/basicAuth.ts index 7e41972fe..bdf28b5a0 100644 --- a/packages/cli/src/middlewares/basicAuth.ts +++ b/packages/cli/src/middlewares/basicAuth.ts @@ -6,7 +6,7 @@ import { compare } from 'bcryptjs'; import type { Config } from '@/config'; import { basicAuthAuthorizationError } from '@/ResponseHelper'; -export const setupBasicAuth = async (app: Application, config: Config, authIgnoreRegex: RegExp) => { +export const setupBasicAuth = (app: Application, config: Config, authIgnoreRegex: RegExp) => { const basicAuthUser = config.getEnv('security.basicAuth.user'); if (basicAuthUser === '') { throw new Error('Basic auth is activated but no user got defined. Please set one!'); diff --git a/packages/cli/src/middlewares/externalJWTAuth.ts b/packages/cli/src/middlewares/externalJWTAuth.ts index 91f622312..8d769933b 100644 --- a/packages/cli/src/middlewares/externalJWTAuth.ts +++ b/packages/cli/src/middlewares/externalJWTAuth.ts @@ -4,11 +4,7 @@ import jwks from 'jwks-rsa'; import type { Config } from '@/config'; import { jwtAuthAuthorizationError } from '@/ResponseHelper'; -export const setupExternalJWTAuth = async ( - app: Application, - config: Config, - authIgnoreRegex: RegExp, -) => { +export const setupExternalJWTAuth = (app: Application, config: Config, authIgnoreRegex: RegExp) => { const jwtAuthHeader = config.getEnv('security.jwtAuth.jwtHeader'); if (jwtAuthHeader === '') { throw new Error('JWT auth is activated but no request header was defined. Please set one!'); diff --git a/packages/cli/test/integration/credentials.ee.test.ts b/packages/cli/test/integration/credentials.ee.test.ts index 61409984a..344e01887 100644 --- a/packages/cli/test/integration/credentials.ee.test.ts +++ b/packages/cli/test/integration/credentials.ee.test.ts @@ -25,7 +25,7 @@ let sharingSpy: jest.SpyInstance; beforeAll(async () => { const app = await utils.initTestServer({ endpointGroups: ['credentials'] }); - utils.initConfigFile(); + await utils.initConfigFile(); const globalOwnerRole = await testDb.getGlobalOwnerRole(); globalMemberRole = await testDb.getGlobalMemberRole(); diff --git a/packages/cli/test/integration/credentials.test.ts b/packages/cli/test/integration/credentials.test.ts index 3f5b7e74a..597f4528e 100644 --- a/packages/cli/test/integration/credentials.test.ts +++ b/packages/cli/test/integration/credentials.test.ts @@ -31,7 +31,7 @@ let authAgent: AuthAgent; beforeAll(async () => { app = await utils.initTestServer({ endpointGroups: ['credentials'] }); - utils.initConfigFile(); + await utils.initConfigFile(); globalOwnerRole = await testDb.getGlobalOwnerRole(); globalMemberRole = await testDb.getGlobalMemberRole(); diff --git a/packages/cli/test/integration/eventbus.test.ts b/packages/cli/test/integration/eventbus.test.ts index 8c0b9b86e..62106557f 100644 --- a/packages/cli/test/integration/eventbus.test.ts +++ b/packages/cli/test/integration/eventbus.test.ts @@ -103,7 +103,7 @@ beforeAll(async () => { mockedSyslog.createClient.mockImplementation(() => new syslog.Client()); - utils.initConfigFile(); + await utils.initConfigFile(); config.set('eventBus.logWriter.logBaseName', 'n8n-test-logwriter'); config.set('eventBus.logWriter.keepLogCount', 1); config.set('userManagement.disabled', false); diff --git a/packages/cli/test/integration/ldap/ldap.api.test.ts b/packages/cli/test/integration/ldap/ldap.api.test.ts index da1e5de44..0e9688c63 100644 --- a/packages/cli/test/integration/ldap/ldap.api.test.ts +++ b/packages/cli/test/integration/ldap/ldap.api.test.ts @@ -58,7 +58,7 @@ beforeAll(async () => { defaultLdapConfig.bindingAdminPassword, ); - utils.initConfigFile(); + await utils.initConfigFile(); await setCurrentAuthenticationMethod('email'); }); diff --git a/packages/cli/test/integration/nodes.api.test.ts b/packages/cli/test/integration/nodes.api.test.ts index fb6166bd9..c22b43494 100644 --- a/packages/cli/test/integration/nodes.api.test.ts +++ b/packages/cli/test/integration/nodes.api.test.ts @@ -54,7 +54,7 @@ beforeAll(async () => { ownerShell = await testDb.createUserShell(globalOwnerRole); authOwnerShellAgent = utils.createAuthAgent(app)(ownerShell); - utils.initConfigFile(); + await utils.initConfigFile(); }); beforeEach(async () => { diff --git a/packages/cli/test/integration/publicApi/credentials.test.ts b/packages/cli/test/integration/publicApi/credentials.test.ts index a9754ceb3..23f52c294 100644 --- a/packages/cli/test/integration/publicApi/credentials.test.ts +++ b/packages/cli/test/integration/publicApi/credentials.test.ts @@ -25,7 +25,7 @@ beforeAll(async () => { enablePublicAPI: true, }); - utils.initConfigFile(); + await utils.initConfigFile(); const [globalOwnerRole, fetchedGlobalMemberRole, _, fetchedCredentialOwnerRole] = await testDb.getAllRoles(); @@ -51,7 +51,7 @@ beforeAll(async () => { saveCredential = testDb.affixRoleToSaveCredential(credentialOwnerRole); - utils.initCredentialsTypes(); + await utils.initCredentialsTypes(); }); beforeEach(async () => { diff --git a/packages/cli/test/integration/publicApi/executions.test.ts b/packages/cli/test/integration/publicApi/executions.test.ts index d71e0aa2e..8e00d4699 100644 --- a/packages/cli/test/integration/publicApi/executions.test.ts +++ b/packages/cli/test/integration/publicApi/executions.test.ts @@ -81,7 +81,7 @@ afterAll(async () => { const testWithAPIKey = (method: 'get' | 'post' | 'put' | 'delete', url: string, apiKey: string | null) => async () => { - authOwnerAgent.set({ 'X-N8N-API-KEY': apiKey }); + void authOwnerAgent.set({ 'X-N8N-API-KEY': apiKey }); const response = await authOwnerAgent[method](url); expect(response.statusCode).toBe(401); }; diff --git a/packages/cli/test/integration/publicApi/workflows.test.ts b/packages/cli/test/integration/publicApi/workflows.test.ts index c730cd07c..1dd63488d 100644 --- a/packages/cli/test/integration/publicApi/workflows.test.ts +++ b/packages/cli/test/integration/publicApi/workflows.test.ts @@ -40,7 +40,7 @@ beforeAll(async () => { apiKey: randomApiKey(), }); - utils.initConfigFile(); + await utils.initConfigFile(); await utils.initNodeTypes(); workflowRunner = await utils.initActiveWorkflowRunner(); }); @@ -76,7 +76,7 @@ afterAll(async () => { const testWithAPIKey = (method: 'get' | 'post' | 'put' | 'delete', url: string, apiKey: string | null) => async () => { - authOwnerAgent.set({ 'X-N8N-API-KEY': apiKey }); + void authOwnerAgent.set({ 'X-N8N-API-KEY': apiKey }); const response = await authOwnerAgent[method](url); expect(response.statusCode).toBe(401); }; diff --git a/packages/cli/test/integration/shared/utils.ts b/packages/cli/test/integration/shared/utils.ts index 8ae489a25..a3bd47691 100644 --- a/packages/cli/test/integration/shared/utils.ts +++ b/packages/cli/test/integration/shared/utils.ts @@ -295,7 +295,7 @@ const classifyEndpointGroups = (endpointGroups: EndpointGroup[]) => { */ export async function initActiveWorkflowRunner(): Promise { const workflowRunner = Container.get(ActiveWorkflowRunner); - workflowRunner.init(); + await workflowRunner.init(); return workflowRunner; } @@ -654,12 +654,12 @@ export async function initBinaryManager() { /** * Initialize a user settings config file if non-existent. */ -export function initConfigFile() { +export async function initConfigFile() { const settingsPath = UserSettings.getUserSettingsPath(); if (!existsSync(settingsPath)) { const userSettings = { encryptionKey: randomBytes(24).toString('base64') }; - UserSettings.writeUserSettings(userSettings, settingsPath); + await UserSettings.writeUserSettings(userSettings, settingsPath); } } @@ -677,7 +677,7 @@ export function createAgent( const agent = request.agent(app); if (options?.apiPath === undefined || options?.apiPath === 'internal') { - agent.use(prefix(REST_PATH_SEGMENT)); + void agent.use(prefix(REST_PATH_SEGMENT)); if (options?.auth && options?.user) { const { token } = issueJWT(options.user); agent.jar.setCookie(`${AUTH_COOKIE_NAME}=${token}`); @@ -685,10 +685,10 @@ export function createAgent( } if (options?.apiPath === 'public') { - agent.use(prefix(`${PUBLIC_API_REST_PATH_SEGMENT}/v${options?.version}`)); + void agent.use(prefix(`${PUBLIC_API_REST_PATH_SEGMENT}/v${options?.version}`)); if (options?.auth && options?.user.apiKey) { - agent.set({ 'X-N8N-API-KEY': options.user.apiKey }); + void agent.set({ 'X-N8N-API-KEY': options.user.apiKey }); } } diff --git a/packages/cli/test/integration/users.api.test.ts b/packages/cli/test/integration/users.api.test.ts index 3e3fe82db..b600fd838 100644 --- a/packages/cli/test/integration/users.api.test.ts +++ b/packages/cli/test/integration/users.api.test.ts @@ -514,7 +514,7 @@ describe('UserManagementMailer expect NodeMailer.verifyConnection', () => { test('not be called when SMTP not set up', async () => { const userManagementMailer = new UserManagementMailer(); // NodeMailer.verifyConnection gets called only explicitly - expect(async () => userManagementMailer.verifyConnection()).rejects.toThrow(); + await expect(async () => userManagementMailer.verifyConnection()).rejects.toThrow(); expect(NodeMailer.prototype.verifyConnection).toHaveBeenCalledTimes(0); }); diff --git a/packages/cli/test/integration/variables.test.ts b/packages/cli/test/integration/variables.test.ts index d97df3e32..abe70572a 100644 --- a/packages/cli/test/integration/variables.test.ts +++ b/packages/cli/test/integration/variables.test.ts @@ -21,7 +21,7 @@ const licenseLike = { beforeAll(async () => { app = await utils.initTestServer({ endpointGroups: ['variables'] }); - utils.initConfigFile(); + await utils.initConfigFile(); utils.mockInstance(License, licenseLike); ownerUser = await testDb.createOwner(); diff --git a/packages/cli/test/unit/ActiveExecutions.test.ts b/packages/cli/test/unit/ActiveExecutions.test.ts index c635fe7d2..db2e502c7 100644 --- a/packages/cli/test/unit/ActiveExecutions.test.ts +++ b/packages/cli/test/unit/ActiveExecutions.test.ts @@ -3,7 +3,7 @@ import { ActiveExecutions } from '@/ActiveExecutions'; import { mocked } from 'jest-mock'; import PCancelable from 'p-cancelable'; import { v4 as uuid } from 'uuid'; -import type { IDeferredPromise, IExecuteResponsePromiseData, IRun } from 'n8n-workflow'; +import type { IExecuteResponsePromiseData, IRun } from 'n8n-workflow'; import { createDeferredPromise } from 'n8n-workflow'; import type { IWorkflowExecutionDataProcess } from '@/Interfaces'; @@ -86,7 +86,7 @@ describe('ActiveExecutions', () => { const fakeResponse = { data: { resultData: { runData: {} } } }; activeExecutions.resolveResponsePromise(FAKE_EXECUTION_ID, fakeResponse); - expect(deferredPromise.promise()).resolves.toEqual(fakeResponse); + await expect(deferredPromise.promise()).resolves.toEqual(fakeResponse); }); test('Should remove an existing execution', async () => { @@ -108,11 +108,11 @@ describe('ActiveExecutions', () => { const fakeOutput = mockFullRunData(); activeExecutions.remove(executionId, fakeOutput); - expect(postExecutePromise).resolves.toEqual(fakeOutput); + await expect(postExecutePromise).resolves.toEqual(fakeOutput); }); test('Should throw error when trying to create a promise with invalid execution', async () => { - expect(activeExecutions.getPostExecutePromise(FAKE_EXECUTION_ID)).rejects.toThrow(); + await expect(activeExecutions.getPostExecutePromise(FAKE_EXECUTION_ID)).rejects.toThrow(); }); test('Should call function to cancel execution when asked to stop', async () => { @@ -122,7 +122,7 @@ describe('ActiveExecutions', () => { const cancellablePromise = mockCancelablePromise(); cancellablePromise.cancel = cancelExecution; activeExecutions.attachWorkflowExecution(executionId, cancellablePromise); - activeExecutions.stopExecution(executionId); + void activeExecutions.stopExecution(executionId); expect(cancelExecution).toHaveBeenCalledTimes(1); }); @@ -156,12 +156,7 @@ function mockFullRunData(): IRun { }; } -async function mockCancelablePromise(): PCancelable { - return new PCancelable(async (resolve) => { - resolve(); - }); -} - -async function mockDeferredPromise(): Promise> { - return createDeferredPromise(); -} +// eslint-disable-next-line @typescript-eslint/promise-function-async +const mockCancelablePromise = () => new PCancelable((resolve) => resolve()); +// eslint-disable-next-line @typescript-eslint/promise-function-async +const mockDeferredPromise = () => createDeferredPromise(); diff --git a/packages/cli/test/unit/PermissionChecker.test.ts b/packages/cli/test/unit/PermissionChecker.test.ts index c69bc597a..44127f50a 100644 --- a/packages/cli/test/unit/PermissionChecker.test.ts +++ b/packages/cli/test/unit/PermissionChecker.test.ts @@ -213,7 +213,7 @@ describe('PermissionChecker.check()', () => { const workflow = new Workflow(workflowDetails); - expect(PermissionChecker.check(workflow, member.id)).rejects.toThrow(); + await expect(PermissionChecker.check(workflow, member.id)).rejects.toThrow(); }); }); @@ -274,11 +274,7 @@ describe('PermissionChecker.checkSubworkflowExecutePolicy', () => { // Check description try { - await PermissionChecker.checkSubworkflowExecutePolicy( - subworkflow, - subworkflow.settings.userId as string, - 'abcde', - ); + await PermissionChecker.checkSubworkflowExecutePolicy(subworkflow, '', 'abcde'); } catch (error) { if (error instanceof SubworkflowOperationError) { expect(error.description).toBe( diff --git a/packages/cli/test/unit/PostHog.test.ts b/packages/cli/test/unit/PostHog.test.ts index 978108c39..901f39c39 100644 --- a/packages/cli/test/unit/PostHog.test.ts +++ b/packages/cli/test/unit/PostHog.test.ts @@ -73,7 +73,7 @@ describe('PostHog', () => { const ph = new PostHogClient(); await ph.init(instanceId); - ph.getFeatureFlags({ + await ph.getFeatureFlags({ id: userId, createdAt, }); diff --git a/packages/cli/test/unit/Telemetry.test.ts b/packages/cli/test/unit/Telemetry.test.ts index 4b58caf99..988571e51 100644 --- a/packages/cli/test/unit/Telemetry.test.ts +++ b/packages/cli/test/unit/Telemetry.test.ts @@ -1,3 +1,4 @@ +import type RudderStack from '@rudderstack/rudder-sdk-node'; import { Telemetry } from '@/telemetry'; import config from '@/config'; import { flushPromises } from './Helpers'; @@ -18,8 +19,13 @@ describe('Telemetry', () => { let startPulseSpy: jest.SpyInstance; const spyTrack = jest.spyOn(Telemetry.prototype, 'track').mockName('track'); + const mockRudderStack: Pick = { + flush: (resolve) => resolve?.(), + identify: (data, resolve) => resolve?.(), + track: (data, resolve) => resolve?.(), + }; + let telemetry: Telemetry; - const n8nVersion = '0.0.0'; const instanceId = 'Telemetry unit test'; const testDateTime = new Date('2022-01-01 00:00:00'); @@ -33,35 +39,31 @@ describe('Telemetry', () => { config.set('deployment.type', 'n8n-testing'); }); - afterAll(() => { + afterAll(async () => { jest.clearAllTimers(); jest.useRealTimers(); startPulseSpy.mockRestore(); - telemetry.trackN8nStop(); + await telemetry.trackN8nStop(); }); - beforeEach(() => { + beforeEach(async () => { spyTrack.mockClear(); const postHog = new PostHogClient(); - postHog.init(instanceId); + await postHog.init(instanceId); telemetry = new Telemetry(postHog, mock()); telemetry.setInstanceId(instanceId); - (telemetry as any).rudderStack = { - flush: () => {}, - identify: () => {}, - track: () => {}, - }; + (telemetry as any).rudderStack = mockRudderStack; }); - afterEach(() => { - telemetry.trackN8nStop(); + afterEach(async () => { + await telemetry.trackN8nStop(); }); describe('trackN8nStop', () => { - test('should call track method', () => { - telemetry.trackN8nStop(); + test('should call track method', async () => { + await telemetry.trackN8nStop(); expect(spyTrack).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/cli/test/unit/WorkflowCredentials.test.ts b/packages/cli/test/unit/WorkflowCredentials.test.ts index 78afe95a6..5f922adfd 100644 --- a/packages/cli/test/unit/WorkflowCredentials.test.ts +++ b/packages/cli/test/unit/WorkflowCredentials.test.ts @@ -48,21 +48,21 @@ describe('WorkflowCredentials', () => { jest.clearAllMocks(); }); - test('Should return an error if any node has no credential ID', () => { + 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.`, ); - expect(WorkflowCredentials([noIdNode])).rejects.toEqual(expectedError); + await expect(WorkflowCredentials([noIdNode])).rejects.toEqual(expectedError); expect(mocked(Db.collections.Credentials.findOneBy)).toHaveBeenCalledTimes(0); }); - test('Should return an error if credentials cannot be found in the DB', () => { + test('Should return an error if credentials cannot be found in the DB', async () => { const credentials = notFoundNode.credentials!.test; const expectedError = new Error( `Could not find credentials for type "test" with ID "${credentials.id}".`, ); - expect(WorkflowCredentials([notFoundNode])).rejects.toEqual(expectedError); + await expect(WorkflowCredentials([notFoundNode])).rejects.toEqual(expectedError); expect(mocked(Db.collections.Credentials.findOneBy)).toHaveBeenCalledTimes(1); }); diff --git a/packages/cli/test/unit/controllers/me.controller.test.ts b/packages/cli/test/unit/controllers/me.controller.test.ts index 8a622c67e..36299ab86 100644 --- a/packages/cli/test/unit/controllers/me.controller.test.ts +++ b/packages/cli/test/unit/controllers/me.controller.test.ts @@ -26,14 +26,14 @@ describe('MeController', () => { describe('updateCurrentUser', () => { it('should throw BadRequestError if email is missing in the payload', async () => { const req = mock({}); - expect(controller.updateCurrentUser(req, mock())).rejects.toThrowError( + await expect(controller.updateCurrentUser(req, mock())).rejects.toThrowError( new BadRequestError('Email is mandatory'), ); }); it('should throw BadRequestError if email is invalid', async () => { const req = mock({ body: { email: 'invalid-email' } }); - expect(controller.updateCurrentUser(req, mock())).rejects.toThrowError( + await expect(controller.updateCurrentUser(req, mock())).rejects.toThrowError( new BadRequestError('Invalid email address'), ); }); @@ -103,7 +103,7 @@ describe('MeController', () => { user: mock({ password: undefined }), body: { currentPassword: '', newPassword: '' }, }); - expect(controller.updatePassword(req, mock())).rejects.toThrowError( + await expect(controller.updatePassword(req, mock())).rejects.toThrowError( new BadRequestError('Requesting user not set up.'), ); }); @@ -113,7 +113,7 @@ describe('MeController', () => { user: mock({ password: passwordHash }), body: { currentPassword: 'not_old_password', newPassword: '' }, }); - expect(controller.updatePassword(req, mock())).rejects.toThrowError( + await expect(controller.updatePassword(req, mock())).rejects.toThrowError( new BadRequestError('Provided current password is incorrect.'), ); }); @@ -125,7 +125,7 @@ describe('MeController', () => { user: mock({ password: passwordHash }), body: { currentPassword: 'old_password', newPassword }, }); - expect(controller.updatePassword(req, mock())).rejects.toThrowError( + await expect(controller.updatePassword(req, mock())).rejects.toThrowError( new BadRequestError(errorMessage), ); }); diff --git a/packages/cli/test/unit/controllers/owner.controller.test.ts b/packages/cli/test/unit/controllers/owner.controller.test.ts index 0ef8036e0..ad18cf2dd 100644 --- a/packages/cli/test/unit/controllers/owner.controller.test.ts +++ b/packages/cli/test/unit/controllers/owner.controller.test.ts @@ -40,7 +40,7 @@ describe('OwnerController', () => { describe('preSetup', () => { it('should throw a BadRequestError if the instance owner is already setup', async () => { config.getEnv.calledWith('userManagement.isInstanceOwnerSetUp').mockReturnValue(true); - expect(controller.preSetup()).rejects.toThrowError( + await expect(controller.preSetup()).rejects.toThrowError( new BadRequestError('Instance owner already setup'), ); }); @@ -58,7 +58,7 @@ describe('OwnerController', () => { describe('setupOwner', () => { it('should throw a BadRequestError if the instance owner is already setup', async () => { config.getEnv.calledWith('userManagement.isInstanceOwnerSetUp').mockReturnValue(true); - expect(controller.setupOwner(mock(), mock())).rejects.toThrowError( + await expect(controller.setupOwner(mock(), mock())).rejects.toThrowError( new BadRequestError('Instance owner already setup'), ); }); @@ -66,7 +66,7 @@ describe('OwnerController', () => { it('should throw a BadRequestError if the email is invalid', async () => { config.getEnv.calledWith('userManagement.isInstanceOwnerSetUp').mockReturnValue(false); const req = mock({ body: { email: 'invalid email' } }); - expect(controller.setupOwner(req, mock())).rejects.toThrowError( + await expect(controller.setupOwner(req, mock())).rejects.toThrowError( new BadRequestError('Invalid email address'), ); }); @@ -76,7 +76,7 @@ describe('OwnerController', () => { it(password, async () => { config.getEnv.calledWith('userManagement.isInstanceOwnerSetUp').mockReturnValue(false); const req = mock({ body: { email: 'valid@email.com', password } }); - expect(controller.setupOwner(req, mock())).rejects.toThrowError( + await expect(controller.setupOwner(req, mock())).rejects.toThrowError( new BadRequestError(errorMessage), ); }); @@ -88,7 +88,7 @@ describe('OwnerController', () => { const req = mock({ body: { email: 'valid@email.com', password: 'NewPassword123', firstName: '', lastName: '' }, }); - expect(controller.setupOwner(req, mock())).rejects.toThrowError( + await expect(controller.setupOwner(req, mock())).rejects.toThrowError( new BadRequestError('First and last names are mandatory'), ); }); diff --git a/packages/cli/test/unit/controllers/translation.controller.test.ts b/packages/cli/test/unit/controllers/translation.controller.test.ts index 16e9645bb..e23f196d0 100644 --- a/packages/cli/test/unit/controllers/translation.controller.test.ts +++ b/packages/cli/test/unit/controllers/translation.controller.test.ts @@ -19,7 +19,7 @@ describe('TranslationController', () => { const req = mock({ query: { credentialType } }); credentialTypes.recognizes.calledWith(credentialType).mockReturnValue(false); - expect(controller.getCredentialTranslation(req)).rejects.toThrowError( + await expect(controller.getCredentialTranslation(req)).rejects.toThrowError( new BadRequestError(`Invalid Credential type: "${credentialType}"`), ); }); diff --git a/packages/cli/test/unit/middlewares/basicAuth.test.ts b/packages/cli/test/unit/middlewares/basicAuth.test.ts index d4d952c7c..cc03b1ec6 100644 --- a/packages/cli/test/unit/middlewares/basicAuth.test.ts +++ b/packages/cli/test/unit/middlewares/basicAuth.test.ts @@ -8,7 +8,7 @@ describe('Basic Auth Middleware', () => { beforeAll(() => { app = express(); - config.set('security.basicAuth', { user: 'jim', password: 'n8n', hash: false }); + config.set('security.basicAuth', { user: 'jim', password: 'n8n', hash: false, active: true }); setupBasicAuth(app, config, new RegExp('^/skip-auth')); app.get('/test', (req, res) => res.send({ auth: true })); app.get('/skip-auth', (req, res) => res.send({ auth: false })); diff --git a/packages/cli/test/unit/repositories/role.repository.test.ts b/packages/cli/test/unit/repositories/role.repository.test.ts index 73dcc048b..e1a6a46ee 100644 --- a/packages/cli/test/unit/repositories/role.repository.test.ts +++ b/packages/cli/test/unit/repositories/role.repository.test.ts @@ -39,7 +39,7 @@ describe('RoleRepository', () => { test('should throw otherwise', async () => { entityManager.findOneOrFail.mockRejectedValueOnce(new Error()); - expect(async () => roleRepository.findRoleOrFail('global', 'owner')).rejects.toThrow(); + await expect(async () => roleRepository.findRoleOrFail('global', 'owner')).rejects.toThrow(); }); });