@jmruthers/pace-core 0.5.54 → 0.5.56

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 (396) hide show
  1. package/README.md +0 -4
  2. package/dist/{DataTable-7FMFXA7A.js → DataTable-DJQTKX33.js} +11 -11
  3. package/dist/{PublicLoadingSpinner-Bq_-BeK-.d.ts → PublicLoadingSpinner-SL8WaQN7.d.ts} +2 -21
  4. package/dist/{api-H5A3H4IR.js → api-LUNF5O6M.js} +3 -3
  5. package/dist/{appConfig-BVGyuvI7.d.ts → appConfig-DjpeG6P-.d.ts} +9 -1
  6. package/dist/{appNameResolver-7GHF5ED2.js → appNameResolver-UURKN7NF.js} +2 -2
  7. package/dist/{audit-BUW3LMJB.js → audit-6TOCAMKO.js} +2 -2
  8. package/dist/{chunk-NRK4AIHQ.js → chunk-2DFCT6D3.js} +3 -3
  9. package/dist/{chunk-GIO7BFE7.js → chunk-3JKVVLD3.js} +66 -169
  10. package/dist/{chunk-GIO7BFE7.js.map → chunk-3JKVVLD3.js.map} +1 -1
  11. package/dist/{chunk-MZBUOP4P.js → chunk-5BSLGBYI.js} +4 -3
  12. package/dist/chunk-5BSLGBYI.js.map +1 -0
  13. package/dist/{chunk-I5Z3QH5X.js → chunk-66C4BSAY.js} +2 -2
  14. package/dist/{chunk-I5Z3QH5X.js.map → chunk-66C4BSAY.js.map} +1 -1
  15. package/dist/{chunk-EL2O4IUX.js → chunk-ASXSJGPW.js} +20 -24
  16. package/dist/{chunk-EL2O4IUX.js.map → chunk-ASXSJGPW.js.map} +1 -1
  17. package/dist/{chunk-7BNPOCLL.js → chunk-B2WTCLCV.js} +6 -2
  18. package/dist/chunk-B2WTCLCV.js.map +1 -0
  19. package/dist/{chunk-WJARTBCT.js → chunk-D7ARGIA3.js} +16 -7
  20. package/dist/chunk-D7ARGIA3.js.map +1 -0
  21. package/dist/{chunk-MYP2EGHX.js → chunk-GIDCWCHF.js} +21 -14
  22. package/dist/chunk-GIDCWCHF.js.map +1 -0
  23. package/dist/{chunk-MSFACPQQ.js → chunk-HYNGIE5T.js} +11 -11
  24. package/dist/{chunk-MSFACPQQ.js.map → chunk-HYNGIE5T.js.map} +1 -1
  25. package/dist/{chunk-TRIZ7IB7.js → chunk-I5GID3EX.js} +148 -288
  26. package/dist/chunk-I5GID3EX.js.map +1 -0
  27. package/dist/{chunk-GWSBHC4J.js → chunk-KLPVOPRI.js} +261 -38
  28. package/dist/chunk-KLPVOPRI.js.map +1 -0
  29. package/dist/{chunk-BC3S53OZ.js → chunk-N6XMGSGD.js} +30 -14
  30. package/dist/chunk-N6XMGSGD.js.map +1 -0
  31. package/dist/{chunk-6MTY77WU.js → chunk-QB4GXDUM.js} +3 -3
  32. package/dist/{chunk-YDJW5XTN.js → chunk-STT7INZR.js} +25 -1
  33. package/dist/chunk-STT7INZR.js.map +1 -0
  34. package/dist/{chunk-NYUJ4FJR.js → chunk-UETTVYKU.js} +7 -7
  35. package/dist/chunk-UETTVYKU.js.map +1 -0
  36. package/dist/{chunk-22KLBHPS.js → chunk-W66AZIOH.js} +2 -2
  37. package/dist/chunk-W66AZIOH.js.map +1 -0
  38. package/dist/{chunk-NZ655MWE.js → chunk-YEHO6FDW.js} +5 -4
  39. package/dist/chunk-YEHO6FDW.js.map +1 -0
  40. package/dist/{chunk-SS3E6QLB.js → chunk-YNUBMSMV.js} +2 -2
  41. package/dist/chunk-YNUBMSMV.js.map +1 -0
  42. package/dist/{chunk-74C6SNEC.js → chunk-ZPK5656W.js} +3 -3
  43. package/dist/{chunk-74C6SNEC.js.map → chunk-ZPK5656W.js.map} +1 -1
  44. package/dist/components.d.ts +22 -899
  45. package/dist/components.js +436 -3118
  46. package/dist/components.js.map +1 -1
  47. package/dist/file-reference-9xUOnwyt.d.ts +70 -0
  48. package/dist/hooks.d.ts +2 -2
  49. package/dist/hooks.js +10 -10
  50. package/dist/hooks.js.map +1 -1
  51. package/dist/index.d.ts +49 -9
  52. package/dist/index.js +190 -25
  53. package/dist/index.js.map +1 -1
  54. package/dist/{organisation-CO3Sh3_D.d.ts → organisation-t-vvQC3g.d.ts} +1 -8
  55. package/dist/providers.d.ts +2 -2
  56. package/dist/providers.js +5 -5
  57. package/dist/rbac/index.d.ts +65 -46
  58. package/dist/rbac/index.js +10 -12
  59. package/dist/styles/core.css +0 -125
  60. package/dist/types.d.ts +2 -1
  61. package/dist/types.js +3 -1
  62. package/dist/types.js.map +1 -1
  63. package/dist/{usePublicRouteParams-B2OcAsur.d.ts → usePublicRouteParams-CdoFxnJK.d.ts} +1 -1
  64. package/dist/utils.d.ts +3 -4
  65. package/dist/utils.js +44 -13
  66. package/dist/utils.js.map +1 -1
  67. package/docs/FILE_REFERENCE_SYSTEM.md +440 -0
  68. package/docs/INDEX.md +7 -5
  69. package/docs/README.md +0 -1
  70. package/docs/api/README.md +0 -4
  71. package/docs/api/classes/ErrorBoundary.md +1 -1
  72. package/docs/api/classes/InvalidScopeError.md +1 -1
  73. package/docs/api/classes/MissingUserContextError.md +1 -1
  74. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  75. package/docs/api/classes/PermissionDeniedError.md +2 -2
  76. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  77. package/docs/api/classes/RBACAuditManager.md +12 -12
  78. package/docs/api/classes/RBACCache.md +1 -1
  79. package/docs/api/classes/RBACEngine.md +6 -6
  80. package/docs/api/classes/RBACError.md +1 -1
  81. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  82. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  83. package/docs/api/classes/StorageUtils.md +281 -0
  84. package/docs/api/interfaces/AggregateConfig.md +1 -1
  85. package/docs/api/interfaces/ButtonProps.md +1 -1
  86. package/docs/api/interfaces/CardProps.md +1 -1
  87. package/docs/api/interfaces/ColorPalette.md +1 -1
  88. package/docs/api/interfaces/ColorShade.md +1 -1
  89. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  90. package/docs/api/interfaces/DataTableAction.md +1 -1
  91. package/docs/api/interfaces/DataTableColumn.md +1 -1
  92. package/docs/api/interfaces/DataTableProps.md +1 -1
  93. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  94. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  95. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  96. package/docs/api/interfaces/EventContextType.md +1 -1
  97. package/docs/api/interfaces/EventLogoProps.md +1 -1
  98. package/docs/api/interfaces/EventProviderProps.md +1 -1
  99. package/docs/api/interfaces/FileSizeLimits.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 +2 -2
  107. package/docs/api/interfaces/NavigationContextType.md +1 -1
  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 +1 -1
  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 +1 -1
  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 +1 -1
  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/RBACContextType.md +1 -1
  133. package/docs/api/interfaces/RBACLogger.md +1 -1
  134. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  135. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  136. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  137. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  138. package/docs/api/interfaces/RouteConfig.md +2 -2
  139. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  140. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  141. package/docs/api/interfaces/StorageConfig.md +1 -1
  142. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  143. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  144. package/docs/api/interfaces/StorageListOptions.md +1 -1
  145. package/docs/api/interfaces/StorageListResult.md +1 -1
  146. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  147. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  148. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  149. package/docs/api/interfaces/StyleImport.md +1 -1
  150. package/docs/api/interfaces/ToastActionElement.md +1 -1
  151. package/docs/api/interfaces/ToastProps.md +1 -1
  152. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  153. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  154. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  155. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  159. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  160. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  161. package/docs/api/interfaces/UserEventAccess.md +1 -1
  162. package/docs/api/interfaces/UserMenuProps.md +1 -1
  163. package/docs/api/interfaces/UserProfile.md +1 -1
  164. package/docs/api/modules.md +204 -200
  165. package/docs/api-reference/components.md +141 -163
  166. package/docs/api-reference/hooks.md +347 -0
  167. package/docs/core-concepts/rbac-system.md +69 -16
  168. package/docs/getting-started/examples/basic-auth-app.md +0 -1
  169. package/docs/implementation-guides/datatable-rbac-usage.md +12 -11
  170. package/docs/implementation-guides/file-upload-storage.md +733 -0
  171. package/docs/implementation-guides/inactivity-tracking.md +779 -0
  172. package/docs/implementation-guides/organisation-security.md +748 -0
  173. package/docs/implementation-guides/public-pages-advanced.md +1022 -0
  174. package/docs/migration/MIGRATION_GUIDE.md +684 -0
  175. package/docs/migration/README.md +13 -2
  176. package/docs/migration/rbac-migration.md +73 -0
  177. package/docs/rbac/examples/rbac-rls-integration-example.md +11 -13
  178. package/docs/style-guide.md +269 -1
  179. package/package.json +1 -1
  180. package/src/__tests__/TESTING_GUIDELINES.md +331 -18
  181. package/src/__tests__/helpers/supabaseMock.ts +99 -0
  182. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +10 -7
  183. package/src/__tests__/shared.ts +6 -0
  184. package/src/components/DataTable/components/ActionButtons.tsx +2 -2
  185. package/src/components/DataTable/components/DataTableCore.tsx +2 -2
  186. package/src/components/DataTable/components/UnifiedTableBody.tsx +1 -1
  187. package/src/components/DataTable/utils/debugTools.ts +2 -2
  188. package/src/components/Dialog/Dialog.test.tsx +12 -2
  189. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +6 -6
  190. package/src/components/ErrorBoundary/ErrorBoundary.tsx +2 -2
  191. package/src/components/FileDisplay.tsx +233 -0
  192. package/src/components/FileUpload.tsx +176 -0
  193. package/src/components/Footer/Footer.test.tsx +7 -7
  194. package/src/components/NavigationMenu/NavigationMenu.test.tsx +13 -6
  195. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +30 -3
  196. package/src/components/OrganisationSelector/OrganisationSelector.tsx +1 -1
  197. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +558 -0
  198. package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
  199. package/src/components/PublicLayout/PublicPageDebugger.tsx +2 -2
  200. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +2 -2
  201. package/src/components/PublicLayout/PublicPageProvider.tsx +2 -2
  202. package/src/components/Select/Select.test.tsx +50 -15
  203. package/src/components/SuperAdminGuard.tsx +2 -2
  204. package/src/components/__tests__/SuperAdminGuard.test.tsx +559 -0
  205. package/src/components/index.ts +0 -183
  206. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +2 -2
  207. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +1 -1
  208. package/src/hooks/__tests__/useRBAC.unit.test.ts +191 -138
  209. package/src/hooks/public/usePublicEvent.ts +2 -2
  210. package/src/hooks/useAppConfig.ts +3 -3
  211. package/src/hooks/useComponentPerformance.ts +1 -1
  212. package/src/hooks/useDataTablePerformance.ts +1 -1
  213. package/src/hooks/useFileReference.ts +232 -0
  214. package/src/hooks/useOrganisationPermissions.test.ts +254 -344
  215. package/src/hooks/useOrganisationPermissions.ts +15 -7
  216. package/src/hooks/useOrganisationSecurity.test.ts +390 -402
  217. package/src/hooks/usePerformanceMonitor.ts +1 -1
  218. package/src/hooks/usePermissionCache.test.ts +264 -395
  219. package/src/hooks/usePermissionCache.ts +34 -4
  220. package/src/hooks/useSecureDataAccess.test.ts +486 -0
  221. package/src/hooks/useSecureDataAccess.ts +4 -1
  222. package/src/providers/InactivityProvider.tsx +2 -2
  223. package/src/providers/OrganisationProvider.test.simple.tsx +168 -0
  224. package/src/providers/OrganisationProvider.test.tsx +168 -0
  225. package/src/providers/OrganisationProvider.tsx +25 -31
  226. package/src/providers/UnifiedAuthProvider.test.simple.tsx +205 -0
  227. package/src/providers/UnifiedAuthProvider.test.tsx +128 -0
  228. package/src/providers/__tests__/InactivityProvider.test.tsx +3 -4
  229. package/src/providers/__tests__/OrganisationProvider.test.tsx +19 -14
  230. package/src/rbac/__tests__/integration.authflow.test.tsx +123 -0
  231. package/src/rbac/__tests__/integration.navigation.test.tsx +72 -0
  232. package/src/rbac/__tests__/integration.securedata.test.tsx +92 -0
  233. package/src/rbac/__tests__/integration.smoke.test.tsx +73 -0
  234. package/src/rbac/__tests__/rbac-core.test.tsx +26 -22
  235. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +411 -0
  236. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +285 -0
  237. package/src/rbac/__tests__/rbac-functions.test.ts +655 -0
  238. package/src/rbac/__tests__/rbac-integration.test.ts +532 -0
  239. package/src/rbac/__tests__/scenarios.user-role.test.tsx +196 -0
  240. package/src/rbac/api.test.ts +6 -6
  241. package/src/rbac/api.ts +2 -2
  242. package/src/rbac/audit.test.ts +485 -0
  243. package/src/rbac/audit.ts +7 -1
  244. package/src/rbac/cache-invalidation.ts +318 -0
  245. package/src/rbac/cache.test.ts +286 -0
  246. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +559 -0
  247. package/src/rbac/components/EnhancedNavigationMenu.tsx +29 -23
  248. package/src/rbac/components/NavigationProvider.test.tsx +449 -0
  249. package/src/rbac/components/PagePermissionGuard.tsx +4 -4
  250. package/src/rbac/components/PagePermissionProvider.test.tsx +479 -0
  251. package/src/rbac/components/SecureDataProvider.test.tsx +511 -0
  252. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +159 -430
  253. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +4 -5
  254. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +112 -118
  255. package/src/rbac/config.test.ts +410 -0
  256. package/src/rbac/engine.test.simple.ts +237 -0
  257. package/src/rbac/engine.test.ts +233 -0
  258. package/src/rbac/engine.ts +37 -41
  259. package/src/rbac/examples/CompleteRBACExample.tsx +3 -3
  260. package/src/rbac/examples/EventBasedApp.tsx +4 -4
  261. package/src/rbac/hooks/useRBAC.simple.test.ts +16 -0
  262. package/src/rbac/hooks/useRBAC.test.ts +207 -455
  263. package/src/rbac/hooks/useRBAC.ts +30 -22
  264. package/src/rbac/permissions.test.ts +128 -0
  265. package/src/rbac/permissions.ts +56 -141
  266. package/src/rbac/providers/RBACProvider.tsx +1 -1
  267. package/src/rbac/secureClient.test.ts +444 -0
  268. package/src/rbac/security.test.ts +390 -0
  269. package/src/rbac/security.ts +1 -1
  270. package/src/rbac/types.test.ts +382 -0
  271. package/src/rbac/types.ts +2 -2
  272. package/src/styles/core.css +0 -125
  273. package/src/types/file-reference.ts +77 -0
  274. package/src/types/rbac-functions.ts +290 -0
  275. package/src/types/supabase.ts +10 -28
  276. package/src/types/unified.ts +4 -1
  277. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +81 -55
  278. package/src/utils/__tests__/lazyLoad.unit.test.tsx +21 -12
  279. package/src/utils/__tests__/organisationContext.unit.test.ts +13 -7
  280. package/src/utils/__tests__/performanceBudgets.unit.test.ts +3 -3
  281. package/src/utils/__tests__/sessionTracking.unit.test.ts +32 -12
  282. package/src/utils/appConfig.ts +1 -1
  283. package/src/utils/appIdResolver.test.ts +503 -0
  284. package/src/utils/appIdResolver.ts +1 -1
  285. package/src/utils/appNameResolver.test.ts +494 -0
  286. package/src/utils/appNameResolver.ts +3 -2
  287. package/src/utils/bundleAnalysis.ts +3 -3
  288. package/src/utils/debugLogger.ts +1 -1
  289. package/src/utils/file-reference.ts +263 -0
  290. package/src/utils/formatDate.test.ts +2 -2
  291. package/src/utils/organisationContext.test.ts +340 -0
  292. package/src/utils/organisationContext.ts +19 -6
  293. package/src/utils/performanceBudgets.ts +2 -2
  294. package/src/utils/permissionUtils.test.ts +393 -0
  295. package/src/utils/permissionUtils.ts +5 -2
  296. package/src/utils/secureDataAccess.test.ts +715 -0
  297. package/src/utils/secureDataAccess.ts +21 -5
  298. package/src/utils/sessionTracking.ts +34 -4
  299. package/src/utils/storage/__tests__/helpers.unit.test.ts +328 -0
  300. package/src/utils/storage/__tests__/index.unit.test.ts +16 -0
  301. package/src/utils/storage/helpers.ts +20 -25
  302. package/src/utils/storage/index.ts +29 -1
  303. package/src/vite-env.d.ts +17 -0
  304. package/dist/chunk-22KLBHPS.js.map +0 -1
  305. package/dist/chunk-7BNPOCLL.js.map +0 -1
  306. package/dist/chunk-BC3S53OZ.js.map +0 -1
  307. package/dist/chunk-GWSBHC4J.js.map +0 -1
  308. package/dist/chunk-MYP2EGHX.js.map +0 -1
  309. package/dist/chunk-MZBUOP4P.js.map +0 -1
  310. package/dist/chunk-NYUJ4FJR.js.map +0 -1
  311. package/dist/chunk-NZ655MWE.js.map +0 -1
  312. package/dist/chunk-SS3E6QLB.js.map +0 -1
  313. package/dist/chunk-TRIZ7IB7.js.map +0 -1
  314. package/dist/chunk-WJARTBCT.js.map +0 -1
  315. package/dist/chunk-YDJW5XTN.js.map +0 -1
  316. package/docs/print-components/README.md +0 -258
  317. package/docs/print-components/api-reference.md +0 -636
  318. package/docs/print-components/examples/README.md +0 -204
  319. package/docs/print-components/examples/basic-report.tsx +0 -92
  320. package/docs/print-components/examples/card-catalog.tsx +0 -149
  321. package/docs/print-components/examples/cover-page-report.tsx +0 -163
  322. package/docs/print-components/quick-start.md +0 -363
  323. package/src/components/PrintButton/PrintButton.tsx +0 -321
  324. package/src/components/PrintButton/PrintButtonGroup.tsx +0 -84
  325. package/src/components/PrintButton/PrintToolbar.tsx +0 -94
  326. package/src/components/PrintButton/__tests__/PrintButton.test.tsx +0 -271
  327. package/src/components/PrintButton/examples/PrintButtonShowcase.tsx +0 -438
  328. package/src/components/PrintButton/index.ts +0 -33
  329. package/src/components/PrintButton/types.ts +0 -173
  330. package/src/components/PrintCard/PrintCard.tsx +0 -154
  331. package/src/components/PrintCard/PrintCardContent.tsx +0 -57
  332. package/src/components/PrintCard/PrintCardFooter.tsx +0 -60
  333. package/src/components/PrintCard/PrintCardGrid.tsx +0 -91
  334. package/src/components/PrintCard/PrintCardHeader.tsx +0 -78
  335. package/src/components/PrintCard/PrintCardImage.tsx +0 -81
  336. package/src/components/PrintCard/examples/PrintCardShowcase.tsx +0 -239
  337. package/src/components/PrintCard/index.ts +0 -34
  338. package/src/components/PrintCard/types.ts +0 -171
  339. package/src/components/PrintDataTable/PrintDataTable.tsx +0 -215
  340. package/src/components/PrintDataTable/PrintTableGroup.tsx +0 -90
  341. package/src/components/PrintDataTable/PrintTableRow.tsx +0 -76
  342. package/src/components/PrintDataTable/index.ts +0 -25
  343. package/src/components/PrintDataTable/types.ts +0 -67
  344. package/src/components/PrintFooter/PrintFooter.tsx +0 -183
  345. package/src/components/PrintFooter/PrintFooterContent.tsx +0 -71
  346. package/src/components/PrintFooter/PrintFooterInfo.tsx +0 -86
  347. package/src/components/PrintFooter/PrintPageNumber.tsx +0 -90
  348. package/src/components/PrintFooter/examples/PrintFooterShowcase.tsx +0 -390
  349. package/src/components/PrintFooter/index.ts +0 -30
  350. package/src/components/PrintFooter/types.ts +0 -149
  351. package/src/components/PrintGrid/PrintGrid.tsx +0 -180
  352. package/src/components/PrintGrid/PrintGridBreakpoint.tsx +0 -109
  353. package/src/components/PrintGrid/PrintGridContainer.tsx +0 -128
  354. package/src/components/PrintGrid/PrintGridItem.tsx +0 -220
  355. package/src/components/PrintGrid/examples/PrintGridShowcase.tsx +0 -359
  356. package/src/components/PrintGrid/index.ts +0 -31
  357. package/src/components/PrintGrid/types.ts +0 -159
  358. package/src/components/PrintHeader/PrintCoverHeader.tsx +0 -230
  359. package/src/components/PrintHeader/PrintHeader.tsx +0 -150
  360. package/src/components/PrintHeader/index.ts +0 -17
  361. package/src/components/PrintHeader/types.ts +0 -42
  362. package/src/components/PrintLayout/PrintLayout.tsx +0 -122
  363. package/src/components/PrintLayout/PrintLayoutContext.tsx +0 -66
  364. package/src/components/PrintLayout/PrintPageBreak.tsx +0 -52
  365. package/src/components/PrintLayout/examples/PrintShowcase.tsx +0 -230
  366. package/src/components/PrintLayout/index.ts +0 -19
  367. package/src/components/PrintLayout/types.ts +0 -37
  368. package/src/components/PrintPageBreak/PrintPageBreak.tsx +0 -120
  369. package/src/components/PrintPageBreak/PrintPageBreakGroup.tsx +0 -90
  370. package/src/components/PrintPageBreak/PrintPageBreakIndicator.tsx +0 -112
  371. package/src/components/PrintPageBreak/examples/PrintPageBreakShowcase.tsx +0 -279
  372. package/src/components/PrintPageBreak/index.ts +0 -23
  373. package/src/components/PrintPageBreak/types.ts +0 -94
  374. package/src/components/PrintSection/PrintColumn.tsx +0 -104
  375. package/src/components/PrintSection/PrintDivider.tsx +0 -101
  376. package/src/components/PrintSection/PrintSection.tsx +0 -129
  377. package/src/components/PrintSection/PrintSectionContent.tsx +0 -75
  378. package/src/components/PrintSection/PrintSectionHeader.tsx +0 -97
  379. package/src/components/PrintSection/examples/PrintSectionShowcase.tsx +0 -258
  380. package/src/components/PrintSection/index.ts +0 -33
  381. package/src/components/PrintSection/types.ts +0 -155
  382. package/src/components/PrintText/PrintText.tsx +0 -116
  383. package/src/components/PrintText/index.ts +0 -16
  384. package/src/components/PrintText/types.ts +0 -24
  385. package/src/rbac/__tests__/integration.test.tsx +0 -218
  386. package/src/utils/print/PrintDataProcessor.ts +0 -390
  387. package/src/utils/print/examples/PrintUtilitiesShowcase.tsx +0 -397
  388. package/src/utils/print/index.ts +0 -29
  389. package/src/utils/print/types.ts +0 -196
  390. package/src/utils/print/usePrintOptimization.ts +0 -272
  391. /package/dist/{DataTable-7FMFXA7A.js.map → DataTable-DJQTKX33.js.map} +0 -0
  392. /package/dist/{api-H5A3H4IR.js.map → api-LUNF5O6M.js.map} +0 -0
  393. /package/dist/{appNameResolver-7GHF5ED2.js.map → appNameResolver-UURKN7NF.js.map} +0 -0
  394. /package/dist/{audit-BUW3LMJB.js.map → audit-6TOCAMKO.js.map} +0 -0
  395. /package/dist/{chunk-NRK4AIHQ.js.map → chunk-2DFCT6D3.js.map} +0 -0
  396. /package/dist/{chunk-6MTY77WU.js.map → chunk-QB4GXDUM.js.map} +0 -0
