Files
HealthLog/tests/integration/record-settings-authorization.test.ts
T
Marc-André Bombeck d95c48f48d feat: classify managed record settings
- Inventory every Settings destination as an explicit access class\n- Fail closed for unknown deep-link destinations
2026-08-06 02:28:29 +02:00

52 lines
1.9 KiB
TypeScript

import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
import { describe, expect, it } from "vitest";
import { resolveGuardianRecordSettingsAccess } from "@/lib/record-settings/access";
import {
classifySettingsDestination,
SETTINGS_DESTINATION_INVENTORY,
} from "@/lib/record-settings/classification";
const fromRoot = (...segments: string[]) => resolve(process.cwd(), ...segments);
describe("record settings authorization", () => {
it("keeps actor and record separation", async () => {
const [authMeRoute, recordSettingsRoute] = await Promise.all([
readFile(fromRoot("src/app/api/auth/me/route.ts"), "utf8"),
readFile(fromRoot("src/app/api/record-settings/route.ts"), "utf8"),
]);
const access = resolveGuardianRecordSettingsAccess({
actor: { id: "guardian-1" },
grantId: "grant-1",
user: { id: "managed-record-1", managedProfileAt: new Date() },
});
expect(access).toMatchObject({
actorId: "guardian-1",
recordId: "managed-record-1",
recordKind: "managed",
relationship: "guardian",
});
expect(authMeRoute).toContain("requireAuth");
expect(authMeRoute).not.toContain("requireGuardianAuth");
expect(authMeRoute).not.toContain("requireRecordAuth");
expect(recordSettingsRoute).toContain("requireGuardianAuth");
expect(recordSettingsRoute).toContain("toRecordSettingsDto");
});
it("keeps settings classification exhaustive and fail closed", () => {
expect(Object.keys(SETTINGS_DESTINATION_INVENTORY)).not.toHaveLength(0);
expect(classifySettingsDestination("integrations")).toMatchObject({
kind: "managed-guardian",
guardianWritable: false,
});
expect(classifySettingsDestination("ai").kind).toBe("unavailable");
expect(classifySettingsDestination("unknown-settings-path").kind).toBe(
"unavailable",
);
});
});