Files
HealthLog/tests/integration/sharing-scope-routes.test.ts
T
Marc-André Bombeck 78ac2c5aeb refactor(sharing): read and judge grants from a leaf module
lib/sharing/grants.ts held both the grant transitions and the predicates
every reader asks (state, level, scope, the live grant for a pair). The
transitions reach into the managed-profile lifecycle and the OAuth connect
target, and both of those read a live grant, so grants, lifecycle and
connect-target formed an import cycle.

The predicates, findActiveGrant and touchGrantUsage move verbatim to
lib/sharing/grant-access.ts, which imports only the database client and
the scope vocabulary. Importers and the mocks that replaced those
functions point at the new module. Runtime import cycles fall from 7 to 6.
2026-10-23 11:02:10 +02:00

52 lines
1.6 KiB
TypeScript

import { beforeEach, describe, expect, it } from "vitest";
import { getPrismaClient, truncateAllTables } from "./setup";
import { acceptGrant, inviteGrant } from "@/lib/sharing/grants";
import { grantCoversDomain } from "@/lib/sharing/grant-access";
import { SHARE_DOMAINS } from "@/lib/sharing/scope";
let counter = 0;
async function makeUser(label: string) {
const suffix = `${label}-${counter++}`;
return getPrismaClient().user.create({
data: {
username: `scope-route-${suffix}`,
email: `scope-route-${suffix}@example.test`,
timezone: "Europe/Berlin",
},
});
}
beforeEach(async () => {
await truncateAllTables(getPrismaClient());
});
describe("scoped sharing route contract", () => {
it("persists the closed route-family set and excludes record-wide routes", async () => {
expect(SHARE_DOMAINS.length).toBeGreaterThan(0);
const owner = await makeUser("owner");
const delegate = await makeUser("delegate");
const invitation = await inviteGrant({
grantorId: owner.id,
granteeId: delegate.id,
access: "READ",
scope: [...SHARE_DOMAINS],
});
const accepted = await acceptGrant({
grantId: invitation.id,
granteeId: delegate.id,
});
const stored = await getPrismaClient().accountGrant.findUniqueOrThrow({
where: { id: accepted.id },
});
expect(stored.scopeJson).toEqual([...SHARE_DOMAINS]);
for (const domain of SHARE_DOMAINS) {
expect(grantCoversDomain(stored, domain)).toBe(true);
}
expect(grantCoversDomain(stored, "record")).toBe(false);
});
});