const { DEFAULT_MODULE_VISIBILITY, buildDefaultWorkspaceSetting, getSystemNavigation, normalizeModuleVisibilityJson, } = require("../../src/services/workspaceSettings"); const { hasPermission, resolvePermissionsForRoles } = require("../../src/constants/permissions"); function buildPrisma() { return { workspaceSetting: { findFirst: vi.fn().mockResolvedValue(null), }, featureFlag: { findUnique: vi.fn().mockResolvedValue(null), }, }; } function buildConfig() { return { announcementsEnabled: false, attendanceEnabled: false, budgetPrecheckEnabled: false, cutoverConsoleEnabled: false, employeeLifecycleEnabled: false, globalSearchEnabled: false, paymentBatchEnabled: false, portalHomeEnabled: false, presenceBoardEnabled: false, projectDomainEnabled: false, projectLinkingEnabled: false, todoBoardEnabled: false, weeklyReportEnabled: false, workflowDefinitionAdminEnabled: false, }; } describe("workspace small-team navigation defaults", () => { it("keeps only the R66 daily path in default main navigation", () => { const mainModules = Object.entries(DEFAULT_MODULE_VISIBILITY) .filter(([, placement]) => placement === "main") .map(([key]) => key); expect(mainModules).toEqual([ "portal", "team", "leaveRequests", "reimbursements", "assets", "weeklyReports", "todos", "announcements", "projects", ]); expect(DEFAULT_MODULE_VISIBILITY.attendance).toBe("hidden"); }); it("normalizes unknown or invalid module visibility back to the R66 defaults", () => { const normalized = normalizeModuleVisibilityJson({ attendance: "main", purchaseRequests: "hidden", unknownModule: "main", budgets: "invalid", }); expect(normalized.attendance).toBe("main"); expect(normalized.purchaseRequests).toBe("hidden"); expect(normalized.budgets).toBe(DEFAULT_MODULE_VISIBILITY.budgets); expect(normalized.unknownModule).toBeUndefined(); }); it("builds a small-team internal workspace by default", () => { const workspace = buildDefaultWorkspaceSetting(); expect(workspace.profile).toBe("small_team_internal"); expect(workspace.moduleVisibility.attendance).toBe("hidden"); }); it("keeps P2 and finance-only backup modules out of employee navigation", async () => { const employee = { id: "employee-1", department_id: "dept-1", roleCodes: ["employee"], permissionCodes: resolvePermissionsForRoles(["employee"]), }; const navigation = await getSystemNavigation({ prisma: buildPrisma(), config: buildConfig(), employee, hasPermission: (candidate, permissionCode) => hasPermission(candidate.permissionCodes, permissionCode), }); const backupKeys = navigation.sections.backup.map((item) => item.key); expect(backupKeys).toContain("purchaseRequests"); expect(backupKeys).not.toContain("travelRequests"); expect(backupKeys).not.toContain("invoicePool"); expect(backupKeys).not.toContain("contractsRegistry"); expect(backupKeys).not.toContain("budgets"); expect(backupKeys).not.toContain("paymentBatches"); expect(backupKeys).not.toContain("apOperations"); expect(backupKeys).not.toContain("erpIntegrations"); expect(backupKeys).not.toContain("dashboard"); }); it("does not expose workflow task entry to admin-only navigation", async () => { const adminOnly = { id: "admin-1", department_id: "dept-1", roleCodes: ["admin"], permissionCodes: resolvePermissionsForRoles(["admin"]), }; const navigation = await getSystemNavigation({ prisma: buildPrisma(), config: { ...buildConfig(), workflowDefinitionAdminEnabled: true }, employee: adminOnly, hasPermission: (candidate, permissionCode) => hasPermission(candidate.permissionCodes, permissionCode), }); const allKeys = [ ...navigation.sections.main, ...navigation.sections.admin, ...navigation.sections.backup, ].map((item) => item.key); expect(allKeys).toContain("auditLogs"); expect(allKeys).not.toContain("workflowTasks"); }); });