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] 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 ef1ffdbf2f..9d083fe308 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 03865412d0..75c2a69a38 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 f139cd4351..b5db3dc338 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