From bc5749b7ae38a4c0d092b4e55a64e9c9328db9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Fri, 22 Apr 2022 12:38:53 +0200 Subject: [PATCH 1/3] test(core): Implement timeout in SMTP tests (#3152) * :zap: Implement timeout in SMTP tests * :truck: Move timeout to constants --- .../integration/passwordReset.api.test.ts | 42 ++--- .../cli/test/integration/shared/constants.ts | 5 + .../cli/test/integration/users.api.test.ts | 151 ++++++++++-------- 3 files changed, 112 insertions(+), 86 deletions(-) diff --git a/packages/cli/test/integration/passwordReset.api.test.ts b/packages/cli/test/integration/passwordReset.api.test.ts index ef1ffdbf2f3..9d083fe3087 100644 --- a/packages/cli/test/integration/passwordReset.api.test.ts +++ b/packages/cli/test/integration/passwordReset.api.test.ts @@ -13,6 +13,7 @@ import { } from './shared/random'; import * as testDb from './shared/testDb'; import type { Role } from '../../src/databases/entities/Role'; +import { SMTP_TEST_TIMEOUT } from './shared/constants'; jest.mock('../../src/telemetry'); @@ -40,35 +41,40 @@ beforeEach(async () => { config.set('userManagement.isInstanceOwnerSetUp', true); config.set('userManagement.emails.mode', ''); - - jest.setTimeout(30000); // fake SMTP service might be slow }); afterAll(async () => { await testDb.terminate(testDbName); }); -test('POST /forgot-password should send password reset email', async () => { - const owner = await testDb.createUser({ globalRole: globalOwnerRole }); +test( + 'POST /forgot-password should send password reset email', + async () => { + const owner = await testDb.createUser({ globalRole: globalOwnerRole }); - const authlessAgent = utils.createAgent(app); - const member = await testDb.createUser({ email: 'test@test.com', globalRole: globalMemberRole }); + const authlessAgent = utils.createAgent(app); + const member = await testDb.createUser({ + email: 'test@test.com', + globalRole: globalMemberRole, + }); - await utils.configureSmtp(); + await utils.configureSmtp(); - await Promise.all( - [{ email: owner.email }, { email: member.email.toUpperCase() }].map(async (payload) => { - const response = await authlessAgent.post('/forgot-password').send(payload); + await Promise.all( + [{ email: owner.email }, { email: member.email.toUpperCase() }].map(async (payload) => { + const response = await authlessAgent.post('/forgot-password').send(payload); - expect(response.statusCode).toBe(200); - expect(response.body).toEqual({}); + expect(response.statusCode).toBe(200); + expect(response.body).toEqual({}); - const user = await Db.collections.User!.findOneOrFail({ email: payload.email }); - expect(user.resetPasswordToken).toBeDefined(); - expect(user.resetPasswordTokenExpiration).toBeGreaterThan(Math.ceil(Date.now() / 1000)); - }), - ); -}); + const user = await Db.collections.User!.findOneOrFail({ email: payload.email }); + expect(user.resetPasswordToken).toBeDefined(); + expect(user.resetPasswordTokenExpiration).toBeGreaterThan(Math.ceil(Date.now() / 1000)); + }), + ); + }, + SMTP_TEST_TIMEOUT, +); test('POST /forgot-password should fail if emailing is not set up', async () => { const owner = await testDb.createUser({ globalRole: globalOwnerRole }); diff --git a/packages/cli/test/integration/shared/constants.ts b/packages/cli/test/integration/shared/constants.ts index 03865412d0e..75c2a69a38b 100644 --- a/packages/cli/test/integration/shared/constants.ts +++ b/packages/cli/test/integration/shared/constants.ts @@ -57,3 +57,8 @@ export const BOOTSTRAP_POSTGRES_CONNECTION_NAME: Readonly = 'n8n_bs_post * for each suite test run. */ export const BOOTSTRAP_MYSQL_CONNECTION_NAME: Readonly = 'n8n_bs_mysql'; + +/** + * Timeout (in milliseconds) to account for fake SMTP service being slow to respond. + */ +export const SMTP_TEST_TIMEOUT = 30_000; diff --git a/packages/cli/test/integration/users.api.test.ts b/packages/cli/test/integration/users.api.test.ts index f139cd4351f..b5db3dc3385 100644 --- a/packages/cli/test/integration/users.api.test.ts +++ b/packages/cli/test/integration/users.api.test.ts @@ -4,7 +4,7 @@ import { v4 as uuid } from 'uuid'; import { Db } from '../../src'; import config from '../../config'; -import { SUCCESS_RESPONSE_BODY } from './shared/constants'; +import { SMTP_TEST_TIMEOUT, SUCCESS_RESPONSE_BODY } from './shared/constants'; import { randomEmail, randomValidPassword, @@ -47,8 +47,6 @@ beforeAll(async () => { utils.initTestTelemetry(); utils.initTestLogger(); - - jest.setTimeout(30000); // fake SMTP service might be slow }); beforeEach(async () => { @@ -481,91 +479,108 @@ test('POST /users should fail if user management is disabled', async () => { expect(response.statusCode).toBe(500); }); -test('POST /users should email invites and create user shells but ignore existing', async () => { - const owner = await testDb.createUser({ globalRole: globalOwnerRole }); - const member = await testDb.createUser({ globalRole: globalMemberRole }); - const memberShell = await testDb.createUserShell(globalMemberRole); - const authOwnerAgent = utils.createAgent(app, { auth: true, user: owner }); +test( + 'POST /users should email invites and create user shells but ignore existing', + async () => { + const owner = await testDb.createUser({ globalRole: globalOwnerRole }); + const member = await testDb.createUser({ globalRole: globalMemberRole }); + const memberShell = await testDb.createUserShell(globalMemberRole); + const authOwnerAgent = utils.createAgent(app, { auth: true, user: owner }); - await utils.configureSmtp(); + await utils.configureSmtp(); - const testEmails = [randomEmail(), randomEmail().toUpperCase(), memberShell.email, member.email]; + const testEmails = [ + randomEmail(), + randomEmail().toUpperCase(), + memberShell.email, + member.email, + ]; - const payload = testEmails.map((e) => ({ email: e })); + const payload = testEmails.map((e) => ({ email: e })); - const response = await authOwnerAgent.post('/users').send(payload); + const response = await authOwnerAgent.post('/users').send(payload); - expect(response.statusCode).toBe(200); + expect(response.statusCode).toBe(200); - for (const { - user: { id, email: receivedEmail }, - error, - } of response.body.data) { - expect(validator.isUUID(id)).toBe(true); - expect(id).not.toBe(member.id); + for (const { + user: { id, email: receivedEmail }, + error, + } of response.body.data) { + expect(validator.isUUID(id)).toBe(true); + expect(id).not.toBe(member.id); - const lowerCasedEmail = receivedEmail.toLowerCase(); - expect(receivedEmail).toBe(lowerCasedEmail); - expect(payload.some(({ email }) => email.toLowerCase() === lowerCasedEmail)).toBe(true); + const lowerCasedEmail = receivedEmail.toLowerCase(); + expect(receivedEmail).toBe(lowerCasedEmail); + expect(payload.some(({ email }) => email.toLowerCase() === lowerCasedEmail)).toBe(true); - if (error) { - expect(error).toBe('Email could not be sent'); + if (error) { + expect(error).toBe('Email could not be sent'); + } + + const storedUser = await Db.collections.User!.findOneOrFail(id); + const { firstName, lastName, personalizationAnswers, password, resetPasswordToken } = + storedUser; + + expect(firstName).toBeNull(); + expect(lastName).toBeNull(); + expect(personalizationAnswers).toBeNull(); + expect(password).toBeNull(); + expect(resetPasswordToken).toBeNull(); } + }, + SMTP_TEST_TIMEOUT, +); - const storedUser = await Db.collections.User!.findOneOrFail(id); - const { firstName, lastName, personalizationAnswers, password, resetPasswordToken } = - storedUser; +test( + 'POST /users should fail with invalid inputs', + async () => { + const owner = await testDb.createUser({ globalRole: globalOwnerRole }); + const authOwnerAgent = utils.createAgent(app, { auth: true, user: owner }); - expect(firstName).toBeNull(); - expect(lastName).toBeNull(); - expect(personalizationAnswers).toBeNull(); - expect(password).toBeNull(); - expect(resetPasswordToken).toBeNull(); - } -}); + await utils.configureSmtp(); -test('POST /users should fail with invalid inputs', async () => { - const owner = await testDb.createUser({ globalRole: globalOwnerRole }); - const authOwnerAgent = utils.createAgent(app, { auth: true, user: owner }); + const invalidPayloads = [ + randomEmail(), + [randomEmail()], + {}, + [{ name: randomName() }], + [{ email: randomName() }], + ]; - await utils.configureSmtp(); + await Promise.all( + invalidPayloads.map(async (invalidPayload) => { + const response = await authOwnerAgent.post('/users').send(invalidPayload); + expect(response.statusCode).toBe(400); - const invalidPayloads = [ - randomEmail(), - [randomEmail()], - {}, - [{ name: randomName() }], - [{ email: randomName() }], - ]; + const users = await Db.collections.User!.find(); + expect(users.length).toBe(1); // DB unaffected + }), + ); + }, + SMTP_TEST_TIMEOUT, +); - await Promise.all( - invalidPayloads.map(async (invalidPayload) => { - const response = await authOwnerAgent.post('/users').send(invalidPayload); - expect(response.statusCode).toBe(400); +test( + 'POST /users should ignore an empty payload', + async () => { + const owner = await testDb.createUser({ globalRole: globalOwnerRole }); + const authOwnerAgent = utils.createAgent(app, { auth: true, user: owner }); - const users = await Db.collections.User!.find(); - expect(users.length).toBe(1); // DB unaffected - }), - ); -}); + await utils.configureSmtp(); -test('POST /users should ignore an empty payload', async () => { - const owner = await testDb.createUser({ globalRole: globalOwnerRole }); - const authOwnerAgent = utils.createAgent(app, { auth: true, user: owner }); + const response = await authOwnerAgent.post('/users').send([]); - await utils.configureSmtp(); + const { data } = response.body; - const response = await authOwnerAgent.post('/users').send([]); + expect(response.statusCode).toBe(200); + expect(Array.isArray(data)).toBe(true); + expect(data.length).toBe(0); - const { data } = response.body; - - expect(response.statusCode).toBe(200); - expect(Array.isArray(data)).toBe(true); - expect(data.length).toBe(0); - - const users = await Db.collections.User!.find(); - expect(users.length).toBe(1); -}); + const users = await Db.collections.User!.find(); + expect(users.length).toBe(1); + }, + SMTP_TEST_TIMEOUT, +); // TODO: /users/:id/reinvite route tests missing From a790dcae3dec12b70df724f92e17739317261f1c Mon Sep 17 00:00:00 2001 From: Jonathan Bennetts Date: Fri, 22 Apr 2022 11:41:07 +0100 Subject: [PATCH 2/3] fix(QuickBooks Node) Fix pagination (#3169) * Fixed pagination issue * Removed unused import --- packages/nodes-base/nodes/QuickBooks/GenericFunctions.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/nodes-base/nodes/QuickBooks/GenericFunctions.ts b/packages/nodes-base/nodes/QuickBooks/GenericFunctions.ts index 3b86ec9f95c..4d51f43c9db 100644 --- a/packages/nodes-base/nodes/QuickBooks/GenericFunctions.ts +++ b/packages/nodes-base/nodes/QuickBooks/GenericFunctions.ts @@ -7,7 +7,6 @@ import { IDataObject, ILoadOptionsFunctions, INodeExecutionData, - INodeProperties, INodePropertyOptions, NodeApiError, } from 'n8n-workflow'; @@ -126,7 +125,11 @@ export async function quickBooksApiRequestAllItems( const maxResults = 1000; const returnData: IDataObject[] = []; - const maxCount = await getCount.call(this, method, endpoint, qs); + const maxCountQuery = { + query: `SELECT COUNT(*) FROM ${resource}`, + } as IDataObject; + + const maxCount = await getCount.call(this, method, endpoint, maxCountQuery); const originalQuery = qs.query as string; From 15e6d9274ad0627dd5ebc30e70757878368042bc Mon Sep 17 00:00:00 2001 From: Michael Kret <88898367+michael-radency@users.noreply.github.com> Date: Fri, 22 Apr 2022 13:45:11 +0300 Subject: [PATCH 3/3] fix(Slack Node): Fix credential test (#3151) --- packages/nodes-base/credentials/SlackApi.credentials.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nodes-base/credentials/SlackApi.credentials.ts b/packages/nodes-base/credentials/SlackApi.credentials.ts index 588c4b8cb68..ba5e451cada 100644 --- a/packages/nodes-base/credentials/SlackApi.credentials.ts +++ b/packages/nodes-base/credentials/SlackApi.credentials.ts @@ -34,8 +34,8 @@ export class SlackApi implements ICredentialType { { type: 'responseSuccessBody', properties: { - key: 'ok', - value: false, + key: 'error', + value: 'invalid_auth', message: 'Invalid access token', }, },