Skip to content

Commit 0a35afe

Browse files
Merge pull request #2 from LucasMeloSena/finished-server-tests
finished `server` tests
2 parents 949aebe + 802997a commit 0a35afe

File tree

8 files changed

+296
-55
lines changed

8 files changed

+296
-55
lines changed

server/src/controllers/upload.controller.ts

+20-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { signInWithEmailAndPassword } from "firebase/auth";
44
import { Auth, File, UpdateFile, Upload, createAuthSchema, createFileSchema, createFileUpdateSchema } from "../interfaces/upload.interface";
55
import { validarUploadArquivo } from "../utils/validator";
66
import { z } from "zod";
7-
import { auth } from "../utils/constants";
7+
import { auth, uploadReturnMessage } from "../utils/constants";
88
import { FirebaseError } from "firebase/app";
99
const dotenv = require("dotenv");
1010
dotenv.config();
@@ -28,13 +28,18 @@ export const uploadUserImageController = async (req: Request, res: Response, nex
2828
email: authInfo.email,
2929
senha: process.env.FIREBASE_SENHA,
3030
};
31+
32+
if (authFields.email != process.env.FIREBASE_EMAIL) {
33+
throw Error("Dados de autenticação inválidos!");
34+
}
35+
3136
await signInWithEmailAndPassword(auth, authFields.email, authFields.senha!);
3237

3338
const storageRef = ref(storage, `users/${upload.fileName}`);
3439
await uploadBytesResumable(storageRef, upload.buffer!, upload.metadata);
3540
const image: string = await getDownloadURL(storageRef);
3641