@@ -0,0 +1,128 @@
1
+ /**
2
+ * @file Simplified Unified Authentication Provider Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module Providers/UnifiedAuthProvider
5
+ * @since 0.1.0
6
+ *
7
+ * Basic tests for the UnifiedAuthProvider component.
8
+ */
9
+
10
+ import { render, screen } from '@testing-library/react';
11
+ import { vi, describe, it, expect, beforeEach } from 'vitest';
12
+ import { ReactNode } from 'react';
13
+ import { UnifiedAuthProvider, useUnifiedAuth } from './UnifiedAuthProvider';
14
+
15
+ // Mock all the child providers with minimal implementations
16
+ vi.mock('./AuthProvider', () => ({
17
+ AuthProvider: ({ children }: { children: ReactNode }) => <div>{children}</div>,
18
+ useAuth: () => ({
19
+ user: { id: 'test-user', email: 'test@example.com' },
20
+ session: { access_token: 'test-token' },
21
+ authLoading: false,
22
+ authError: null,
23
+ signIn: vi.fn(),
24
+ signUp: vi.fn(),
25
+ signOut: vi.fn(),
26
+ resetPassword: vi.fn(),
27
+ isAuthenticated: true,
28
+ supabase: {}
29
+ })
30
+ }));
31
+
32
+ vi.mock('../rbac/providers/RBACProvider', () => ({
33
+ RBACProvider: ({ children }: { children: ReactNode }) => <div>{children}</div>,
34
+ useRBAC: () => ({
35
+ rbacLoading: false,
36
+ rbacError: null,
37
+ hasPermission: vi.fn().mockReturnValue(true),
38
+ hasRole: vi.fn().mockReturnValue(true),
39
+ hasAccessLevel: vi.fn().mockReturnValue(true),
40
+ validatePermission: vi.fn().mockResolvedValue(true),
41
+ canAccess: vi.fn().mockReturnValue(true),
42
+ getAccessLevel: vi.fn().mockReturnValue('admin'),
43
+ setSelectedEventId: vi.fn(),
44
+ permissions: { 'read:users': true },
45
+ roles: ['admin'],
46
+ accessLevel: 'admin',
47
+ selectedEventId: null,
48
+ appConfig: null,
49
+ userEventAccess: [],
50
+ eventAccessLoading: false,
51
+ selectedOrganisationId: 'org-123',
52
+ requireOrganisationContext: vi.fn().mockReturnValue('org-123'),
53
+ hasAnyPermission: vi.fn().mockReturnValue(true),
54
+ hasAllPermissions: vi.fn().mockReturnValue(true),
55
+ validateAccess: vi.fn().mockResolvedValue(true),
56
+ refreshPermissions: vi.fn().mockResolvedValue(undefined),
57
+ loadUserEventAccess: vi.fn().mockResolvedValue(undefined),
58
+ getUserEventAccess: vi.fn().mockReturnValue(undefined)
59
+ })
60
+ }));
61
+
62
+ vi.mock('./InactivityProvider', () => ({
63
+ InactivityProvider: ({ children }: { children: ReactNode }) => <div>{children}</div>,
64
+ useInactivity: () => ({
65
+ isIdle: false,
66
+ timeRemaining: 30 * 60 * 1000,
67
+ showWarning: false,
68
+ staySignedIn: vi.fn(),
69
+ signOutNow: vi.fn()
70
+ })
71
+ }));
72
+
73
+ // Mock Supabase client
74
+ const mockSupabase = {
75
+ auth: {
76
+ getUser: vi.fn().mockResolvedValue({ data: { user: null }, error: null }),
77
+ getSession: vi.fn().mockResolvedValue({ data: { session: null }, error: null }),
78
+ onAuthStateChange: vi.fn().mockReturnValue({ data: { subscription: { unsubscribe: vi.fn() } } })
79
+ }
80
+ };
81
+
82
+ describe('UnifiedAuthProvider', () => {
83
+ beforeEach(() => {
84
+ vi.clearAllMocks();
85
+ });
86
+
87
+ describe('Basic Functionality', () => {
88
+ it('renders without crashing', () => {
89
+ render(
90
+ <UnifiedAuthProvider supabaseClient={mockSupabase as any} appName="test-app">
91
+ <div data-testid="test-content">Test Content</div>
92
+ </UnifiedAuthProvider>
93
+ );
94
+
95
+ expect(screen.getByTestId('test-content')).toBeInTheDocument();
96
+ });
97
+
98
+ it('provides context without errors', () => {
99
+ const TestConsumer = () => {
100
+ const context = useUnifiedAuth();
101
+ // Just verify context exists without checking specific values
102
+ expect(context).toBeDefined();
103
+ return <div data-testid="context-consumer">Context Available</div>;
104
+ };
105
+
106
+ render(
107
+ <UnifiedAuthProvider supabaseClient={mockSupabase as any} appName="test-app">
108
+ <TestConsumer />
109
+ </UnifiedAuthProvider>
110
+ );
111
+
112
+ expect(screen.getByTestId('context-consumer')).toBeInTheDocument();
113
+ });
114
+
115
+ it('renders children correctly', () => {
116
+ render(
117
+ <UnifiedAuthProvider supabaseClient={mockSupabase as any} appName="test-app">
118
+ <div data-testid="child-1">Child 1</div>
119
+ <div data-testid="child-2">Child 2</div>
120
+ </UnifiedAuthProvider>
121
+ );
122
+
123
+ expect(screen.getByTestId('child-1')).toBeInTheDocument();
124
+ expect(screen.getByTestId('child-2')).toBeInTheDocument();
125
+ });
126
+ });
127
+
128
+ });
@@ -509,9 +509,8 @@ describe('InactivityProvider', () => {
509
509
  it('warns about disabling inactivity in production', () => {
510
510
  const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
511
511
 
512
- // Mock production environment
513
- const originalEnv = process.env.NODE_ENV;
514
- process.env.NODE_ENV = 'production';
512
+ // Mock production environment using vi.stubEnv
513
+ vi.stubEnv('MODE', 'production');
515
514
 
516
515
  render(
517
516
  <TestWrapper dangerouslyDisableInactivity={true}>
@@ -524,7 +523,7 @@ describe('InactivityProvider', () => {
524
523
  );
525
524
 
526
525
  // Restore environment
527
- process.env.NODE_ENV = originalEnv;
526
+ vi.unstubAllEnvs();
528
527
  consoleErrorSpy.mockRestore();
529
528
  });
530
529
 
@@ -178,27 +178,32 @@ describe('OrganisationProvider', () => {
178
178
  // Create mock Supabase client
179
179
  mockSupabaseClient = createMockSupabaseClient();
180
180
  mockSupabaseClient.from = vi.fn((table: string) => {
181
- // Return different responses based on the table
182
- if (table === 'organisation_memberships') {
183
- return {
181
+ // Create a mock query builder that handles the chained calls
182
+ const createMockQueryBuilder = (data: any) => {
183
+ const queryBuilder = {
184
184
  select: vi.fn().mockReturnThis(),
185
185
  eq: vi.fn().mockReturnThis(),
186
186
  is: vi.fn().mockReturnThis(),
187
- in: vi.fn().mockResolvedValue({
188
- data: mockMemberships,
189
- error: null
187
+ in: vi.fn().mockReturnThis(),
188
+ order: vi.fn().mockReturnThis(),
189
+ limit: vi.fn().mockReturnThis(),
190
+ single: vi.fn().mockResolvedValue({ data: data[0] || null, error: null }),
191
+ maybeSingle: vi.fn().mockResolvedValue({ data: data[0] || null, error: null }),
192
+ // Make it thenable
193
+ then: vi.fn().mockImplementation((resolve) => {
194
+ resolve({ data, error: null });
190
195
  }),
191
196
  };
197
+ return queryBuilder;
198
+ };
199
+
200
+ // Return different responses based on the table
201
+ if (table === 'rbac_organisation_roles') {
202
+ return createMockQueryBuilder(mockMemberships);
192
203
  } else if (table === 'organisations') {
193
- return {
194
- select: vi.fn().mockReturnThis(),
195
- in: vi.fn().mockResolvedValue({
196
- data: mockOrganisations,
197
- error: null
198
- }),
199
- };
204
+ return createMockQueryBuilder(mockOrganisations);
200
205
  }
201
- return mockQueryBuilder;
206
+ return createMockQueryBuilder([]);
202
207
  });
203
208
 
204
209
  // Mock auth state
@@ -0,0 +1,123 @@
1
+ import React from 'react';
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
+ import { render, screen, waitFor } from '@testing-library/react';
4
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5
+ import { createMemoryRouter, RouterProvider } from 'react-router-dom';
6
+ import { UnifiedAuthProvider } from '../../providers/UnifiedAuthProvider';
7
+ import { OrganisationProvider } from '../../providers/OrganisationProvider';
8
+ import { RBACProvider } from '../providers/RBACProvider';
9
+ import { useRBAC } from '../hooks/useRBAC';
10
+ import type { SupabaseClient, User } from '@supabase/supabase-js';
11
+
12
+ const mockSupabaseClient = {
13
+ auth: {
14
+ getUser: vi.fn(),
15
+ },
16
+ } as unknown as SupabaseClient;
17
+
18
+ // Local lightweight mocks to avoid importing heavy RBAC modules during bisect
19
+ vi.mock('../hooks/useRBAC', () => ({
20
+ useRBAC: () => ({
21
+ user: { email: 'test@example.com' },
22
+ isAuthenticated: true,
23
+ isLoading: false,
24
+ }),
25
+ }));
26
+
27
+ vi.mock('../providers/RBACProvider', () => ({
28
+ RBACProvider: ({ children }: any) => children,
29
+ }));
30
+
31
+ const mockUser: User = {
32
+ id: 'user-123',
33
+ email: 'test@example.com',
34
+ created_at: '2023-01-01T00:00:00Z',
35
+ updated_at: '2023-01-01T00:00:00Z',
36
+ aud: 'authenticated',
37
+ role: 'authenticated',
38
+ app_metadata: {},
39
+ user_metadata: {},
40
+ identities: [],
41
+ factors: [],
42
+ } as User;
43
+
44
+ const MinimalAuthComponent = () => {
45
+ const { user, isAuthenticated, isLoading } = useRBAC();
46
+ if (isLoading) return <div>Loading...</div>;
47
+ if (!isAuthenticated) return <div>Not authenticated</div>;
48
+ return (
49
+ <div>
50
+ <h1>AuthFlow Minimal</h1>
51
+ <p>User: {user?.email}</p>
52
+ </div>
53
+ );
54
+ };
55
+
56
+ const Wrapper = ({ children }: { children: React.ReactNode }) => {
57
+ const queryClient = new QueryClient({
58
+ defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
59
+ });
60
+ return (
61
+ <QueryClientProvider client={queryClient}>
62
+ <UnifiedAuthProvider supabase={mockSupabaseClient}>
63
+ <OrganisationProvider>
64
+ <RBACProvider>{children}</RBACProvider>
65
+ </OrganisationProvider>
66
+ </UnifiedAuthProvider>
67
+ </QueryClientProvider>
68
+ );
69
+ };
70
+
71
+ describe('RBAC AuthFlow Minimal', () => {
72
+ beforeEach(() => {
73
+ vi.clearAllMocks();
74
+ mockSupabaseClient.auth.getUser = vi
75
+ .fn()
76
+ .mockResolvedValue({ data: { user: mockUser }, error: null });
77
+ });
78
+
79
+ afterEach(() => {
80
+ vi.restoreAllMocks();
81
+ });
82
+
83
+ it('renders authenticated view', async () => {
84
+ const router = createMemoryRouter([{ path: '/', element: <MinimalAuthComponent /> }]);
85
+
86
+ render(
87
+ <Wrapper>
88
+ <RouterProvider router={router} />
89
+ </Wrapper>
90
+ );
91
+
92
+ await waitFor(() => {
93
+ expect(screen.getByText('AuthFlow Minimal')).toBeInTheDocument();
94
+ });
95
+ expect(screen.getByText('User: test@example.com')).toBeInTheDocument();
96
+ });
97
+
98
+ it('renders not authenticated view', async () => {
99
+ const useRBACModule = await import('../hooks/useRBAC');
100
+ vi.spyOn(useRBACModule, 'useRBAC').mockReturnValue({
101
+ user: null,
102
+ isAuthenticated: false,
103
+ isLoading: false,
104
+ } as any);
105
+ mockSupabaseClient.auth.getUser = vi
106
+ .fn()
107
+ .mockResolvedValue({ data: { user: null }, error: null });
108
+
109
+ const router = createMemoryRouter([{ path: '/', element: <MinimalAuthComponent /> }]);
110
+
111
+ render(
112
+ <Wrapper>
113
+ <RouterProvider router={router} />
114
+ </Wrapper>
115
+ );
116
+
117
+ await waitFor(() => {
118
+ expect(screen.getByText('Not authenticated')).toBeInTheDocument();
119
+ });
120
+ });
121
+ });
122
+
123
+
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
+ import { render, screen, waitFor } from '@testing-library/react';
4
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5
+ import { createMemoryRouter, RouterProvider } from 'react-router-dom';
6
+ import { UnifiedAuthProvider } from '../../providers/UnifiedAuthProvider';
7
+ import { OrganisationProvider } from '../../providers/OrganisationProvider';
8
+ import { RBACProvider } from '../providers/RBACProvider';
9
+ import { NavigationProvider } from '../components/NavigationProvider';
10
+ import { EnhancedNavigationMenu } from '../components/EnhancedNavigationMenu';
11
+
12
+ // Local lightweight mocks
13
+ vi.mock('../components/EnhancedNavigationMenu', () => ({
14
+ EnhancedNavigationMenu: () => (
15
+ <div>
16
+ <div>Users</div>
17
+ <div>Settings</div>
18
+ <div>Admin</div>
19
+ </div>
20
+ ),
21
+ }));
22
+
23
+ const Wrapper = ({ children }: { children: React.ReactNode }) => {
24
+ const queryClient = new QueryClient({
25
+ defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
26
+ });
27
+ return (
28
+ <QueryClientProvider client={queryClient}>
29
+ <UnifiedAuthProvider supabase={{} as any}>
30
+ <OrganisationProvider>
31
+ <RBACProvider>{children}</RBACProvider>
32
+ </OrganisationProvider>
33
+ </UnifiedAuthProvider>
34
+ </QueryClientProvider>
35
+ );
36
+ };
37
+
38
+ const NavUnderTest = () => {
39
+ const navigationItems = [
40
+ { label: 'Users', path: '/users', permissions: ['read:users'] },
41
+ { label: 'Settings', path: '/settings', permissions: ['write:users'] },
42
+ { label: 'Admin', path: '/admin', permissions: ['delete:users'] },
43
+ ];
44
+ return (
45
+ <NavigationProvider navigationItems={navigationItems}>
46
+ <EnhancedNavigationMenu />
47
+ </NavigationProvider>
48
+ );
49
+ };
50
+
51
+ describe('RBAC Navigation Integration', () => {
52
+ beforeEach(() => {
53
+ vi.clearAllMocks();
54
+ });
55
+ afterEach(() => vi.restoreAllMocks());
56
+
57
+ it('shows all mocked navigation items', async () => {
58
+ const router = createMemoryRouter([{ path: '/', element: <NavUnderTest /> }]);
59
+ render(
60
+ <Wrapper>
61
+ <RouterProvider router={router} />
62
+ </Wrapper>
63
+ );
64
+ await waitFor(() => {
65
+ expect(screen.getByText('Users')).toBeInTheDocument();
66
+ expect(screen.getByText('Settings')).toBeInTheDocument();
67
+ expect(screen.getByText('Admin')).toBeInTheDocument();
68
+ });
69
+ });
70
+ });
71
+
72
+
@@ -0,0 +1,92 @@
1
+ import React from 'react';
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
+ import { render, screen, waitFor } from '@testing-library/react';
4
+ import userEvent from '@testing-library/user-event';
5
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
+ import { createMemoryRouter, RouterProvider } from 'react-router-dom';
7
+ import { UnifiedAuthProvider } from '../../providers/UnifiedAuthProvider';
8
+ import { OrganisationProvider } from '../../providers/OrganisationProvider';
9
+ import { RBACProvider } from '../providers/RBACProvider';
10
+ import { useSecureDataAccess } from '../../hooks/useSecureDataAccess';
11
+
12
+ // Local lightweight mock for secure data access
13
+ vi.mock('../../hooks/useSecureDataAccess', () => ({
14
+ useSecureDataAccess: () => ({
15
+ secureDataAccess: {
16
+ secureQuery: vi.fn().mockResolvedValue([
17
+ { id: '1', name: 'User 1', email: 'user1@example.com' },
18
+ { id: '2', name: 'User 2', email: 'user2@example.com' },
19
+ ]),
20
+ },
21
+ }),
22
+ }));
23
+
24
+ const Wrapper = ({ children }: { children: React.ReactNode }) => {
25
+ const queryClient = new QueryClient({
26
+ defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
27
+ });
28
+ return (
29
+ <QueryClientProvider client={queryClient}>
30
+ <UnifiedAuthProvider supabase={{} as any}>
31
+ <OrganisationProvider>
32
+ <RBACProvider>{children}</RBACProvider>
33
+ </OrganisationProvider>
34
+ </UnifiedAuthProvider>
35
+ </QueryClientProvider>
36
+ );
37
+ };
38
+
39
+ const SecureDataProbe = () => {
40
+ const { secureDataAccess: secureData } = useSecureDataAccess();
41
+ const [data, setData] = React.useState<any[] | null>(null);
42
+ const [loading, setLoading] = React.useState(false);
43
+
44
+ const fetchData = async () => {
45
+ setLoading(true);
46
+ const result = await secureData.secureQuery({
47
+ table: 'users',
48
+ select: 'id, name, email',
49
+ organisationId: 'org-123',
50
+ });
51
+ setData(result);
52
+ setLoading(false);
53
+ };
54
+
55
+ return (
56
+ <div>
57
+ <button onClick={fetchData} disabled={loading}>
58
+ {loading ? 'Loading...' : 'Fetch Data'}
59
+ </button>
60
+ {data && (
61
+ <>
62
+ <div>{data[0]?.name}</div>
63
+ <div>{data[1]?.name}</div>
64
+ </>
65
+ )}
66
+ </div>
67
+ );
68
+ };
69
+
70
+ describe('RBAC Secure Data Integration', () => {
71
+ beforeEach(() => vi.clearAllMocks());
72
+ afterEach(() => vi.restoreAllMocks());
73
+
74
+ it('fetches data with organisation context via secureQuery', async () => {
75
+ const router = createMemoryRouter([{ path: '/', element: <SecureDataProbe /> }]);
76
+ render(
77
+ <Wrapper>
78
+ <RouterProvider router={router} />
79
+ </Wrapper>
80
+ );
81
+
82
+ const user = userEvent.setup();
83
+ await user.click(screen.getByText('Fetch Data'));
84
+
85
+ await waitFor(() => {
86
+ expect(screen.getByText('User 1')).toBeInTheDocument();
87
+ expect(screen.getByText('User 2')).toBeInTheDocument();
88
+ });
89
+ });
90
+ });
91
+
92
+
@@ -0,0 +1,73 @@
1
+ import React from 'react';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { render, screen } from '@testing-library/react';
4
+ import { UnifiedAuthProvider } from '../../providers/UnifiedAuthProvider';
5
+ import { OrganisationProvider } from '../../providers/OrganisationProvider';
6
+ import { RBACProvider } from '../providers/RBACProvider';
7
+ import { useCan } from '../hooks';
8
+
9
+ describe('RBAC Integration Smoke', () => {
10
+ it('renders trivial component without providers', () => {
11
+ render(<div>RBAC Smoke OK</div>);
12
+ expect(screen.getByText('RBAC Smoke OK')).toBeInTheDocument();
13
+ });
14
+
15
+ it('renders with UnifiedAuthProvider only', () => {
16
+ render(
17
+ <UnifiedAuthProvider supabase={{} as any}>
18
+ <div>Auth Only</div>
19
+ </UnifiedAuthProvider>
20
+ );
21
+ expect(screen.getByText('Auth Only')).toBeInTheDocument();
22
+ });
23
+
24
+ it('renders with OrganisationProvider only', () => {
25
+ render(
26
+ <OrganisationProvider>
27
+ <div>Org Only</div>
28
+ </OrganisationProvider>
29
+ );
30
+ expect(screen.getByText('Org Only')).toBeInTheDocument();
31
+ });
32
+
33
+ it('renders with RBACProvider only', () => {
34
+ render(
35
+ <RBACProvider>
36
+ <div>RBAC Only</div>
37
+ </RBACProvider>
38
+ );
39
+ expect(screen.getByText('RBAC Only')).toBeInTheDocument();
40
+ });
41
+
42
+ it('renders full minimal stack without RBAC hooks usage', () => {
43
+ render(
44
+ <UnifiedAuthProvider supabase={{} as any}>
45
+ <OrganisationProvider>
46
+ <RBACProvider>
47
+ <div>Full Stack Minimal</div>
48
+ </RBACProvider>
49
+ </OrganisationProvider>
50
+ </UnifiedAuthProvider>
51
+ );
52
+ expect(screen.getByText('Full Stack Minimal')).toBeInTheDocument();
53
+ });
54
+
55
+ it('mounts a component that calls useCan() (global mock) without leaking', () => {
56
+ const Probe = () => {
57
+ const { hasPermission } = useCan() as any;
58
+ return <div>{hasPermission('read:users') ? 'HasPerm' : 'NoPerm'}</div>;
59
+ };
60
+ render(
61
+ <UnifiedAuthProvider supabase={{} as any}>
62
+ <OrganisationProvider>
63
+ <RBACProvider>
64
+ <Probe />
65
+ </RBACProvider>
66
+ </OrganisationProvider>
67
+ </UnifiedAuthProvider>
68
+ );
69
+ expect(screen.getByText('HasPerm')).toBeInTheDocument();
70
+ });
71
+ });
72
+
73
+