@jmruthers/pace-core 0.5.68 → 0.5.69

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 (375) hide show
  1. package/dist/{DataTable-4IUY7BXB.js → DataTable-MPBSXUC6.js} +5 -6
  2. package/dist/{PublicLoadingSpinner-DdKXTkCZ.d.ts → PublicLoadingSpinner-BOdyU3u-.d.ts} +1 -1
  3. package/dist/{chunk-PXWEDX7Y.js → chunk-2ARQW6VX.js} +3 -3
  4. package/dist/{chunk-MOJXHWDE.js → chunk-6JILXFEA.js} +335 -5
  5. package/dist/chunk-6JILXFEA.js.map +1 -0
  6. package/dist/{chunk-D7ARGIA3.js → chunk-6RBH67W7.js} +23 -6
  7. package/dist/chunk-6RBH67W7.js.map +1 -0
  8. package/dist/{chunk-ZMS23NS5.js → chunk-FJTAWPAQ.js} +3 -5
  9. package/dist/{chunk-ZMS23NS5.js.map → chunk-FJTAWPAQ.js.map} +1 -1
  10. package/dist/{chunk-OPCWH3A4.js → chunk-NO5QHMDX.js} +7 -6
  11. package/dist/chunk-NO5QHMDX.js.map +1 -0
  12. package/dist/{chunk-ZPK5656W.js → chunk-O3NWNXDY.js} +4 -5
  13. package/dist/chunk-O3NWNXDY.js.map +1 -0
  14. package/dist/{chunk-UYA6U6H7.js → chunk-Q2UP3ZWQ.js} +4 -4
  15. package/dist/{chunk-KRCRNXPD.js → chunk-RVYGJPOD.js} +79 -18
  16. package/dist/chunk-RVYGJPOD.js.map +1 -0
  17. package/dist/{chunk-NN45OBIS.js → chunk-UCMHBF7Y.js} +3 -5
  18. package/dist/{chunk-NN45OBIS.js.map → chunk-UCMHBF7Y.js.map} +1 -1
  19. package/dist/{chunk-ZPG4XPV5.js → chunk-V3QO3LL7.js} +5 -7
  20. package/dist/chunk-V3QO3LL7.js.map +1 -0
  21. package/dist/{chunk-U6GPOF6J.js → chunk-ZXJGZLLO.js} +17 -17
  22. package/dist/{chunk-U6GPOF6J.js.map → chunk-ZXJGZLLO.js.map} +1 -1
  23. package/dist/components.d.ts +1 -1
  24. package/dist/components.js +8 -9
  25. package/dist/components.js.map +1 -1
  26. package/dist/hooks.d.ts +1 -1
  27. package/dist/hooks.js +9 -6
  28. package/dist/hooks.js.map +1 -1
  29. package/dist/index.d.ts +3 -3
  30. package/dist/index.js +16 -16
  31. package/dist/index.js.map +1 -1
  32. package/dist/providers.js +5 -7
  33. package/dist/rbac/index.js +5 -6
  34. package/dist/{usePublicRouteParams-CdoFxnJK.d.ts → usePublicRouteParams-Ua1Vz-HG.d.ts} +35 -1
  35. package/dist/utils.d.ts +4 -1
  36. package/dist/utils.js +3 -3
  37. package/docs/DOCUMENTATION_CHECKLIST.md +281 -0
  38. package/docs/README.md +22 -10
  39. package/docs/api/classes/ColumnFactory.md +1 -1
  40. package/docs/api/classes/ErrorBoundary.md +1 -1
  41. package/docs/api/classes/InvalidScopeError.md +1 -1
  42. package/docs/api/classes/MissingUserContextError.md +1 -1
  43. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  44. package/docs/api/classes/PermissionDeniedError.md +1 -1
  45. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  46. package/docs/api/classes/RBACAuditManager.md +1 -1
  47. package/docs/api/classes/RBACCache.md +1 -1
  48. package/docs/api/classes/RBACEngine.md +1 -1
  49. package/docs/api/classes/RBACError.md +1 -1
  50. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  51. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  52. package/docs/api/classes/StorageUtils.md +1 -1
  53. package/docs/api/interfaces/AggregateConfig.md +1 -1
  54. package/docs/api/interfaces/ButtonProps.md +1 -1
  55. package/docs/api/interfaces/CardProps.md +1 -1
  56. package/docs/api/interfaces/ColorPalette.md +1 -1
  57. package/docs/api/interfaces/ColorShade.md +1 -1
  58. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  59. package/docs/api/interfaces/DataTableAction.md +1 -1
  60. package/docs/api/interfaces/DataTableColumn.md +1 -1
  61. package/docs/api/interfaces/DataTableProps.md +1 -1
  62. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  63. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  64. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  65. package/docs/api/interfaces/EventContextType.md +1 -1
  66. package/docs/api/interfaces/EventLogoProps.md +1 -1
  67. package/docs/api/interfaces/EventProviderProps.md +1 -1
  68. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  69. package/docs/api/interfaces/FileUploadProps.md +1 -1
  70. package/docs/api/interfaces/FooterProps.md +1 -1
  71. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  72. package/docs/api/interfaces/InputProps.md +1 -1
  73. package/docs/api/interfaces/LabelProps.md +1 -1
  74. package/docs/api/interfaces/LoginFormProps.md +1 -1
  75. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  76. package/docs/api/interfaces/NavigationContextType.md +1 -1
  77. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  78. package/docs/api/interfaces/NavigationItem.md +1 -1
  79. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  80. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  81. package/docs/api/interfaces/Organisation.md +1 -1
  82. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  83. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  84. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  85. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  86. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  87. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  88. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  89. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  90. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  91. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  92. package/docs/api/interfaces/PaletteData.md +1 -1
  93. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  94. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  95. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  96. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  97. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  98. package/docs/api/interfaces/PublicPageHeaderProps.md +2 -2
  99. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  100. package/docs/api/interfaces/RBACConfig.md +1 -1
  101. package/docs/api/interfaces/RBACContextType.md +1 -1
  102. package/docs/api/interfaces/RBACLogger.md +1 -1
  103. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  104. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  105. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  106. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  107. package/docs/api/interfaces/RouteConfig.md +1 -1
  108. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  109. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  110. package/docs/api/interfaces/StorageConfig.md +1 -1
  111. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  112. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  113. package/docs/api/interfaces/StorageListOptions.md +1 -1
  114. package/docs/api/interfaces/StorageListResult.md +1 -1
  115. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  116. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  117. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  118. package/docs/api/interfaces/StyleImport.md +1 -1
  119. package/docs/api/interfaces/SwitchProps.md +1 -1
  120. package/docs/api/interfaces/ToastActionElement.md +1 -1
  121. package/docs/api/interfaces/ToastProps.md +1 -1
  122. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  123. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  124. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  125. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  126. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  127. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  128. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  129. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  130. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  131. package/docs/api/interfaces/UserEventAccess.md +1 -1
  132. package/docs/api/interfaces/UserMenuProps.md +1 -1
  133. package/docs/api/interfaces/UserProfile.md +1 -1
  134. package/docs/api/modules.md +39 -14
  135. package/docs/architecture/services.md +374 -0
  136. package/docs/best-practices/README.md +1 -1
  137. package/docs/best-practices/testing.md +1 -1
  138. package/docs/breaking-changes.md +182 -0
  139. package/docs/common-patterns.md +445 -0
  140. package/docs/core-concepts/authentication.md +26 -11
  141. package/docs/core-concepts/events.md +2 -0
  142. package/docs/core-concepts/organisations.md +2 -0
  143. package/docs/core-concepts/permissions.md +2 -0
  144. package/docs/{INDEX.md → documentation-index.md} +26 -38
  145. package/docs/faq.md +286 -0
  146. package/docs/{FILE_REFERENCE_SYSTEM.md → file-reference-system.md} +1 -1
  147. package/docs/getting-started/installation-guide.md +284 -0
  148. package/docs/getting-started/quick-start.md +8 -1
  149. package/docs/implementation-guides/app-layout.md +3 -1
  150. package/docs/implementation-guides/data-tables.md +2 -0
  151. package/docs/implementation-guides/dynamic-colors.md +47 -2
  152. package/docs/implementation-guides/event-theming-summary.md +220 -0
  153. package/docs/implementation-guides/forms.md +9 -7
  154. package/docs/implementation-guides/navigation.md +2 -0
  155. package/docs/migration/service-architecture.md +351 -0
  156. package/docs/rbac/README-rbac-rls-integration.md +2 -2
  157. package/docs/rbac/README.md +1 -1
  158. package/docs/rbac/examples/rbac-rls-integration-example.md +3 -3
  159. package/docs/rbac/quick-start.md +2 -0
  160. package/docs/rbac/rbac-rls-integration.md +2 -2
  161. package/docs/style-guide.md +136 -1
  162. package/docs/testing/README.md +1 -1
  163. package/docs/troubleshooting/authentication-issues.md +334 -0
  164. package/docs/troubleshooting/common-issues.md +2 -0
  165. package/docs/troubleshooting/styling-issues.md +199 -144
  166. package/docs/usage.md +23 -2
  167. package/package.json +1 -1
  168. package/src/__tests__/{TESTING_GUIDELINES.md → TEST_GUIDE_CURSOR.md} +20 -0
  169. package/src/__tests__/TEST_GUIDE_HUMAN.md +103 -0
  170. package/src/__tests__/fixtures/test-data.ts +90 -0
  171. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +260 -0
  172. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +224 -0
  173. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +273 -0
  174. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +98 -0
  175. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +436 -0
  176. package/src/__tests__/helpers/__tests__/timer-utils.test.ts +371 -0
  177. package/src/__tests__/helpers/component-test-utils.tsx +14 -4
  178. package/src/__tests__/helpers/optimized-test-setup.ts +68 -0
  179. package/src/__tests__/helpers/test-providers.tsx +329 -0
  180. package/src/__tests__/helpers/test-utils.tsx +91 -45
  181. package/src/__tests__/helpers/timer-utils.ts +71 -0
  182. package/src/__tests__/hooks/usePermissions.test.ts +1 -5
  183. package/src/__tests__/integration/UserProfile.test.tsx +1 -5
  184. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +42 -12
  185. package/src/__tests__/setup.ts +34 -28
  186. package/src/components/Alert/Alert.test.tsx +1 -5
  187. package/src/components/Avatar/Avatar.test.tsx +1 -5
  188. package/src/components/Button/Button.test.tsx +4 -20
  189. package/src/components/Card/Card.test.tsx +1 -5
  190. package/src/components/Checkbox/Checkbox.test.tsx +1 -5
  191. package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -5
  192. package/src/components/DataTable/__tests__/DataTable.test.tsx +45 -49
  193. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +1 -5
  194. package/src/components/DataTable/__tests__/styles.test.ts +382 -0
  195. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +409 -0
  196. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +634 -0
  197. package/src/components/DataTable/core/__tests__/DataManager.test.ts +519 -0
  198. package/src/components/DataTable/core/__tests__/StateManager.test.ts +714 -0
  199. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +592 -0
  200. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +354 -0
  201. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +539 -0
  202. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +1 -5
  203. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +1 -8
  204. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +34 -38
  205. package/src/components/Footer/Footer.test.tsx +1 -5
  206. package/src/components/Form/Form.test.tsx +22 -35
  207. package/src/components/Header/Header.test.tsx +1 -9
  208. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +1 -5
  209. package/src/components/Input/Input.test.tsx +2 -10
  210. package/src/components/LoginForm/LoginForm.test.tsx +1 -5
  211. package/src/components/NavigationMenu/NavigationMenu.test.tsx +24 -24
  212. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +1 -6
  213. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +6 -16
  214. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +1 -5
  215. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +1 -5
  216. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +1 -7
  217. package/src/components/PasswordReset/PasswordChangeForm.test.tsx +1 -9
  218. package/src/components/PasswordReset/PasswordResetForm.test.tsx +1 -9
  219. package/src/components/PublicLayout/PublicErrorBoundary.tsx +4 -5
  220. package/src/components/PublicLayout/PublicPageHeader.tsx +13 -9
  221. package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +666 -0
  222. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +457 -0
  223. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +393 -0
  224. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +351 -0
  225. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +374 -0
  226. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +388 -0
  227. package/src/components/Select/Select.bug-test.tsx +69 -0
  228. package/src/components/Select/Select.refactored.tsx +497 -0
  229. package/src/components/Select/Select.test.tsx +42 -49
  230. package/src/components/Select/Select.tsx +5 -2
  231. package/src/components/Select/hooks.ts +254 -0
  232. package/src/components/Switch/Switch.test.tsx +1 -5
  233. package/src/components/Table/__tests__/Table.test.tsx +775 -0
  234. package/src/components/Toast/Toast.test.tsx +15 -8
  235. package/src/components/Tooltip/Tooltip.test.tsx +1 -5
  236. package/src/components/UserMenu/UserMenu.test.tsx +3 -15
  237. package/src/components/__tests__/FileDisplay.test.tsx +575 -0
  238. package/src/components/__tests__/FileUpload.test.tsx +446 -0
  239. package/src/components/__tests__/SuperAdminGuard.test.tsx +422 -354
  240. package/src/hooks/__tests__/ServiceHooks.test.tsx +613 -0
  241. package/src/hooks/__tests__/hooks.integration.test.tsx +1 -10
  242. package/src/hooks/__tests__/useApiFetch.unit.test.ts +10 -14
  243. package/src/hooks/__tests__/useAppConfig.unit.test.ts +307 -0
  244. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +1 -6
  245. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +1 -5
  246. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +6 -9
  247. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +321 -0
  248. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +583 -0
  249. package/src/hooks/__tests__/usePublicEventLogo.unit.test.ts +640 -0
  250. package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +435 -0
  251. package/src/hooks/__tests__/useRBAC.unit.test.ts +10 -10
  252. package/src/hooks/__tests__/useStorage.unit.test.ts +751 -0
  253. package/src/hooks/index.ts +3 -0
  254. package/src/hooks/public/usePublicEvent.ts +30 -9
  255. package/src/hooks/public/usePublicRouteParams.ts +13 -3
  256. package/src/hooks/services/useAuth.ts +50 -0
  257. package/src/hooks/services/useAuthService.ts +30 -0
  258. package/src/hooks/services/useCurrentEvent.ts +36 -0
  259. package/src/hooks/services/useCurrentOrganisation.ts +52 -0
  260. package/src/hooks/services/useEventService.ts +30 -0
  261. package/src/hooks/services/useInactivityService.ts +30 -0
  262. package/src/hooks/services/useOrganisationService.ts +30 -0
  263. package/src/hooks/services/usePermissions.ts +70 -0
  264. package/src/hooks/services/useRBACService.ts +30 -0
  265. package/src/hooks/useCounter.test.ts +1 -5
  266. package/src/hooks/useEventTheme.ts +86 -0
  267. package/src/hooks/useOrganisationPermissions.test.ts +2 -5
  268. package/src/hooks/useOrganisationSecurity.test.ts +1 -5
  269. package/src/hooks/usePermissionCache.test.ts +1 -5
  270. package/src/hooks/usePermissionCheck.ts +150 -0
  271. package/src/hooks/useSecureDataAccess.test.ts +1 -5
  272. package/src/index.ts +1 -0
  273. package/src/providers/OrganisationProvider.test.tsx +1 -5
  274. package/src/providers/OrganisationProvider.tsx +56 -4
  275. package/src/providers/UnifiedAuthProvider.test.tsx +1 -5
  276. package/src/providers/__tests__/AuthProvider.test.tsx +105 -439
  277. package/src/providers/__tests__/AuthProvider.test.tsx.backup +771 -0
  278. package/src/providers/__tests__/EventProvider.test.tsx +211 -110
  279. package/src/providers/__tests__/EventProvider.test.tsx.backup +824 -0
  280. package/src/providers/__tests__/InactivityProvider.test.tsx +1 -5
  281. package/src/providers/__tests__/OrganisationProvider.test.tsx +97 -261
  282. package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +820 -0
  283. package/src/providers/__tests__/ServiceProviders.test.tsx +477 -0
  284. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +72 -504
  285. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +911 -0
  286. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +166 -0
  287. package/src/providers/services/AuthServiceProvider.tsx +65 -0
  288. package/src/providers/services/EventServiceProvider.tsx +83 -0
  289. package/src/providers/services/InactivityServiceProvider.tsx +83 -0
  290. package/src/providers/services/OrganisationServiceProvider.tsx +77 -0
  291. package/src/providers/services/RBACServiceProvider.tsx +79 -0
  292. package/src/providers/services/UnifiedAuthProvider.tsx +368 -0
  293. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +210 -0
  294. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +269 -0
  295. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +892 -0
  296. package/src/rbac/__tests__/engine.comprehensive.test.ts +954 -0
  297. package/src/rbac/__tests__/integration.authflow.test.tsx +1 -5
  298. package/src/rbac/__tests__/integration.navigation.test.tsx +1 -4
  299. package/src/rbac/__tests__/rbac-core.test.tsx +2 -7
  300. package/src/rbac/__tests__/rbac-functions.test.ts +1 -9
  301. package/src/rbac/__tests__/rbac-integration.test.ts +1 -9
  302. package/src/rbac/api.test.ts +1 -9
  303. package/src/rbac/cache.test.ts +10 -8
  304. package/src/rbac/cli/__tests__/policy-manager.test.ts +339 -0
  305. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +1 -5
  306. package/src/rbac/components/NavigationProvider.test.tsx +1 -5
  307. package/src/rbac/components/PagePermissionProvider.test.tsx +1 -5
  308. package/src/rbac/components/SecureDataProvider.test.tsx +1 -5
  309. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +25 -29
  310. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +27 -30
  311. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +23 -27
  312. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +18 -22
  313. package/src/rbac/config.test.ts +1 -5
  314. package/src/rbac/hooks/useCan.test.ts +262 -9
  315. package/src/rbac/hooks/usePermissions.test.ts +246 -6
  316. package/src/rbac/hooks/useRBAC.simple.test.ts +1 -5
  317. package/src/rbac/hooks/useRBAC.test.ts +472 -198
  318. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +1 -9
  319. package/src/services/AuthService.ts +416 -0
  320. package/src/services/EventService.ts +366 -0
  321. package/src/services/InactivityService.ts +388 -0
  322. package/src/services/OrganisationService.ts +592 -0
  323. package/src/services/RBACService.ts +522 -0
  324. package/src/services/__tests__/AuthService.test.ts +356 -0
  325. package/src/services/__tests__/BaseService.test.ts +314 -0
  326. package/src/services/__tests__/EventService.test.ts +489 -0
  327. package/src/services/__tests__/InactivityService.test.ts +403 -0
  328. package/src/services/__tests__/OrganisationService.test.ts +660 -0
  329. package/src/services/__tests__/RBACService.test.ts +492 -0
  330. package/src/services/base/BaseService.ts +87 -0
  331. package/src/services/interfaces/IAuthService.ts +39 -0
  332. package/src/services/interfaces/IEventService.ts +30 -0
  333. package/src/services/interfaces/IInactivityService.ts +31 -0
  334. package/src/services/interfaces/IOrganisationService.ts +41 -0
  335. package/src/services/interfaces/IRBACService.ts +62 -0
  336. package/src/theming/__tests__/runtime.test.ts +540 -0
  337. package/src/types/__tests__/file-reference.test.ts +447 -0
  338. package/src/types/__tests__/organisation.test.ts +1133 -0
  339. package/src/types/__tests__/theme.test.ts +830 -0
  340. package/src/types/__tests__/type-validation.test.ts +527 -0
  341. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +1 -5
  342. package/src/utils/__tests__/debugLogger.test.ts +417 -0
  343. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -6
  344. package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -5
  345. package/src/utils/__tests__/lazyLoad.unit.test.tsx +35 -35
  346. package/src/utils/__tests__/organisationContext.unit.test.ts +1 -5
  347. package/src/utils/__tests__/performanceBudgets.unit.test.ts +5 -11
  348. package/src/utils/__tests__/secureErrors.unit.test.ts +1 -6
  349. package/src/utils/__tests__/secureStorage.unit.test.ts +1 -5
  350. package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -5
  351. package/src/utils/__tests__/sessionTracking.unit.test.ts +1 -5
  352. package/src/utils/appIdResolver.test.ts +6 -10
  353. package/src/utils/appNameResolver.simple.test.ts +142 -0
  354. package/src/utils/appNameResolver.test.ts +31 -458
  355. package/src/utils/appNameResolver.test.ts.backup +494 -0
  356. package/src/utils/debugLogger.ts +26 -5
  357. package/src/utils/formatDate.test.ts +1 -5
  358. package/src/utils/organisationContext.test.ts +1 -5
  359. package/src/utils/performanceBudgets.ts +3 -4
  360. package/src/utils/secureDataAccess.test.ts +1 -5
  361. package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -5
  362. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +1 -5
  363. package/dist/chunk-D7ARGIA3.js.map +0 -1
  364. package/dist/chunk-IPCH4YPT.js +0 -315
  365. package/dist/chunk-IPCH4YPT.js.map +0 -1
  366. package/dist/chunk-KRCRNXPD.js.map +0 -1
  367. package/dist/chunk-MOJXHWDE.js.map +0 -1
  368. package/dist/chunk-OPCWH3A4.js.map +0 -1
  369. package/dist/chunk-ZPG4XPV5.js.map +0 -1
  370. package/dist/chunk-ZPK5656W.js.map +0 -1
  371. package/docs/getting-started/installation.md +0 -269
  372. package/src/__tests__/REBUILD_PLAN.md +0 -223
  373. /package/dist/{DataTable-4IUY7BXB.js.map → DataTable-MPBSXUC6.js.map} +0 -0
  374. /package/dist/{chunk-PXWEDX7Y.js.map → chunk-2ARQW6VX.js.map} +0 -0
  375. /package/dist/{chunk-UYA6U6H7.js.map → chunk-Q2UP3ZWQ.js.map} +0 -0
