import { expect } from "bun:test"; import { forEachDb } from "./helpers"; import { makeApp } from "./app"; forEachDb("admin API is owner-only and manages roles, groups, access and library", async (db) => { const t = await makeApp(db); const owner = await t.signUp("owner@example.com"); const learner = await t.signUp("learner@example.com"); expect((await t.call("GET", "/api/admin/users")).status).toBe(401); expect((await t.call("GET", "/api/admin/users", { cookie: learner })).status).toBe(403); const users = await (await t.call("GET", "/api/admin/users", { cookie: owner })).json(); expect(users.map((u: { email: string }) => u.email)).toEqual(["owner@example.com", "learner@example.com"]); const [o, l] = users; // the last owner keeps the role expect((await t.call("PUT", `/api/admin/users/${o.id}/roles`, { cookie: owner, body: { roles: ["learner"] } })).status).toBe(409); expect((await t.call("PUT", `/api/admin/users/${l.id}/roles`, { cookie: owner, body: { roles: ["bogus"] } })).status).toBe(400); const r = await t.call("PUT", `/api/admin/users/${l.id}/roles`, { cookie: owner, body: { roles: ["author", "learner"] } }); expect((await r.json()).roles).toEqual(["author", "learner"]); expect((await (await t.call("GET", "/api/me", { cookie: learner })).json()).user.roles).toEqual(["author", "learner"]); const g = await (await t.call("POST", "/api/admin/groups", { cookie: owner, body: { name: "DevOps Team" } })).json(); expect(g.id).toBe("devops-team"); await t.call("PUT", `/api/admin/groups/${g.id}/members`, { cookie: owner, body: { userIds: [l.id] } }); const groups = await (await t.call("GET", "/api/admin/groups", { cookie: owner })).json(); expect(groups).toEqual([{ id: "devops-team", name: "DevOps Team", members: [l.id] }]); expect((await (await t.call("GET", "/api/me", { cookie: learner })).json()).user.groups).toEqual(["devops-team"]); await t.call("PUT", "/api/admin/courses/sample/access", { cookie: owner, body: { acl: [{ principal_type: "group", principal_id: g.id }], authors: [l.id] } }); const access = await (await t.call("GET", "/api/admin/courses/sample/access", { cookie: owner })).json(); expect(access).toEqual({ visibility: "public", acl: [{ principal_type: "group", principal_id: "devops-team" }], authors: [l.id] }); expect((await t.call("GET", "/api/admin/courses/nope/access", { cookie: owner })).status).toBe(404); const libr = await (await t.call("PUT", "/api/admin/library", { cookie: owner, body: { featured: "sample", collections: [{ title: "Getting started", courseIds: ["sample"] }] } })).json(); expect(libr.featured).toBe("sample"); expect(libr.collections).toEqual([{ id: "getting-started", title: "Getting started", sort: 0, courseIds: ["sample"] }]); const cleared = await (await t.call("PUT", "/api/admin/library", { cookie: owner, body: { collections: [] } })).json(); expect(cleared.collections).toEqual([]); await t.call("DELETE", `/api/admin/groups/${g.id}`, { cookie: owner }); expect(await (await t.call("GET", "/api/admin/groups", { cookie: owner })).json()).toEqual([]); }, 30_000);