From 9663fb4b2b7913a97eeb02b25ef90acd040095f3 Mon Sep 17 00:00:00 2001 From: jlenon7 Date: Sat, 11 May 2024 14:36:40 +0100 Subject: [PATCH] test(helpers): add base test class --- src/helpers/queue.ts | 2 +- src/models/user.ts | 3 +- storage/queues.json | 6 +--- tests/e2e/auth.controller.test.ts | 27 +++++--------- tests/e2e/user.controller.test.ts | 59 ++++++++++++++++--------------- tests/helpers/base.e2e.test.ts | 45 +++++++++++++++++++++++ 6 files changed, 88 insertions(+), 54 deletions(-) create mode 100644 tests/helpers/base.e2e.test.ts diff --git a/src/helpers/queue.ts b/src/helpers/queue.ts index 3aa602a..fd39d46 100644 --- a/src/helpers/queue.ts +++ b/src/helpers/queue.ts @@ -15,7 +15,7 @@ class VanillaQueue { const path = Path.storage('queues.json') return new File(path, '').setContent( - JSON.stringify({ default: [], deadletter: [] }) + JSON.stringify({ default: [], deadletter: [] }, null, 2) ) } diff --git a/src/models/user.ts b/src/models/user.ts index 1257fbd..65a1514 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -66,7 +66,8 @@ export class User extends BaseModel { return { name: this.faker.person.firstName(), email: this.faker.internet.email(), - password: this.faker.internet.password() + token: this.faker.string.uuid(), + password: await bcrypt.hash('12345', 10) } } } diff --git a/storage/queues.json b/storage/queues.json index 6937488..6701659 100644 --- a/storage/queues.json +++ b/storage/queues.json @@ -1,8 +1,4 @@ { "default":[], - "deadletter":[], - "user:email":[], - "user:password":[], - "user:email:password":[], - "user:confirm":[] + "deadletter":[] } diff --git a/tests/e2e/auth.controller.test.ts b/tests/e2e/auth.controller.test.ts index 696c2ba..2f6e44f 100644 --- a/tests/e2e/auth.controller.test.ts +++ b/tests/e2e/auth.controller.test.ts @@ -1,17 +1,14 @@ import bcrypt from 'bcrypt' -import jwt from 'jsonwebtoken' -import { Uuid } from '@athenna/common' import { User } from '#src/models/user' import { Role } from '#src/models/role' -import { Config } from '@athenna/config' import { SmtpServer } from '@athenna/mail' import { Database } from '@athenna/database' import { RoleUser } from '#src/models/roleuser' import { Queue } from '#src/providers/facades/queue' -import { BaseHttpTest } from '@athenna/core/testing/BaseHttpTest' +import { BaseE2ETest } from '#tests/helpers/base.e2e.test' import { Test, type Context, AfterAll, BeforeAll } from '@athenna/test' -export default class AuthControllerTest extends BaseHttpTest { +export default class AuthControllerTest extends BaseE2ETest { @BeforeAll() public async beforeAll() { await SmtpServer.create({ disabledCommands: ['AUTH'] }).listen(5025) @@ -30,7 +27,7 @@ export default class AuthControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToGetTheAuthenticatedUserUsingMeEndpoint({ request }: Context) { - const token = await ioc.use('authService').login('customer@athenna.io', '12345') + const token = await this.getCustomerToken() const response = await request.get('/api/v1/me', { headers: { authorization: token } }) response.assertStatusCode(200) @@ -41,9 +38,7 @@ export default class AuthControllerTest extends BaseHttpTest { @Test() public async shouldThrowUnauthorizedExceptionIfAuthenticatedDontHaveRolesKey({ request }: Context) { - const token = jwt.sign({ user: { id: -1 } }, Config.get('auth.jwt.secret'), { - expiresIn: Config.get('auth.jwt.expiresIn') - }) + const token = this.createFakeToken({ user: { id: -1 } }) const response = await request.get('/api/v1/me', { headers: { authorization: token } }) @@ -55,9 +50,7 @@ export default class AuthControllerTest extends BaseHttpTest { @Test() public async shouldThrowUnauthorizedExceptionIfAuthenticatedUserCannotBeFound({ request }: Context) { - const token = jwt.sign({ user: { id: -1, roles: [] } }, Config.get('auth.jwt.secret'), { - expiresIn: Config.get('auth.jwt.expiresIn') - }) + const token = this.createFakeToken({ user: { id: -1, roles: [] } }) const response = await request.get('/api/v1/me', { headers: { authorization: token } }) @@ -136,8 +129,6 @@ export default class AuthControllerTest extends BaseHttpTest { const queue = await Queue.queue('user:confirm') - console.log(response.response) - assert.deepEqual(await queue.length(), 1) assert.isTrue(await User.exists({ email: 'test@athenna.io' })) response.assertStatusCode(201) @@ -269,7 +260,7 @@ export default class AuthControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToConfirmUserAccount({ assert, request }: Context) { - const user = await User.factory().create({ token: Uuid.generate(), emailVerifiedAt: null }) + const user = await User.factory().create({ emailVerifiedAt: null }) const response = await request.get('/api/v1/confirm/account', { query: { @@ -303,7 +294,7 @@ export default class AuthControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToConfirmUserEmail({ assert, request }: Context) { - const user = await User.factory().create({ token: Uuid.generate() }) + const user = await User.factory().create() const response = await request.get('/api/v1/confirm/email', { query: { @@ -338,7 +329,7 @@ export default class AuthControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToConfirmUserPassword({ assert, request }: Context) { - const user = await User.factory().create({ token: Uuid.generate() }) + const user = await User.factory().create() const response = await request.get('/api/v1/confirm/password', { query: { @@ -373,7 +364,7 @@ export default class AuthControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToConfirmUserEmailPassword({ assert, request }: Context) { - const user = await User.factory().create({ token: Uuid.generate() }) + const user = await User.factory().create() const response = await request.get('/api/v1/confirm/email/password', { query: { diff --git a/tests/e2e/user.controller.test.ts b/tests/e2e/user.controller.test.ts index 91b2064..acadbba 100644 --- a/tests/e2e/user.controller.test.ts +++ b/tests/e2e/user.controller.test.ts @@ -5,18 +5,19 @@ import { SmtpServer } from '@athenna/mail' import { Database } from '@athenna/database' import { RoleUser } from '#src/models/roleuser' import { Queue } from '#src/providers/facades/queue' -import { BaseHttpTest } from '@athenna/core/testing/BaseHttpTest' -import { Test, type Context, AfterEach, BeforeEach } from '@athenna/test' +import { BaseE2ETest } from '#tests/helpers/base.e2e.test' +import { Test, type Context, AfterAll, BeforeAll } from '@athenna/test' -export default class UserControllerTest extends BaseHttpTest { - @BeforeEach() - public async beforeEach() { +export default class UserControllerTest extends BaseE2ETest { + @BeforeAll() + public async beforeAll() { await SmtpServer.create({ disabledCommands: ['AUTH'] }).listen(5025) await Database.runSeeders() } - @AfterEach() - public async afterEach() { + @AfterAll() + public async afterAll() { + await Queue.truncate() await User.truncate() await Role.truncate() await RoleUser.truncate() @@ -26,7 +27,7 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToGetAllUsers({ request }: Context) { - const token = await ioc.use('authService').login('admin@athenna.io', '12345') + const token = await this.getAdminToken() const response = await request.get('/api/v1/users', { headers: { authorization: token } }) response.assertStatusCode(200) @@ -60,7 +61,7 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldThrowUnauthorizedExceptionWhenTryingToGetAllUsersAsACustomer({ request }: Context) { - const token = await ioc.use('authService').login('customer@athenna.io', '12345') + const token = await this.getCustomerToken() const response = await request.get('/api/v1/users', { headers: { authorization: token } }) response.assertStatusCode(401) @@ -72,7 +73,7 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToGetAUserById({ request }: Context) { const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('admin@athenna.io', '12345') + const token = await this.getAdminToken() const response = await request.get(`/api/v1/users/${user.id}`, { headers: { authorization: token } }) response.assertStatusCode(200) @@ -84,7 +85,7 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToGetOwnUserByIdAsACustomer({ request }: Context) { const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('customer@athenna.io', '12345') + const token = await this.getCustomerToken() const response = await request.get(`/api/v1/users/${user.id}`, { headers: { authorization: token } }) response.assertStatusCode(200) @@ -116,7 +117,7 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldThrowUnauthorizedExceptionWhenTryingToGetAUserDifferentThenYoursAsACustomer({ request }: Context) { const user = await User.find({ email: 'admin@athenna.io' }) - const token = await ioc.use('authService').login('customer@athenna.io', '12345') + const token = await this.getCustomerToken() const response = await request.get(`/api/v1/users/${user.id}`, { headers: { authorization: token } }) response.assertStatusCode(401) @@ -127,8 +128,8 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToUpdateAUserName({ assert, request }: Context) { - const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('admin@athenna.io', '12345') + const user = await this.createCustomer() + const token = await this.createToken(user) const response = await request.put(`/api/v1/users/${user.id}`, { body: { name: 'Customer Updated' }, headers: { authorization: token } @@ -139,14 +140,14 @@ export default class UserControllerTest extends BaseHttpTest { assert.deepEqual(user.name, 'Customer Updated') response.assertStatusCode(200) response.assertBodyContains({ - data: { name: 'Customer Updated', email: 'customer@athenna.io' } + data: { name: 'Customer Updated' } }) } @Test() public async shouldNotBeAbleToUpdateAUserEmailWithoutEmailConfirmation({ assert, request }: Context) { const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('admin@athenna.io', '12345') + const token = await this.getAdminToken() const response = await request.put(`/api/v1/users/${user.id}`, { body: { name: 'Customer Updated', email: 'customer-updated@athenna.io' }, headers: { authorization: token } @@ -168,7 +169,7 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldNotBeAbleToUpdateAUserPasswordWithoutEmailConfirmation({ assert, request }: Context) { const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('admin@athenna.io', '12345') + const token = await this.getAdminToken() const response = await request.put(`/api/v1/users/${user.id}`, { body: { name: 'Customer Updated', password: '12345678', password_confirmation: '12345678' }, headers: { authorization: token } @@ -190,7 +191,7 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldNotBeAbleToUpdateAUserEmailAndPasswordWithoutEmailConfirmation({ assert, request }: Context) { const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('admin@athenna.io', '12345') + const token = await this.getAdminToken() const response = await request.put(`/api/v1/users/${user.id}`, { body: { name: 'Customer Updated', @@ -216,8 +217,8 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToUpdateOwnUserByIdAsACustomer({ assert, request }: Context) { - const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('customer@athenna.io', '12345') + const user = await this.createCustomer() + const token = await this.createToken(user) const response = await request.put(`/api/v1/users/${user.id}`, { body: { name: 'Customer Updated' @@ -230,7 +231,7 @@ export default class UserControllerTest extends BaseHttpTest { assert.deepEqual(user.name, 'Customer Updated') response.assertStatusCode(200) response.assertBodyContains({ - data: { name: 'Customer Updated', email: 'customer@athenna.io' } + data: { name: 'Customer Updated' } }) } @@ -259,7 +260,7 @@ export default class UserControllerTest extends BaseHttpTest { request }: Context) { const user = await User.find({ email: 'admin@athenna.io' }) - const token = await ioc.use('authService').login('customer@athenna.io', '12345') + const token = await this.getCustomerToken() const response = await request.put(`/api/v1/users/${user.id}`, { body: { name: 'Admin Updated' }, headers: { authorization: token } @@ -273,8 +274,8 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToDeleteAUser({ assert, request }: Context) { - const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('admin@athenna.io', '12345') + const user = await this.createCustomer() + const token = await this.getAdminToken() const response = await request.delete(`/api/v1/users/${user.id}`, { headers: { authorization: token } }) @@ -287,8 +288,8 @@ export default class UserControllerTest extends BaseHttpTest { @Test() public async shouldBeAbleToDeleteOwnUserByIdAsACustomer({ assert, request }: Context) { - const user = await User.find({ email: 'customer@athenna.io' }) - const token = await ioc.use('authService').login('customer@athenna.io', '12345') + const user = await this.createCustomer() + const token = await this.createToken(user) const response = await request.delete(`/api/v1/users/${user.id}`, { headers: { authorization: token } }) @@ -323,9 +324,9 @@ export default class UserControllerTest extends BaseHttpTest { public async shouldThrowUnauthorizedExceptionWhenTryingToDeleteAnUserDifferentThenYoursAsACustomer({ request }: Context) { - const user = await User.find({ email: 'admin@athenna.io' }) - const token = await ioc.use('authService').login('customer@athenna.io', '12345') - const response = await request.delete(`/api/v1/users/${user.id}`, { + const user = await this.createCustomer() + const token = await this.createToken(user) + const response = await request.delete('/api/v1/users/2', { headers: { authorization: token } }) diff --git a/tests/helpers/base.e2e.test.ts b/tests/helpers/base.e2e.test.ts new file mode 100644 index 0000000..14d032a --- /dev/null +++ b/tests/helpers/base.e2e.test.ts @@ -0,0 +1,45 @@ +import jwt from 'jsonwebtoken' +import { User } from '#src/models/user' +import { Role } from '#src/models/role' +import { Config } from '@athenna/config' +import { RoleEnum } from '#src/enums/role.enum' +import { RoleUser } from '#src/models/roleuser' +import { BaseHttpTest } from '@athenna/core/testing/BaseHttpTest' + +export class BaseE2ETest extends BaseHttpTest { + public async getAdminToken() { + return ioc.use('authService').login('admin@athenna.io', '12345') + } + + public async getCustomerToken() { + return ioc.use('authService').login('customer@athenna.io', '12345') + } + + public createFakeToken(data: any) { + return jwt.sign(data, Config.get('auth.jwt.secret'), { + expiresIn: Config.get('auth.jwt.expiresIn') + }) + } + + public async createToken(user: User) { + return ioc.use('authService').login(user.email, '12345') + } + + public async createAdmin() { + const user = await User.factory().create() + const role = await Role.find({ name: RoleEnum.ADMIN }) + + await RoleUser.create({ userId: user.id, roleId: role.id }) + + return user + } + + public async createCustomer() { + const user = await User.factory().create() + const role = await Role.find({ name: RoleEnum.CUSTOMER }) + + await RoleUser.create({ userId: user.id, roleId: role.id }) + + return user + } +}