159 lines
4.7 KiB
JavaScript
159 lines
4.7 KiB
JavaScript
jest.mock("../models/household.model", () => ({
|
|
getUserRole: jest.fn(),
|
|
reorderUserHouseholds: jest.fn(),
|
|
transferOwnership: jest.fn(),
|
|
updateMemberRole: jest.fn(),
|
|
}));
|
|
|
|
jest.mock("../utils/logger", () => ({
|
|
logError: jest.fn(),
|
|
}));
|
|
|
|
const householdModel = require("../models/household.model");
|
|
const controller = require("../controllers/households.controller");
|
|
|
|
function createResponse() {
|
|
const res = {};
|
|
res.status = jest.fn().mockReturnValue(res);
|
|
res.json = jest.fn().mockReturnValue(res);
|
|
return res;
|
|
}
|
|
|
|
describe("households.controller updateMemberRole", () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
householdModel.getUserRole.mockResolvedValue("member");
|
|
householdModel.transferOwnership.mockResolvedValue({ user_id: 7, role: "owner" });
|
|
householdModel.updateMemberRole.mockResolvedValue({ user_id: 7, role: "admin" });
|
|
});
|
|
|
|
test("owner can transfer household ownership", async () => {
|
|
const req = {
|
|
params: { householdId: "3", userId: "7" },
|
|
body: { role: "owner" },
|
|
user: { id: 1 },
|
|
household: { id: 3, role: "owner" },
|
|
};
|
|
const res = createResponse();
|
|
|
|
await controller.updateMemberRole(req, res);
|
|
|
|
expect(householdModel.transferOwnership).toHaveBeenCalledWith("3", 1, 7);
|
|
expect(householdModel.updateMemberRole).not.toHaveBeenCalled();
|
|
expect(res.json).toHaveBeenCalledWith({
|
|
message: "Household ownership transferred successfully",
|
|
member: { user_id: 7, role: "owner" },
|
|
});
|
|
});
|
|
|
|
test("admin cannot transfer household ownership", async () => {
|
|
const req = {
|
|
params: { householdId: "3", userId: "7" },
|
|
body: { role: "owner" },
|
|
user: { id: 1 },
|
|
household: { id: 3, role: "admin" },
|
|
};
|
|
const res = createResponse();
|
|
|
|
await controller.updateMemberRole(req, res);
|
|
|
|
expect(householdModel.transferOwnership).not.toHaveBeenCalled();
|
|
expect(res.status).toHaveBeenCalledWith(403);
|
|
expect(res.json).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
error: expect.objectContaining({
|
|
message: "Only the household owner can transfer ownership",
|
|
}),
|
|
})
|
|
);
|
|
});
|
|
|
|
test("owner can still update a member to admin without transfer flow", async () => {
|
|
const req = {
|
|
params: { householdId: "3", userId: "7" },
|
|
body: { role: "admin" },
|
|
user: { id: 1 },
|
|
household: { id: 3, role: "owner" },
|
|
};
|
|
const res = createResponse();
|
|
|
|
await controller.updateMemberRole(req, res);
|
|
|
|
expect(householdModel.updateMemberRole).toHaveBeenCalledWith("3", "7", "admin");
|
|
expect(householdModel.transferOwnership).not.toHaveBeenCalled();
|
|
expect(res.json).toHaveBeenCalledWith({
|
|
message: "Member role updated successfully",
|
|
member: { user_id: 7, role: "admin" },
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("households.controller reorderHouseholds", () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
householdModel.reorderUserHouseholds.mockResolvedValue([
|
|
{ id: 3, name: "Third" },
|
|
{ id: 1, name: "First" },
|
|
]);
|
|
});
|
|
|
|
test("updates the current user's household order", async () => {
|
|
const req = {
|
|
body: { household_ids: [3, 1] },
|
|
user: { id: 9 },
|
|
};
|
|
const res = createResponse();
|
|
|
|
await controller.reorderHouseholds(req, res);
|
|
|
|
expect(householdModel.reorderUserHouseholds).toHaveBeenCalledWith(9, [3, 1]);
|
|
expect(res.json).toHaveBeenCalledWith({
|
|
message: "Household order updated successfully",
|
|
households: [
|
|
{ id: 3, name: "Third" },
|
|
{ id: 1, name: "First" },
|
|
],
|
|
});
|
|
});
|
|
|
|
test("rejects duplicate household IDs", async () => {
|
|
const req = {
|
|
body: { household_ids: [3, 3] },
|
|
user: { id: 9 },
|
|
};
|
|
const res = createResponse();
|
|
|
|
await controller.reorderHouseholds(req, res);
|
|
|
|
expect(householdModel.reorderUserHouseholds).not.toHaveBeenCalled();
|
|
expect(res.status).toHaveBeenCalledWith(400);
|
|
expect(res.json).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
error: expect.objectContaining({
|
|
message: "household_ids must contain unique positive household IDs",
|
|
}),
|
|
})
|
|
);
|
|
});
|
|
|
|
test("rejects orders that do not match current memberships", async () => {
|
|
householdModel.reorderUserHouseholds.mockResolvedValue(null);
|
|
const req = {
|
|
body: { household_ids: [999] },
|
|
user: { id: 9 },
|
|
};
|
|
const res = createResponse();
|
|
|
|
await controller.reorderHouseholds(req, res);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(400);
|
|
expect(res.json).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
error: expect.objectContaining({
|
|
message: "Household order must include every household you belong to",
|
|
}),
|
|
})
|
|
);
|
|
});
|
|
});
|