@@ -0,0 +1,435 @@
1
+ import React from 'react';
2
+ import { renderHook, waitFor } from '@testing-library/react';
3
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
4
+ import {
5
+ usePublicRouteParams,
6
+ usePublicEventCode,
7
+ generatePublicRoutePath,
8
+ extractEventCodeFromPath
9
+ } from '../public/usePublicRouteParams';
10
+ import { usePublicEvent } from '../public/usePublicEvent';
11
+
12
+ // Mock React Router
13
+ const mockParams = {};
14
+ const mockLocation = { pathname: '/public/event/test-event' };
15
+
16
+ vi.mock('react-router-dom', () => ({
17
+ useParams: () => mockParams,
18
+ useLocation: () => mockLocation
19
+ }));
20
+
21
+ // Mock usePublicEvent
22
+ vi.mock('../public/usePublicEvent', () => ({
23
+ usePublicEvent: vi.fn(() => ({
24
+ event: null,
25
+ isLoading: false,
26
+ error: null,
27
+ refetch: vi.fn()
28
+ }))
29
+ }));
30
+
31
+ describe('usePublicRouteParams', () => {
32
+ beforeEach(() => {
33
+ // Clear mockParams for each test
34
+ Object.keys(mockParams).forEach(key => delete (mockParams as any)[key]);
35
+ });
36
+
37
+ afterEach(() => {
38
+ vi.clearAllMocks();
39
+ });
40
+
41
+ describe('Basic Functionality', () => {
42
+ it('should extract event code from URL parameters', () => {
43
+ mockParams.eventCode = 'test-event';
44
+
45
+ const { result } = renderHook(() => usePublicRouteParams());
46
+
47
+ expect(result.current.eventCode).toBe('test-event');
48
+ });
49
+
50
+ it('should handle missing event code parameter', () => {
51
+ // No eventCode in params
52
+
53
+ const { result } = renderHook(() => usePublicRouteParams());
54
+
55
+ expect(result.current.eventCode).toBe(null);
56
+ });
57
+
58
+ it('should validate event code format', () => {
59
+ mockParams.eventCode = 'invalid@code!';
60
+
61
+ const { result } = renderHook(() => usePublicRouteParams());
62
+
63
+ expect(result.current.eventCode).toBe(null);
64
+ expect(result.current.error).toEqual(new Error('Invalid event code format: invalid@code!'));
65
+ });
66
+
67
+ it('should accept valid event code formats', () => {
68
+ const validCodes = [
69
+ 'test-event',
70
+ 'test_event',
71
+ 'test123',
72
+ 'TEST-EVENT',
73
+ 'test-event-123',
74
+ 'a1b2c3'
75
+ ];
76
+
77
+ validCodes.forEach(code => {
78
+ mockParams.eventCode = code;
79
+ const { result } = renderHook(() => usePublicRouteParams());
80
+ expect(result.current.eventCode).toBe(code);
81
+ });
82
+ });
83
+
84
+ it('should reject invalid event code formats', () => {
85
+ const invalidCodes = [
86
+ 'ab', // too short
87
+ 'a'.repeat(51), // too long
88
+ 'test@event', // invalid character
89
+ 'test event', // space
90
+ 'test.event', // dot
91
+ 'test/event', // slash
92
+ 'test\\event', // backslash
93
+ '', // empty
94
+ ' ', // whitespace only
95
+ 'test-event-', // trailing hyphen
96
+ '-test-event', // leading hyphen
97
+ 'test--event', // double hyphen
98
+ 'test__event' // double underscore
99
+ ];
100
+
101
+ invalidCodes.forEach(code => {
102
+ mockParams.eventCode = code;
103
+ const { result } = renderHook(() => usePublicRouteParams());
104
+ expect(result.current.eventCode).toBe(null);
105
+ if (code.length > 0) {
106
+ expect(result.current.error).toEqual(new Error(`Invalid event code format: ${code}`));
107
+ }
108
+ });
109
+ });
110
+ });
111
+
112
+ describe('Event Data Fetching', () => {
113
+ it('should fetch event data when fetchEventData is true', async () => {
114
+ mockParams.eventCode = 'test-event';
115
+
116
+ const mockEvent = {
117
+ id: '123',
118
+ event_id: '123',
119
+ event_name: 'Test Event',
120
+ event_code: 'test-event',
121
+ event_date: '2024-01-01',
122
+ event_venue: 'Test Venue',
123
+ event_participants: 100,
124
+ event_logo: null,
125
+ event_colours: { primary: '#000000' },
126
+ organisation_id: 'org-123',
127
+ is_visible: true,
128
+ created_at: '2024-01-01T00:00:00Z',
129
+ updated_at: '2024-01-01T00:00:00Z',
130
+ name: 'Test Event',
131
+ start_date: '2024-01-01'
132
+ };
133
+
134
+ (usePublicEvent as any).mockReturnValue({
135
+ event: mockEvent,
136
+ isLoading: false,
137
+ error: null,
138
+ refetch: vi.fn()
139
+ });
140
+
141
+ const { result } = renderHook(() => usePublicRouteParams({ fetchEventData: true }));
142
+
143
+ expect(result.current.event).toEqual(mockEvent);
144
+ expect(result.current.eventId).toBe('123');
145
+ expect(result.current.isLoading).toBe(false);
146
+ expect(result.current.error).toBe(null);
147
+ });
148
+
149
+ it('should not fetch event data when fetchEventData is false', () => {
150
+ mockParams.eventCode = 'test-event';
151
+
152
+ const { result } = renderHook(() => usePublicRouteParams({ fetchEventData: false }));
153
+
154
+ expect(result.current.event).toBe(null);
155
+ expect(result.current.eventId).toBe(null);
156
+ expect(result.current.isLoading).toBe(false);
157
+ // Note: usePublicEvent might still be called for validation, but the event data should not be used
158
+ });
159
+
160
+ it('should handle event loading state', () => {
161
+ mockParams.eventCode = 'test-event';
162
+
163
+ (usePublicEvent as any).mockReturnValue({
164
+ event: null,
165
+ isLoading: true,
166
+ error: null,
167
+ refetch: vi.fn()
168
+ });
169
+
170
+ const { result } = renderHook(() => usePublicRouteParams({ fetchEventData: true }));
171
+
172
+ expect(result.current.isLoading).toBe(true);
173
+ expect(result.current.event).toBe(null);
174
+ });
175
+
176
+ it('should handle event error state', () => {
177
+ mockParams.eventCode = 'test-event';
178
+
179
+ (usePublicEvent as any).mockReturnValue({
180
+ event: null,
181
+ isLoading: false,
182
+ error: new Error('Event not found'),
183
+ refetch: vi.fn()
184
+ });
185
+
186
+ const { result } = renderHook(() => usePublicRouteParams({ fetchEventData: true }));
187
+
188
+ expect(result.current.isLoading).toBe(false);
189
+ expect(result.current.event).toBe(null);
190
+ expect(result.current.error).toEqual(new Error('Event not found'));
191
+ });
192
+
193
+ it('should handle event code validation error', () => {
194
+ mockParams.eventCode = 'invalid@code!';
195
+
196
+ const { result } = renderHook(() => usePublicRouteParams({ fetchEventData: true }));
197
+
198
+ expect(result.current.isLoading).toBe(false);
199
+ expect(result.current.event).toBe(null);
200
+ expect(result.current.error).toEqual(new Error('Invalid event code format: invalid@code!'));
201
+ });
202
+ });
203
+
204
+ describe('Custom Configuration', () => {
205
+ it('should use custom event code parameter name', () => {
206
+ mockParams.customEventCode = 'test-event';
207
+
208
+ const { result } = renderHook(() =>
209
+ usePublicRouteParams({ eventCodeParam: 'customEventCode' })
210
+ );
211
+
212
+ expect(result.current.eventCode).toBe('test-event');
213
+ });
214
+
215
+ it('should disable event code validation when requested', () => {
216
+ mockParams.eventCode = 'invalid@code!';
217
+
218
+ const { result } = renderHook(() =>
219
+ usePublicRouteParams({ validateEventCode: false })
220
+ );
221
+
222
+ expect(result.current.eventCode).toBe('invalid@code!');
223
+ expect(result.current.error).toBe(null);
224
+ });
225
+
226
+ it('should pass correct options to usePublicEvent', () => {
227
+ mockParams.eventCode = 'test-event';
228
+
229
+ (usePublicEvent as any).mockReturnValue({
230
+ event: null,
231
+ isLoading: false,
232
+ error: null,
233
+ refetch: vi.fn()
234
+ });
235
+
236
+ renderHook(() => usePublicRouteParams({ fetchEventData: true }));
237
+
238
+ expect(usePublicEvent).toHaveBeenCalledWith('test-event', {
239
+ enableCache: true,
240
+ cacheTtl: 5 * 60 * 1000 // 5 minutes
241
+ });
242
+ });
243
+ });
244
+
245
+ describe('Refetch Functionality', () => {
246
+ it('should provide refetch function', async () => {
247
+ mockParams.eventCode = 'test-event';
248
+
249
+ const mockRefetch = vi.fn();
250
+ (usePublicEvent as any).mockReturnValue({
251
+ event: null,
252
+ isLoading: false,
253
+ error: null,
254
+ refetch: mockRefetch
255
+ });
256
+
257
+ const { result } = renderHook(() => usePublicRouteParams({ fetchEventData: true }));
258
+
259
+ await result.current.refetch();
260
+
261
+ expect(mockRefetch).toHaveBeenCalled();
262
+ });
263
+
264
+ it('should not refetch when fetchEventData is false', async () => {
265
+ mockParams.eventCode = 'test-event';
266
+
267
+ const { result } = renderHook(() => usePublicRouteParams({ fetchEventData: false }));
268
+
269
+ await result.current.refetch();
270
+
271
+ // Should not throw or call any refetch function
272
+ expect(result.current.refetch).toBeDefined();
273
+ });
274
+ });
275
+
276
+ describe('Logging', () => {
277
+ it('should log route access for debugging', () => {
278
+ const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
279
+
280
+ mockParams.eventCode = 'test-event';
281
+
282
+ const mockEvent = {
283
+ id: '123',
284
+ event_id: '123',
285
+ event_name: 'Test Event',
286
+ event_code: 'test-event',
287
+ event_date: '2024-01-01',
288
+ event_venue: 'Test Venue',
289
+ event_participants: 100,
290
+ event_logo: null,
291
+ event_colours: { primary: '#000000' },
292
+ organisation_id: 'org-123',
293
+ is_visible: true,
294
+ created_at: '2024-01-01T00:00:00Z',
295
+ updated_at: '2024-01-01T00:00:00Z',
296
+ name: 'Test Event',
297
+ start_date: '2024-01-01'
298
+ };
299
+
300
+ (usePublicEvent as any).mockReturnValue({
301
+ event: mockEvent,
302
+ isLoading: false,
303
+ error: null,
304
+ refetch: vi.fn()
305
+ });
306
+
307
+ renderHook(() => usePublicRouteParams({ fetchEventData: true }));
308
+
309
+ expect(consoleSpy).toHaveBeenCalledWith('[usePublicRouteParams] Public route accessed:', {
310
+ eventCode: 'test-event',
311
+ eventId: '123',
312
+ eventName: 'Test Event',
313
+ path: '/public/event/test-event'
314
+ });
315
+
316
+ consoleSpy.mockRestore();
317
+ });
318
+ });
319
+
320
+ describe('usePublicEventCode', () => {
321
+ it('should extract event code without fetching data', () => {
322
+ mockParams.eventCode = 'test-event';
323
+
324
+ const { result } = renderHook(() => usePublicEventCode());
325
+
326
+ expect(result.current.eventCode).toBe('test-event');
327
+ expect(result.current.error).toBe(null);
328
+ });
329
+
330
+ it('should handle missing event code', () => {
331
+ // No eventCode in params
332
+
333
+ const { result } = renderHook(() => usePublicEventCode());
334
+
335
+ expect(result.current.eventCode).toBe(null);
336
+ expect(result.current.error).toEqual(new Error("Event code parameter 'eventCode' not found or invalid"));
337
+ });
338
+
339
+ it('should handle invalid event code format', () => {
340
+ mockParams.eventCode = 'invalid@code!';
341
+
342
+ const { result } = renderHook(() => usePublicEventCode());
343
+
344
+ expect(result.current.eventCode).toBe(null);
345
+ expect(result.current.error).toEqual(new Error("Event code parameter 'eventCode' not found or invalid"));
346
+ });
347
+
348
+ it('should use custom parameter name', () => {
349
+ mockParams.customEventCode = 'test-event';
350
+
351
+ const { result } = renderHook(() => usePublicEventCode('customEventCode'));
352
+
353
+ expect(result.current.eventCode).toBe('test-event');
354
+ expect(result.current.error).toBe(null);
355
+ });
356
+ });
357
+
358
+ describe('Utility Functions', () => {
359
+ describe('generatePublicRoutePath', () => {
360
+ it('should generate correct route path', () => {
361
+ expect(generatePublicRoutePath('test-event')).toBe('/public/event/test-event/index');
362
+ expect(generatePublicRoutePath('test-event', 'details')).toBe('/public/event/test-event/details');
363
+ expect(generatePublicRoutePath('test-event', 'registration')).toBe('/public/event/test-event/registration');
364
+ });
365
+
366
+ it('should throw error for invalid event code', () => {
367
+ expect(() => generatePublicRoutePath('invalid@code!')).toThrow('Invalid event code for route generation');
368
+ expect(() => generatePublicRoutePath('ab')).toThrow('Invalid event code for route generation');
369
+ expect(() => generatePublicRoutePath('')).toThrow('Invalid event code for route generation');
370
+ });
371
+ });
372
+
373
+ describe('extractEventCodeFromPath', () => {
374
+ it('should extract event code from valid paths', () => {
375
+ expect(extractEventCodeFromPath('/public/event/test-event')).toBe('test-event');
376
+ expect(extractEventCodeFromPath('/public/event/test-event/')).toBe('test-event');
377
+ expect(extractEventCodeFromPath('/public/event/test-event/details')).toBe('test-event');
378
+ expect(extractEventCodeFromPath('/public/event/test-event/details/step1')).toBe('test-event');
379
+ expect(extractEventCodeFromPath('/public/event/test-event-123')).toBe('test-event-123');
380
+ expect(extractEventCodeFromPath('/public/event/test_event')).toBe('test_event');
381
+ expect(extractEventCodeFromPath('/public/event/test123')).toBe('test123');
382
+ });
383
+
384
+ it('should return null for invalid paths', () => {
385
+ expect(extractEventCodeFromPath('/public/event/')).toBe(null);
386
+ expect(extractEventCodeFromPath('/public/event/ab')).toBe(null); // too short
387
+ expect(extractEventCodeFromPath('/public/event/test@event')).toBe(null); // invalid character
388
+ expect(extractEventCodeFromPath('/public/event/test event')).toBe(null); // space
389
+ expect(extractEventCodeFromPath('/public/event/')).toBe(null);
390
+ expect(extractEventCodeFromPath('/public/event')).toBe(null);
391
+ expect(extractEventCodeFromPath('/public/')).toBe(null);
392
+ expect(extractEventCodeFromPath('/')).toBe(null);
393
+ expect(extractEventCodeFromPath('')).toBe(null);
394
+ expect(extractEventCodeFromPath('/other/path')).toBe(null);
395
+ expect(extractEventCodeFromPath('/public/event/')).toBe(null);
396
+ });
397
+ });
398
+ });
399
+
400
+ describe('Edge Cases', () => {
401
+ it('should handle rapid parameter changes', () => {
402
+ // Test that the hook works with different parameter values
403
+ mockParams.eventCode = 'event1';
404
+
405
+ const { result } = renderHook(() => usePublicRouteParams());
406
+
407
+ expect(result.current.eventCode).toBe('event1');
408
+ expect(result.current.error).toBe(null);
409
+ });
410
+
411
+ it('should handle undefined parameters', () => {
412
+ mockParams.eventCode = undefined;
413
+
414
+ const { result } = renderHook(() => usePublicRouteParams());
415
+
416
+ expect(result.current.eventCode).toBe(null);
417
+ });
418
+
419
+ it('should handle null parameters', () => {
420
+ mockParams.eventCode = null;
421
+
422
+ const { result } = renderHook(() => usePublicRouteParams());
423
+
424
+ expect(result.current.eventCode).toBe(null);
425
+ });
426
+
427
+ it('should handle empty string parameters', () => {
428
+ mockParams.eventCode = '';
429
+
430
+ const { result } = renderHook(() => usePublicRouteParams());
431
+
432
+ expect(result.current.eventCode).toBe(null);
433
+ });
434
+ });
435
+ });
@@ -147,7 +147,7 @@ describe('useRBAC', () => {
147
147
  expect(result.current.globalRole).toBe('super_admin');
148
148
  expect(result.current.organisationRole).toBeNull();
149
149
  expect(result.current.eventAppRole).toBeNull();
150
- }, { timeout: 3000 });
150
+ }, { interval: 10, timeout: 3000 });
151
151
  });
