import { beforeEach, describe, expect, it, vi } from "vitest"; const mockMemberData = ( role: string, overrides: Record = {}, ) => ({ id: "member-1", role, userId: "user-1", organizationId: "org-1", accessedProjects: [] as string[], accessedServices: [] as string[], accessedEnvironments: [] as string[], canCreateProjects: overrides.canCreateProjects ?? false, canDeleteProjects: overrides.canDeleteProjects ?? false, canCreateServices: overrides.canCreateServices ?? false, canDeleteServices: overrides.canDeleteServices ?? false, canCreateEnvironments: overrides.canCreateEnvironments ?? false, canDeleteEnvironments: overrides.canDeleteEnvironments ?? false, canAccessToTraefikFiles: overrides.canAccessToTraefikFiles ?? false, canAccessToDocker: overrides.canAccessToDocker ?? false, canAccessToAPI: overrides.canAccessToAPI ?? false, canAccessToSSHKeys: overrides.canAccessToSSHKeys ?? false, canAccessToGitProviders: overrides.canAccessToGitProviders ?? false, user: { id: "user-1", email: "test@test.com" }, }); let memberToReturn: ReturnType = mockMemberData("member"); vi.mock("@dokploy/server/db", () => ({ db: { query: { member: { findFirst: vi.fn(() => Promise.resolve(memberToReturn)), findMany: vi.fn(() => Promise.resolve([])), }, organizationRole: { findFirst: vi.fn(), findMany: vi.fn(() => Promise.resolve([])), }, }, }, })); vi.mock("@dokploy/server/services/proprietary/license-key", () => ({ hasValidLicense: vi.fn(() => Promise.resolve(false)), })); const { resolvePermissions } = await import( "@dokploy/server/services/permission" ); const { enterpriseOnlyResources, statements } = await import( "@dokploy/server/lib/access-control" ); const ctx = { user: { id: "user-1" }, session: { activeOrganizationId: "org-1" }, }; beforeEach(() => { vi.clearAllMocks(); }); describe("enterprise resources for static roles", () => { it("owner gets true for all enterprise resources", async () => { memberToReturn = mockMemberData("owner"); const perms = await resolvePermissions(ctx); for (const resource of enterpriseOnlyResources) { const actions = statements[resource as keyof typeof statements]; for (const action of actions) { expect((perms as any)[resource][action]).toBe(true); } } }); it("admin gets true for all enterprise resources", async () => { memberToReturn = mockMemberData("admin"); const perms = await resolvePermissions(ctx); for (const resource of enterpriseOnlyResources) { const actions = statements[resource as keyof typeof statements]; for (const action of actions) { expect((perms as any)[resource][action]).toBe(true); } } }); it("member gets true for service-level enterprise resources", async () => { memberToReturn = mockMemberData("member"); const perms = await resolvePermissions(ctx); expect(perms.deployment.read).toBe(true); expect(perms.deployment.create).toBe(true); expect(perms.domain.read).toBe(true); expect(perms.backup.read).toBe(true); expect(perms.logs.read).toBe(true); expect(perms.monitoring.read).toBe(true); }); it("member gets false for org-level enterprise resources", async () => { memberToReturn = mockMemberData("member"); const perms = await resolvePermissions(ctx); expect(perms.server.read).toBe(false); expect(perms.registry.read).toBe(false); expect(perms.certificate.read).toBe(false); expect(perms.destination.read).toBe(false); expect(perms.notification.read).toBe(false); expect(perms.auditLog.read).toBe(false); }); }); describe("free-tier resources for member", () => { it("member gets service.read=true", async () => { memberToReturn = mockMemberData("member"); const perms = await resolvePermissions(ctx); expect(perms.service.read).toBe(true); }); it("member gets project.create=false without legacy override", async () => { memberToReturn = mockMemberData("member"); const perms = await resolvePermissions(ctx); expect(perms.project.create).toBe(false); }); it("member gets project.create=true with canCreateProjects", async () => { memberToReturn = mockMemberData("member", { canCreateProjects: true }); const perms = await resolvePermissions(ctx); expect(perms.project.create).toBe(true); }); it("member gets docker.read=false without legacy override", async () => { memberToReturn = mockMemberData("member"); const perms = await resolvePermissions(ctx); expect(perms.docker.read).toBe(false); }); it("member gets docker.read=true with canAccessToDocker", async () => { memberToReturn = mockMemberData("member", { canAccessToDocker: true }); const perms = await resolvePermissions(ctx); expect(perms.docker.read).toBe(true); }); }); describe("free-tier resources for owner", () => { it("owner gets all free-tier permissions as true", async () => { memberToReturn = mockMemberData("owner"); const perms = await resolvePermissions(ctx); expect(perms.project.create).toBe(true); expect(perms.project.delete).toBe(true); expect(perms.service.create).toBe(true); expect(perms.service.read).toBe(true); expect(perms.service.delete).toBe(true); expect(perms.docker.read).toBe(true); expect(perms.traefikFiles.read).toBe(true); expect(perms.traefikFiles.write).toBe(true); }); });