test(polls): cover merged partial updates
This commit is contained in:
1 parent
abb04f8362
commit
e69633b753
1 file changed
+122
@@ -0,0 +1,122 @@
|
||||
// @ts-nocheck
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { selectLimit, updateSet, updateWhere } = vi.hoisted(() => ({
|
||||
selectLimit: vi.fn(),
|
||||
updateSet: vi.fn(() => ({ where: updateWhere })),
|
||||
updateWhere: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/db", () => ({
|
||||
db: {
|
||||
select: vi.fn(() => ({
|
||||
from: vi.fn(() => ({
|
||||
where: vi.fn(() => ({ limit: selectLimit })),
|
||||
})),
|
||||
})),
|
||||
update: vi.fn(() => ({ set: updateSet })),
|
||||
},
|
||||
WebsitePoll: {
|
||||
id: "id",
|
||||
title: "title",
|
||||
description: "description",
|
||||
status: "status",
|
||||
showResults: "showResults",
|
||||
multipleChoice: "multipleChoice",
|
||||
startsAt: "startsAt",
|
||||
endsAt: "endsAt",
|
||||
},
|
||||
WebsitePollQuestion: {
|
||||
id: "id",
|
||||
pollId: "pollId",
|
||||
question: "question",
|
||||
type: "type",
|
||||
sortOrder: "sortOrder",
|
||||
options: "options",
|
||||
},
|
||||
WebsitePollVote: { id: "id", questionId: "questionId", userId: "userId" },
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/permissions", () => ({ PERMS: { POLLS_EDIT: "polls.edit" } }));
|
||||
vi.mock("@/lib/services/audit", () => ({ logAudit: vi.fn() }));
|
||||
vi.mock("next/cache", () => ({ revalidatePath: vi.fn() }));
|
||||
vi.mock("@/lib/safe-action", () => ({
|
||||
adminAction: (options, handler) => async (input) => {
|
||||
const parsed = options.schema.safeParse(input);
|
||||
if (!parsed.success) return { ok: false, error: "Validation failed" };
|
||||
try {
|
||||
return await handler({
|
||||
data: parsed.data,
|
||||
session: { user: { id: "1" } },
|
||||
});
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
error: error instanceof Error ? error.message : "Internal server error",
|
||||
};
|
||||
}
|
||||
},
|
||||
authAction: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/safe-action-shared", () => ({
|
||||
actionOk: (data) => ({ ok: true, data: data ?? {} }),
|
||||
actionError: (error) => ({ ok: false, error }),
|
||||
ActionError: class ActionError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "ActionError";
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
import { updatePoll, updatePollQuestion } from "./polls";
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
selectLimit.mockReset();
|
||||
updateSet.mockClear();
|
||||
updateWhere.mockClear();
|
||||
});
|
||||
|
||||
describe("poll update merge validation", () => {
|
||||
it("rejects a partial end time before the persisted start without updating", async () => {
|
||||
selectLimit.mockResolvedValueOnce([
|
||||
{
|
||||
id: 1,
|
||||
title: "Schedule",
|
||||
description: null,
|
||||
status: "draft",
|
||||
showResults: 1,
|
||||
multipleChoice: 0,
|
||||
startsAt: new Date("2026-09-02T12:00:00.000Z"),
|
||||
endsAt: null,
|
||||
},
|
||||
]);
|
||||
|
||||
const result = await updatePoll({
|
||||
id: 1,
|
||||
endsAt: "2026-09-02T11:59:00.000Z",
|
||||
});
|
||||
|
||||
expect(result).toEqual({ ok: false, error: "Invalid poll schedule" });
|
||||
expect(updateSet).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects a partial options patch for a persisted text question without updating", async () => {
|
||||
selectLimit.mockResolvedValueOnce([
|
||||
{
|
||||
pollId: 1,
|
||||
question: "Why?",
|
||||
type: "text",
|
||||
sortOrder: 0,
|
||||
options: "",
|
||||
},
|
||||
]);
|
||||
|
||||
const result = await updatePollQuestion({ id: 1, options: "Not allowed" });
|
||||
|
||||
expect(result).toEqual({ ok: false, error: "Invalid poll question" });
|
||||
expect(updateSet).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user