diff --git a/src/controllers/__tests__/authController.test.ts b/src/controllers/__tests__/authController.test.ts index e3ca858..ad7fcc4 100644 --- a/src/controllers/__tests__/authController.test.ts +++ b/src/controllers/__tests__/authController.test.ts @@ -5,107 +5,114 @@ import supertest from "supertest"; import USER from "../../models/User"; import { httpRequest, httpResponse } from "../mock/user.mock"; import GoogleController from "../googleAuthController"; -import Tokens from "../../models/token" +import Tokens from "../../models/token"; -import createServer from '../../utils/server' +import createServer from "../../utils/server"; const app = createServer(); - - jest.setTimeout(120000); describe("Login via google", () => { - afterAll(async () => { - await USER.destroy({ - where: { email: "example@example.com" }, + afterAll(async () => { + await USER.destroy({ + where: { email: "example@example.com" }, + }); + }); + test("redirect to google and authenticate", async () => { + const data = await GoogleController.googleAuth( + httpRequest("example@example.com"), + httpResponse() + ); + expect(data.body).toHaveProperty("user"); }); - }); - test("redirect to google and authenticate", async () => { - const data = await GoogleController.googleAuth( - httpRequest("example@example.com"), - httpResponse() - ); - expect(data.body).toHaveProperty("user"); - }); - test("testing register", async () => { - const data: any = await GoogleController.googleAuth( - httpRequest("example@example.com"), - httpResponse() - ); - expect(data.body).toHaveProperty("user"); - }); - test("testing 500", async () => { - const data: any = await GoogleController.googleAuth( - "helll", - httpResponse() - ); - expect(data.body.status).toBe(500); - }); + test("testing register", async () => { + const data: any = await GoogleController.googleAuth( + httpRequest("example@example.com"), + httpResponse() + ); + expect(data.body).toHaveProperty("user"); + }); + test("testing 500", async () => { + const data: any = await GoogleController.googleAuth( + "helll", + httpResponse() + ); + expect(data.body.status).toBe(500); + }); }); /* eslint-disable @typescript-eslint/no-explicit-any */ describe("Math functions", () => { - it("should multiply 5 by 3", () => { - const result = multiply(5, 3); - expect(result).toEqual(15); - }); + it("should multiply 5 by 3", () => { + const result = multiply(5, 3); + expect(result).toEqual(15); + }); - it("should add 5 by 3", () => { - const result = add(5, 3); - expect(result).toEqual(8); - }); + it("should add 5 by 3", () => { + const result = add(5, 3); + expect(result).toEqual(8); + }); }); // reset password coontroller tests -describe('reset password', () => { - describe('send link to email', () => { - test('incase of unregistered email', async () => { - const response = await supertest(app) - .post('/resetpassword/link') - .send({ email: 'unregistered@gmail.com' }) - expect(response.status).toBe(400) - }) // timeout 30 seconds - }) - test('incase of a registered email', async () => { - const response = await supertest(app) - .post('/resetpassword/link') - .send({ email: 'josephrukundo2002@gmail.com' }) - expect(response.status).toBe(200) - }) - test('incase invalid email input', async () => { - const response = await supertest(app) - .post('/resetpassword/link') - .send({ email: 'rukundjoseph' }) - expect(response.status).toBe(400) - }) - describe('add token and change password', () => { - test('incase incorrect token', async () => { - const response = await supertest(app) - .patch('/changepassword/josephrukundo2002@gmail.com/65328dba23') - .send({ newpassword: 'newpassword', confirmpass: 'newpassword' }) - expect(response.status).toBe(401) - }) - test('incase of a unmatching passwords', async () => { - const user: any = await USER.findOne({ - where: { email: 'josephrukundo2002@gmail.com' }, - }) - const token: any = await Tokens.findOne({ where: { userId: `${user.id}` } }) - const response = await supertest(app) - .patch(`/changepassword/josephrukundo2002@gmail.com/${token.token}`) - .send({ newpassword: 'newpas', confirmpass: 'newpaa' }) - expect(response.status).toBe(400) - }) - test('incase of a valid token and email', async () => { - const user: any = await USER.findOne({ - where: { email: 'josephrukundo2002@gmail.com' }, - }) - const token: any = await Tokens.findOne({ where: { userId: `${user.id}` } }) - const response = await supertest(app) - .patch(`/changepassword/josephrukundo2002@gmail.com/${token.token}`) - .send({ newpassword: 'newpas', confirmpass: 'newpas' }) - expect(response.status).toBe(200) - }) - }) -}) - - +describe("reset password", () => { + describe("send link to email", () => { + test("incase of unregistered email", async () => { + const response = await supertest(app) + .post("/resetpassword/link") + .send({ email: "unregistered@gmail.com" }); + expect(response.status).toBe(400); + }); // timeout 30 seconds + }); + test("incase of a registered email", async () => { + const response = await supertest(app) + .post("/resetpassword/link") + .send({ email: "josephrukundo2002@gmail.com" }); + expect(response.status).toBe(200); + }); + test("incase invalid email input", async () => { + const response = await supertest(app) + .post("/resetpassword/link") + .send({ email: "rukundjoseph" }); + expect(response.status).toBe(400); + }); + describe("add token and change password", () => { + test("incase incorrect token", async () => { + const response = await supertest(app) + .patch("/changepassword/josephrukundo2002@gmail.com/65328dba23") + .send({ + newpassword: "newpassword", + confirmpass: "newpassword", + }); + expect(response.status).toBe(401); + }); + test("incase of a unmatching passwords", async () => { + const user: any = await USER.findOne({ + where: { email: "josephrukundo2002@gmail.com" }, + }); + const token: any = await Tokens.findOne({ + where: { userId: `${user.id}` }, + }); + const response = await supertest(app) + .patch( + `/changepassword/josephrukundo2002@gmail.com/${token.token}` + ) + .send({ newpassword: "newpas", confirmpass: "newpaa" }); + expect(response.status).toBe(400); + }); + test("incase of a valid token and email", async () => { + const user: any = await USER.findOne({ + where: { email: "josephrukundo2002@gmail.com" }, + }); + const token: any = await Tokens.findOne({ + where: { userId: `${user.id}` }, + }); + const response = await supertest(app) + .patch( + `/changepassword/josephrukundo2002@gmail.com/${token.token}` + ) + .send({ newpassword: "newpas", confirmpass: "newpas" }); + expect(response.status).toBe(200); + }); + }); +}); diff --git a/src/controllers/__tests__/product.test.ts b/src/controllers/__tests__/product.test.ts new file mode 100644 index 0000000..030b43e --- /dev/null +++ b/src/controllers/__tests__/product.test.ts @@ -0,0 +1,29 @@ +import supertest from "supertest"; +import createServer from "../../utils/server"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +const app = createServer(); +let token; +beforeAll(async () => { + const res = await supertest(app).post("/login").send({ + email: "tec@gmail.com", + password: "adminpass", + }); + token = res.body.token; +}, 40000); + +describe("Seller Collection", () => { + describe("Seller update product availability", () => { + test("Seller update non-existing product", async () => { + const response = await supertest(app).patch( + "/products/delete/72753" + ); + expect(response.status).toBe(404); + }, 60000); + test("unauthorised access", async () => { + const response = await supertest(app).patch( + "/products/delete/72753" + ); + expect(response.status).toBe(404); + }, 60000); + }); +}); diff --git a/src/controllers/prodController.ts b/src/controllers/prodController.ts index efbeca8..9a9fb17 100644 --- a/src/controllers/prodController.ts +++ b/src/controllers/prodController.ts @@ -164,12 +164,15 @@ class ProductController { try { const ProductID = req.params.product_id; const available = req.body.isAvailable; - if (typeof available === "boolean") { + console.log(typeof available); + if (typeof available !== "boolean") { res.status(400).json({ statusCode: 400, - message: "Use true or false for avalilable", + message: + "The 'isAvailable' field must be a boolean value (true or false)", }); } + const bToken = req.headers.authorization ? req.headers.authorization.split(" ")[1] : ""; @@ -482,6 +485,50 @@ class ProductController { }); } } -} + static async deleteOneProduct(req: Request, res: Response) { + try { + const ProductID = req.params.product_id; + const bToken = req.headers.authorization + ? req.headers.authorization.split(" ")[1] + : ""; + const userData: any = decode(bToken); + const checkProduct: any = await Product.findOne({ + where: { ProductID }, + }); + if (checkProduct && userData) { + if (checkProduct.ProductOwner == userData.id) { + console.log("YOU OWN THIS PRODUCT"); + // const deletedProduct = await checkProduct.desctroy(); + await Product.destroy({ + where: { + ProductID, + }, + }); + return res.status(201).json({ + statusCode: 201, + message: "product deleted successfully", + data: checkProduct, + }); + } else { + return res.status(403).json({ + statusCode: 403, + message: + "you can not authorised to delete this product", + }); + } + } else { + return res.status(404).json({ + statusCode: 404, + message: `product with id ${ProductID} does not exist`, + }); + } + } catch (error) { + return res.json({ + statusCode: 400, + message: error, + }); + } + } +} export default ProductController; diff --git a/src/controllers/rolesPermissionControllers/__tests__/roles.test.ts b/src/controllers/rolesPermissionControllers/__tests__/roles.test.ts new file mode 100644 index 0000000..d556aed --- /dev/null +++ b/src/controllers/rolesPermissionControllers/__tests__/roles.test.ts @@ -0,0 +1,29 @@ +import supertest from "supertest"; +import createServer from "../../../utils/server"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +const app = createServer(); +let token; +beforeAll(async () => { + const res = await supertest(app).post("/login").send({ + email: "admin@gmail.com", + password: "adminpass", + }); + token = res.body.token; +}, 40000); + +describe("Admin Manage roles", () => { + describe("Authorised Access", () => { + test("View All Roles", async () => { + const response = await supertest(app).get("/role"); + expect(response.status).toBe(404); + }, 60000); + test("Get role by name", async () => { + const response = await supertest(app).get("/role/admin"); + expect(response.status).toBe(404); + }, 60000); + test("Delete role by name", async () => { + const response = await supertest(app).get("/role/abc"); + expect(response.status).toBe(404); + }, 60000); + }); +}); diff --git a/src/routes/docs.ts b/src/routes/docs.ts index 4eaeeb8..06dc772 100644 --- a/src/routes/docs.ts +++ b/src/routes/docs.ts @@ -313,6 +313,33 @@ * description: Product is already on your wishlist */ +/** + * @swagger + * /products/delete/{productId}: + * delete: + * tags: + * - Products + * summary: Seller delete the product in their collection + * security: + * - authsecurity: [] + * parameters: + * - in: path + * name: productId + * required: true + * schema: + * type: string + * description: The ID of the product to delete + * responses: + * '200': + * description: Product deleted successfuly + * '400': + * description: The request was malformed or missing required data + * '403': + * description: The user does not have permission to update the product + * '404': + * description: The specified product ID does not exist + */ + /** * @swagger * /signup: diff --git a/src/routes/productRoutes.ts b/src/routes/productRoutes.ts index 28bb336..44d31d7 100644 --- a/src/routes/productRoutes.ts +++ b/src/routes/productRoutes.ts @@ -9,12 +9,20 @@ prod.post("/add", ProductController.saveProduct); prod.patch("/update/:id", ProductController.updateProduct); prod.get("/allSellerCollection", ProductController.getAllSellerProducts); prod.get("/search", ProductController.searchProducts); +// seller manage their product availbility prod.patch( "/available/:product_id", roleAuthorization(["admin", "seller"]), ProductController.updateProductAvailability ); +// seller delete their product +prod.delete( + "/delete/:product_id", + roleAuthorization(["seller"]), + ProductController.deleteOneProduct +); + prod.post( "/wishlist/add/:id", verifyToken,