grocery-app/backend/tests/available-items.routes.test.js
2026-03-28 22:35:34 -07:00

110 lines
3.3 KiB
JavaScript

jest.mock("../middleware/auth", () => (req, res, next) => {
req.user = { id: 42, role: "user" };
next();
});
jest.mock("../middleware/household", () => ({
householdAccess: (req, res, next) => {
req.household = {
id: Number.parseInt(req.params.householdId, 10),
role: req.headers["x-household-role"] || "user",
};
next();
},
requireHouseholdAdmin: (req, res, next) => {
if (["owner", "admin"].includes(req.household?.role)) {
return next();
}
return res.status(403).json({
error: { code: "FORBIDDEN", message: "Admin role required" },
request_id: req.request_id,
});
},
storeAccess: (req, res, next) => next(),
}));
jest.mock("../middleware/image", () => ({
upload: {
single: () => (req, res, next) => next(),
},
processImage: (req, res, next) => next(),
}));
jest.mock("../controllers/households.controller", () => ({
createHousehold: jest.fn(),
deleteHousehold: jest.fn(),
getHousehold: jest.fn(),
getMembers: jest.fn(),
getUserHouseholds: jest.fn(),
joinHousehold: jest.fn(),
refreshInviteCode: jest.fn(),
removeMember: jest.fn(),
updateHousehold: jest.fn(),
updateMemberRole: jest.fn(),
}));
jest.mock("../controllers/lists.controller.v2", () => ({
addItem: jest.fn(),
deleteItem: jest.fn(),
getClassification: jest.fn(),
getItemByName: jest.fn(),
getList: jest.fn(),
getRecentlyBought: jest.fn(),
getSuggestions: jest.fn(),
markBought: jest.fn(),
setClassification: jest.fn(),
updateItem: jest.fn(),
updateItemImage: jest.fn(),
}));
jest.mock("../controllers/available-items.controller", () => ({
createAvailableItem: jest.fn((req, res) => res.status(201).json({ message: "created" })),
deleteAvailableItem: jest.fn((req, res) => res.json({ message: "deleted" })),
getAvailableItems: jest.fn((req, res) => res.json({ items: [] })),
importCurrentItems: jest.fn((req, res) => res.json({ imported_count: 1 })),
updateAvailableItem: jest.fn((req, res) => res.json({ message: "updated" })),
}));
const express = require("express");
const request = require("supertest");
const router = require("../routes/households.routes");
const availableItemsController = require("../controllers/available-items.controller");
describe("available-items routes", () => {
let app;
beforeEach(() => {
app = express();
app.use(express.json());
app.use("/households", router);
jest.clearAllMocks();
});
test("members can read available items", async () => {
const response = await request(app).get("/households/1/stores/2/available-items");
expect(response.status).toBe(200);
expect(availableItemsController.getAvailableItems).toHaveBeenCalled();
});
test("members cannot mutate available items", async () => {
const response = await request(app)
.post("/households/1/stores/2/available-items")
.set("x-household-role", "user")
.send({ item_name: "milk" });
expect(response.status).toBe(403);
expect(availableItemsController.createAvailableItem).not.toHaveBeenCalled();
});
test("admins can create available items", async () => {
const response = await request(app)
.post("/households/1/stores/2/available-items")
.set("x-household-role", "admin")
.send({ item_name: "milk" });
expect(response.status).toBe(201);
expect(availableItemsController.createAvailableItem).toHaveBeenCalled();
});
});