152
152
 
153
153
  it('detects organisation role from permissions', async () => {
@@ -168,7 +168,7 @@ describe('useRBAC', () => {
168
168
  expect(result.current.globalRole).toBeNull();
169
169
  expect(result.current.organisationRole).toBe('org_admin');
170
170
  expect(result.current.eventAppRole).toBeNull();
171
- }, { timeout: 3000 });
171
+ }, { interval: 10, timeout: 3000 });
172
172
  });
173
173
 
174
174
  it('detects event app role from permissions', async () => {
@@ -190,7 +190,7 @@ describe('useRBAC', () => {
190
190
  expect(result.current.globalRole).toBeNull();
191
191
  expect(result.current.organisationRole).toBeNull();
192
192
  expect(result.current.eventAppRole).toBe('event_admin');
193
- }, { timeout: 3000 });
193
+ }, { interval: 10, timeout: 3000 });
194
194
  });
195
195
 
196
196
  it('detects multiple roles from permissions', async () => {
@@ -224,7 +224,7 @@ describe('useRBAC', () => {
224
224
  expect(result.current.globalRole).toBe('super_admin');
225
225
  expect(result.current.organisationRole).toBe('org_admin');
226
226
  expect(result.current.eventAppRole).toBe('event_admin');
227
- }, { timeout: 3000 });
227
+ }, { interval: 10, timeout: 3000 });
228
228
  });
