From ab6913166bc15576f7096e265989423ed2e24982 Mon Sep 17 00:00:00 2001 From: Victoire Rabeau Date: Thu, 5 Oct 2023 15:02:53 +0200 Subject: [PATCH] feat(account): Add routes parameters class validator --- src/account/account.controller.ts | 43 +-- src/account/account.dto.ts | 23 ++ src/prophecy/prophecy.controller.ts | 1 - src/prophecy/prophecy.dto.ts | 1 - tests/api/account/account.spec.ts | 354 ------------------ tests/api/account/delete.spec.ts | 98 +++++ tests/api/account/reset-passwod.spec.ts | 59 +++ .../account/send-password-reset-link.spec.ts | 67 ++++ tests/api/account/update-email.spec.ts | 187 +++++++++ tests/api/account/update-password.spec.ts | 166 ++++++++ tests/api/account/update-username.spec.ts | 178 +++++++++ tests/api/army-list/create.spec.ts | 2 +- tests/tests.helper.ts | 2 + 13 files changed, 792 insertions(+), 389 deletions(-) create mode 100644 src/account/account.dto.ts delete mode 100644 tests/api/account/account.spec.ts create mode 100644 tests/api/account/delete.spec.ts create mode 100644 tests/api/account/reset-passwod.spec.ts create mode 100644 tests/api/account/send-password-reset-link.spec.ts create mode 100644 tests/api/account/update-email.spec.ts create mode 100644 tests/api/account/update-password.spec.ts create mode 100644 tests/api/account/update-username.spec.ts diff --git a/src/account/account.controller.ts b/src/account/account.controller.ts index 79af0c7..9bf794b 100644 --- a/src/account/account.controller.ts +++ b/src/account/account.controller.ts @@ -18,6 +18,7 @@ import { AuthService } from "@auth/auth.service"; import { EmailConfirmationService } from "@email/email-confirmation.service"; import { ForgottenPasswordService } from "@email/forgotten-password.service"; import { PasswordUpdateService } from "@email/password-update.service"; +import { PasswordParameterDTO, EmailParameterDTO, UsernameParameterDTO } from "@account/account.dto"; dotenv.config(); @@ -73,8 +74,8 @@ export class AccountController { */ @Post("send-password-reset-link") @HttpCode(HttpStatus.OK) - async sendPasswordResetLink(@Body("email") email: string): Promise { - if (!this.isFieldValid(email) || await this.profileService.findOneByEmail(email) === null) { + async sendPasswordResetLink(@Body() { email }: EmailParameterDTO): Promise { + if (await this.profileService.findOneByEmail(email) === null) { throw new BadRequestException("Invalid email address"); } await this.forgottenPasswordService.sendPasswordResetLink(email); @@ -90,12 +91,10 @@ export class AccountController { */ @Put("reset-password") @HttpCode(HttpStatus.OK) - async resetPassword(@Query("token") token: string, @Body("password") password: string): Promise { + async resetPassword(@Query("token") token: string, + @Body() { password }: PasswordParameterDTO): Promise { const username: string = await this.forgottenPasswordService.decodeResetToken(token); - if (!this.isFieldValid(password)) { - throw new BadRequestException("Invalid password field"); - } await this.forgottenPasswordService.resetPassword(username, password); } @@ -126,13 +125,10 @@ export class AccountController { @UseGuards(JwtAuthGuard) @Put("password") @HttpCode(HttpStatus.OK) - async updatePassword(@Request() req, @Body("password") password: string): Promise { + async updatePassword(@Request() req, @Body() { password }: PasswordParameterDTO): Promise { const username = req.user.username; const profile: Profile = await this.profileService.findOneByUsername(username); - if (!this.isFieldValid(password)) { - throw new BadRequestException(); - } await this.profileService.updatePassword(username, password); await this.passwordUpdateService.sendPasswordUpdateEmail(profile.email); } @@ -147,13 +143,10 @@ export class AccountController { @UseGuards(JwtAuthGuard) @Put("email") @HttpCode(HttpStatus.OK) - async updateEmail(@Request() req, @Body("email") email: string): Promise { + async updateEmail(@Request() req, @Body() { email }: EmailParameterDTO): Promise { const username = req.user.username; const _profile: Profile = await this.profileService.findOneByUsername(username); - if (!this.isFieldValid(email)) { - throw new BadRequestException(); - } await this.profileService.updateEmail(username, email); await this.emailConfirmationService.sendVerificationLink(email); } @@ -168,15 +161,12 @@ export class AccountController { @UseGuards(JwtAuthGuard) @Put("username") @HttpCode(HttpStatus.OK) - async updateUsername(@Request() req, @Body("username") newUsername: string): Promise<{username: string}> { - const username = req.user.username; + async updateUsername(@Request() req, @Body() { username }: UsernameParameterDTO): Promise { + const u = req.user.username; - if (!this.isFieldValid(newUsername)) { - throw new BadRequestException(); - } - await this.profileService.updateUsername(username, newUsername); + await this.profileService.updateUsername(u, username); return { - username: newUsername + username }; } @@ -195,15 +185,4 @@ export class AccountController { email: profile.email }; } - - /** - * @brief Checks if a string parameter is valid - * Checks if it is not undefined, null or empty - * @param str The parameter to check - * @return True if the parameter is valid, false otherwise - * @private - */ - private isFieldValid(str: string): boolean { - return (str !== undefined && str !== null && str !== ""); - } } diff --git a/src/account/account.dto.ts b/src/account/account.dto.ts new file mode 100644 index 0000000..d9733a1 --- /dev/null +++ b/src/account/account.dto.ts @@ -0,0 +1,23 @@ +import { IsDefined, IsEmail, IsNotEmpty, IsString } from "class-validator"; + +export class EmailParameterDTO { + @IsDefined() + @IsString() + @IsNotEmpty() + @IsEmail() + public email: string; +} + +export class PasswordParameterDTO { + @IsDefined() + @IsString() + @IsNotEmpty() + public password: string; +} + +export class UsernameParameterDTO { + @IsDefined() + @IsString() + @IsNotEmpty() + public username: string; +} diff --git a/src/prophecy/prophecy.controller.ts b/src/prophecy/prophecy.controller.ts index fb3b9c2..1ca9057 100644 --- a/src/prophecy/prophecy.controller.ts +++ b/src/prophecy/prophecy.controller.ts @@ -26,7 +26,6 @@ import { ProphecyArmyWithIdDTO } from "@prophecy/army/prophecy-army.dto"; import { ArmyList } from "@army-list/army-list.entity"; import { ProphecyUnitMathsResponseDTO } from "@prophecy/maths/prophecy-unit-maths.dto"; import { ProphecyArmyRequestDTO, ProphecyUnitRequestDTO } from "@prophecy/prophecy.dto"; -import { IsDefined } from "class-validator"; @Controller("prophecies") export class ProphecyController { diff --git a/src/prophecy/prophecy.dto.ts b/src/prophecy/prophecy.dto.ts index 9826a98..65ee28d 100644 --- a/src/prophecy/prophecy.dto.ts +++ b/src/prophecy/prophecy.dto.ts @@ -4,7 +4,6 @@ import { import { ProphecyUnitAttackingPosition } from "@prophecy/unit/prophecy-unit.entity"; import { IsDefined, IsEnum, IsNotEmpty, IsString, ValidateNested } from "class-validator"; import { Type } from "class-transformer"; -import { Body } from "@nestjs/common"; export class ProphecyUnitRequestDTO { @IsDefined() diff --git a/tests/api/account/account.spec.ts b/tests/api/account/account.spec.ts deleted file mode 100644 index abe5b17..0000000 --- a/tests/api/account/account.spec.ts +++ /dev/null @@ -1,354 +0,0 @@ -import { Test, TestingModule } from "@nestjs/testing"; -import { HttpStatus, INestApplication } from "@nestjs/common"; -import * as request from "supertest"; -import { faker } from "@faker-js/faker"; - -import { AppModule } from "@app/app.module"; -import { TestsHelper } from "@tests/tests.helper"; - -const USERNAME = faker.internet.userName(); -const EMAIL = faker.internet.email(); -const PASSWORD = faker.internet.password(); - -const USERNAME1 = faker.internet.userName(); -const EMAIL1 = faker.internet.email(); -const PASSWORD1 = faker.internet.password(); - -// TODO - -describe("Account Route", () => { - let app: INestApplication; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [AppModule] - }).compile(); - - app = module.createNestApplication(); - await app.init(); - }); - - afterEach(async () => { - let token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - await TestsHelper.deleteAccount(app.getHttpServer(), token); - - token = await TestsHelper.getToken(app.getHttpServer(), USERNAME1, PASSWORD); - await TestsHelper.deleteAccount(app.getHttpServer(), token); - - token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD1); - await TestsHelper.deleteAccount(app.getHttpServer(), token); - }); - - /** - * DELETE ACCOUNT - */ - - it("delete-account: Delete existing account", async () => { - // creating account - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - // deleting account - const response1 = await TestsHelper.deleteAccount(app.getHttpServer(), token); - - expect(response1.status == HttpStatus.OK); - - // trying to login - const response2 = await request(app.getHttpServer()) - .post(TestsHelper.SIGN_IN_ROUTE) - .send({ - username: USERNAME, - password: PASSWORD, - }); - - expect(response2.status).toEqual(HttpStatus.UNAUTHORIZED); - }); - - it("delete-account: Delete with invalid token", async () => { - const token = "token" - const response1 = await TestsHelper.deleteAccount(app.getHttpServer(), token) - - expect(response1.status == HttpStatus.UNAUTHORIZED); - }); - - it("delete-account: Delete not existing account", async () => { - const response1 = await TestsHelper.signUp(app.getHttpServer(), USERNAME1, EMAIL1, PASSWORD1); - - expect(response1.status).toEqual(HttpStatus.CREATED); - - const response2 = await request(app.getHttpServer()) - .post(TestsHelper.SIGN_IN_ROUTE) - .send({ - username: USERNAME1, - password: PASSWORD1, - }); - - expect(response2.status).toEqual(HttpStatus.OK); - - const token = response2.body.access_token; - - const response3 = await TestsHelper.deleteAccount(app.getHttpServer(), token); - - expect(response3.status == HttpStatus.OK); - - const response4 = await TestsHelper.deleteAccount(app.getHttpServer(), token); - - expect(response4.status == HttpStatus.UNAUTHORIZED); - }) - - /** - * SETTINGS UPDATE PASSWORD - */ - - it("settings/update-password: Update password", async () => { - // creating account - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_PASSWORD_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({ - password: PASSWORD1 - }); - - expect(response1.status).toEqual(HttpStatus.OK); - - // sign in with new password - const [response2] = await Promise.all([request(app.getHttpServer()) - .post(TestsHelper.SIGN_IN_ROUTE) - .send({ - username: USERNAME, - password: PASSWORD1 - })]); - - return expect(response2.status).toEqual(HttpStatus.OK); - - // sign in with old password - const response3 = await request(app.getHttpServer()) - .post(TestsHelper.SIGN_IN_ROUTE) - .send({ - username: USERNAME, - password: PASSWORD - }); - - expect(response3.status).toEqual(HttpStatus.UNAUTHORIZED); - }); - - it("settings/update-password: Update password with empty password", async () => { - // creating account - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_PASSWORD_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({ - password: "" - }); - - expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); - }); - - it("settings/update-password: Update password without password", async () => { - // creating account - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_PASSWORD_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({}); - - expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); - }); - - /** - * UPDATE EMAIL ADDRESS - */ - - it("settings/update-email-address: Update email", async () => { - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - // updating email - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_EMAIL_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({ - email: EMAIL1 - }); - - expect(response1.status).toEqual(HttpStatus.OK); - - // trying to sign in with the old email - const response2 = await request(app.getHttpServer()) - .post(TestsHelper.SIGN_IN_ROUTE) - .send({ - username: EMAIL, - password: PASSWORD - }); - - expect(response2.status).toEqual(HttpStatus.UNAUTHORIZED); - - // trying to sign in with the new email - const response3 = await request(app.getHttpServer()) - .post(TestsHelper.SIGN_IN_ROUTE) - .send({ - username: EMAIL1, - password: PASSWORD - }); - - expect(response3.status).toEqual(HttpStatus.OK); - expect(response3.body.username).toBeDefined(); - expect(response3.body.username).toEqual(USERNAME); - }); - - it("settings/update-email-address: Update email with empty email", async () => { - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - // updating email - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_EMAIL_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({ - email: "" - }); - - expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); - }); - - it("settings/update-email-address: Update email without email", async () => { - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - // updating email - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_EMAIL_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({ - }); - - expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); - }); - - /** - * UPDATE USERNAME - */ - - it("settings/update-username: Update username", async () => { - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - // updating username - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_USERNAME_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({ - username: USERNAME1 - }); - - expect(response1.status).toEqual(HttpStatus.OK); - expect(response1.body.username).toBeDefined(); - expect(response1.body.username).toEqual(USERNAME1); - - // trying to sign in with old username - const response2 = await request(app.getHttpServer()) - .post(TestsHelper.SIGN_IN_ROUTE) - .send({ - username: USERNAME, - password: PASSWORD - }); - - expect(response2.status).toEqual(HttpStatus.UNAUTHORIZED); - - // logging in with the new username - const response3 = await request(app.getHttpServer()) - .post(TestsHelper.SIGN_IN_ROUTE) - .send({ - username: USERNAME1, - password: PASSWORD - }); - - expect(response3.status).toEqual(HttpStatus.OK); - - // try to update email with old token - const response4 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_EMAIL_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({ - email: EMAIL1 - }); - - expect(response4.status).toEqual(HttpStatus.OK); - }); - - it("settings/update-username: Update username with empty username", async () => { - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - // updating username - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_USERNAME_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({ - username: "" - }); - - expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); - }); - - it("settings/update-username: Update username without username", async () => { - const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); - - expect(r.status).toEqual(HttpStatus.CREATED); - - // retrieving token - const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); - - // updating username - const response1 = await request(app.getHttpServer()) - .put(TestsHelper.UPDATE_USERNAME_ROUTE) - .set("Authorization", `Bearer ${token}`) - .send({}); - - expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); - }); -}) diff --git a/tests/api/account/delete.spec.ts b/tests/api/account/delete.spec.ts new file mode 100644 index 0000000..6826036 --- /dev/null +++ b/tests/api/account/delete.spec.ts @@ -0,0 +1,98 @@ +import { Test, TestingModule } from "@nestjs/testing"; +import { AppModule } from "../../../src/app.module"; +import { TestsHelper } from "../../tests.helper"; +import { faker } from "@faker-js/faker"; +import { HttpStatus, INestApplication, ValidationPipe } from "@nestjs/common"; +import * as request from "supertest"; + +const USERNAME = faker.internet.userName(); +const EMAIL = faker.internet.email(); +const PASSWORD = faker.internet.password(); + +const USERNAME1 = faker.internet.userName(); +const EMAIL1 = faker.internet.email(); +const PASSWORD1 = faker.internet.password(); + +let app: INestApplication; + +describe("account/delete", () => { + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [AppModule] + }).compile(); + + app = module.createNestApplication(); + app.useGlobalPipes(new ValidationPipe()); + await app.init(); + }); + + afterEach(async () => { + let token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + + token = await TestsHelper.getToken(app.getHttpServer(), USERNAME1, PASSWORD); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + + token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD1); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + }); + + it("delete existing account - should return 200 (OK)", async () => { + // creating account + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // deleting account + const response1 = await TestsHelper.deleteAccount(app.getHttpServer(), token); + + expect(response1.status == HttpStatus.OK); + + // trying to login + const response2 = await request(app.getHttpServer()) + .post(TestsHelper.SIGN_IN_ROUTE) + .send({ + username: USERNAME, + password: PASSWORD, + }); + + expect(response2.status).toEqual(HttpStatus.UNAUTHORIZED); + }); + + it("invalid token - should return 401 (Unauthorized)", async () => { + const token = "token" + const response1 = await TestsHelper.deleteAccount(app.getHttpServer(), token) + + expect(response1.status == HttpStatus.UNAUTHORIZED); + }); + + it("not existing account - should return 401 (Unauthorized)", async () => { + const response1 = await TestsHelper.signUp(app.getHttpServer(), USERNAME1, EMAIL1, PASSWORD1); + + expect(response1.status).toEqual(HttpStatus.CREATED); + + const response2 = await request(app.getHttpServer()) + .post(TestsHelper.SIGN_IN_ROUTE) + .send({ + username: USERNAME1, + password: PASSWORD1, + }); + + expect(response2.status).toEqual(HttpStatus.OK); + + const token = response2.body.access_token; + + const response3 = await TestsHelper.deleteAccount(app.getHttpServer(), token); + + expect(response3.status == HttpStatus.OK); + + const response4 = await TestsHelper.deleteAccount(app.getHttpServer(), token); + + expect(response4.status == HttpStatus.UNAUTHORIZED); + }) + +}); diff --git a/tests/api/account/reset-passwod.spec.ts b/tests/api/account/reset-passwod.spec.ts new file mode 100644 index 0000000..e3854c1 --- /dev/null +++ b/tests/api/account/reset-passwod.spec.ts @@ -0,0 +1,59 @@ +import { HttpStatus, INestApplication, ValidationPipe } from "@nestjs/common"; +import { Test, TestingModule } from "@nestjs/testing"; +import { AppModule } from "../../../src/app.module"; +import { TestsHelper } from "../../tests.helper"; +import * as request from "supertest"; + +let app: INestApplication; + +describe("account/reset-password", () => { + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [AppModule] + }).compile(); + + app = module.createNestApplication(); + app.useGlobalPipes(new ValidationPipe()); + await app.init(); + }); + + it("null parameter - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .put(TestsHelper.RESET_PASSWORD_ROUTE) + .send(null); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined parameter - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .put(TestsHelper.RESET_PASSWORD_ROUTE) + .send(undefined); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined password - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .put(TestsHelper.RESET_PASSWORD_ROUTE) + .send({ password: undefined }); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("null password - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .put(TestsHelper.RESET_PASSWORD_ROUTE) + .send({ password: null }); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("empty password - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .put(TestsHelper.RESET_PASSWORD_ROUTE) + .send({ password: "" }); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); +}); diff --git a/tests/api/account/send-password-reset-link.spec.ts b/tests/api/account/send-password-reset-link.spec.ts new file mode 100644 index 0000000..63e3b84 --- /dev/null +++ b/tests/api/account/send-password-reset-link.spec.ts @@ -0,0 +1,67 @@ +import { HttpStatus, INestApplication, ValidationPipe } from "@nestjs/common"; +import { Test, TestingModule } from "@nestjs/testing"; +import { AppModule } from "../../../src/app.module"; +import { TestsHelper } from "../../tests.helper"; +import * as request from "supertest"; + +let app: INestApplication; + +describe("account/send-password-reset-link", () => { + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [AppModule] + }).compile(); + + app = module.createNestApplication(); + app.useGlobalPipes(new ValidationPipe()); + await app.init(); + }); + + it("null parameter - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .post(TestsHelper.SEND_PASSWORD_RESET_LINK_ROUTE) + .send(null); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined parameter - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .post(TestsHelper.SEND_PASSWORD_RESET_LINK_ROUTE) + .send(undefined); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined email - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .post(TestsHelper.SEND_PASSWORD_RESET_LINK_ROUTE) + .send({ email: undefined }); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("null email - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .post(TestsHelper.SEND_PASSWORD_RESET_LINK_ROUTE) + .send({ email: null }); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("empty email - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .post(TestsHelper.SEND_PASSWORD_RESET_LINK_ROUTE) + .send({ email: "" }); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("not email email - should return 400 (Bad Request)", async () => { + const res = await request(app.getHttpServer()) + .post(TestsHelper.SEND_PASSWORD_RESET_LINK_ROUTE) + .send({ email: "abcdef" }); + + expect(res.status).toEqual(HttpStatus.BAD_REQUEST); + }); +}); diff --git a/tests/api/account/update-email.spec.ts b/tests/api/account/update-email.spec.ts new file mode 100644 index 0000000..103f7fb --- /dev/null +++ b/tests/api/account/update-email.spec.ts @@ -0,0 +1,187 @@ +import { faker } from "@faker-js/faker"; +import { HttpStatus, INestApplication, ValidationPipe } from "@nestjs/common"; +import { Test, TestingModule } from "@nestjs/testing"; +import { AppModule } from "../../../src/app.module"; +import { TestsHelper } from "../../tests.helper"; +import * as request from "supertest"; + +const USERNAME = faker.internet.userName(); +const EMAIL = faker.internet.email(); +const PASSWORD = faker.internet.password(); + +const USERNAME1 = faker.internet.userName(); +const EMAIL1 = faker.internet.email(); +const PASSWORD1 = faker.internet.password(); + +let app: INestApplication; + +describe("account/update-email", () => { + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [AppModule] + }).compile(); + + app = module.createNestApplication(); + app.useGlobalPipes(new ValidationPipe()); + await app.init(); + }); + + afterEach(async () => { + let token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + + token = await TestsHelper.getToken(app.getHttpServer(), USERNAME1, PASSWORD); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + + token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD1); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + }); + + it("update email - should return 200 (OK)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating email + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_EMAIL_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ + email: EMAIL1 + }); + + expect(response1.status).toEqual(HttpStatus.OK); + + // trying to sign in with the old email + const response2 = await request(app.getHttpServer()) + .post(TestsHelper.SIGN_IN_ROUTE) + .send({ + username: EMAIL, + password: PASSWORD + }); + + expect(response2.status).toEqual(HttpStatus.UNAUTHORIZED); + + // trying to sign in with the new email + const response3 = await request(app.getHttpServer()) + .post(TestsHelper.SIGN_IN_ROUTE) + .send({ + username: EMAIL1, + password: PASSWORD + }); + + expect(response3.status).toEqual(HttpStatus.OK); + expect(response3.body.username).toBeDefined(); + expect(response3.body.username).toEqual(USERNAME); + }); + + it("null parameter - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating email + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_EMAIL_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send(null); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined parameter - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating email + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_EMAIL_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send(undefined); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("empty email - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating email + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_EMAIL_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ + email: "" + }); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("not email email - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating email + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_EMAIL_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ + email: "abcdef" + }); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("null email - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating email + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_EMAIL_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send(null); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined email - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating email + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_EMAIL_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send(undefined); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); +}); diff --git a/tests/api/account/update-password.spec.ts b/tests/api/account/update-password.spec.ts new file mode 100644 index 0000000..f605f3a --- /dev/null +++ b/tests/api/account/update-password.spec.ts @@ -0,0 +1,166 @@ +import { faker } from "@faker-js/faker"; +import { HttpStatus, INestApplication, ValidationPipe } from "@nestjs/common"; +import { Test, TestingModule } from "@nestjs/testing"; +import { AppModule } from "../../../src/app.module"; +import { TestsHelper } from "../../tests.helper"; +import * as request from "supertest"; + +const USERNAME = faker.internet.userName(); +const EMAIL = faker.internet.email(); +const PASSWORD = faker.internet.password(); + +const USERNAME1 = faker.internet.userName(); +const EMAIL1 = faker.internet.email(); +const PASSWORD1 = faker.internet.password(); + +let app: INestApplication; + +describe("account/update-password", () => { + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [AppModule] + }).compile(); + + app = module.createNestApplication(); + app.useGlobalPipes(new ValidationPipe()); + await app.init(); + }); + + afterEach(async () => { + let token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + + token = await TestsHelper.getToken(app.getHttpServer(), USERNAME1, PASSWORD); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + + token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD1); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + }); + + it("update password - should return 200 (OK)", async () => { + // creating account + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_PASSWORD_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ + password: PASSWORD1 + }); + + expect(response1.status).toEqual(HttpStatus.OK); + + // sign in with new password + const [response2] = await Promise.all([request(app.getHttpServer()) + .post(TestsHelper.SIGN_IN_ROUTE) + .send({ + username: USERNAME, + password: PASSWORD1 + })]); + + return expect(response2.status).toEqual(HttpStatus.OK); + + // sign in with old password + const response3 = await request(app.getHttpServer()) + .post(TestsHelper.SIGN_IN_ROUTE) + .send({ + username: USERNAME, + password: PASSWORD + }); + + expect(response3.status).toEqual(HttpStatus.UNAUTHORIZED); + }); + + it("empty password - should return 400 (Bad Request)", async () => { + // creating account + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_PASSWORD_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ + password: "" + }); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined password - should return 400 (Bad Request)", async () => { + // creating account + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_PASSWORD_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ password: undefined }); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("null password - should return 400 (Bad Request)", async () => { + // creating account + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_PASSWORD_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ password: null }); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("null parameter - should return 400 (Bad Request)", async () => { + // creating account + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_PASSWORD_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send(null); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined parameter - should return 400 (Bad Request)", async () => { + // creating account + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_PASSWORD_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send(undefined); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); +}); diff --git a/tests/api/account/update-username.spec.ts b/tests/api/account/update-username.spec.ts new file mode 100644 index 0000000..0435ce1 --- /dev/null +++ b/tests/api/account/update-username.spec.ts @@ -0,0 +1,178 @@ +import { faker } from "@faker-js/faker"; +import { HttpStatus, INestApplication, ValidationPipe } from "@nestjs/common"; +import { Test, TestingModule } from "@nestjs/testing"; +import { AppModule } from "../../../src/app.module"; +import { TestsHelper } from "../../tests.helper"; +import * as request from "supertest"; + +const USERNAME = faker.internet.userName(); +const EMAIL = faker.internet.email(); +const PASSWORD = faker.internet.password(); + +const USERNAME1 = faker.internet.userName(); +const EMAIL1 = faker.internet.email(); +const PASSWORD1 = faker.internet.password(); + +let app: INestApplication; + +describe("account/update-username", () => { + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [AppModule] + }).compile(); + + app = module.createNestApplication(); + app.useGlobalPipes(new ValidationPipe()); + await app.init(); + }); + + afterEach(async () => { + let token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + + token = await TestsHelper.getToken(app.getHttpServer(), USERNAME1, PASSWORD); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + + token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD1); + await TestsHelper.deleteAccount(app.getHttpServer(), token); + }); + + it("update username - should return 200 (OK)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating username + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_USERNAME_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ + username: USERNAME1 + }); + + expect(response1.status).toEqual(HttpStatus.OK); + expect(response1.body.username).toBeDefined(); + expect(response1.body.username).toEqual(USERNAME1); + + // trying to sign in with old username + const response2 = await request(app.getHttpServer()) + .post(TestsHelper.SIGN_IN_ROUTE) + .send({ + username: USERNAME, + password: PASSWORD + }); + + expect(response2.status).toEqual(HttpStatus.UNAUTHORIZED); + + // logging in with the new username + const response3 = await request(app.getHttpServer()) + .post(TestsHelper.SIGN_IN_ROUTE) + .send({ + username: USERNAME1, + password: PASSWORD + }); + + expect(response3.status).toEqual(HttpStatus.OK); + + // try to update email with old token + const response4 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_EMAIL_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ + email: EMAIL1 + }); + + expect(response4.status).toEqual(HttpStatus.OK); + }); + + it("empty username - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating username + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_USERNAME_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ + username: "" + }); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("null parameter - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating username + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_USERNAME_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send(null); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined parameter - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating username + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_USERNAME_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send(undefined); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("undefined username - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating username + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_USERNAME_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ username: undefined }); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); + + it("null username - should return 400 (Bad Request)", async () => { + const r = await TestsHelper.signUp(app.getHttpServer(), USERNAME, EMAIL, PASSWORD); + + expect(r.status).toEqual(HttpStatus.CREATED); + + // retrieving token + const token = await TestsHelper.getToken(app.getHttpServer(), USERNAME, PASSWORD); + + // updating username + const response1 = await request(app.getHttpServer()) + .put(TestsHelper.UPDATE_USERNAME_ROUTE) + .set("Authorization", `Bearer ${token}`) + .send({ username: null }); + + expect(response1.status).toEqual(HttpStatus.BAD_REQUEST); + }); +}); diff --git a/tests/api/army-list/create.spec.ts b/tests/api/army-list/create.spec.ts index 5a769e9..e9e4ffc 100644 --- a/tests/api/army-list/create.spec.ts +++ b/tests/api/army-list/create.spec.ts @@ -40,7 +40,7 @@ describe("armies-lists/create", () => { }); afterAll(async () => { - const res = await request(app.getHttpServer()) + const res = await request(app.getHttpServer()) .get(TestsHelper.ARMIES_LISTS_ROUTE) .set("Authorization", `Bearer ${token}`); diff --git a/tests/tests.helper.ts b/tests/tests.helper.ts index b3fe91b..8ca5c2e 100644 --- a/tests/tests.helper.ts +++ b/tests/tests.helper.ts @@ -51,6 +51,8 @@ export class TestsHelper { static UPDATE_PASSWORD_ROUTE: string = "/account/password"; static UPDATE_EMAIL_ROUTE: string = "/account/email"; static UPDATE_USERNAME_ROUTE: string = "/account/username"; + static SEND_PASSWORD_RESET_LINK_ROUTE: string = "/account/send-password-reset-link"; + static RESET_PASSWORD_ROUTE: string = "/account/reset-password"; /** * PROPHECIES