37-
res.status(201).json({ image: image });
42+
res.status(201).json({ image: image, message: uploadReturnMessage.upload });
3843
} catch (err) {
3944
const errMessage: string = (err as Error).message ?? "Ocorreu um erro ao tentar fazer o upload da imagem! Por favor, tente novamente mais tarde!";
4045

@@ -57,18 +62,23 @@ export const uploadUserImageController = async (req: Request, res: Response, nex
5762

5863
export const removeUserImageController = async (req: Request, res: Response, next: NextFunction) => {
5964
try {
65+
const authInfo: Auth = createAuthSchema.parse(req.body);
6066
const file: File = createFileSchema.parse(req.body);
6167

6268
const storage = getStorage();
6369
const storageRef = ref(storage, `users/${file.fileName}`);
6470
const authFields = {
65-
email: process.env.FIREBASE_EMAIL,
71+
email: authInfo.email,
6672
senha: process.env.FIREBASE_SENHA,
6773
};
6874

75+
if (authFields.email != process.env.FIREBASE_EMAIL) {
76+
throw Error("Dados de autenticação inválidos!");
77+
}
78+
6979
await signInWithEmailAndPassword(auth, authFields.email!, authFields.senha!);
7080
await deleteObject(storageRef);
71-
res.status(200).json({ message: "Imagem excluída com sucesso!" });
81+
res.status(200).json({ message: uploadReturnMessage.delete });
7282
} catch (err) {
7383
const errMessage: string = (err as Error).message ?? "Ocorreu um erro ao tentar remover a imagem! Por favor, tente novamente mais tarde!";
7484

@@ -101,6 +111,11 @@ export const updateUserImageController = async (req: Request, res: Response, nex
101111
email: authInfo.email,
102112
senha: process.env.FIREBASE_SENHA,
103113
};
114+
115+
if (authFields.email != process.env.FIREBASE_EMAIL) {
116+
throw Error("Dados de autenticação inválidos!");
117+
}
118+
104119
await signInWithEmailAndPassword(auth, authFields.email!, authFields.senha!);
105120
await deleteObject(storageRef);
106121

@@ -118,7 +133,7 @@ export const updateUserImageController = async (req: Request, res: Response, nex
118133
await uploadBytesResumable(newStorageRef, upload.buffer!, upload.metadata);
119134
const image: string = await getDownloadURL(newStorageRef);
120135

121-
res.status(200).json({ message: "Imagem atualizada com sucesso!", image: image });
136+
res.status(200).json({ message: uploadReturnMessage.update, image: image });
122137
} catch (err) {
123138
const errMessage: string = (err as Error).message ?? "Ocorreu um erro ao tentar atualizar a imagem! Por favor, tente novamente mais tarde!";
124139

server/src/controllers/user.controller.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ export const updateUserController = async (req: Request, res: Response, next: Ne
274274
});
275275

276276
if (!userInfo) {
277-
return res.status(404).json({message: "Usuário não encontrado!"})
277+
return res.status(404).json({ message: "Usuário não encontrado!" });
278278
}
279279

280280
if (userInfo?.senha != user.senha) {
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { Request, Response, NextFunction } from "express";
2+
import { getStorage, ref, deleteObject } from "firebase/storage";
3+
import { signInWithEmailAndPassword } from "firebase/auth";
4+
import orchestrator from "../orchestrator";
5+
import { auth, uploadReturnMessage } from "../../utils/constants";
6+
import { removeUserImageController } from "../../controllers/upload.controller";
7+
8+
jest.mock("firebase/storage");
9+
jest.mock("firebase/auth");
10+
11+
describe("Delete File", () => {
12+
let req: Partial<Request>;
13+
let res: Partial<Response>;
14+
let next: NextFunction;
15+
16+
const email = process.env.FIREBASE_EMAIL;
17+
const pass = process.env.FIREBASE_SENHA;
18+
const mockStorage = getStorage as jest.Mock;
19+
const mockRef = ref as jest.Mock;
20+
const mockSignIn = signInWithEmailAndPassword as jest.Mock;
21+
const mockDelete = deleteObject as jest.Mock;
22+
23+
beforeEach(() => {
24+
req = {
25+
body: { fileName: "test.png", email: email },
26+
};
27+
res = {
28+
status: jest.fn().mockReturnThis(),
29+
json: jest.fn(),
30+
};
31+
next = jest.fn();
32+
33+
mockStorage.mockReturnValue({});
34+
mockRef.mockReturnValue({});
35+
mockSignIn.mockResolvedValue({});
36+
mockDelete.mockReturnValue({});
37+
});
38+
39+
afterEach(() => {
40+
jest.clearAllMocks();
41+
});
42+
43+
beforeAll(async () => {
44+
await orchestrator.waitForAllServices();
45+
});
46+
47+
it("DELETE to upload/user/image should return 200", async () => {
48+
await removeUserImageController(req as Request, res as Response, next);
49+
50+
expect(mockRef).toHaveBeenCalledWith(expect.any(Object), expect.any(String));
51+
expect(mockSignIn).toHaveBeenCalledWith(auth, email, pass);
52+
expect(mockDelete).toHaveBeenCalledWith(expect.any(Object));
53+
expect(res.status).toHaveBeenCalledWith(200);
54+
expect(res.json).toHaveBeenCalledWith({ message: uploadReturnMessage.delete });
55+
});
56+
57+
it("DELETE to upload/user/image should not be able to delete with wrong auth data", async () => {
58+
req.body.email = "[email protected]";
59+
60+
await removeUserImageController(req as Request, res as Response, next);
61+
62+
expect(res.status).toHaveBeenCalledWith(500);
63+
expect(res.json).toHaveBeenCalledWith({ message: "Dados de autenticação inválidos!" });
64+
});
65+
});
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { Request, Response, NextFunction } from "express";
2+
import { updateUserImageController, uploadUserImageController } from "../../controllers/upload.controller";
3+
import { getStorage, ref, uploadBytesResumable, getDownloadURL, deleteObject } from "firebase/storage";
4+
import { signInWithEmailAndPassword } from "firebase/auth";
5+
import orchestrator from "../orchestrator";
6+
import { auth, uploadReturnMessage } from "../../utils/constants";
7+
8+
jest.mock("firebase/storage");
9+
jest.mock("firebase/auth");
10+
11+
describe("Update File", () => {
12+
let req: Partial<Request>;
13+
let res: Partial<Response>;
14+
let next: NextFunction;
15+
16+
const email = process.env.FIREBASE_EMAIL;
17+
const pass = process.env.FIREBASE_SENHA;
18+
const mockStorage = getStorage as jest.Mock;
19+
const mockRef = ref as jest.Mock;
20+
const mockUpload = uploadBytesResumable as jest.Mock;
21+
const mockImage = getDownloadURL as jest.Mock;
22+
const mockSignIn = signInWithEmailAndPassword as jest.Mock;
23+
const mockDelete = deleteObject as jest.Mock;
24+
25+
beforeEach(() => {
26+
req = {
27+
body: { email: email, oldFileName: "test.png" },
28+
file: {
29+
originalname: "test.png",
30+
mimetype: "image/png",
31+
buffer: Buffer.from("test"),
32+
fieldname: "test",
33+
filename: "file",
34+
encoding: "7bit",
35+
size: 1234,
36+
stream: jest.fn() as any,
37+
destination: "test",
38+
path: "./test.png",
39+
},
40+
};
41+
res = {
42+
status: jest.fn().mockReturnThis(),
43+
json: jest.fn(),
44+
};
45+
next = jest.fn();
46+
47+
mockStorage.mockReturnValue({});
48+
mockRef.mockReturnValue({});
49+
mockUpload.mockResolvedValue({});
50+
mockImage.mockReturnValue("https://imagemvalida.com.br");
51+
mockSignIn.mockResolvedValue({});
52+
mockDelete.mockReturnValue({});
53+
});
54+
55+
afterEach(() => {
56+
jest.clearAllMocks();
57+
});
58+
59+
beforeAll(async () => {
60+
await orchestrator.waitForAllServices();
61+
});
62+
63+
it("POST to upload/update/user/image should return 200", async () => {
64+
await updateUserImageController(req as Request, res as Response, next);
65+
66+
expect(mockRef).toHaveBeenCalledWith(expect.any(Object), expect.any(String));
67+
expect(mockSignIn).toHaveBeenCalledWith(auth, email, pass);
68+
expect(mockDelete).toHaveBeenCalledWith(expect.any(Object));
69+
expect(mockUpload).toHaveBeenCalledWith(expect.any(Object), expect.any(Buffer), expect.any(Object));
70+
expect(mockImage).toHaveBeenCalledWith(expect.any(Object));
71+
expect(res.status).toHaveBeenCalledWith(200);
72+
expect(res.json).toHaveBeenCalledWith({ image: "https://imagemvalida.com.br", message: uploadReturnMessage.update });
73+
});
74+
75+
it("POST to upload/update/user/image should not be able to upload file with wrong login data", async () => {
76+
req.body.email = "[email protected]";
77+
78+
await uploadUserImageController(req as Request, res as Response, next);
79+
80+
expect(res.status).toHaveBeenCalledWith(500);
81+
expect(res.json).toHaveBeenCalledWith({ message: "Dados de autenticação inválidos!" });
82+
});
83+
});
+74-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,81 @@
1-
import request from "supertest";
1+
import { Request, Response, NextFunction } from "express";
2+
import { uploadUserImageController } from "../../controllers/upload.controller";
3+
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
4+
import { signInWithEmailAndPassword } from "firebase/auth";
25
import orchestrator from "../orchestrator";
3-
import { app } from "../../app";
6+
import { auth, uploadReturnMessage } from "../../utils/constants";
7+
8+
jest.mock("firebase/storage");
9+
jest.mock("firebase/auth");
410

511
describe("Upload File", () => {
12+
let req: Partial<Request>;
13+
let res: Partial<Response>;
14+
let next: NextFunction;
15+
16+
const email = process.env.FIREBASE_EMAIL;
17+
const pass = process.env.FIREBASE_SENHA;
18+
const mockStorage = getStorage as jest.Mock;
19+
const mockRef = ref as jest.Mock;
20+
const mockUpload = uploadBytesResumable as jest.Mock;
21+
const mockImage = getDownloadURL as jest.Mock;
22+
const mockSignIn = signInWithEmailAndPassword as jest.Mock;
23+
24+
beforeEach(() => {
25+
req = {
26+
body: { email: email },
27+
file: {
28+
originalname: "test.png",
29+
mimetype: "image/png",
30+
buffer: Buffer.from("test"),
31+
fieldname: "test",
32+
filename: "file",
33+
encoding: "7bit",
34+
size: 1234,
35+
stream: jest.fn() as any,
36+
destination: "test",
37+
path: "./test.png",
38+
},
39+
};
40+
res = {
41+
status: jest.fn().mockReturnThis(),
42+
json: jest.fn(),
43+
};
44+
next = jest.fn();
45+
46+
mockStorage.mockReturnValue({});
47+
mockRef.mockReturnValue({});
48+
mockUpload.mockResolvedValue({});
49+
mockImage.mockReturnValue("https://imagemvalida.com.br");
50+
mockSignIn.mockResolvedValue({});
51+
});
52+
53+
afterEach(() => {
54+
jest.clearAllMocks();
55+
});
56+
657
beforeAll(async () => {
758
await orchestrator.waitForAllServices();
859
});
960

10-
it("POST to upload/user/image should return 200", async () => {
11-
12-
})
13-
})
61+
it("POST to upload/user/image should return 201", async () => {
62+
await uploadUserImageController(req as Request, res as Response, next);
63+
64+
// toHaveBeenCalledWith -> Asserção jest para verificar se a função mock realmente recebeu os parâmetros desejados!
65+
expect(mockRef).toHaveBeenCalledWith(expect.any(Object), expect.any(String));
66+
expect(mockSignIn).toHaveBeenCalledWith(auth, email, pass);
67+
expect(mockUpload).toHaveBeenCalledWith(expect.any(Object), expect.any(Buffer), expect.any(Object));
68+
expect(mockImage).toHaveBeenCalledWith(expect.any(Object));
69+
expect(res.status).toHaveBeenCalledWith(201);
70+
expect(res.json).toHaveBeenCalledWith({ image: "https://imagemvalida.com.br", message: uploadReturnMessage.upload });
71+
});
72+
73+
it("POST to upload/user/image should not be able to upload file with wrong login data", async () => {
74+
req.body.email = "[email protected]";
75+
76+
await uploadUserImageController(req as Request, res as Response, next);
77+
78+
expect(res.status).toHaveBeenCalledWith(500);
79+
expect(res.json).toHaveBeenCalledWith({ message: "Dados de autenticação inválidos!" });
80+
});
81+
});

server/src/tests/user/delete-recipe.test.ts

+8-10
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ describe("Delete Favorite Recipe", () => {
6464
recipeId: 1,
6565
})
6666
.set("Authorization", `Bearer ${loginResponse.body.token}`);
67-
68-
expect(response.status).toBe(404)
69-
expect(response.body.message).toBe("Não é possível remover uma receita que não está nos seus favoritos!")
70-
})
67+
68+
expect(response.status).toBe(404);
69+
expect(response.body.message).toBe("Não é possível remover uma receita que não está nos seus favoritos!");
70+
});
7171

7272
it("DELETE to /user/favorite/recipe should not be able to remove without token", async () => {
7373
const loginResponse = await request(app).post("/user/login").send({
@@ -83,12 +83,10 @@ describe("Delete Favorite Recipe", () => {
8383
})
8484
.set("Authorization", `Bearer ${loginResponse.body.token}`);
8585

86-
const response = await request(app)
87-
.delete("/user/favorite/recipe")
88-
.send({
89-
userId: loginResponse.body.user.id,
90-
recipeId: 1,
91-
})
86+
const response = await request(app).delete("/user/favorite/recipe").send({
87+
userId: loginResponse.body.user.id,
88+
recipeId: 1,
89+
});
9290

9391
expect(response.status).toBe(404);
9492
expect(response.body.message).toBe("Token não fornecido!");

0 commit comments

Comments
 (0)