229
229
 
230
230
  it('handles empty permissions array', async () => {
@@ -261,7 +261,7 @@ describe('useRBAC', () => {
261
261
 
262
262
  await waitFor(() => {
263
263
  expect(result.current.globalRole).toBe('super_admin');
264
- }, { timeout: 3000 });
264
+ }, { interval: 10, timeout: 3000 });
265
265
 
266
266
  const hasPermission = await result.current.hasPermission('read', 'dashboard');
267
267
  expect(hasPermission).toBe(true);
@@ -298,7 +298,7 @@ describe('useRBAC', () => {
298
298
 
299
299
  await waitFor(() => {
300
300
  expect(result.current.organisationRole).toBe('org_admin');
301
- }, { timeout: 3000 });
301
+ }, { interval: 10, timeout: 3000 });
302
302
 
303
303
  const hasPermission = await result.current.hasPermission('read', 'dashboard');
304
304
  expect(hasPermission).toBe(true);
@@ -343,7 +343,7 @@ describe('useRBAC', () => {
343
343
 
344
344
  await waitFor(() => {
345
345
  expect(result.current.organisationRole).toBe('org_admin');
346
- }, { timeout: 3000 });
346
+ }, { interval: 10, timeout: 3000 });
347
347
 
348
348
  const hasPermission = await result.current.hasPermission('write', 'admin');
349
349
  expect(hasPermission).toBe(false);
@@ -382,7 +382,7 @@ describe('useRBAC', () => {
382
382
 
383
383
  await waitFor(() => {
384
384
  expect(result.current.organisationRole).toBe('org_admin');
385
- }, { timeout: 3000 });
385
+ }, { interval: 10, timeout: 3000 });
386
386
 
387
387
  const hasPermission = await result.current.hasPermission('read', 'dashboard');
388
388
  expect(hasPermission).toBe(false);
@@ -421,7 +421,7 @@ describe('useRBAC', () => {
421
421
 
422
422
  await waitFor(() => {
423
423
  expect(result.current.organisationRole).toBe('org_admin');
424
- }, { timeout: 3000 });
424
+ }, { interval: 10, timeout: 3000 });
425
425
 
426
426
  await result.current.hasPermission('read');
427
427
 
@@ -801,7 +801,7 @@ describe('useRBAC', () => {
801
801
 
802
802
  await waitFor(() => {
803
803
  expect(result.current.organisationRole).toBe('org_admin');
804
- }, { timeout: 3000 });
804
+ }, { interval: 10, timeout: 3000 });
805
805
 
806
806
  // Change organisation
807
807
  mockUseOrganisations.mockReturnValue({