@jmruthers/pace-core 0.5.76 → 0.5.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/{RBACService-C4udt_Zp.d.ts → AuthService-Df3IozMG.d.ts} +10 -118
  3. package/dist/{DataTable-ntgmhO2W.d.ts → DataTable-BE0OXZKQ.d.ts} +9 -2
  4. package/dist/{DataTable-4GAVPIEG.js → DataTable-ETGVF4Y5.js} +50 -13
  5. package/dist/{PublicLoadingSpinner-BiNER8F5.d.ts → PublicLoadingSpinner-CnUaz0vG.d.ts} +5 -2
  6. package/dist/{UnifiedAuthProvider-Bj6YCf7c.d.ts → UnifiedAuthProvider-B391Aqum.d.ts} +42 -45
  7. package/dist/{UnifiedAuthProvider-3NKDOSOK.js → UnifiedAuthProvider-P5SOJAQ6.js} +4 -5
  8. package/dist/{api-DDMUKIUD.js → api-KG4A2X7P.js} +9 -3
  9. package/dist/{audit-6TOCAMKO.js → audit-65VNHEV2.js} +2 -2
  10. package/dist/{chunk-K34IM5CT.js → chunk-2OGV6IRV.js} +196 -626
  11. package/dist/chunk-2OGV6IRV.js.map +1 -0
  12. package/dist/{chunk-NTNILOBC.js → chunk-5BO3MI5Y.js} +4 -4
  13. package/dist/{chunk-XLZ7U46Z.js → chunk-CVMVPYAL.js} +9 -60
  14. package/dist/chunk-CVMVPYAL.js.map +1 -0
  15. package/dist/{chunk-URUTVZ7N.js → chunk-FL4ZCQLD.js} +2 -2
  16. package/dist/{chunk-LW7MMEAQ.js → chunk-FT2M4R4F.js} +2 -2
  17. package/dist/{chunk-5BSLGBYI.js → chunk-JCQZ6LA7.js} +2 -8
  18. package/dist/{chunk-5BSLGBYI.js.map → chunk-JCQZ6LA7.js.map} +1 -1
  19. package/dist/{chunk-KHJS6VIA.js → chunk-LRQ6RBJC.js} +157 -112
  20. package/dist/chunk-LRQ6RBJC.js.map +1 -0
  21. package/dist/{chunk-WN6XJWOS.js → chunk-MNJXXD6C.js} +274 -743
  22. package/dist/chunk-MNJXXD6C.js.map +1 -0
  23. package/dist/{chunk-KK73ZB4E.js → chunk-PTR5PMPE.js} +153 -132
  24. package/dist/chunk-PTR5PMPE.js.map +1 -0
  25. package/dist/{chunk-B2WTCLCV.js → chunk-Q7APDV6H.js} +18 -8
  26. package/dist/chunk-Q7APDV6H.js.map +1 -0
  27. package/dist/{chunk-A4FUBC7B.js → chunk-QGVSOUJ2.js} +2 -4
  28. package/dist/{chunk-A4FUBC7B.js.map → chunk-QGVSOUJ2.js.map} +1 -1
  29. package/dist/{chunk-FGMFQSHX.js → chunk-S63MFSY6.js} +500 -551
  30. package/dist/chunk-S63MFSY6.js.map +1 -0
  31. package/dist/{chunk-AFGTSUAD.js → chunk-VSOKOFRF.js} +4 -4
  32. package/dist/chunk-WUXCWRL6.js +20 -0
  33. package/dist/chunk-WUXCWRL6.js.map +1 -0
  34. package/dist/{chunk-Y6TXWPJO.js → chunk-YVVGHRGI.js} +105 -31
  35. package/dist/chunk-YVVGHRGI.js.map +1 -0
  36. package/dist/{chunk-M5IWZRBT.js → chunk-ZMNXIJP4.js} +2187 -981
  37. package/dist/chunk-ZMNXIJP4.js.map +1 -0
  38. package/dist/components.d.ts +6 -6
  39. package/dist/components.js +14 -18
  40. package/dist/components.js.map +1 -1
  41. package/dist/{database-C3Szpi5J.d.ts → database-BXAfr2Y_.d.ts} +18 -0
  42. package/dist/hooks.d.ts +5 -5
  43. package/dist/hooks.js +8 -9
  44. package/dist/hooks.js.map +1 -1
  45. package/dist/index.d.ts +19 -27
  46. package/dist/index.js +21 -29
  47. package/dist/index.js.map +1 -1
  48. package/dist/{organisation-BtshODVF.d.ts → organisation-D6qRDtbF.d.ts} +1 -1
  49. package/dist/providers.d.ts +7 -21
  50. package/dist/providers.js +3 -10
  51. package/dist/rbac/index.d.ts +71 -221
  52. package/dist/rbac/index.js +15 -16
  53. package/dist/{types-CGX9Vyf5.d.ts → types-BDg1mAGG.d.ts} +36 -6
  54. package/dist/types.d.ts +3 -3
  55. package/dist/types.js +61 -18
  56. package/dist/types.js.map +1 -1
  57. package/dist/{unified-CM7T0aTK.d.ts → unified-DQ4VcT7H.d.ts} +1 -1
  58. package/dist/{usePublicRouteParams-B-CumWRc.d.ts → usePublicRouteParams-BlgwXweB.d.ts} +3 -3
  59. package/dist/utils.d.ts +2 -2
  60. package/dist/utils.js +52 -9
  61. package/dist/utils.js.map +1 -1
  62. package/docs/CONTENT_AUDIT_REPORT.md +253 -0
  63. package/docs/DOCUMENTATION_AUDIT.md +172 -0
  64. package/docs/README.md +142 -147
  65. package/docs/STYLE_GUIDE.md +37 -0
  66. package/docs/api/classes/ColumnFactory.md +17 -17
  67. package/docs/api/classes/ErrorBoundary.md +1 -1
  68. package/docs/api/classes/InvalidScopeError.md +4 -4
  69. package/docs/api/classes/MissingUserContextError.md +4 -4
  70. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  71. package/docs/api/classes/PermissionDeniedError.md +5 -5
  72. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  73. package/docs/api/classes/RBACAuditManager.md +8 -8
  74. package/docs/api/classes/RBACCache.md +35 -5
  75. package/docs/api/classes/RBACEngine.md +49 -20
  76. package/docs/api/classes/RBACError.md +4 -4
  77. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  78. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  79. package/docs/api/classes/StorageUtils.md +1 -1
  80. package/docs/api/enums/FileCategory.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +4 -4
  82. package/docs/api/interfaces/ButtonProps.md +1 -1
  83. package/docs/api/interfaces/CardProps.md +1 -1
  84. package/docs/api/interfaces/ColorPalette.md +1 -1
  85. package/docs/api/interfaces/ColorShade.md +1 -1
  86. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  87. package/docs/api/interfaces/DataRecord.md +11 -0
  88. package/docs/api/interfaces/DataTableAction.md +65 -29
  89. package/docs/api/interfaces/DataTableColumn.md +36 -23
  90. package/docs/api/interfaces/DataTableProps.md +80 -38
  91. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  92. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  93. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  94. package/docs/api/interfaces/EventLogoProps.md +1 -1
  95. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  96. package/docs/api/interfaces/FileMetadata.md +1 -1
  97. package/docs/api/interfaces/FileReference.md +1 -1
  98. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  99. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  100. package/docs/api/interfaces/FileUploadProps.md +1 -1
  101. package/docs/api/interfaces/FooterProps.md +1 -1
  102. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  103. package/docs/api/interfaces/InputProps.md +1 -1
  104. package/docs/api/interfaces/LabelProps.md +1 -1
  105. package/docs/api/interfaces/LoginFormProps.md +1 -1
  106. package/docs/api/interfaces/NavigationAccessRecord.md +11 -11
  107. package/docs/api/interfaces/NavigationContextType.md +9 -9
  108. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  109. package/docs/api/interfaces/NavigationItem.md +1 -1
  110. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  111. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  112. package/docs/api/interfaces/Organisation.md +1 -1
  113. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  114. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  115. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  116. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  117. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  118. package/docs/api/interfaces/PaceLoginPageProps.md +16 -3
  119. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  120. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  121. package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
  122. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  123. package/docs/api/interfaces/PaletteData.md +1 -1
  124. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  125. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  126. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  127. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  128. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  130. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  131. package/docs/api/interfaces/RBACConfig.md +1 -1
  132. package/docs/api/interfaces/RBACLogger.md +1 -1
  133. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  134. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  135. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  136. package/docs/api/interfaces/RouteConfig.md +2 -2
  137. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  138. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  139. package/docs/api/interfaces/StorageConfig.md +1 -1
  140. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  141. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  142. package/docs/api/interfaces/StorageListOptions.md +1 -1
  143. package/docs/api/interfaces/StorageListResult.md +1 -1
  144. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  145. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  146. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  147. package/docs/api/interfaces/StyleImport.md +1 -1
  148. package/docs/api/interfaces/SwitchProps.md +1 -1
  149. package/docs/api/interfaces/ToastActionElement.md +1 -1
  150. package/docs/api/interfaces/ToastProps.md +1 -1
  151. package/docs/api/interfaces/UnifiedAuthContextType.md +94 -521
  152. package/docs/api/interfaces/UnifiedAuthProviderProps.md +16 -16
  153. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  154. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  155. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  159. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  160. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  161. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  162. package/docs/api/interfaces/UserEventAccess.md +11 -11
  163. package/docs/api/interfaces/UserMenuProps.md +1 -1
  164. package/docs/api/interfaces/UserProfile.md +1 -1
  165. package/docs/api/modules.md +251 -269
  166. package/docs/api-reference/components.md +193 -0
  167. package/docs/api-reference/hooks.md +265 -0
  168. package/docs/api-reference/providers.md +6 -0
  169. package/docs/api-reference/types.md +6 -0
  170. package/docs/api-reference/utilities.md +207 -0
  171. package/docs/architecture/README.md +6 -0
  172. package/docs/{database-schema-requirements.md → architecture/database-schema-requirements.md} +6 -0
  173. package/docs/architecture/rbac-security-architecture.md +258 -0
  174. package/docs/architecture/services.md +9 -1
  175. package/docs/best-practices/README.md +6 -0
  176. package/docs/best-practices/accessibility.md +6 -0
  177. package/docs/{common-patterns.md → best-practices/common-patterns.md} +6 -0
  178. package/docs/best-practices/deployment.md +6 -0
  179. package/docs/best-practices/performance.md +475 -2
  180. package/docs/best-practices/security.md +6 -0
  181. package/docs/best-practices/testing.md +6 -0
  182. package/docs/core-concepts/authentication.md +6 -0
  183. package/docs/core-concepts/events.md +6 -0
  184. package/docs/core-concepts/organisations.md +6 -0
  185. package/docs/core-concepts/permissions.md +6 -0
  186. package/docs/core-concepts/rbac-system.md +8 -0
  187. package/docs/documentation-index.md +121 -182
  188. package/docs/{consuming-app-vite-config.md → getting-started/consuming-app-vite-config.md} +6 -0
  189. package/docs/getting-started/documentation-index.md +40 -0
  190. package/docs/getting-started/examples/README.md +878 -35
  191. package/docs/{faq.md → getting-started/faq.md} +7 -1
  192. package/docs/getting-started/installation-guide.md +6 -0
  193. package/docs/{quick-reference.md → getting-started/quick-reference.md} +6 -0
  194. package/docs/implementation-guides/app-layout.md +6 -0
  195. package/docs/implementation-guides/authentication.md +1021 -0
  196. package/docs/implementation-guides/component-styling.md +6 -0
  197. package/docs/implementation-guides/data-tables.md +1264 -2076
  198. package/docs/implementation-guides/dynamic-colors.md +6 -0
  199. package/docs/implementation-guides/event-theming-summary.md +6 -0
  200. package/docs/{file-reference-system.md → implementation-guides/file-reference-system.md} +6 -0
  201. package/docs/implementation-guides/file-upload-storage.md +6 -0
  202. package/docs/implementation-guides/forms.md +6 -0
  203. package/docs/implementation-guides/inactivity-tracking.md +6 -0
  204. package/docs/implementation-guides/navigation.md +6 -0
  205. package/docs/implementation-guides/organisation-security.md +6 -0
  206. package/docs/implementation-guides/permission-enforcement.md +6 -0
  207. package/docs/implementation-guides/public-pages-advanced.md +6 -0
  208. package/docs/implementation-guides/public-pages.md +6 -0
  209. package/docs/migration/MIGRATION_GUIDE.md +827 -351
  210. package/docs/migration/README.md +7 -1
  211. package/docs/migration/organisation-context-timing-fix.md +6 -0
  212. package/docs/migration/rbac-migration.md +44 -1
  213. package/docs/migration/service-architecture.md +6 -0
  214. package/docs/migration/v0.4.15-tailwind-scanning.md +6 -0
  215. package/docs/migration/v0.4.16-css-first-approach.md +6 -0
  216. package/docs/migration/v0.4.17-source-path-fix.md +6 -0
  217. package/docs/rbac/README-rbac-rls-integration.md +6 -0
  218. package/docs/rbac/README.md +6 -0
  219. package/docs/rbac/advanced-patterns.md +6 -0
  220. package/docs/rbac/api-reference.md +7 -1
  221. package/docs/rbac/breaking-changes-v3.md +222 -0
  222. package/docs/rbac/examples/rbac-rls-integration-example.md +6 -0
  223. package/docs/rbac/examples.md +6 -0
  224. package/docs/rbac/getting-started.md +6 -0
  225. package/docs/rbac/migration-guide.md +260 -0
  226. package/docs/rbac/quick-start.md +70 -13
  227. package/docs/rbac/rbac-rls-integration.md +6 -0
  228. package/docs/rbac/super-admin-guide.md +6 -0
  229. package/docs/rbac/troubleshooting.md +6 -0
  230. package/docs/security/README.md +6 -0
  231. package/docs/security/checklist.md +6 -0
  232. package/docs/styles/README.md +7 -1
  233. package/docs/{usage.md → styles/usage.md} +6 -0
  234. package/docs/testing/README.md +6 -0
  235. package/docs/{visual-testing.md → testing/visual-testing.md} +6 -0
  236. package/docs/troubleshooting/README.md +387 -5
  237. package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +6 -0
  238. package/docs/troubleshooting/common-issues.md +6 -0
  239. package/docs/troubleshooting/database-view-compatibility.md +6 -0
  240. package/docs/troubleshooting/organisation-context-setup.md +6 -0
  241. package/docs/troubleshooting/react-hooks-issue-analysis.md +6 -0
  242. package/docs/troubleshooting/styling-issues.md +6 -0
  243. package/docs/troubleshooting/tailwind-content-scanning.md +6 -0
  244. package/package.json +1 -1
  245. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -1
  246. package/src/__tests__/helpers/test-providers.tsx +3 -53
  247. package/src/components/DataTable/DataTable.test.tsx +319 -0
  248. package/src/components/DataTable/DataTable.tsx +32 -11
  249. package/src/components/DataTable/__tests__/{DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx.skip} +6 -4
  250. package/src/components/DataTable/__tests__/{DataTable.test.tsx → DataTable.test.tsx.skip} +6 -4
  251. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +31 -9
  252. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +601 -0
  253. package/src/components/DataTable/__tests__/keyboard.test.tsx +615 -0
  254. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +639 -0
  255. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx.skip +330 -0
  256. package/src/components/DataTable/components/AccessDeniedPage.tsx +2 -2
  257. package/src/components/DataTable/components/ActionButtons.tsx +88 -104
  258. package/src/components/DataTable/components/DataTableCore.tsx +309 -337
  259. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +4 -2
  260. package/src/components/DataTable/components/DataTableModals.tsx +22 -1
  261. package/src/components/DataTable/components/EditableRow.tsx +69 -84
  262. package/src/components/DataTable/components/EmptyState.tsx +5 -1
  263. package/src/components/DataTable/components/ImportModal.tsx +65 -36
  264. package/src/components/DataTable/components/PaginationControls.tsx +40 -100
  265. package/src/components/DataTable/components/UnifiedTableBody.tsx +125 -148
  266. package/src/components/DataTable/context/DataTableContext.tsx +1 -1
  267. package/src/components/DataTable/core/ColumnFactory.ts +5 -0
  268. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +12 -10
  269. package/src/components/DataTable/examples/HierarchicalExample.tsx +1 -1
  270. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +1 -0
  271. package/src/components/DataTable/examples/PerformanceExample.tsx +1 -0
  272. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +1 -5
  273. package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +167 -0
  274. package/src/components/DataTable/hooks/index.ts +7 -0
  275. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +32 -15
  276. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +102 -0
  277. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +89 -0
  278. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +117 -0
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +71 -27
  280. package/src/components/DataTable/hooks/useDataTableState.ts +39 -11
  281. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +33 -0
  282. package/src/components/DataTable/hooks/useHierarchicalState.ts +15 -1
  283. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +447 -0
  284. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +94 -0
  285. package/src/components/DataTable/hooks/useTableColumns.ts +10 -7
  286. package/src/components/DataTable/hooks/useTableHandlers.ts +174 -0
  287. package/src/components/DataTable/index.ts +12 -3
  288. package/src/components/DataTable/types.ts +129 -9
  289. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +159 -22
  290. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +111 -0
  291. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +15 -29
  292. package/src/components/DataTable/utils/a11yUtils.ts +244 -0
  293. package/src/components/DataTable/utils/debugTools.ts +609 -0
  294. package/src/components/DataTable/utils/exportUtils.ts +114 -16
  295. package/src/components/DataTable/utils/flexibleImport.ts +202 -32
  296. package/src/components/DataTable/utils/hierarchicalUtils.ts +1 -1
  297. package/src/components/DataTable/utils/index.ts +2 -0
  298. package/src/components/DataTable/utils/paginationUtils.ts +350 -0
  299. package/src/components/DataTable/utils/rowUtils.ts +6 -5
  300. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -24
  301. package/src/components/NavigationMenu/NavigationMenu.tsx +19 -8
  302. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +1 -23
  303. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +56 -6
  304. package/src/components/PaceLoginPage/PaceLoginPage.tsx +137 -13
  305. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +1 -1
  306. package/src/components/Select/Select.tsx +1 -0
  307. package/src/components/examples/PermissionExample.tsx +173 -0
  308. package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
  309. package/src/examples/PublicEventPage.tsx +274 -0
  310. package/src/examples/PublicPageApp.tsx +308 -0
  311. package/src/examples/PublicPageUsageExample.tsx +216 -0
  312. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +12 -1
  313. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +129 -17
  314. package/src/hooks/__tests__/useRBAC.unit.test.ts +151 -846
  315. package/src/hooks/useOrganisationPermissions.test.ts +42 -18
  316. package/src/hooks/useOrganisationPermissions.ts +12 -6
  317. package/src/hooks/useOrganisationSecurity.test.ts +138 -85
  318. package/src/hooks/useOrganisationSecurity.ts +41 -10
  319. package/src/index.ts +0 -1
  320. package/src/providers/AuthProvider.simplified.tsx +880 -0
  321. package/src/providers/UnifiedAuthProvider.test.simple.tsx +8 -8
  322. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +29 -19
  323. package/src/providers/index.ts +0 -1
  324. package/src/providers/services/EventServiceProvider.tsx +19 -15
  325. package/src/providers/services/InactivityServiceProvider.tsx +19 -15
  326. package/src/providers/services/OrganisationServiceProvider.tsx +19 -15
  327. package/src/providers/services/UnifiedAuthProvider.tsx +156 -127
  328. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +1 -1
  329. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -3
  330. package/src/rbac/README.md +1 -1
  331. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +25 -27
  332. package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +313 -0
  333. package/src/rbac/__tests__/engine.comprehensive.test.ts +114 -348
  334. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +28 -110
  335. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +33 -85
  336. package/src/rbac/__tests__/scenarios.user-role.test.tsx +2 -2
  337. package/src/rbac/adapters.tsx +26 -69
  338. package/src/rbac/api.test.ts +90 -27
  339. package/src/rbac/api.ts +61 -10
  340. package/src/rbac/audit.test.ts +33 -38
  341. package/src/rbac/audit.ts +21 -6
  342. package/src/rbac/cache.ts +33 -1
  343. package/src/rbac/components/NavigationGuard.tsx +11 -11
  344. package/src/rbac/components/NavigationProvider.test.tsx +11 -5
  345. package/src/rbac/components/NavigationProvider.tsx +37 -13
  346. package/src/rbac/components/PagePermissionGuard.tsx +111 -50
  347. package/src/rbac/components/PagePermissionProvider.tsx +5 -5
  348. package/src/rbac/components/PermissionEnforcer.tsx +11 -11
  349. package/src/rbac/components/RoleBasedRouter.tsx +5 -5
  350. package/src/rbac/components/SecureDataProvider.tsx +5 -5
  351. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +8 -8
  352. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +14 -14
  353. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +12 -12
  354. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +6 -6
  355. package/src/rbac/engine.test.simple.ts +19 -13
  356. package/src/rbac/engine.test.ts +1 -0
  357. package/src/rbac/engine.ts +330 -766
  358. package/src/rbac/errors.ts +156 -0
  359. package/src/rbac/hooks/usePermissions.ts +32 -10
  360. package/src/rbac/hooks/useRBAC.test.ts +126 -512
  361. package/src/rbac/hooks/useRBAC.ts +147 -193
  362. package/src/rbac/hooks/useResolvedScope.ts +12 -0
  363. package/src/rbac/index.ts +7 -4
  364. package/src/rbac/security.ts +109 -18
  365. package/src/rbac/types.ts +12 -1
  366. package/src/services/AuthService.ts +2 -15
  367. package/src/services/EventService.ts +43 -46
  368. package/src/services/OrganisationService.ts +51 -31
  369. package/src/services/__tests__/AuthService.test.ts +1 -1
  370. package/src/services/__tests__/EventService.test.ts +1 -1
  371. package/src/services/__tests__/OrganisationService.test.ts +1 -1
  372. package/src/services/base/BaseService.ts +8 -0
  373. package/src/styles/base.css +208 -0
  374. package/src/styles/semantic.css +24 -0
  375. package/src/types/database.generated.ts +7347 -0
  376. package/src/types/database.ts +20 -0
  377. package/src/utils/logger.ts +179 -0
  378. package/src/utils/organisationContext.ts +11 -4
  379. package/src/utils/storage/__tests__/helpers.unit.test.ts +6 -2
  380. package/dist/appNameResolver-UURKN7NF.js +0 -22
  381. package/dist/audit-6TOCAMKO.js.map +0 -1
  382. package/dist/chunk-B2WTCLCV.js.map +0 -1
  383. package/dist/chunk-FGMFQSHX.js.map +0 -1
  384. package/dist/chunk-K34IM5CT.js.map +0 -1
  385. package/dist/chunk-KHJS6VIA.js.map +0 -1
  386. package/dist/chunk-KK73ZB4E.js.map +0 -1
  387. package/dist/chunk-M5IWZRBT.js.map +0 -1
  388. package/dist/chunk-ULBI5JGB.js +0 -109
  389. package/dist/chunk-ULBI5JGB.js.map +0 -1
  390. package/dist/chunk-WN6XJWOS.js.map +0 -1
  391. package/dist/chunk-XLZ7U46Z.js.map +0 -1
  392. package/dist/chunk-Y6TXWPJO.js.map +0 -1
  393. package/docs/DOCUMENTATION_CHECKLIST.md +0 -281
  394. package/docs/TERMINOLOGY.md +0 -231
  395. package/docs/api/interfaces/RBACContextType.md +0 -468
  396. package/docs/api/interfaces/RBACProviderProps.md +0 -107
  397. package/docs/best-practices/performance-expansion.md +0 -473
  398. package/docs/breaking-changes.md +0 -179
  399. package/docs/consuming-app-example.md +0 -290
  400. package/docs/documentation-templates.md +0 -539
  401. package/docs/examples/navigation-menu-auth-fix.md +0 -344
  402. package/docs/getting-started/examples/basic-auth-app.md +0 -520
  403. package/docs/getting-started/examples/full-featured-app.md +0 -616
  404. package/docs/getting-started/quick-start.md +0 -376
  405. package/docs/implementation-guides/datatable-filtering.md +0 -313
  406. package/docs/implementation-guides/datatable-rbac-usage.md +0 -317
  407. package/docs/implementation-guides/hierarchical-datatable.md +0 -850
  408. package/docs/implementation-guides/large-datasets.md +0 -281
  409. package/docs/implementation-guides/performance.md +0 -403
  410. package/docs/migration/quick-migration-guide.md +0 -320
  411. package/docs/migration-guide.md +0 -193
  412. package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +0 -226
  413. package/docs/performance/README.md +0 -551
  414. package/docs/style-guide.md +0 -964
  415. package/docs/troubleshooting/authentication-issues.md +0 -334
  416. package/docs/troubleshooting/debugging.md +0 -1117
  417. package/docs/troubleshooting/migration.md +0 -918
  418. package/src/__tests__/hooks/usePermissions.test.ts +0 -261
  419. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +0 -574
  420. package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -613
  421. package/src/hooks/services/__tests__/useServiceHooks.test.tsx +0 -137
  422. package/src/hooks/services/usePermissions.ts +0 -70
  423. package/src/hooks/services/useRBACService.ts +0 -30
  424. package/src/hooks/usePermissionCheck.ts +0 -150
  425. package/src/providers/__tests__/ServiceProviders.test.tsx +0 -477
  426. package/src/providers/services/RBACServiceProvider.tsx +0 -79
  427. package/src/rbac/__tests__/integration.authflow.test.tsx +0 -119
  428. package/src/rbac/__tests__/integration.navigation.test.tsx +0 -69
  429. package/src/rbac/__tests__/integration.securedata.test.tsx +0 -92
  430. package/src/rbac/__tests__/integration.smoke.test.tsx +0 -73
  431. package/src/rbac/providers/RBACProvider.tsx +0 -645
  432. package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +0 -688
  433. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +0 -1186
  434. package/src/rbac/providers/index.ts +0 -11
  435. package/src/services/RBACService.ts +0 -522
  436. package/src/services/__tests__/RBACService.test.ts +0 -492
  437. package/src/services/interfaces/IRBACService.ts +0 -62
  438. package/src/utils/appNameResolver.test 2.ts +0 -494
  439. /package/dist/{DataTable-4GAVPIEG.js.map → DataTable-ETGVF4Y5.js.map} +0 -0
  440. /package/dist/{UnifiedAuthProvider-3NKDOSOK.js.map → UnifiedAuthProvider-P5SOJAQ6.js.map} +0 -0
  441. /package/dist/{api-DDMUKIUD.js.map → api-KG4A2X7P.js.map} +0 -0
  442. /package/dist/{appNameResolver-UURKN7NF.js.map → audit-65VNHEV2.js.map} +0 -0
  443. /package/dist/{chunk-NTNILOBC.js.map → chunk-5BO3MI5Y.js.map} +0 -0
  444. /package/dist/{chunk-URUTVZ7N.js.map → chunk-FL4ZCQLD.js.map} +0 -0
  445. /package/dist/{chunk-LW7MMEAQ.js.map → chunk-FT2M4R4F.js.map} +0 -0
  446. /package/dist/{chunk-AFGTSUAD.js.map → chunk-VSOKOFRF.js.map} +0 -0
  447. /package/docs/{app.css.example → styles/app.css.example} +0 -0
