Files
minecraft-account-manager/apps/web/src/app/admin/(console)/groups/actions.schedule.test.ts
T
dmg c131465ff5
CI / validate (push) Successful in 6m15s
Release / release (push) Successful in 7m49s
feat(admission): add scheduled group access
2026-08-02 14:04:48 -04:00

99 lines
3.4 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
const actionState = vi.hoisted(() => ({
selected: [] as unknown[][],
inserted: [] as unknown[],
deleted: 0,
authorized: 0,
failAudit: false,
}));
vi.mock("@/lib/auth/require-admin", () => ({
requireAdminSession: async () => {
actionState.authorized += 1;
return { email: "admin@example.test", name: "Admin" };
},
}));
vi.mock("next/headers", () => ({ headers: async () => new Headers() }));
vi.mock("next/navigation", () => ({
redirect: (path: string) => {
throw new Error(`REDIRECT:${path}`);
},
}));
vi.mock("@/lib/database", () => {
function selection(response: unknown[]) {
const chain: Record<string, unknown> = {};
for (const method of ["from", "where", "orderBy"]) chain[method] = () => chain;
chain.limit = () => Promise.resolve(response);
chain.then = (resolve: (value: unknown[]) => unknown, reject: (reason: unknown) => unknown) =>
Promise.resolve(response).then(resolve, reject);
return chain;
}
const tx = {
execute: async () => undefined,
select: () => selection(actionState.selected.shift() ?? []),
delete: () => ({ where: async () => { actionState.deleted += 1; } }),
insert: () => ({
values: async (value: unknown) => {
if (actionState.failAudit && !Array.isArray(value)) throw new Error("audit unavailable");
actionState.inserted.push(value);
},
}),
};
return { db: { transaction: async (callback: (transaction: typeof tx) => Promise<unknown>) => callback(tx) } };
});
import { replaceGroupSchedule } from "./actions";
function scheduleForm() {
const formData = new FormData();
formData.set("groupId", "11111111-1111-4111-8111-111111111111");
formData.append("startMinuteOfWeek", "6960");
formData.append("endMinuteOfWeek", "7200");
return formData;
}
describe("replaceGroupSchedule", () => {
beforeEach(() => {
actionState.selected = [
[{ id: "11111111-1111-4111-8111-111111111111", name: "Friday friends" }],
[{ startMinuteOfWeek: 480, endMinuteOfWeek: 540 }],
];
actionState.inserted = [];
actionState.deleted = 0;
actionState.authorized = 0;
actionState.failAudit = false;
});
it("reauthorizes and replaces all windows with an audit in one transaction", async () => {
await expect(replaceGroupSchedule(scheduleForm())).rejects.toThrow("REDIRECT:/admin/groups/11111111-1111-4111-8111-111111111111?saved=schedule");
expect(actionState.authorized).toBe(1);
expect(actionState.deleted).toBe(1);
expect(actionState.inserted[0]).toEqual([{
groupId: "11111111-1111-4111-8111-111111111111",
startMinuteOfWeek: 6960,
endMinuteOfWeek: 7200,
}]);
expect(actionState.inserted[1]).toEqual(expect.objectContaining({
type: "games.minecraft.account-manager.group.schedule-updated",
data: expect.objectContaining({
previousWindows: [{ startMinuteOfWeek: 480, endMinuteOfWeek: 540 }],
windows: [{ startMinuteOfWeek: 6960, endMinuteOfWeek: 7200 }],
adminEmail: "admin@example.test",
}),
}));
});
it("does not report success when the atomic audit write fails", async () => {
actionState.failAudit = true;
await expect(replaceGroupSchedule(scheduleForm())).rejects.toThrow("audit unavailable");
expect(actionState.inserted).toEqual([[{
groupId: "11111111-1111-4111-8111-111111111111",
startMinuteOfWeek: 6960,
endMinuteOfWeek: 7200,
}]]);
});
});