From 641d672889082be3b107c2fdd4338cb6a6b54f23 Mon Sep 17 00:00:00 2001 From: sabilillah Date: Sat, 5 Aug 2023 09:26:29 +0700 Subject: [PATCH] feat: add cancel order feature --- __test__/order.test.js | 43 +++++++++++++++++++++++++++++ src/controllers/order-controller.js | 17 +++++++++++- src/routes/api.js | 1 + src/services/order-service.js | 16 +++++++++-- src/validation/order-validation.js | 4 ++- 5 files changed, 77 insertions(+), 4 deletions(-) diff --git a/__test__/order.test.js b/__test__/order.test.js index c15a7b9..b5161aa 100644 --- a/__test__/order.test.js +++ b/__test__/order.test.js @@ -131,3 +131,46 @@ describe("GET /api/orders/:orderId", function () { expect(result.body.data).toBeUndefined(); }); }); + +describe("POST /api/orders/:orderId/cancel", function () { + beforeEach(async () => { + await createTestUser(); + }); + + afterEach(async () => { + await removeTestUser(); + }); + + it("should can cancel order", async () => { + const order = await request.post("/api/orders").set("Authorization", token); + const result = await request.post(`/api/orders/${order.body.data.id}/cancel`).set("Authorization", token); + + expect(result.status).toBe(200); + expect(result.body.data.id).toBe(order.body.data.id); + expect(result.body.data.status).toBe("canceled"); + }); + + it("should reject if token is invalid", async () => { + const order = await request.post("/api/orders").set("Authorization", token); + const result = await request.post(`/api/orders/${order.body.data.id}/cancel`).set("Authorization", "invalid=token"); + + expect(result.status).toBe(401); + expect(result.body.data).toBeUndefined(); + expect(result.body.errors).toBeDefined(); + }); + + it("should reject if cancel other user order", async () => { + const user = await request + .post("/api/users") + .send({ username: "test-order", name: "Test Order", password: "rahasia123", phonenumberForm: { number: "+6288293106563", countryId: "ID" } }); + const authUser = await request.post("/api/users/login").send({ username: user.body.data.username, password: "rahasia123" }); + const product = await request.get("/api/products/pizza-0"); + await request.put("/api/users/current/carts/items").set("Authorization", authUser.body.data.token).send({ productSlug: product.body.data.slug, quantity: 5 }); + const order = await request.post("/api/orders").set("Authorization", authUser.body.data.token); + const result = await request.post(`/api/orders/${order.body.data.id}/cancel`).set("Authorization", token); + + expect(result.status).toBe(404); + expect(result.body.data).toBeUndefined(); + expect(result.body.errors).toBeDefined(); + }); +}); diff --git a/src/controllers/order-controller.js b/src/controllers/order-controller.js index 94d82b9..8d248e7 100644 --- a/src/controllers/order-controller.js +++ b/src/controllers/order-controller.js @@ -43,4 +43,19 @@ const get = async (req, res, next) => { } }; -export default { create, checkout, get }; +const cancel = async (req, res, next) => { + try { + const request = { + username: req.user.username, + orderId: req.params.orderId, + }; + + const result = await orderService.cancel(request); + + res.status(200).send({ data: result }); + } catch (error) { + next(error); + } +}; + +export default { create, checkout, get, cancel }; diff --git a/src/routes/api.js b/src/routes/api.js index 74bd3f6..6395460 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -30,5 +30,6 @@ userRouter.delete("/api/products/:productSlug/like", likeProductController.neutr userRouter.post("/api/orders", orderController.create); userRouter.get("/api/orders/:orderId", orderController.get); userRouter.post("/api/orders/checkout", orderController.checkout); +userRouter.post("/api/orders/:orderId/cancel", orderController.cancel); export { userRouter }; diff --git a/src/services/order-service.js b/src/services/order-service.js index 4c57600..144a818 100644 --- a/src/services/order-service.js +++ b/src/services/order-service.js @@ -1,5 +1,5 @@ import validate from "../validation/validation.js"; -import { checkoutValidation, createOrderValidation, deleteOrderValidation, getOrderValidation } from "../validation/order-validation.js"; +import { cancelOrderValidation, checkoutValidation, createOrderValidation, deleteOrderValidation, getOrderValidation } from "../validation/order-validation.js"; import { prismaClient } from "../app/database.js"; import { ResponseError } from "../errors/response-error.js"; import { stripe } from "../plugin/stripe.js"; @@ -140,4 +140,16 @@ const get = async (request) => { return order.orders[0]; }; -export default { create, checkout, get }; +const cancel = async (request) => { + request = validate(cancelOrderValidation, request); + + const order = await get(request); + + if (!order) { + throw new ResponseError(404, "Order not found"); + } + + return prismaClient.order.update({ where: { id: order.id }, data: { status: "canceled" } }); +}; + +export default { create, checkout, get, cancel }; diff --git a/src/validation/order-validation.js b/src/validation/order-validation.js index ab08a89..06d4e06 100644 --- a/src/validation/order-validation.js +++ b/src/validation/order-validation.js @@ -17,4 +17,6 @@ const checkoutValidation = z const getOrderValidation = z.object({ username: usernameValidation, orderId: orderIdValidation }).strict(); -export { createOrderValidation, checkoutValidation, getOrderValidation }; +const cancelOrderValidation = z.object({ username: usernameValidation, orderId: orderIdValidation }).strict(); + +export { createOrderValidation, checkoutValidation, getOrderValidation, cancelOrderValidation };