@@ -1,574 +0,0 @@
1
- /**
2
- * @file PaceAppLayout RBAC Tests
3
- * @package @jmruthers/pace-core
4
- * @module Components/PaceAppLayout
5
- * @since 1.0.0
6
- *
7
- * Comprehensive tests for PaceAppLayout RBAC functionality and permission enforcement.
8
- */
9
-
10
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
11
- import { render, screen, waitFor, act } from '@testing-library/react';
12
- import userEvent from '@testing-library/user-event';
13
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
14
- import { createMemoryRouter, RouterProvider, MemoryRouter } from 'react-router-dom';
15
- import { PaceAppLayout } from '../PaceAppLayout';
16
- import { UnifiedAuthProvider } from '../../../providers/UnifiedAuthProvider';
17
- import { RBACProvider } from '../../../rbac/providers/RBACProvider';
18
- import { OrganisationProvider } from '../../../providers/OrganisationProvider';
19
- import { useUnifiedAuth } from '../../../providers/UnifiedAuthProvider';
20
- import { useRBAC } from '../../../rbac/hooks/useRBAC';
21
- import { isPermitted } from '../../../rbac/api';
22
- import { isSuperAdmin } from '../../../rbac/api';
23
- import type { SupabaseClient } from '@supabase/supabase-js';
24
- import type { User } from '@supabase/supabase-js';
25
- import type { Organisation } from '../../../types/organisation';
26
- import type { Permission } from '../../../rbac/types/permission';
27
- import type { AccessLevel } from '../../../rbac/types/access';
28
-
29
- // Mock Supabase client
30
- const mockSupabaseClient = {
31
- auth: {
32
- getUser: vi.fn(),
33
- signIn: vi.fn(),
34
- signOut: vi.fn(),
35
- onAuthStateChange: vi.fn(),
36
- },
37
- from: vi.fn(),
38
- rpc: vi.fn(),
39
- } as unknown as SupabaseClient;
40
-
41
- // Mock RBAC API functions
42
- vi.mock('../../../rbac/api', () => ({
43
- isPermitted: vi.fn(),
44
- isSuperAdmin: vi.fn(),
45
- }));
46
-
47
- // Mock useUnifiedAuth hook
48
- const mockUseUnifiedAuth = vi.fn();
49
- vi.mock('../../../providers/UnifiedAuthProvider', () => ({
50
- useUnifiedAuth: () => mockUseUnifiedAuth(),
51
- UnifiedAuthProvider: ({ children }: { children: React.ReactNode }) => children,
52
- }));
53
-
54
- // Mock useRBAC hook
55
- const mockUseRBAC = vi.fn();
56
- vi.mock('../../../rbac/hooks/useRBAC', () => ({
57
- useRBAC: () => mockUseRBAC(),
58
- }));
59
-
60
- // Mock OrganisationProvider
61
- vi.mock('../../../providers/OrganisationProvider', () => ({
62
- OrganisationProvider: ({ children }: { children: React.ReactNode }) => children,
63
- }));
64
-
65
- // Mock EventSelector and useEvents to avoid EventServiceProvider requirement
66
- vi.mock('../../EventSelector/EventSelector', () => ({
67
- EventSelector: () => null,
68
- }));
69
-
70
- vi.mock('../../../hooks/useEvents', () => ({
71
- useEvents: () => ({
72
- events: [],
73
- selectedEvent: null,
74
- isLoading: false,
75
- error: null,
76
- setSelectedEvent: vi.fn(),
77
- refreshEvents: vi.fn(),
78
- }),
79
- }));
80
-
81
- // Mock RBACProvider
82
- vi.mock('../../../rbac/providers/RBACProvider', () => ({
83
- RBACProvider: ({ children }: { children: React.ReactNode }) => children,
84
- }));
85
-
86
- // Test data
87
- const mockUser: User = {
88
- id: 'user-123',
89
- email: 'test@example.com',
90
- created_at: '2023-01-01T00:00:00Z',
91
- updated_at: '2023-01-01T00:00:00Z',
92
- aud: 'authenticated',
93
- role: 'authenticated',
94
- app_metadata: {
95
- organisationId: 'org-123',
96
- eventId: 'event-123',
97
- appId: 'app-123',
98
- },
99
- user_metadata: {
100
- organisationId: 'org-123',
101
- eventId: 'event-123',
102
- appId: 'app-123',
103
- },
104
- identities: [],
105
- factors: [],
106
- } as User;
107
-
108
- const mockOrganisation: Organisation = {
109
- id: 'org-123',
110
- name: 'Test Organisation',
111
- slug: 'test-org',
112
- createdAt: '2023-01-01T00:00:00Z',
113
- updatedAt: '2023-01-01T00:00:00Z',
114
- };
115
-
116
- // Test components
117
- const TestPage = () => <div>Test Page Content</div>;
118
- const AccessDeniedPage = () => <div>Access Denied</div>;
119
- const LoadingPage = () => <div>Loading...</div>;
120
-
121
- // Test wrapper
122
- const TestWrapper = ({ children }: { children: React.ReactNode }) => {
123
- const queryClient = new QueryClient({
124
- defaultOptions: {
125
- queries: { retry: false },
126
- mutations: { retry: false },
127
- },
128
- });
129
-
130
- return (
131
- <QueryClientProvider client={queryClient}>
132
- <UnifiedAuthProvider
133
- supabaseClient={mockSupabaseClient}
134
- appName="Test App"
135
- idleTimeoutMs={30 * 60 * 1000}
136
- warnBeforeMs={60 * 1000}
137
- onIdleLogout={() => {}}
138
- >
139
- <RBACProvider>
140
- {children}
141
- </RBACProvider>
142
- </UnifiedAuthProvider>
143
- </QueryClientProvider>
144
- );
145
- };
146
-
147
- describe('PaceAppLayout RBAC Tests', () => {
148
- beforeEach(() => {
149
- vi.clearAllMocks();
150
-
151
- // Setup default mocks
152
- mockUseUnifiedAuth.mockReturnValue({
153
- user: mockUser,
154
- session: { user: mockUser },
155
- isLoading: false,
156
- error: null,
157
- });
158
-
159
- mockUseRBAC.mockReturnValue({
160
- hasPermission: vi.fn().mockResolvedValue(true),
161
- isSuperAdmin: vi.fn().mockResolvedValue(false),
162
- isLoading: false,
163
- error: null,
164
- });
165
-
166
- // Mock isPermitted to always return true
167
- (isPermitted as any).mockImplementation(async (input) => {
168
- console.log('isPermitted called with:', input);
169
- return true;
170
- });
171
- (isSuperAdmin as any).mockResolvedValue(false);
172
- });
173
-
174
- describe('Basic Rendering', () => {
175
- it('should render with basic configuration', async () => {
176
- const router = createMemoryRouter([
177
- {
178
- path: '/',
179
- element: (
180
- <PaceAppLayout
181
- appName="Test App"
182
- enforcePermissions={true}
183
- defaultPermission="read"
184
- />
185
- ),
186
- children: [
187
- {
188
- index: true,
189
- element: <TestPage />,
190
- },
191
- ],
192
- },
193
- ]);
194
-
195
- render(
196
- <TestWrapper>
197
- <RouterProvider router={router} />
198
- </TestWrapper>
199
- );
200
-
201
- await waitFor(() => {
202
- expect(screen.getByText('Test Page Content')).toBeInTheDocument();
203
- });
204
- });
205
-
206
- it('should render without permission enforcement', async () => {
207
- const router = createMemoryRouter([
208
- {
209
- path: '/',
210
- element: (
211
- <PaceAppLayout
212
- appName="Test App"
213
- enforcePermissions={false}
214
- />
215
- ),
216
- children: [
217
- {
218
- index: true,
219
- element: <TestPage />,
220
- },
221
- ],
222
- },
223
- ]);
224
-
225
- render(
226
- <TestWrapper>
227
- <RouterProvider router={router} />
228
- </TestWrapper>
229
- );
230
-
231
- await waitFor(() => {
232
- expect(screen.getByText('Test Page Content')).toBeInTheDocument();
233
- });
234
- });
235
- });
236
-
237
- describe('Permission Enforcement', () => {
238
- it('should show access denied when permission is denied', async () => {
239
- (isPermitted as any).mockResolvedValue(false);
240
-
241
- const router = createMemoryRouter([
242
- {
243
- path: '/',
244
- element: (
245
- <PaceAppLayout
246
- appName="Test App"
247
- enforcePermissions={true}
248
- defaultPermission="read"
249
- />
250
- ),
251
- children: [
252
- {
253
- index: true,
254
- element: <TestPage />,
255
- },
256
- ],
257
- },
258
- ]);
259
-
260
- render(
261
- <TestWrapper>
262
- <RouterProvider router={router} />
263
- </TestWrapper>
264
- );
265
-
266
- await waitFor(() => {
267
- expect(screen.getByText("You don't have permission to access this page.")).toBeInTheDocument();
268
- });
269
-
270
- expect(screen.queryByText('Test Page Content')).not.toBeInTheDocument();
271
- });
272
-
273
- it('should show custom fallback when permission is denied', async () => {
274
- (isPermitted as any).mockResolvedValue(false);
275
-
276
- const router = createMemoryRouter([
277
- {
278
- path: '/',
279
- element: (
280
- <PaceAppLayout
281
- appName="Test App"
282
- enforcePermissions={true}
283
- defaultPermission="read"
284
- permissionFallback={<AccessDeniedPage />}
285
- />
286
- ),
287
- children: [
288
- {
289
- index: true,
290
- element: <TestPage />,
291
- },
292
- ],
293
- },
294
- ]);
295
-
296
- render(
297
- <TestWrapper>
298
- <RouterProvider router={router} />
299
- </TestWrapper>
300
- );
301
-
302
- await waitFor(() => {
303
- expect(screen.getByText('Access Denied')).toBeInTheDocument();
304
- });
305
-
306
- expect(screen.queryByText('Test Page Content')).not.toBeInTheDocument();
307
- });
308
- });
309
-
310
- describe('Route-Specific Permissions', () => {
311
- it('should check route-specific permissions', async () => {
312
- const router = createMemoryRouter([
313
- {
314
- path: '/',
315
- element: (
316
- <PaceAppLayout
317
- appName="Test App"
318
- enforcePermissions={true}
319
- defaultPermission="read"
320
- routePermissions={{
321
- '/dashboard': 'write',
322
- '/settings': 'delete',
323
- }}
324
- />
325
- ),
326
- children: [
327
- {
328
- index: true,
329
- element: <TestPage />,
330
- },
331
- ],
332
- },
333
- ]);
334
-
335
- render(
336
- <TestWrapper>
337
- <RouterProvider router={router} />
338
- </TestWrapper>
339
- );
340
-
341
- await waitFor(() => {
342
- expect(screen.getByText('Test Page Content')).toBeInTheDocument();
343
- });
344
-
345
- expect(isPermitted).toHaveBeenCalledWith({
346
- userId: 'user-123',
347
- scope: {
348
- organisationId: 'org-123',
349
- eventId: 'event-123',
350
- appId: 'app-123',
351
- },
352
- permission: 'read',
353
- pageId: 'home',
354
- });
355
- });
356
-
357
- it('should use custom page ID mapping', async () => {
358
- const router = createMemoryRouter([
359
- {
360
- path: '/',
361
- element: (
362
- <PaceAppLayout
363
- appName="Test App"
364
- enforcePermissions={true}
365
- defaultPermission="read"
366
- pageIdMapping={{
367
- '/': 'homepage',
368
- '/dashboard': 'dashboard-page',
369
- }}
370
- />
371
- ),
372
- children: [
373
- {
374
- index: true,
375
- element: <TestPage />,
376
- },
377
- ],
378
- },
379
- ]);
380
-
381
- render(
382
- <TestWrapper>
383
- <RouterProvider router={router} />
384
- </TestWrapper>
385
- );
386
-
387
- await waitFor(() => {
388
- expect(screen.getByText('Test Page Content')).toBeInTheDocument();
389
- });
390
-
391
- expect(isPermitted).toHaveBeenCalledWith({
392
- userId: 'user-123',
393
- scope: {
394
- organisationId: 'org-123',
395
- eventId: 'event-123',
396
- appId: 'app-123',
397
- },
398
- permission: 'read',
399
- pageId: 'homepage',
400
- });
401
- });
402
- });
403
-
404
- describe('Loading States', () => {
405
- it('should show loading state while checking permissions', async () => {
406
- mockUseRBAC.mockReturnValue({
407
- hasPermission: vi.fn().mockResolvedValue(true),
408
- isSuperAdmin: vi.fn().mockResolvedValue(false),
409
- isLoading: true,
410
- error: null,
411
- });
412
-
413
- const router = createMemoryRouter([
414
- {
415
- path: '/',
416
- element: (
417
- <PaceAppLayout
418
- appName="Test App"
419
- enforcePermissions={true}
420
- defaultPermission="read"
421
- />
422
- ),
423
- children: [
424
- {
425
- index: true,
426
- element: <TestPage />,
427
- },
428
- ],
429
- },
430
- ]);
431
-
432
- render(
433
- <TestWrapper>
434
- <RouterProvider router={router} />
435
- </TestWrapper>
436
- );
437
-
438
- await waitFor(() => {
439
- expect(screen.getByText('Test Page Content')).toBeInTheDocument();
440
- });
441
- });
442
- });
443
-
444
- describe('Audit Logging', () => {
445
- it('should log page access when audit logging is enabled', async () => {
446
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
447
- (isPermitted as any).mockResolvedValue(true);
448
-
449
- const router = createMemoryRouter([
450
- {
451
- path: '/',
452
- element: (
453
- <PaceAppLayout
454
- appName="Test App"
455
- enforcePermissions={true}
456
- defaultPermission="read"
457
- auditLog={true}
458
- />
459
- ),
460
- children: [
461
- {
462
- index: true,
463
- element: <TestPage />,
464
- },
465
- ],
466
- },
467
- ]);
468
-
469
- render(
470
- <TestWrapper>
471
- <RouterProvider router={router} />
472
- </TestWrapper>
473
- );
474
-
475
- await waitFor(() => {
476
- expect(screen.getByText('Test Page Content')).toBeInTheDocument();
477
- });
478
-
479
- expect(consoleSpy).toHaveBeenCalledWith(
480
- '[PaceAppLayout] Page access attempt:',
481
- expect.objectContaining({
482
- pageName: 'home',
483
- operation: 'read',
484
- userId: 'user-123',
485
- allowed: true,
486
- strictMode: true,
487
- })
488
- );
489
-
490
- consoleSpy.mockRestore();
491
- });
492
-
493
- it('should not log when audit logging is disabled', async () => {
494
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
495
- (isPermitted as any).mockResolvedValue(true);
496
-
497
- const router = createMemoryRouter([
498
- {
499
- path: '/',
500
- element: (
501
- <PaceAppLayout
502
- appName="Test App"
503
- enforcePermissions={true}
504
- defaultPermission="read"
505
- auditLog={false}
506
- />
507
- ),
508
- children: [
509
- {
510
- index: true,
511
- element: <TestPage />,
512
- },
513
- ],
514
- },
515
- ]);
516
-
517
- render(
518
- <TestWrapper>
519
- <RouterProvider router={router} />
520
- </TestWrapper>
521
- );
522
-
523
- await waitFor(() => {
524
- expect(screen.getByText('Test Page Content')).toBeInTheDocument();
525
- });
526
-
527
- expect(consoleSpy).not.toHaveBeenCalledWith(
528
- expect.stringContaining('[PaceAppLayout] Page access attempt:')
529
- );
530
-
531
- consoleSpy.mockRestore();
532
- });
533
- });
534
-
535
- describe('Error Handling', () => {
536
- it('should handle RBAC errors gracefully', async () => {
537
- mockUseRBAC.mockReturnValue({
538
- hasPermission: vi.fn().mockRejectedValue(new Error('RBAC Error')),
539
- isSuperAdmin: vi.fn().mockResolvedValue(false),
540
- isLoading: false,
541
- error: new Error('RBAC Error'),
542
- });
543
-
544
- const router = createMemoryRouter([
545
- {
546
- path: '/',
547
- element: (
548
- <PaceAppLayout
549
- appName="Test App"
550
- enforcePermissions={true}
551
- defaultPermission="read"
552
- />
553
- ),
554
- children: [
555
- {
556
- index: true,
557
- element: <TestPage />,
558
- },
559
- ],
560
- },
561
- ]);
562
-
563
- render(
564
- <TestWrapper>
565
- <RouterProvider router={router} />
566
- </TestWrapper>
567
- );
568
-
569
- await waitFor(() => {
570
- expect(screen.getByText('Test Page Content')).toBeInTheDocument();
571
- });
572
- });
573
- });
574
- });