From ebf2ec17d134707b35891b47dec4926b9cfa556b Mon Sep 17 00:00:00 2001 From: Alie Date: Sat, 6 Jan 2024 12:57:22 +0100 Subject: [PATCH] added tests and auth to PUT images --- src/app.ts | 3 +- src/controllers/ImageController.ts | 6 +- src/index.ts | 2 +- src/services/ImageService.ts | 4 +- tests/app.test.ts | 89 +++++++++++++++++++++++++++++- 5 files changed, 96 insertions(+), 8 deletions(-) diff --git a/src/app.ts b/src/app.ts index 9c985eb..e76640e 100644 --- a/src/app.ts +++ b/src/app.ts @@ -15,7 +15,7 @@ app.get("/", (_, res) => { app.get("/images", imageController.getAllImages); app.get("/images/:id", imageController.getImageById); -app.put("/images/:id", imageController.editImage) +app.put("/images/:id", authControler.authorize, imageController.editImage); app.post("/images", authControler.authorize, imageController.addImage); app.post("/login", authControler.login); @@ -31,6 +31,7 @@ export const startApp = async () => { user: mongo_user, pass: mongo_pass, }); + mongoose.set("runValidators", true); app.listen(port, () => console.log(`Express server listening on port ${port}`) ); diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index ac1c207..47cc0ae 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -16,6 +16,9 @@ class ImageController { } catch (error: any) { if (error instanceof mongoose.Error.CastError) { res.status(400).json({ error: "Invalid Id" }); + } else if (error instanceof mongoose.Error.ValidationError) { + // Should return 400 Bad request for invalid requests + res.status(400).json({ error: error.message }); } else if ( error instanceof mongo.MongoServerError && error.code === 11000 @@ -24,9 +27,6 @@ class ImageController { res.status(409).json({ error: `the image with URL ${error.keyValue.url} already exists`, }); - } else if (error instanceof mongoose.Error.ValidationError) { - // Should return 400 Bad request for invalid requests - res.status(400).json({ error: error.message }); } else { res.status(500).json({ error: "Internal Server Error" }); } diff --git a/src/index.ts b/src/index.ts index 0d016b7..b431ebd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ await startApp(); // This try carch is to prevent hot reload from making the process die due to coliding entries try { // Not insert test data into production - if (process.env.NODE_ENV != "production"){ + if (process.env.NODE_ENV != "production") { await populateDatabase(); } } catch {} diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index c4b6f7a..257ef77 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -2,8 +2,8 @@ import imageModel, { Image } from "../models/ImageModel"; class ImageService { async replaceOne(id: string, newimage: Image) { - const image = await imageModel.updateOne({ _id: id }, newimage); - return image; + const result = await imageModel.updateOne({ _id: id }, newimage); + return result; } async findById(id: string) { const image = await imageModel.findOne({ _id: id }); diff --git a/tests/app.test.ts b/tests/app.test.ts index 91987dd..befa85a 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -3,6 +3,7 @@ import request, { Response } from "supertest"; import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; import populateDatabase from "./populateDatabase"; +import { Image } from "../src/models/ImageModel"; const imageServiceOriginal = imageService; @@ -178,7 +179,7 @@ describe("POST /images works properly", () => { }); }); -describe("/images/:id works properly", () => { +describe("GET /images/ works properly", () => { it("should return 200 for existing ids", async () => { const list = await request(app).get("/images"); const id = list.body.images[0]._id; @@ -200,3 +201,89 @@ describe("/images/:id works properly", () => { expect(res.status).toBe(400); }); }); + +describe("PUT /images/ works properly", () => { + let id: string; + let list: Image[]; + beforeAll(async () => { + const res = await request(app).get("/images"); + list = res.body.images; + id = list[0]._id; + }); + + it("should return 204 for valid modifications", async () => { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "available" }); + expect(res.status).toBe(204); + }); + + it("should return 404 for non-existing ids", async () => { + const id = "000000000000000000000000"; // this was the least posible to exist ID + if (!(id in list)) { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "available" }); + expect(res.status).toBe(404); + } + }); + + it("should return 400 for malformed ids", async () => { + const res = await request(app) + .put("/images/98439384") + .set("authorization", `Bearer ${token}`) + .send({ status: "available" }); + expect(res.status).toBe(400); + expect(res.body).toEqual({ error: "Invalid Id" }); + }); + + it("should return 400 for malformed requests", async () => { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "wrong" }); + expect(res.status).toBe(400); + }); + + it("should return 409 if we try to modify the url into an existing one", async () => { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ url: "https://test.url.com/2" }); + expect(res.status).toBe(409); + }); + + it("should return 500 for an error on the service", async () => { + mock.module("../src/services/ImageService", () => ({ + default: { + replaceOne: () => { + throw new Error("This is an expected testing error"); + }, + }, + })); + + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "available" }); + + expect(res.status).toBe(500); + }); + + it("should return 401 for unauthenticated requests", async () => { + const res = await request(app) + .put(`/images/${id}`) + .send({ status: "available" }); + expect(res.status).toBe(401); + }); + + it("should return 403 for invalid tokens", async () => { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer token`) + .send({ status: "available" }); + expect(res.status).toBe(403); + }); +});