Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exercícios testes back end #1

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .env.example

This file was deleted.

23 changes: 1 addition & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1 @@
# Testes no Backend III - Exercício

<strong>A partir dessa semana os exercícios voltam a ser independentes. Não se preocupe em centralizá-los em um mesmo repo.</strong>
<br><br>
Utilize esse template para criar um repo pessoal na sua conta e trabalhe nele.

## Enunciado

Temos nesse repo o gabarito dos exercícios anteriores, mas sem os testes de erro implementados em aula.<br>
A diferença para o template é que já existem as implementações de DELETE /users/:id e GET /users/:id.

### Exercício 1

Atinja 75% de coverage na UserBusiness.

### Exercício 2

Atinja 90% de coverage na UserBusiness.

### Exercício 3

Atinja 100% de coverage na UserBusiness.
![image](https://user-images.githubusercontent.com/111308068/222246578-2150a211-6cd1-4952-9b1e-519f3311d3ee.png)
6,219 changes: 6,219 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions src/business/UserBusiness.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UserDatabase } from "../database/UserDatabase"
import { DeleteUserInputDTO, GetAllOutputDTO, GetByIdInputDTO, GetByIdOutputDTO, LoginInputDTO, LoginOutputDTO, SignupInputDTO, SignupOutputDTO } from "../dtos/userDTO";
import { DeleteUserInputDTO, DeleteUserOutputDTO, GetAllOutputDTO, GetByIdInputDTO, GetByIdOutputDTO, LoginInputDTO, LoginOutputDTO, SignupInputDTO, SignupOutputDTO } from "../dtos/userDTO";
import { BadRequestError } from "../errors/BadRequestError";
import { NotFoundError } from "../errors/NotFoundError";
import { User } from "../models/User";
Expand Down Expand Up @@ -139,7 +139,7 @@ export class UserBusiness {
return output
}

