refactor(api): share owned resource read access
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
assertCanReadOwnedResource,
|
||||
canManageOwnedResourceReads,
|
||||
findOwnedReadResourceId,
|
||||
resolveOwnedResourceReadFilter,
|
||||
} from "../router/resource-owned-read-access.js";
|
||||
|
||||
function createContext(options: {
|
||||
role?: string | null;
|
||||
userId?: string | null;
|
||||
resourceFindFirst?: ReturnType<typeof vi.fn>;
|
||||
} = {}) {
|
||||
return {
|
||||
dbUser: options.userId === null
|
||||
? null
|
||||
: {
|
||||
id: options.userId ?? "user_1",
|
||||
systemRole: options.role ?? "USER",
|
||||
},
|
||||
db: {
|
||||
resource: options.resourceFindFirst
|
||||
? { findFirst: options.resourceFindFirst }
|
||||
: {
|
||||
findFirst: vi.fn().mockResolvedValue({ id: "res_own" }),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("resource-owned-read-access", () => {
|
||||
it("treats admins and managers as broad readers", () => {
|
||||
expect(canManageOwnedResourceReads(createContext({ role: "ADMIN" }))).toBe(true);
|
||||
expect(canManageOwnedResourceReads(createContext({ role: "MANAGER" }))).toBe(true);
|
||||
expect(canManageOwnedResourceReads(createContext({ role: "USER" }))).toBe(false);
|
||||
});
|
||||
|
||||
it("finds the signed-in user's owned resource id", async () => {
|
||||
const resourceFindFirst = vi.fn().mockResolvedValue({ id: "res_123" });
|
||||
|
||||
await expect(findOwnedReadResourceId(createContext({ resourceFindFirst }))).resolves.toBe("res_123");
|
||||
expect(resourceFindFirst).toHaveBeenCalledWith({
|
||||
where: { userId: "user_1" },
|
||||
select: { id: true },
|
||||
});
|
||||
});
|
||||
|
||||
it("scopes regular readers to their own resource filter", async () => {
|
||||
await expect(
|
||||
resolveOwnedResourceReadFilter(
|
||||
createContext({ role: "USER" }),
|
||||
undefined,
|
||||
"forbidden",
|
||||
),
|
||||
).resolves.toBe("res_own");
|
||||
});
|
||||
|
||||
it("preserves the requested filter for managers", async () => {
|
||||
await expect(
|
||||
resolveOwnedResourceReadFilter(
|
||||
createContext({ role: "MANAGER" }),
|
||||
"res_other",
|
||||
"forbidden",
|
||||
),
|
||||
).resolves.toBe("res_other");
|
||||
});
|
||||
|
||||
it("rejects access to another resource for regular readers", async () => {
|
||||
await expect(
|
||||
assertCanReadOwnedResource(
|
||||
createContext({ role: "USER" }),
|
||||
"res_other",
|
||||
"forbidden",
|
||||
),
|
||||
).rejects.toMatchObject({
|
||||
code: "FORBIDDEN",
|
||||
message: "forbidden",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user