evOo-local/packages/db/src/scope.test.ts
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline
(Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/*
packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
2026-09-20 17:15:16 +02:00

59 lines
1.8 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import type { PrismaClient } from "./client.js";
import { IsolationError, requireMembership } from "./scope.js";
function prismaForMembership(found: boolean) {
return {
spaceMember: {
findFirst: vi.fn(async ({ where }: { where: { userId: string; spaceId?: string } }) =>
found
? {
userId: where.userId,
spaceId: where.spaceId ?? "space-default",
member: { user: { email: "owner@example.test" } },
}
: null,
),
},
deploymentSettings: {
findUnique: vi.fn(async () => ({ ownerUserId: "user-1" })),
},
} as unknown as PrismaClient;
}
describe("requireMembership", () => {
it("scopes the actor to an explicitly requested space", async () => {
const prisma = prismaForMembership(true);
await expect(requireMembership(prisma, "user-1", "space-support")).resolves.toEqual({
userId: "user-1",
spaceId: "space-support",
email: "owner@example.test",
isDeploymentOwner: true,
});
expect(prisma.spaceMember.findFirst).toHaveBeenCalledWith(
expect.objectContaining({
where: { userId: "user-1", spaceId: "space-support" },
}),
);
});
it("rejects a requested space the user does not belong to", async () => {
await expect(
requireMembership(prismaForMembership(false), "user-1", "space-foreign"),
).rejects.toBeInstanceOf(IsolationError);
});
it("selects the explicit default Space before older non-default memberships", async () => {
const prisma = prismaForMembership(true);
await requireMembership(prisma, "user-1");
expect(prisma.spaceMember.findFirst).toHaveBeenCalledWith(
expect.objectContaining({
orderBy: [{ space: { isDefault: "desc" } }, { createdAt: "asc" }, { id: "asc" }],
}),
);
});
});