public deleteUser = async (input: DeleteUserInputDTO): Promise<void> => {
public deleteUser = async (input: DeleteUserInputDTO) => {
const { idToDelete, token } = input

if (typeof token !== "string") {
Expand All @@ -162,8 +162,13 @@ export class UserBusiness {
throw new NotFoundError("'id' não existe")
}

await this.userDatabase.deleteById(idToDelete)
await this.userDatabase.deleteById(idToDelete as string)

const output: DeleteUserOutputDTO = {
message: "USER DELETED SUCCESSFULLY",
}
return output
}

public getById = async (input: GetByIdInputDTO): Promise<GetByIdOutputDTO> => {
const { idToFind } = input
Expand Down
2 changes: 1 addition & 1 deletion src/database/UserDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class UserDatabase extends BaseDatabase {
return result[0]
}

public deleteById = async (id: string): Promise<void> => {
public deleteById = async (id: string) => {
await BaseDatabase
.connection(UserDatabase.TABLE_USERS)
.delete()
Expand Down
4 changes: 4 additions & 0 deletions src/dtos/userDTO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export interface DeleteUserInputDTO {
token: unknown
}

export interface DeleteUserOutputDTO {
message: string
}

export interface GetByIdInputDTO {
idToFind: string
}
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ export interface UserModel {
name: string,
email: string,
password: string,
role: USER_ROLES,
createdAt: string
createdAt: string,
role: USER_ROLES
}
80 changes: 80 additions & 0 deletions tests/UserBusiness/deleteUser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { UserBusiness } from "../../src/business/UserBusiness"
import { HashManagerMock } from "../mocks/HashManagerMock"
import { IdGeneratorMock } from "../mocks/IdGeneratorMock"
import { TokenManagerMock } from "../mocks/TokenManagerMock"
import { UserDatabaseMock } from "../mocks/UserDatabaseMock"
import { DeleteUserInputDTO } from "../../src/dtos/userDTO"
import { BadRequestError } from "../../src/errors/BadRequestError"

describe("deleteUser", () => {
const userBusiness = new UserBusiness(
new UserDatabaseMock(),
new IdGeneratorMock(),
new TokenManagerMock(),
new HashManagerMock()
)

test("Deve deletar um usuário a partir do(id)", async () => {
const input: DeleteUserInputDTO = {
idToDelete: "id-mock-normal",
token: "token-mock-admin",
}

const response = await userBusiness.deleteUser(input)
// expect(response.message).toBe("USER DELETED SUCCESSFULLY")
expect(response).toEqual({ message: "USER DELETED SUCCESSFULLY" })
})

test ("Testar erro de formato no token",async () => {
expect.assertions(1);

const input: DeleteUserInputDTO = {
idToDelete: "id-mock-normal",
token: true,
}

try{
await userBusiness.deleteUser(input);
}catch(error){
if(error instanceof BadRequestError){
expect(error.message).toBe("requer token")
}
}
})


//Teste com toThrow (sem try / catch)
test ("Testar input de token inexistente",async () => {
const input: DeleteUserInputDTO = {
idToDelete: "id-mock-normal",
token: "newtoken-mock-admin",
}

expect(async ()=>{
await userBusiness.deleteUser(input)
}).rejects.toThrow("token inválido")
})

test ("Testar regra de 'role' para excluir users",async () => {
const input: DeleteUserInputDTO = {
idToDelete: "id-mock-normal",
token: "token-mock-normal",
}

expect(async ()=>{
await userBusiness.deleteUser(input)
}).rejects.toThrow("somente admins podem deletar contas")
})

test ("Testar se o 'id' existe",async () => {
const input: DeleteUserInputDTO = {
idToDelete: "newid-mock-normal",
token: "token-mock-admin",
}

expect(async ()=>{
await userBusiness.deleteUser(input)
}).rejects.toThrow("'id' não existe")
})
})

43 changes: 43 additions & 0 deletions tests/UserBusiness/getById.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { UserBusiness } from "../../src/business/UserBusiness"
import { GetByIdInputDTO } from "../../src/dtos/userDTO"
import { USER_ROLES } from "../../src/types"
import { HashManagerMock } from "../mocks/HashManagerMock"
import { IdGeneratorMock } from "../mocks/IdGeneratorMock"
import { TokenManagerMock } from "../mocks/TokenManagerMock"
import { UserDatabaseMock } from "../mocks/UserDatabaseMock"

describe("getUserById", () => {
const userBusiness = new UserBusiness(
new UserDatabaseMock(),
new IdGeneratorMock(),
new TokenManagerMock(),
new HashManagerMock()
)

test("Deve retornar um Usuário a partir do (id)", async () => {
const input: GetByIdInputDTO = {
idToFind: "id-mock-normal"
}

const response = await userBusiness.getById(input)
expect(response).toEqual({
id: "id-mock-normal",
name: "Normal Mock",
email: "normal@email.com",
password: "hash-bananinha",
createdAt: expect.any(String), // valor dinâmico (pode ser qualquer string)
role: USER_ROLES.NORMAL
})
})
})

// test ("Testar se o 'id' existe",async () => {
// const input: DeleteUserInputDTO = {
// idToDelete: "newid-mock-normal",
// token: "token-mock-admin",
// }

// expect(async ()=>{
// await userBusiness.deleteUser(input)
// }).rejects.toThrow("'id' não existe")
// })
61 changes: 61 additions & 0 deletions tests/UserBusiness/login.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { UserBusiness } from "../../src/business/UserBusiness"
import { LoginInputDTO } from "../../src/dtos/userDTO"
import { BadRequestError } from "../../src/errors/BadRequestError"
import { HashManagerMock } from "../mocks/HashManagerMock"
import { IdGeneratorMock } from "../mocks/IdGeneratorMock"
import { TokenManagerMock } from "../mocks/TokenManagerMock"
Expand Down Expand Up @@ -32,4 +33,64 @@ describe("login", () => {
const response = await userBusiness.login(input)
expect(response.token).toBe("token-mock-admin")
})

test ("Testar erro de formato no signup 'email'",async () => {
expect.assertions(2);

const input: LoginInputDTO = {
email: 539,
password: "bananinha"
}

try{
await userBusiness.login(input);
}catch(error){
if(error instanceof BadRequestError){
expect(error.message).toBe("'email' deve ser string")
expect(error.statusCode).toBe(400)
}
}
})

test ("Testar erro de formato no signup 'password'",async () => {
expect.assertions(2);

const input: LoginInputDTO = {
email: "normal@email.com",
password: false
}

try{
await userBusiness.login(input);
}catch(error){
if(error instanceof BadRequestError){
expect(error.message).toBe("'password' deve ser string")
expect(error.statusCode).toBe(400)
}
}
})


//Teste com toThrow (sem try / catch)
test ("Testar erro 'email' não cadastrado",async () => {
const input: LoginInputDTO = {
email: "newemail@email.com",
password: "bananinha"
}

expect(async ()=>{
await userBusiness.login(input)
}).rejects.toThrow("'email' não cadastrado")
})

test ("Testar erro 'password' incorreta",async () => {
const input: LoginInputDTO = {
email: "normal@email.com",
password: "bolinha"
}

expect(async ()=>{
await userBusiness.login(input)
}).rejects.toThrow("'password' incorreto")
})
})
74 changes: 74 additions & 0 deletions tests/UserBusiness/signup.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { UserBusiness } from "../../src/business/UserBusiness"
import { SignupInputDTO } from "../../src/dtos/userDTO"
import { BadRequestError } from "../../src/errors/BadRequestError"
import { HashManagerMock } from "../mocks/HashManagerMock"
import { IdGeneratorMock } from "../mocks/IdGeneratorMock"
import { TokenManagerMock } from "../mocks/TokenManagerMock"
Expand All @@ -23,4 +24,77 @@ describe("signup", () => {
const response = await userBusiness.signup(input)
expect(response.token).toBe("token-mock-normal")
})

//Teste com assertions (try/catch)
test ("Testar erro de formato no signup 'name'",async () => {
expect.assertions(2);

const input: SignupInputDTO = {
email: "normal@email.com",
name: 2578,
password: "bananinha"
}

try{
await userBusiness.signup(input);
}catch(error){
if(error instanceof BadRequestError){
expect(error.message).toBe("'name' deve ser string")
expect(error.statusCode).toBe(400)
}
}
})


test ("Testar erro de formato no signup 'email'",async () => {
expect.assertions(2);

const input: SignupInputDTO = {
email: true,
name: "Normal Mock",
password: "bananinha"
}

try{
await userBusiness.signup(input);
}catch(error){
if(error instanceof BadRequestError){
expect(error.message).toBe("'email' deve ser string")
expect(error.statusCode).toBe(400)
}
}
})

test ("Testar erro de formato no signup 'password'",async () => {
expect.assertions(2);

const input: SignupInputDTO = {
email: "normal@email.com",
name: "Normal Mock",
password: 859
}

try{
await userBusiness.signup(input);
}catch(error){
if(error instanceof BadRequestError){
expect(error.message).toBe("'password' deve ser string")
expect(error.statusCode).toBe(400)
}
}
})


//Teste com toThrow (sem try / catch)
test ("Testar erro 'email' já cadastrado",async () => {
const input: SignupInputDTO = {
email: "admin@email.com",
name: "Example Mock",
password: "bananinha"
}

expect(async ()=>{
await userBusiness.signup(input)
}).rejects.toThrow("'email' já existe")
})
})