Files
EpicNext-Cms/src/lib/admin-search-permissions.test.ts
T
openhands 8638e81444
CI / check (push) Successful in 4m10s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m4s
refactor(db): typed query helpers, shared test FormData helper
Replace raw db.execute tuple casts with queryRows/rowsFrom/execResult/
affectedRows helpers from lib/db, drop redundant mysql2 casts on typed
query builders, and centralize per-test fakeForm into test/fake-form.
Update db mocks in tests so helpers resolve against mocked execute.
2026-09-17 21:02:57 +02:00

95 lines
2.3 KiB
TypeScript

import { beforeEach, expect, it, vi } from "vitest";
const state = vi.hoisted(() => ({
allowed: new Set<string>(),
queried: [] as unknown[],
}));
vi.mock("@/lib/api-handler", () => ({
withAdmin:
(_: unknown, handler: (...args: unknown[]) => unknown) =>
(request: unknown) =>
handler(request, {
session: { user: { id: 1, rank: 7 } },
permissions: { isSuperAdmin: false },
}),
}));
vi.mock("@/lib/rate-limit", () => ({ rateLimit: async () => ({ ok: true }) }));
vi.mock("@/lib/permissions", async () => ({
...(await import("@/lib/permission-slugs")),
canAccess: (_: unknown, slug: string) => state.allowed.has(slug),
}));
vi.mock("@/lib/db", async () => {
const tables = Object.fromEntries(
[
"User",
"Rooms",
"Guilds",
"WebsiteArticles",
"WebsiteRareValues",
"WebsiteShopArticles",
].map((name) => [
name,
{
name,
id: `${name}Id`,
username: `${name}Name`,
mail: `${name}Mail`,
slug: `${name}Slug`,
ownerName: `${name}Owner`,
itemId: `${name}Item`,
description: `${name}Description`,
},
]),
);
return {
...tables,
db: {
select() {
let table: unknown;
const query = {
from(value: unknown) {
table = value;
return query;
},
where() {
return query;
},
orderBy() {
return query;
},
async limit() {
state.queried.push(table);
return [{ id: 1, title: "Match", subtitle: "Data" }];
},
};
return query;
},
},
};
});
import { GET } from "@/app/api/admin/search/route";
import { PERMS } from "@/lib/permission-slugs";
beforeEach(() => {
state.allowed.clear();
state.queried.length = 0;
});
const request = () =>
({
nextUrl: new URL("https://test.invalid/api/admin/search?q=match"),
}) as Parameters<typeof GET>[0];
it("does not query or expose categories without their view permission", async () => {
const response = await GET(request(), {});
expect((await response.json()).results).toEqual([]);
expect(state.queried).toHaveLength(0);
});
it("searches only the permitted category", async () => {
state.allowed.add(PERMS.NEWS_VIEW);
const response = await GET(request(), {});
const body = await response.json();
expect(body.results).toHaveLength(1);
expect(body.results[0].type).toBe("articles");
expect(state.queried).toHaveLength(1);
});