Billie/storage/projects/asynchronous-programming/tests-backup2/unit/modul4-unit.test.js
2025-05-14 09:03:05 +07:00

237 lines
6.7 KiB
JavaScript

const mongoose = require("mongoose");
const Order = require("../../src/models/orderModel");
const Meja = require("../../src/models/mejaModel");
const Menu = require("../../src/models/menuModel");
const orderController = require("../../src/controllers/orderController");
const mockRequest = (body = {}, params = {}) => ({
body,
params,
});
const mockResponse = () => {
const res = {};
res.status = jest.fn().mockReturnValue(res);
res.json = jest.fn().mockReturnValue(res);
return res;
};
jest.mock("../../src/models/orderModel");
jest.mock("../../src/models/mejaModel");
jest.mock("../../src/models/menuModel");
const mockObjectId = new mongoose.Types.ObjectId();
describe("Modul 4 - Order Controller", () => {
let req, res, next;
beforeEach(() => {
jest.clearAllMocks();
req = {
body: {
tableNumber: 3,
items: [
{ menuId: mockObjectId.toString(), quantity: 1 },
{ menuId: mockObjectId.toString(), quantity: 2 },
],
},
params: {
orderId: mockObjectId.toString(),
},
};
res = mockResponse();
next = jest.fn();
});
describe("createOrder", () => {
test("harus berhasil membuat pesanan baru", async () => {
const mockMeja = {
tableNumber: 3,
status: "available",
};
const mockMenuItems = [
{ _id: mockObjectId, price: 25000 },
{ _id: mockObjectId, price: 20000 },
];
const mockSavedOrder = {
_id: mockObjectId,
tableNumber: 3,
items: req.body.items,
total: 65000,
status: "pending",
};
Meja.findOne.mockResolvedValue(mockMeja);
Menu.find.mockResolvedValue(mockMenuItems);
Order.prototype.save = jest.fn().mockResolvedValue(mockSavedOrder);
Meja.findOneAndUpdate.mockResolvedValue({ status: "reserved" });
await orderController.createOrder(req, res, next);
expect(Meja.findOne).toHaveBeenCalledWith({
tableNumber: 3,
status: "available",
});
expect(Menu.find).toHaveBeenCalled();
expect(Order.prototype.save).toHaveBeenCalled();
expect(Meja.findOneAndUpdate).toHaveBeenCalledWith(
{ tableNumber: 3 },
{ status: "reserved" },
);
expect(res.status).toHaveBeenCalledWith(201);
expect(res.json).toHaveBeenCalledWith({
success: true,
data: mockSavedOrder,
});
expect(next).not.toHaveBeenCalled();
});
test("harus menangani error ketika meja tidak tersedia", async () => {
Meja.findOne.mockResolvedValue(null);
await orderController.createOrder(req, res, next);
expect(Meja.findOne).toHaveBeenCalledWith({
tableNumber: 3,
status: "available",
});
expect(next).toHaveBeenCalledWith(expect.any(Error));
expect(next.mock.calls[0][0].message).toBe(
"Meja tidak tersedia atau sedang dipesan",
);
expect(next.mock.calls[0][0].statusCode).toBe(400);
});
test("harus menangani error ketika item menu tidak valid", async () => {
Meja.findOne.mockResolvedValue({ tableNumber: 3, status: "available" });
Menu.find.mockResolvedValue([]);
await orderController.createOrder(req, res, next);
expect(Menu.find).toHaveBeenCalled();
expect(next).toHaveBeenCalledWith(expect.any(Error));
expect(next.mock.calls[0][0].message).toBe(
"Beberapa item menu tidak valid",
);
expect(next.mock.calls[0][0].statusCode).toBe(400);
});
});
describe("getAllOrders", () => {
test("harus mengembalikan semua pesanan", async () => {
const mockOrders = [
{ _id: mockObjectId, tableNumber: 1, total: 50000, status: "pending" },
{
_id: mockObjectId,
tableNumber: 2,
total: 75000,
status: "completed",
},
];
const mockSort = jest.fn().mockResolvedValue(mockOrders);
Order.find = jest.fn().mockReturnValue({ sort: mockSort });
await orderController.getAllOrders(req, res);
expect(Order.find).toHaveBeenCalled();
expect(mockSort).toHaveBeenCalledWith({ createdAt: -1 });
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith({
success: true,
data: mockOrders,
});
});
test("harus menangani error saat mengambil pesanan", async () => {
const errorMessage = "Database error";
Order.find = jest.fn().mockImplementation(() => {
throw new Error(errorMessage);
});
await orderController.getAllOrders(req, res);
expect(Order.find).toHaveBeenCalled();
expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
success: false,
error: errorMessage,
});
});
});
describe("updateOrderStatus", () => {
test("harus berhasil mengupdate status pesanan", async () => {
req.body = { status: "completed" };
const mockUpdatedOrder = {
_id: mockObjectId,
tableNumber: 3,
status: "completed",
};
Order.findByIdAndUpdate.mockResolvedValue(mockUpdatedOrder);
Meja.findOneAndUpdate.mockResolvedValue({ status: "available" });
await orderController.updateOrderStatus(req, res);
expect(Order.findByIdAndUpdate).toHaveBeenCalledWith(
mockObjectId.toString(),
{ status: "completed" },
{ new: true },
);
expect(Meja.findOneAndUpdate).toHaveBeenCalledWith(
{ tableNumber: 3 },
{ status: "available" },
);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith({
success: true,
data: mockUpdatedOrder,
});
});
test("harus mengembalikan 404 ketika pesanan tidak ditemukan", async () => {
req.body = { status: "completed" };
Order.findByIdAndUpdate.mockResolvedValue(null);
await orderController.updateOrderStatus(req, res);
expect(Order.findByIdAndUpdate).toHaveBeenCalledWith(
mockObjectId.toString(),
{ status: "completed" },
{ new: true },
);
expect(res.status).toHaveBeenCalledWith(404);
expect(res.json).toHaveBeenCalledWith({
success: false,
error: "Pesanan tidak ditemukan",
});
});
test("harus menangani error saat mengupdate status", async () => {
req.body = { status: "completed" };
const errorMessage = "Database error";
Order.findByIdAndUpdate.mockRejectedValue(new Error(errorMessage));
await orderController.updateOrderStatus(req, res);
expect(Order.findByIdAndUpdate).toHaveBeenCalled();
expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
success: false,
error: errorMessage,
});
});
});
});