-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
desenvolvendo funcionalidade de upload da imagem do jogo
- Loading branch information
1 parent
436aae7
commit efa65ba
Showing
26 changed files
with
630 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
# api-rest-loja-games-online | ||
# api-rest-loja-games-online | ||
testando mo teclado d | ||
|
||
|
||
5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import crypto from "crypto"; | ||
import { Request } from "express"; | ||
import multer, { FileFilterCallback } from "multer"; | ||
import { resolve } from "path"; | ||
|
||
import { AppError } from "@shared/errors/AppError"; | ||
|
||
const tmpFolder = resolve(__dirname, "..", "..", "tmp"); | ||
|
||
const configUploadImage = { | ||
storage: multer.diskStorage({ | ||
destination: tmpFolder, | ||
filename: (_, file, callback) => { | ||
const fileHash = crypto.randomBytes(16).toString("hex"); | ||
|
||
const fileName = `${fileHash}-${file.originalname}`; | ||
|
||
return callback(null, fileName); | ||
}, | ||
}), | ||
|
||
limits: { | ||
fileSize: 5242880, // 5242880 Bytes = 5 MB | ||
}, | ||
|
||
fileFilter: ( | ||
_: Request, | ||
file: Express.Multer.File, | ||
callback: FileFilterCallback | ||
) => { | ||
const validExtensions = ["jpeg", "png"]; | ||
|
||
if (!validExtensions.map((ex) => `image/${ex}`).includes(file.mimetype)) { | ||
return callback(AppError.badRequest("Invalid file extension")); | ||
} | ||
|
||
return callback(null, true); | ||
}, | ||
}; | ||
|
||
const uploadImage = multer(configUploadImage); | ||
|
||
export { tmpFolder, uploadImage }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
169 changes: 169 additions & 0 deletions
169
src/modules/games/useCases/UploadGameImage/UploadGameImageController.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
/** | ||
* @jest-environment ./prisma/prisma-environment-jest | ||
*/ | ||
import crypto from "crypto"; | ||
import request from "supertest"; | ||
|
||
import { app } from "@shared/infra/http/app"; | ||
|
||
import { createTestFile, deleteTestFile } from "./fileTest"; | ||
|
||
const URL = "/games"; | ||
|
||
let token: string; | ||
let adminToken: string; | ||
const imageName = "test.png"; | ||
|
||
describe("Upload game image controller", () => { | ||
beforeAll(async () => { | ||
const adminUserEmail = "[email protected]"; | ||
const userEmail = "[email protected]"; | ||
const password = "1234"; | ||
|
||
await request(app).post("/users").send({ | ||
name: "Test admin user", | ||
email: adminUserEmail, | ||
password, | ||
admin: true, | ||
}); | ||
|
||
const responseAdminToken = await request(app).post("/users/sessions").send({ | ||
email: adminUserEmail, | ||
password, | ||
}); | ||
|
||
adminToken = responseAdminToken.body.token; | ||
|
||
await request(app).post("/users").send({ | ||
name: "Test user", | ||
email: userEmail, | ||
password, | ||
admin: false, | ||
}); | ||
|
||
const responseToken = await request(app).post("/users/sessions").send({ | ||
email: userEmail, | ||
password, | ||
}); | ||
|
||
token = responseToken.body.token; | ||
await createTestFile(imageName, __dirname); | ||
}); | ||
|
||
afterAll(async () => { | ||
await deleteTestFile(imageName, __dirname); | ||
}); | ||
|
||
it("should be able to upload the game image", async () => { | ||
const gameCreatResponse = await request(app) | ||
.post(URL) | ||
.send({ | ||
title: "Test game name", | ||
release_date: new Date(), | ||
value: 78.5, | ||
description: "Test game description", | ||
genres: [], | ||
}) | ||
.set({ | ||
Authorization: `Bearer ${adminToken}`, | ||
}); | ||
|
||
const gameUpdateResponse = await request(app) | ||
.patch(`${URL}/${gameCreatResponse.body.id}/image`) | ||
.attach("image", `${__dirname}/${imageName}`) | ||
.set({ | ||
Authorization: `Bearer ${adminToken}`, | ||
}); | ||
|
||
expect(gameUpdateResponse.statusCode).toEqual(200); | ||
expect(gameUpdateResponse.body).toHaveProperty("id"); | ||
expect(gameUpdateResponse.body).toHaveProperty("image_name"); | ||
expect(gameUpdateResponse.body.image_name).not.toBeNull(); | ||
|
||
await deleteTestFile(`games/${gameUpdateResponse.body.image_name}`); | ||
}); | ||
|
||
it("should be able to update game image if it already exists", async () => { | ||
await createTestFile(imageName, __dirname); | ||
|
||
const gameCreatResponse = await request(app) | ||
.post(URL) | ||
.send({ | ||
title: "Test game name 2", | ||
release_date: new Date(), | ||
value: 78.5, | ||
description: "Test game description", | ||
genres: [], | ||
}) | ||
.set({ | ||
Authorization: `Bearer ${adminToken}`, | ||
}); | ||
|
||
const gameUpdateResponse1 = await request(app) | ||
.patch(`${URL}/${gameCreatResponse.body.id}/image`) | ||
.attach("image", `${__dirname}/${imageName}`) | ||
.set({ | ||
Authorization: `Bearer ${adminToken}`, | ||
}); | ||
|
||
await createTestFile(imageName, __dirname); | ||
|
||
const gameUpdateResponse2 = await request(app) | ||
.patch(`${URL}/${gameCreatResponse.body.id}/image`) | ||
.attach("image", `${__dirname}/${imageName}`) | ||
.set({ | ||
Authorization: `Bearer ${adminToken}`, | ||
}); | ||
|
||
expect(gameUpdateResponse1.statusCode).toEqual(200); | ||
expect(gameUpdateResponse2.statusCode).toEqual(200); | ||
expect(gameUpdateResponse1.body).toHaveProperty("id"); | ||
expect(gameUpdateResponse2.body).toHaveProperty("id"); | ||
expect(gameUpdateResponse1.body).toHaveProperty("image_name"); | ||
expect(gameUpdateResponse2.body).toHaveProperty("image_name"); | ||
expect(gameUpdateResponse1.body.image_name).not.toBeNull(); | ||
expect(gameUpdateResponse2.body.image_name).not.toBeNull(); | ||
expect(gameUpdateResponse2.body.image_name).not.toEqual( | ||
gameUpdateResponse1.body.image_name | ||
); | ||
|
||
await deleteTestFile(`games/${gameUpdateResponse2.body.image_name}`); | ||
}); | ||
|
||
it("should not be able to upload the game image if user is not admin", async () => { | ||
const gameCreatResponse = await request(app) | ||
.post(URL) | ||
.send({ | ||
title: "Test game name 3", | ||
release_date: new Date(), | ||
value: 78.5, | ||
description: "Test game description", | ||
genres: [], | ||
}) | ||
.set({ | ||
Authorization: `Bearer ${adminToken}`, | ||
}); | ||
|
||
const gameUpdateResponse = await request(app) | ||
.patch(`${URL}/${gameCreatResponse.body.id}/image`) | ||
.attach("image", `${__dirname}/${imageName}`) | ||
.set({ | ||
Authorization: `Bearer ${token}`, | ||
}); | ||
|
||
expect(gameUpdateResponse.statusCode).toEqual(400); | ||
}); | ||
|
||
it("should not be able to upload the image unregistered game", async () => { | ||
const fakeId = crypto.randomUUID(); | ||
|
||
const gameUpdateResponse = await request(app) | ||
.patch(`${URL}/${fakeId}/image`) | ||
.attach("image", `${__dirname}/${imageName}`) | ||
.set({ | ||
Authorization: `Bearer ${adminToken}`, | ||
}); | ||
|
||
expect(gameUpdateResponse.statusCode).toEqual(404); | ||
}); | ||
}); |
25 changes: 25 additions & 0 deletions
25
src/modules/games/useCases/UploadGameImage/UploadGameImageController.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { Request, Response } from "express"; | ||
import { container } from "tsyringe"; | ||
|
||
import { HttpResponse } from "@shared/infra/http/models/HttpResponse"; | ||
|
||
import { UploadGameImageUseCase } from "./UploadGameImageUseCase"; | ||
|
||
class UploadGameImageController { | ||
async handle(request: Request, response: Response): Promise<Response> { | ||
const { id } = request.params; | ||
|
||
const imageName = request.file.filename; | ||
|
||
const uploadGameImageUseCase = container.resolve(UploadGameImageUseCase); | ||
|
||
const game = await uploadGameImageUseCase.execute({ | ||
gameId: id, | ||
imageName, | ||
}); | ||
|
||
return new HttpResponse(response).ok(game); | ||
} | ||
} | ||
|
||
export { UploadGameImageController }; |
Oops, something went wrong.