import { describe, expect, it } from "vitest"; import { PermissionKey, SystemRole, type PermissionKey as PermissionKeyValue } from "@capakraken/shared"; import { getAvailableAssistantTools } from "../router/assistant-tool-policy.js"; import { TOOL_DEFINITIONS } from "../router/assistant-tools.js"; function getToolNames( permissions: PermissionKeyValue[], userRole: SystemRole = SystemRole.ADMIN, ) { return getAvailableAssistantTools(new Set(permissions), userRole).map((tool) => tool.function.name); } describe("assistant tool policy admin parity", () => { it("keeps import/dispo parity tools aligned to router roles and permissions", () => { const managerNames = getToolNames([PermissionKey.IMPORT_DATA], SystemRole.MANAGER); const controllerNames = getToolNames([], SystemRole.CONTROLLER); const adminNames = getToolNames([], SystemRole.ADMIN); const userNames = getToolNames([PermissionKey.IMPORT_DATA], SystemRole.USER); expect(managerNames).toContain("import_csv_data"); expect(controllerNames).toContain("export_resources_csv"); expect(controllerNames).toContain("export_projects_csv"); expect(adminNames).toContain("list_dispo_import_batches"); expect(adminNames).toContain("get_dispo_import_batch"); expect(adminNames).toContain("stage_dispo_import_batch"); expect(adminNames).toContain("validate_dispo_import_batch"); expect(adminNames).toContain("cancel_dispo_import_batch"); expect(adminNames).toContain("list_dispo_staged_resources"); expect(adminNames).toContain("list_dispo_staged_projects"); expect(adminNames).toContain("list_dispo_staged_assignments"); expect(adminNames).toContain("list_dispo_staged_vacations"); expect(adminNames).toContain("list_dispo_staged_unresolved_records"); expect(adminNames).toContain("resolve_dispo_staged_record"); expect(adminNames).toContain("commit_dispo_import_batch"); expect(userNames).not.toContain("import_csv_data"); expect(userNames).not.toContain("export_resources_csv"); expect(userNames).not.toContain("export_projects_csv"); expect(userNames).not.toContain("list_dispo_import_batches"); expect(userNames).not.toContain("get_dispo_import_batch"); expect(userNames).not.toContain("stage_dispo_import_batch"); expect(userNames).not.toContain("validate_dispo_import_batch"); expect(userNames).not.toContain("list_dispo_staged_resources"); expect(userNames).not.toContain("commit_dispo_import_batch"); }); it("keeps settings and webhook admin tools hidden while preserving protected parity tools", () => { const adminNames = getToolNames([], SystemRole.ADMIN); const managerNames = getToolNames([], SystemRole.MANAGER); const userNames = getToolNames([], SystemRole.USER); expect(adminNames).toContain("get_system_settings"); expect(adminNames).toContain("update_system_settings"); expect(adminNames).toContain("clear_stored_runtime_secrets"); expect(adminNames).toContain("test_ai_connection"); expect(adminNames).toContain("test_smtp_connection"); expect(adminNames).toContain("test_gemini_connection"); expect(adminNames).toContain("list_system_role_configs"); expect(adminNames).toContain("update_system_role_config"); expect(adminNames).toContain("list_webhooks"); expect(adminNames).toContain("get_webhook"); expect(adminNames).toContain("create_webhook"); expect(adminNames).toContain("update_webhook"); expect(adminNames).toContain("delete_webhook"); expect(adminNames).toContain("test_webhook"); expect(adminNames).toContain("get_ai_configured"); expect(managerNames).not.toContain("get_system_settings"); expect(managerNames).not.toContain("update_system_settings"); expect(managerNames).not.toContain("clear_stored_runtime_secrets"); expect(managerNames).not.toContain("test_ai_connection"); expect(managerNames).not.toContain("get_ai_configured"); expect(managerNames).not.toContain("list_system_role_configs"); expect(managerNames).not.toContain("update_system_role_config"); expect(managerNames).not.toContain("list_webhooks"); expect(managerNames).not.toContain("create_webhook"); expect(userNames).not.toContain("get_system_settings"); expect(userNames).not.toContain("update_system_settings"); expect(userNames).not.toContain("clear_stored_runtime_secrets"); expect(userNames).not.toContain("test_ai_connection"); expect(userNames).not.toContain("get_ai_configured"); expect(userNames).not.toContain("list_system_role_configs"); expect(userNames).not.toContain("update_system_role_config"); expect(userNames).not.toContain("list_webhooks"); expect(userNames).not.toContain("create_webhook"); }); it("keeps client deletion admin-only while still allowing manager client maintenance", () => { const adminNames = getToolNames([], SystemRole.ADMIN); const managerNames = getToolNames([], SystemRole.MANAGER); const userNames = getToolNames([], SystemRole.USER); expect(adminNames).toContain("create_client"); expect(adminNames).toContain("update_client"); expect(adminNames).toContain("delete_client"); expect(managerNames).toContain("create_client"); expect(managerNames).toContain("update_client"); expect(managerNames).not.toContain("delete_client"); expect(userNames).not.toContain("create_client"); expect(userNames).not.toContain("update_client"); expect(userNames).not.toContain("delete_client"); }); it("keeps holiday calendar catalog tools admin-only while leaving preview available", () => { const adminNames = getToolNames([], SystemRole.ADMIN); const managerNames = getToolNames([], SystemRole.MANAGER); const userNames = getToolNames([], SystemRole.USER); expect(adminNames).toContain("list_holiday_calendars"); expect(adminNames).toContain("get_holiday_calendar"); expect(adminNames).toContain("preview_resolved_holiday_calendar"); expect(adminNames).toContain("create_holiday_calendar"); expect(managerNames).not.toContain("list_holiday_calendars"); expect(managerNames).not.toContain("get_holiday_calendar"); expect(managerNames).toContain("preview_resolved_holiday_calendar"); expect(userNames).not.toContain("list_holiday_calendars"); expect(userNames).not.toContain("get_holiday_calendar"); expect(userNames).toContain("preview_resolved_holiday_calendar"); expect(managerNames).not.toContain("create_holiday_calendar"); expect(managerNames).not.toContain("update_holiday_calendar"); expect(managerNames).not.toContain("delete_holiday_calendar"); expect(managerNames).not.toContain("create_holiday_calendar_entry"); expect(managerNames).not.toContain("update_holiday_calendar_entry"); expect(managerNames).not.toContain("delete_holiday_calendar_entry"); }); it("keeps country and metro-city mutation tools admin-only while leaving read tools available", () => { const adminNames = getToolNames([], SystemRole.ADMIN); const managerNames = getToolNames([], SystemRole.MANAGER); const userNames = getToolNames([], SystemRole.USER); const userWithResourceOverview = getToolNames([PermissionKey.VIEW_ALL_RESOURCES], SystemRole.USER); const userWithManagedResources = getToolNames([PermissionKey.MANAGE_RESOURCES], SystemRole.USER); expect(adminNames).toContain("list_countries"); expect(adminNames).toContain("create_country"); expect(adminNames).toContain("update_country"); expect(adminNames).toContain("create_metro_city"); expect(adminNames).toContain("update_metro_city"); expect(adminNames).toContain("delete_metro_city"); expect(managerNames).toContain("list_countries"); expect(managerNames).not.toContain("create_country"); expect(managerNames).not.toContain("update_country"); expect(managerNames).not.toContain("create_metro_city"); expect(managerNames).not.toContain("update_metro_city"); expect(managerNames).not.toContain("delete_metro_city"); expect(userNames).not.toContain("search_resources"); expect(userNames).not.toContain("get_country"); expect(userNames).not.toContain("list_org_units"); expect(userWithResourceOverview).toContain("search_resources"); expect(userWithResourceOverview).toContain("get_country"); expect(userWithResourceOverview).toContain("list_org_units"); expect(userWithManagedResources).toContain("search_resources"); expect(userWithManagedResources).toContain("get_country"); expect(userWithManagedResources).toContain("list_org_units"); }); it("attaches explicit access metadata to legacy monolithic tools with restricted visibility", () => { const toolAccess = new Map( TOOL_DEFINITIONS.map((tool) => [tool.function.name, tool.access]), ); expect(toolAccess.get("run_report")).toEqual({ allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER], }); expect(toolAccess.get("simulate_scenario")).toEqual({ allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER], }); expect(toolAccess.get("detect_anomalies")).toEqual({ allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER], }); expect(toolAccess.get("get_insights_summary")).toEqual({ allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER], }); expect(toolAccess.get("lookup_rate")).toEqual({ allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER], requiredPermissions: [PermissionKey.VIEW_COSTS], }); expect(toolAccess.get("list_rate_cards")).toEqual({ allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER], requiresCostView: true, }); expect(toolAccess.get("resolve_rate")).toEqual({ allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER, SystemRole.CONTROLLER], requiresCostView: true, }); expect(toolAccess.get("import_csv_data")).toEqual({ requiredPermissions: [PermissionKey.IMPORT_DATA], allowedSystemRoles: [SystemRole.ADMIN, SystemRole.MANAGER], }); }); it("aligns assistant tool visibility with router role and permission rules", () => { const managerWithRolePermission = getToolNames( [PermissionKey.MANAGE_ROLES], SystemRole.MANAGER, ); const managerWithoutRolePermission = getToolNames([], SystemRole.MANAGER); expect(managerWithRolePermission).toContain("create_role"); expect(managerWithRolePermission).toContain("update_role"); expect(managerWithRolePermission).toContain("delete_role"); expect(managerWithRolePermission).toContain("create_client"); expect(managerWithRolePermission).toContain("update_client"); expect(managerWithRolePermission).not.toContain("create_org_unit"); expect(managerWithRolePermission).not.toContain("update_org_unit"); expect(managerWithoutRolePermission).not.toContain("create_role"); expect(managerWithoutRolePermission).not.toContain("update_role"); expect(managerWithoutRolePermission).not.toContain("delete_role"); expect(managerWithoutRolePermission).toContain("create_client"); expect(managerWithoutRolePermission).toContain("update_client"); const adminWithRolePermission = getToolNames( [PermissionKey.MANAGE_ROLES], SystemRole.ADMIN, ); expect(adminWithRolePermission).toContain("create_org_unit"); expect(adminWithRolePermission).toContain("update_org_unit"); const standardUserTools = getToolNames([], SystemRole.USER); expect(standardUserTools).toContain("get_vacation_balance"); expect(standardUserTools).toContain("create_vacation"); expect(standardUserTools).toContain("cancel_vacation"); expect(standardUserTools).not.toContain("approve_vacation"); expect(standardUserTools).not.toContain("reject_vacation"); expect(standardUserTools).not.toContain("set_entitlement"); const managerVacationTools = getToolNames([], SystemRole.MANAGER); expect(managerVacationTools).toContain("approve_vacation"); expect(managerVacationTools).toContain("reject_vacation"); expect(managerVacationTools).toContain("set_entitlement"); }); });