@jmruthers/pace-core 0.5.67 → 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 (384) hide show
  1. package/README.md +26 -0
  2. package/dist/{DataTable-MFUXNGPR.js → DataTable-MPBSXUC6.js} +5 -6
  3. package/dist/{PublicLoadingSpinner-DdKXTkCZ.d.ts → PublicLoadingSpinner-BOdyU3u-.d.ts} +1 -1
  4. package/dist/{UnifiedAuthProvider-CQNiemcB.d.ts → UnifiedAuthProvider-D02AMXgO.d.ts} +3 -3
  5. package/dist/{chunk-CKNY7HYS.js → chunk-2ARQW6VX.js} +3 -3
  6. package/dist/{chunk-T2MQY57J.js → chunk-6JILXFEA.js} +335 -5
  7. package/dist/chunk-6JILXFEA.js.map +1 -0
  8. package/dist/{chunk-D7ARGIA3.js → chunk-6RBH67W7.js} +23 -6
  9. package/dist/chunk-6RBH67W7.js.map +1 -0
  10. package/dist/{chunk-C7GUF747.js → chunk-FJTAWPAQ.js} +3 -5
  11. package/dist/{chunk-C7GUF747.js.map → chunk-FJTAWPAQ.js.map} +1 -1
  12. package/dist/{chunk-4HQ5BOVZ.js → chunk-NO5QHMDX.js} +7 -6
  13. package/dist/chunk-NO5QHMDX.js.map +1 -0
  14. package/dist/{chunk-ZPK5656W.js → chunk-O3NWNXDY.js} +4 -5
  15. package/dist/chunk-O3NWNXDY.js.map +1 -0
  16. package/dist/{chunk-BTCA3ENN.js → chunk-Q2UP3ZWQ.js} +4 -4
  17. package/dist/{chunk-QVEOQVD4.js → chunk-RVYGJPOD.js} +173 -20
  18. package/dist/chunk-RVYGJPOD.js.map +1 -0
  19. package/dist/{chunk-FVDOEGGG.js → chunk-UCMHBF7Y.js} +3 -5
  20. package/dist/{chunk-FVDOEGGG.js.map → chunk-UCMHBF7Y.js.map} +1 -1
  21. package/dist/{chunk-T6HVDA24.js → chunk-V3QO3LL7.js} +5 -7
  22. package/dist/chunk-V3QO3LL7.js.map +1 -0
  23. package/dist/{chunk-ZB6AEA7I.js → chunk-ZXJGZLLO.js} +17 -17
  24. package/dist/{chunk-ZB6AEA7I.js.map → chunk-ZXJGZLLO.js.map} +1 -1
  25. package/dist/components.d.ts +2 -2
  26. package/dist/components.js +8 -9
  27. package/dist/components.js.map +1 -1
  28. package/dist/hooks.d.ts +1 -1
  29. package/dist/hooks.js +9 -6
  30. package/dist/hooks.js.map +1 -1
  31. package/dist/index.d.ts +4 -4
  32. package/dist/index.js +16 -16
  33. package/dist/index.js.map +1 -1
  34. package/dist/providers.d.ts +1 -1
  35. package/dist/providers.js +5 -7
  36. package/dist/rbac/index.js +5 -6
  37. package/dist/{usePublicRouteParams-CdoFxnJK.d.ts → usePublicRouteParams-Ua1Vz-HG.d.ts} +35 -1
  38. package/dist/utils.d.ts +4 -1
  39. package/dist/utils.js +3 -3
  40. package/docs/DOCUMENTATION_CHECKLIST.md +281 -0
  41. package/docs/README.md +22 -10
  42. package/docs/api/README.md +26 -0
  43. package/docs/api/classes/ColumnFactory.md +1 -1
  44. package/docs/api/classes/ErrorBoundary.md +1 -1
  45. package/docs/api/classes/InvalidScopeError.md +1 -1
  46. package/docs/api/classes/MissingUserContextError.md +1 -1
  47. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  48. package/docs/api/classes/PermissionDeniedError.md +1 -1
  49. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  50. package/docs/api/classes/RBACAuditManager.md +1 -1
  51. package/docs/api/classes/RBACCache.md +1 -1
  52. package/docs/api/classes/RBACEngine.md +1 -1
  53. package/docs/api/classes/RBACError.md +1 -1
  54. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  55. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  56. package/docs/api/classes/StorageUtils.md +1 -1
  57. package/docs/api/interfaces/AggregateConfig.md +1 -1
  58. package/docs/api/interfaces/ButtonProps.md +1 -1
  59. package/docs/api/interfaces/CardProps.md +1 -1
  60. package/docs/api/interfaces/ColorPalette.md +1 -1
  61. package/docs/api/interfaces/ColorShade.md +1 -1
  62. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  63. package/docs/api/interfaces/DataTableAction.md +1 -1
  64. package/docs/api/interfaces/DataTableColumn.md +1 -1
  65. package/docs/api/interfaces/DataTableProps.md +1 -1
  66. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  67. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  68. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  69. package/docs/api/interfaces/EventContextType.md +1 -1
  70. package/docs/api/interfaces/EventLogoProps.md +1 -1
  71. package/docs/api/interfaces/EventProviderProps.md +1 -1
  72. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  73. package/docs/api/interfaces/FileUploadProps.md +1 -1
  74. package/docs/api/interfaces/FooterProps.md +1 -1
  75. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  76. package/docs/api/interfaces/InputProps.md +1 -1
  77. package/docs/api/interfaces/LabelProps.md +1 -1
  78. package/docs/api/interfaces/LoginFormProps.md +1 -1
  79. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  80. package/docs/api/interfaces/NavigationContextType.md +1 -1
  81. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  82. package/docs/api/interfaces/NavigationItem.md +1 -1
  83. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  84. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  85. package/docs/api/interfaces/Organisation.md +1 -1
  86. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  87. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  88. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  89. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  90. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  91. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  92. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  93. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  94. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  95. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  96. package/docs/api/interfaces/PaletteData.md +1 -1
  97. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  98. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  99. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  100. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  101. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  102. package/docs/api/interfaces/PublicPageHeaderProps.md +2 -2
  103. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  104. package/docs/api/interfaces/RBACConfig.md +1 -1
  105. package/docs/api/interfaces/RBACContextType.md +1 -1
  106. package/docs/api/interfaces/RBACLogger.md +1 -1
  107. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  108. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  109. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  110. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  111. package/docs/api/interfaces/RouteConfig.md +1 -1
  112. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  113. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  114. package/docs/api/interfaces/StorageConfig.md +1 -1
  115. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  116. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  117. package/docs/api/interfaces/StorageListOptions.md +1 -1
  118. package/docs/api/interfaces/StorageListResult.md +1 -1
  119. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  120. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  121. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  122. package/docs/api/interfaces/StyleImport.md +1 -1
  123. package/docs/api/interfaces/SwitchProps.md +1 -1
  124. package/docs/api/interfaces/ToastActionElement.md +1 -1
  125. package/docs/api/interfaces/ToastProps.md +1 -1
  126. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  127. package/docs/api/interfaces/UnifiedAuthProviderProps.md +4 -4
  128. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  129. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  130. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  131. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  132. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  133. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  134. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  135. package/docs/api/interfaces/UserEventAccess.md +1 -1
  136. package/docs/api/interfaces/UserMenuProps.md +1 -1
  137. package/docs/api/interfaces/UserProfile.md +1 -1
  138. package/docs/api/modules.md +39 -14
  139. package/docs/api-reference/providers.md +16 -7
  140. package/docs/architecture/services.md +374 -0
  141. package/docs/best-practices/README.md +1 -1
  142. package/docs/best-practices/testing.md +1 -1
  143. package/docs/breaking-changes.md +182 -0
  144. package/docs/common-patterns.md +445 -0
  145. package/docs/core-concepts/authentication.md +26 -11
  146. package/docs/core-concepts/events.md +2 -0
  147. package/docs/core-concepts/organisations.md +2 -0
  148. package/docs/core-concepts/permissions.md +2 -0
  149. package/docs/{INDEX.md → documentation-index.md} +26 -38
  150. package/docs/faq.md +286 -0
  151. package/docs/{FILE_REFERENCE_SYSTEM.md → file-reference-system.md} +1 -1
  152. package/docs/getting-started/installation-guide.md +284 -0
  153. package/docs/getting-started/quick-start.md +8 -1
  154. package/docs/implementation-guides/app-layout.md +3 -1
  155. package/docs/implementation-guides/data-tables.md +2 -0
  156. package/docs/implementation-guides/dynamic-colors.md +47 -2
  157. package/docs/implementation-guides/event-theming-summary.md +220 -0
  158. package/docs/implementation-guides/forms.md +9 -7
  159. package/docs/implementation-guides/navigation.md +2 -0
  160. package/docs/migration/service-architecture.md +351 -0
  161. package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +226 -0
  162. package/docs/rbac/README-rbac-rls-integration.md +2 -2
  163. package/docs/rbac/README.md +1 -1
  164. package/docs/rbac/examples/rbac-rls-integration-example.md +3 -3
  165. package/docs/rbac/quick-start.md +2 -0
  166. package/docs/rbac/rbac-rls-integration.md +2 -2
  167. package/docs/security/README.md +5 -1
  168. package/docs/style-guide.md +136 -1
  169. package/docs/testing/README.md +1 -1
  170. package/docs/troubleshooting/authentication-issues.md +334 -0
  171. package/docs/troubleshooting/common-issues.md +2 -0
  172. package/docs/troubleshooting/styling-issues.md +199 -144
  173. package/docs/usage.md +23 -2
  174. package/package.json +1 -1
  175. package/src/__tests__/{TESTING_GUIDELINES.md → TEST_GUIDE_CURSOR.md} +20 -0
  176. package/src/__tests__/TEST_GUIDE_HUMAN.md +103 -0
  177. package/src/__tests__/fixtures/test-data.ts +90 -0
  178. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +260 -0
  179. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +224 -0
  180. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +273 -0
  181. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +98 -0
  182. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +436 -0
  183. package/src/__tests__/helpers/__tests__/timer-utils.test.ts +371 -0
  184. package/src/__tests__/helpers/component-test-utils.tsx +14 -4
  185. package/src/__tests__/helpers/optimized-test-setup.ts +68 -0
  186. package/src/__tests__/helpers/test-providers.tsx +329 -0
  187. package/src/__tests__/helpers/test-utils.tsx +91 -45
  188. package/src/__tests__/helpers/timer-utils.ts +71 -0
  189. package/src/__tests__/hooks/usePermissions.test.ts +1 -5
  190. package/src/__tests__/integration/UserProfile.test.tsx +1 -5
  191. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +42 -12
  192. package/src/__tests__/setup.ts +34 -28
  193. package/src/components/Alert/Alert.test.tsx +1 -5
  194. package/src/components/Avatar/Avatar.test.tsx +1 -5
  195. package/src/components/Button/Button.test.tsx +4 -20
  196. package/src/components/Card/Card.test.tsx +1 -5
  197. package/src/components/Checkbox/Checkbox.test.tsx +1 -5
  198. package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -5
  199. package/src/components/DataTable/__tests__/DataTable.test.tsx +45 -49
  200. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +1 -5
  201. package/src/components/DataTable/__tests__/styles.test.ts +382 -0
  202. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +409 -0
  203. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +634 -0
  204. package/src/components/DataTable/core/__tests__/DataManager.test.ts +519 -0
  205. package/src/components/DataTable/core/__tests__/StateManager.test.ts +714 -0
  206. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +592 -0
  207. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +354 -0
  208. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +539 -0
  209. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +1 -5
  210. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +1 -8
  211. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +34 -38
  212. package/src/components/Footer/Footer.test.tsx +1 -5
  213. package/src/components/Form/Form.test.tsx +22 -35
  214. package/src/components/Header/Header.test.tsx +1 -9
  215. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +1 -5
  216. package/src/components/Input/Input.test.tsx +2 -10
  217. package/src/components/LoginForm/LoginForm.test.tsx +1 -5
  218. package/src/components/NavigationMenu/NavigationMenu.test.tsx +24 -24
  219. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +1 -6
  220. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +6 -16
  221. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +1 -5
  222. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +1 -5
  223. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +1 -7
  224. package/src/components/PasswordReset/PasswordChangeForm.test.tsx +1 -9
  225. package/src/components/PasswordReset/PasswordResetForm.test.tsx +1 -9
  226. package/src/components/PublicLayout/PublicErrorBoundary.tsx +4 -5
  227. package/src/components/PublicLayout/PublicPageHeader.tsx +13 -9
  228. package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +666 -0
  229. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +457 -0
  230. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +393 -0
  231. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +351 -0
  232. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +374 -0
  233. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +388 -0
  234. package/src/components/Select/Select.bug-test.tsx +69 -0
  235. package/src/components/Select/Select.refactored.tsx +497 -0
  236. package/src/components/Select/Select.test.tsx +42 -49
  237. package/src/components/Select/Select.tsx +5 -2
  238. package/src/components/Select/hooks.ts +254 -0
  239. package/src/components/Switch/Switch.test.tsx +1 -5
  240. package/src/components/Table/__tests__/Table.test.tsx +775 -0
  241. package/src/components/Toast/Toast.test.tsx +15 -8
  242. package/src/components/Tooltip/Tooltip.test.tsx +1 -5
  243. package/src/components/UserMenu/UserMenu.test.tsx +3 -15
  244. package/src/components/__tests__/FileDisplay.test.tsx +575 -0
  245. package/src/components/__tests__/FileUpload.test.tsx +446 -0
  246. package/src/components/__tests__/SuperAdminGuard.test.tsx +422 -354
  247. package/src/hooks/__tests__/ServiceHooks.test.tsx +613 -0
  248. package/src/hooks/__tests__/hooks.integration.test.tsx +1 -10
  249. package/src/hooks/__tests__/useApiFetch.unit.test.ts +10 -14
  250. package/src/hooks/__tests__/useAppConfig.unit.test.ts +307 -0
  251. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +1 -6
  252. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +1 -5
  253. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +6 -9
  254. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +321 -0
  255. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +583 -0
  256. package/src/hooks/__tests__/usePublicEventLogo.unit.test.ts +640 -0
  257. package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +435 -0
  258. package/src/hooks/__tests__/useRBAC.unit.test.ts +10 -10
  259. package/src/hooks/__tests__/useStorage.unit.test.ts +751 -0
  260. package/src/hooks/index.ts +3 -0
  261. package/src/hooks/public/usePublicEvent.ts +181 -13
  262. package/src/hooks/public/usePublicRouteParams.ts +13 -3
  263. package/src/hooks/services/useAuth.ts +50 -0
  264. package/src/hooks/services/useAuthService.ts +30 -0
  265. package/src/hooks/services/useCurrentEvent.ts +36 -0
  266. package/src/hooks/services/useCurrentOrganisation.ts +52 -0
  267. package/src/hooks/services/useEventService.ts +30 -0
  268. package/src/hooks/services/useInactivityService.ts +30 -0
  269. package/src/hooks/services/useOrganisationService.ts +30 -0
  270. package/src/hooks/services/usePermissions.ts +70 -0
  271. package/src/hooks/services/useRBACService.ts +30 -0
  272. package/src/hooks/useCounter.test.ts +1 -5
  273. package/src/hooks/useEventTheme.ts +86 -0
  274. package/src/hooks/useOrganisationPermissions.test.ts +2 -5
  275. package/src/hooks/useOrganisationSecurity.test.ts +1 -5
  276. package/src/hooks/usePermissionCache.test.ts +1 -5
  277. package/src/hooks/usePermissionCheck.ts +150 -0
  278. package/src/hooks/useSecureDataAccess.test.ts +1 -5
  279. package/src/index.ts +1 -0
  280. package/src/providers/OrganisationProvider.test.tsx +1 -5
  281. package/src/providers/OrganisationProvider.tsx +56 -4
  282. package/src/providers/UnifiedAuthProvider.test.simple.tsx +42 -6
  283. package/src/providers/UnifiedAuthProvider.test.tsx +1 -5
  284. package/src/providers/UnifiedAuthProvider.tsx +4 -4
  285. package/src/providers/__tests__/AuthProvider.test.tsx +105 -439
  286. package/src/providers/__tests__/AuthProvider.test.tsx.backup +771 -0
  287. package/src/providers/__tests__/EventProvider.test.tsx +211 -110
  288. package/src/providers/__tests__/EventProvider.test.tsx.backup +824 -0
  289. package/src/providers/__tests__/InactivityProvider.test.tsx +1 -5
  290. package/src/providers/__tests__/OrganisationProvider.test.tsx +97 -261
  291. package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +820 -0
  292. package/src/providers/__tests__/ServiceProviders.test.tsx +477 -0
  293. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +72 -504
  294. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +911 -0
  295. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +166 -0
  296. package/src/providers/services/AuthServiceProvider.tsx +65 -0
  297. package/src/providers/services/EventServiceProvider.tsx +83 -0
  298. package/src/providers/services/InactivityServiceProvider.tsx +83 -0
  299. package/src/providers/services/OrganisationServiceProvider.tsx +77 -0
  300. package/src/providers/services/RBACServiceProvider.tsx +79 -0
  301. package/src/providers/services/UnifiedAuthProvider.tsx +368 -0
  302. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +210 -0
  303. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +269 -0
  304. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +892 -0
  305. package/src/rbac/__tests__/engine.comprehensive.test.ts +954 -0
  306. package/src/rbac/__tests__/integration.authflow.test.tsx +1 -5
  307. package/src/rbac/__tests__/integration.navigation.test.tsx +1 -4
  308. package/src/rbac/__tests__/rbac-core.test.tsx +2 -7
  309. package/src/rbac/__tests__/rbac-functions.test.ts +1 -9
  310. package/src/rbac/__tests__/rbac-integration.test.ts +1 -9
  311. package/src/rbac/api.test.ts +1 -9
  312. package/src/rbac/cache.test.ts +10 -8
  313. package/src/rbac/cli/__tests__/policy-manager.test.ts +339 -0
  314. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +1 -5
  315. package/src/rbac/components/NavigationProvider.test.tsx +1 -5
  316. package/src/rbac/components/PagePermissionProvider.test.tsx +1 -5
  317. package/src/rbac/components/SecureDataProvider.test.tsx +1 -5
  318. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +25 -29
  319. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +27 -30
  320. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +23 -27
  321. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +18 -22
  322. package/src/rbac/config.test.ts +1 -5
  323. package/src/rbac/hooks/useCan.test.ts +262 -9
  324. package/src/rbac/hooks/usePermissions.test.ts +246 -6
  325. package/src/rbac/hooks/useRBAC.simple.test.ts +1 -5
  326. package/src/rbac/hooks/useRBAC.test.ts +472 -198
  327. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +1 -9
  328. package/src/services/AuthService.ts +416 -0
  329. package/src/services/EventService.ts +366 -0
  330. package/src/services/InactivityService.ts +388 -0
  331. package/src/services/OrganisationService.ts +592 -0
  332. package/src/services/RBACService.ts +522 -0
  333. package/src/services/__tests__/AuthService.test.ts +356 -0
  334. package/src/services/__tests__/BaseService.test.ts +314 -0
  335. package/src/services/__tests__/EventService.test.ts +489 -0
  336. package/src/services/__tests__/InactivityService.test.ts +403 -0
  337. package/src/services/__tests__/OrganisationService.test.ts +660 -0
  338. package/src/services/__tests__/RBACService.test.ts +492 -0
  339. package/src/services/base/BaseService.ts +87 -0
  340. package/src/services/interfaces/IAuthService.ts +39 -0
  341. package/src/services/interfaces/IEventService.ts +30 -0
  342. package/src/services/interfaces/IInactivityService.ts +31 -0
  343. package/src/services/interfaces/IOrganisationService.ts +41 -0
  344. package/src/services/interfaces/IRBACService.ts +62 -0
  345. package/src/theming/__tests__/runtime.test.ts +540 -0
  346. package/src/types/__tests__/file-reference.test.ts +447 -0
  347. package/src/types/__tests__/organisation.test.ts +1133 -0
  348. package/src/types/__tests__/theme.test.ts +830 -0
  349. package/src/types/__tests__/type-validation.test.ts +527 -0
  350. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +1 -5
  351. package/src/utils/__tests__/debugLogger.test.ts +417 -0
  352. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -6
  353. package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -5
  354. package/src/utils/__tests__/lazyLoad.unit.test.tsx +35 -35
  355. package/src/utils/__tests__/organisationContext.unit.test.ts +1 -5
  356. package/src/utils/__tests__/performanceBudgets.unit.test.ts +5 -11
  357. package/src/utils/__tests__/secureErrors.unit.test.ts +1 -6
  358. package/src/utils/__tests__/secureStorage.unit.test.ts +1 -5
  359. package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -5
  360. package/src/utils/__tests__/sessionTracking.unit.test.ts +1 -5
  361. package/src/utils/appIdResolver.test.ts +6 -10
  362. package/src/utils/appNameResolver.simple.test.ts +142 -0
  363. package/src/utils/appNameResolver.test.ts +31 -458
  364. package/src/utils/appNameResolver.test.ts.backup +494 -0
  365. package/src/utils/debugLogger.ts +26 -5
  366. package/src/utils/formatDate.test.ts +1 -5
  367. package/src/utils/organisationContext.test.ts +1 -5
  368. package/src/utils/performanceBudgets.ts +3 -4
  369. package/src/utils/secureDataAccess.test.ts +1 -5
  370. package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -5
  371. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +1 -5
  372. package/dist/chunk-4HQ5BOVZ.js.map +0 -1
  373. package/dist/chunk-D7ARGIA3.js.map +0 -1
  374. package/dist/chunk-QVEOQVD4.js.map +0 -1
  375. package/dist/chunk-T2MQY57J.js.map +0 -1
  376. package/dist/chunk-T6HVDA24.js.map +0 -1
  377. package/dist/chunk-VTJ5HCZB.js +0 -315
  378. package/dist/chunk-VTJ5HCZB.js.map +0 -1
  379. package/dist/chunk-ZPK5656W.js.map +0 -1
  380. package/docs/getting-started/installation.md +0 -269
  381. package/src/__tests__/REBUILD_PLAN.md +0 -223
  382. /package/dist/{DataTable-MFUXNGPR.js.map → DataTable-MPBSXUC6.js.map} +0 -0
  383. /package/dist/{chunk-CKNY7HYS.js.map → chunk-2ARQW6VX.js.map} +0 -0
  384. /package/dist/{chunk-BTCA3ENN.js.map → chunk-Q2UP3ZWQ.js.map} +0 -0
@@ -0,0 +1,519 @@
1
+ /**
2
+ * @file DataManager Unit Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module Components/DataTable/Core/DataManager
5
+ * @since 0.3.0
6
+ */
7
+
8
+ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
9
+ import { DataManager } from '../DataManager';
10
+ import type { DataAdapter, FetchOptions } from '../interfaces';
11
+ import type { DataRecord } from '../../types';
12
+
13
+ // Test data types
14
+ interface TestDataRecord extends DataRecord {
15
+ id: string;
16
+ name: string;
17
+ email: string;
18
+ created_at: string;
19
+ }
20
+
21
+ // Mock data adapter
22
+ const createMockAdapter = (): DataAdapter<TestDataRecord> => ({
23
+ name: 'test-adapter',
24
+ fetchData: vi.fn(),
25
+ updateData: vi.fn(),
26
+ deleteData: vi.fn(),
27
+ createData: vi.fn(),
28
+ exportData: vi.fn(),
29
+ importData: vi.fn(),
30
+ isConnected: vi.fn(() => true),
31
+ getError: vi.fn(() => null),
32
+ });
33
+
34
+ // Test data fixtures
35
+ const createTestData = (overrides: Partial<TestDataRecord> = {}): TestDataRecord => ({
36
+ id: 'test-id-1',
37
+ name: 'Test User',
38
+ email: 'test@example.com',
39
+ created_at: '2023-01-01T00:00:00Z',
40
+ ...overrides,
41
+ });
42
+
43
+ const createTestDataArray = (count: number): TestDataRecord[] =>
44
+ Array.from({ length: count }, (_, i) => createTestData({
45
+ id: `test-id-${i + 1}`,
46
+ name: `Test User ${i + 1}`,
47
+ email: `test${i + 1}@example.com`,
48
+ }));
49
+
50
+ describe('[unit] DataManager', () => {
51
+ let dataManager: DataManager<TestDataRecord>;
52
+ let mockAdapter: DataAdapter<TestDataRecord>;
53
+
54
+ beforeEach(() => {
55
+ mockAdapter = createMockAdapter();
56
+ dataManager = new DataManager(mockAdapter, 5000); // 5 second cache timeout
57
+ });
58
+
59
+ afterEach(() => {
60
+ vi.clearAllMocks();
61
+ });
62
+
63
+ describe('Initialization', () => {
64
+ it('should initialize with empty data and default state', () => {
65
+ expect(dataManager.getData()).toEqual([]);
66
+ expect(dataManager.isLoading()).toBe(false);
67
+ expect(dataManager.getError()).toBe(null);
68
+ });
69
+
70
+ it('should initialize with custom cache timeout', () => {
71
+ const customTimeout = 10000;
72
+ const manager = new DataManager(mockAdapter, customTimeout);
73
+ expect(manager).toBeDefined();
74
+ });
75
+
76
+ it('should set adapter correctly', () => {
77
+ expect(dataManager.getAdapter()).toBe(mockAdapter);
78
+ });
79
+ });
80
+
81
+ describe('Data Retrieval', () => {
82
+ it('should return current data', () => {
83
+ const testData = createTestDataArray(3);
84
+ // Manually set data for testing (simulating internal state)
85
+ (dataManager as any).data = testData;
86
+
87
+ expect(dataManager.getData()).toEqual(testData);
88
+ });
89
+
90
+ it('should return empty array when no data', () => {
91
+ expect(dataManager.getData()).toEqual([]);
92
+ });
93
+ });
94
+
95
+ describe('CRUD Operations', () => {
96
+ describe('Create Data', () => {
97
+ it('should create new data item successfully', async () => {
98
+ const newData = { name: 'New User', email: 'new@example.com' };
99
+ const createdItem = createTestData(newData);
100
+
101
+ vi.mocked(mockAdapter.createData).mockResolvedValue(createdItem);
102
+
103
+ const result = await dataManager.createData(newData);
104
+
105
+ expect(mockAdapter.createData).toHaveBeenCalledWith(newData);
106
+ expect(result).toEqual(createdItem);
107
+ expect(dataManager.getData()).toContain(createdItem);
108
+ expect(dataManager.isLoading()).toBe(false);
109
+ expect(dataManager.getError()).toBe(null);
110
+ });
111
+
112
+ it('should handle create data errors', async () => {
113
+ const newData = { name: 'New User', email: 'new@example.com' };
114
+ const error = new Error('Create failed');
115
+
116
+ vi.mocked(mockAdapter.createData).mockRejectedValue(error);
117
+
118
+ await expect(dataManager.createData(newData)).rejects.toThrow('Create failed');
119
+
120
+ expect(dataManager.getError()).toBe(error);
121
+ expect(dataManager.isLoading()).toBe(false);
122
+ expect(dataManager.getData()).toEqual([]);
123
+ });
124
+
125
+ it('should set loading state during create operation', async () => {
126
+ const newData = { name: 'New User', email: 'new@example.com' };
127
+ const createdItem = createTestData(newData);
128
+
129
+ let resolveCreate: (value: TestDataRecord) => void;
130
+ const createPromise = new Promise<TestDataRecord>((resolve) => {
131
+ resolveCreate = resolve;
132
+ });
133
+
134
+ vi.mocked(mockAdapter.createData).mockReturnValue(createPromise);
135
+
136
+ const createPromise2 = dataManager.createData(newData);
137
+
138
+ // Check loading state during operation
139
+ expect(dataManager.isLoading()).toBe(true);
140
+
141
+ resolveCreate!(createdItem);
142
+ await createPromise2;
143
+
144
+ expect(dataManager.isLoading()).toBe(false);
145
+ });
146
+ });
147
+
148
+ describe('Update Data', () => {
149
+ beforeEach(() => {
150
+ // Set up initial data
151
+ const testData = createTestDataArray(3);
152
+ (dataManager as any).data = testData;
153
+ });
154
+
155
+ it('should update existing data item successfully', async () => {
156
+ const id = 'test-id-1';
157
+ const updates = { name: 'Updated User' };
158
+
159
+ vi.mocked(mockAdapter.updateData).mockResolvedValue(undefined);
160
+
161
+ await dataManager.updateData(id, updates);
162
+
163
+ expect(mockAdapter.updateData).toHaveBeenCalledWith(id, updates);
164
+
165
+ const updatedItem = dataManager.getData().find(item => item.id === id);
166
+ expect(updatedItem).toMatchObject(updates);
167
+ expect(dataManager.isLoading()).toBe(false);
168
+ expect(dataManager.getError()).toBe(null);
169
+ });
170
+
171
+ it('should handle update data errors', async () => {
172
+ const id = 'test-id-1';
173
+ const updates = { name: 'Updated User' };
174
+ const error = new Error('Update failed');
175
+
176
+ vi.mocked(mockAdapter.updateData).mockRejectedValue(error);
177
+
178
+ await expect(dataManager.updateData(id, updates)).rejects.toThrow('Update failed');
179
+
180
+ expect(dataManager.getError()).toBe(error);
181
+ expect(dataManager.isLoading()).toBe(false);
182
+ });
183
+
184
+ it('should not update local data if item not found', async () => {
185
+ const id = 'non-existent-id';
186
+ const updates = { name: 'Updated User' };
187
+
188
+ vi.mocked(mockAdapter.updateData).mockResolvedValue(undefined);
189
+
190
+ await dataManager.updateData(id, updates);
191
+
192
+ expect(mockAdapter.updateData).toHaveBeenCalledWith(id, updates);
193
+ // Local data should remain unchanged
194
+ expect(dataManager.getData()).toEqual(createTestDataArray(3));
195
+ });
196
+
197
+ it('should set loading state during update operation', async () => {
198
+ const id = 'test-id-1';
199
+ const updates = { name: 'Updated User' };
200
+
201
+ let resolveUpdate: () => void;
202
+ const updatePromise = new Promise<void>((resolve) => {
203
+ resolveUpdate = resolve;
204
+ });
205
+
206
+ vi.mocked(mockAdapter.updateData).mockReturnValue(updatePromise);
207
+
208
+ const updatePromise2 = dataManager.updateData(id, updates);
209
+
210
+ // Check loading state during operation
211
+ expect(dataManager.isLoading()).toBe(true);
212
+
213
+ resolveUpdate!();
214
+ await updatePromise2;
215
+
216
+ expect(dataManager.isLoading()).toBe(false);
217
+ });
218
+ });
219
+
220
+ describe('Delete Data', () => {
221
+ beforeEach(() => {
222
+ // Set up initial data
223
+ const testData = createTestDataArray(3);
224
+ (dataManager as any).data = testData;
225
+ });
226
+
227
+ it('should delete data item successfully', async () => {
228
+ const id = 'test-id-1';
229
+
230
+ vi.mocked(mockAdapter.deleteData).mockResolvedValue(undefined);
231
+
232
+ await dataManager.deleteData(id);
233
+
234
+ expect(mockAdapter.deleteData).toHaveBeenCalledWith(id);
235
+ expect(dataManager.getData()).toHaveLength(2);
236
+ expect(dataManager.getData().find(item => item.id === id)).toBeUndefined();
237
+ expect(dataManager.isLoading()).toBe(false);
238
+ expect(dataManager.getError()).toBe(null);
239
+ });
240
+
241
+ it('should handle delete data errors', async () => {
242
+ const id = 'test-id-1';
243
+ const error = new Error('Delete failed');
244
+
245
+ vi.mocked(mockAdapter.deleteData).mockRejectedValue(error);
246
+
247
+ await expect(dataManager.deleteData(id)).rejects.toThrow('Delete failed');
248
+
249
+ expect(dataManager.getError()).toBe(error);
250
+ expect(dataManager.isLoading()).toBe(false);
251
+ // Data should remain unchanged on error
252
+ expect(dataManager.getData()).toHaveLength(3);
253
+ });
254
+
255
+ it('should not remove item if not found locally', async () => {
256
+ const id = 'non-existent-id';
257
+
258
+ vi.mocked(mockAdapter.deleteData).mockResolvedValue(undefined);
259
+
260
+ await dataManager.deleteData(id);
261
+
262
+ expect(mockAdapter.deleteData).toHaveBeenCalledWith(id);
263
+ // Local data should remain unchanged
264
+ expect(dataManager.getData()).toHaveLength(3);
265
+ });
266
+
267
+ it('should set loading state during delete operation', async () => {
268
+ const id = 'test-id-1';
269
+
270
+ let resolveDelete: () => void;
271
+ const deletePromise = new Promise<void>((resolve) => {
272
+ resolveDelete = resolve;
273
+ });
274
+
275
+ vi.mocked(mockAdapter.deleteData).mockReturnValue(deletePromise);
276
+
277
+ const deletePromise2 = dataManager.deleteData(id);
278
+
279
+ // Check loading state during operation
280
+ expect(dataManager.isLoading()).toBe(true);
281
+
282
+ resolveDelete!();
283
+ await deletePromise2;
284
+
285
+ expect(dataManager.isLoading()).toBe(false);
286
+ });
287
+ });
288
+ });
289
+
290
+ describe('Caching', () => {
291
+ it('should cache data with timestamp', async () => {
292
+ const cacheKey = 'test-cache-key';
293
+ const testData = createTestDataArray(3);
294
+
295
+ dataManager.setCachedData(cacheKey, testData);
296
+
297
+ const cachedData = await dataManager.getCachedData(cacheKey);
298
+ expect(cachedData).toEqual(testData);
299
+ });
300
+
301
+ it('should return null for non-existent cache key', async () => {
302
+ const cacheKey = 'non-existent-key';
303
+
304
+ const cachedData = await dataManager.getCachedData(cacheKey);
305
+ expect(cachedData).toBeNull();
306
+ });
307
+
308
+ it('should return null for expired cache', async () => {
309
+ const cacheKey = 'expired-cache-key';
310
+ const testData = createTestDataArray(3);
311
+
312
+ // Set cache with old timestamp
313
+ (dataManager as any).cache.set(cacheKey, {
314
+ data: testData,
315
+ timestamp: Date.now() - 10000, // 10 seconds ago
316
+ });
317
+
318
+ const cachedData = await dataManager.getCachedData(cacheKey);
319
+ expect(cachedData).toBeNull();
320
+ });
321
+
322
+ it('should clear cache after CRUD operations', async () => {
323
+ const cacheKey = 'test-cache-key';
324
+ const testData = createTestDataArray(3);
325
+
326
+ dataManager.setCachedData(cacheKey, testData);
327
+ expect(await dataManager.getCachedData(cacheKey)).toEqual(testData);
328
+
329
+ // Perform CRUD operation
330
+ const newData = { name: 'New User', email: 'new@example.com' };
331
+ const createdItem = createTestData(newData);
332
+ vi.mocked(mockAdapter.createData).mockResolvedValue(createdItem);
333
+
334
+ await dataManager.createData(newData);
335
+
336
+ // Cache should be cleared
337
+ expect(await dataManager.getCachedData(cacheKey)).toBeNull();
338
+ });
339
+
340
+ it('should clear all cache', () => {
341
+ const testData = createTestDataArray(3);
342
+
343
+ dataManager.setCachedData('key1', testData);
344
+ dataManager.setCachedData('key2', testData);
345
+
346
+ expect((dataManager as any).cache.size).toBe(2);
347
+
348
+ dataManager.clearCache();
349
+
350
+ expect((dataManager as any).cache.size).toBe(0);
351
+ });
352
+
353
+ it('should handle cache timeout configuration', async () => {
354
+ const shortTimeoutManager = new DataManager(mockAdapter, 1000); // 1 second timeout
355
+ const cacheKey = 'test-cache-key';
356
+ const testData = createTestDataArray(3);
357
+
358
+ shortTimeoutManager.setCachedData(cacheKey, testData);
359
+
360
+ // Should be available immediately
361
+ expect(await shortTimeoutManager.getCachedData(cacheKey)).toEqual(testData);
362
+
363
+ // Wait for timeout
364
+ await new Promise(resolve => setTimeout(resolve, 1100));
365
+
366
+ // Should be expired now
367
+ expect(await shortTimeoutManager.getCachedData(cacheKey)).toBeNull();
368
+ });
369
+ });
370
+
371
+ describe('Error Handling', () => {
372
+ it('should set error state on create failure', async () => {
373
+ const error = new Error('Create failed');
374
+ vi.mocked(mockAdapter.createData).mockRejectedValue(error);
375
+
376
+ await expect(dataManager.createData({})).rejects.toThrow();
377
+ expect(dataManager.getError()).toBe(error);
378
+ });
379
+
380
+ it('should set error state on update failure', async () => {
381
+ const error = new Error('Update failed');
382
+ vi.mocked(mockAdapter.updateData).mockRejectedValue(error);
383
+
384
+ await expect(dataManager.updateData('id', {})).rejects.toThrow();
385
+ expect(dataManager.getError()).toBe(error);
386
+ });
387
+
388
+ it('should set error state on delete failure', async () => {
389
+ const error = new Error('Delete failed');
390
+ vi.mocked(mockAdapter.deleteData).mockRejectedValue(error);
391
+
392
+ await expect(dataManager.deleteData('id')).rejects.toThrow();
393
+ expect(dataManager.getError()).toBe(error);
394
+ });
395
+
396
+ it('should clear error state on successful operation', async () => {
397
+ // First, set an error
398
+ const error = new Error('Previous error');
399
+ (dataManager as any).error = error;
400
+ expect(dataManager.getError()).toBe(error);
401
+
402
+ // Then perform successful operation
403
+ const newData = { name: 'New User', email: 'new@example.com' };
404
+ const createdItem = createTestData(newData);
405
+ vi.mocked(mockAdapter.createData).mockResolvedValue(createdItem);
406
+
407
+ await dataManager.createData(newData);
408
+
409
+ expect(dataManager.getError()).toBe(null);
410
+ });
411
+ });
412
+
413
+ describe('Adapter Management', () => {
414
+ it('should set new adapter', () => {
415
+ const newAdapter = createMockAdapter();
416
+
417
+ dataManager.setAdapter(newAdapter);
418
+
419
+ expect(dataManager.getAdapter()).toBe(newAdapter);
420
+ });
421
+
422
+ it('should clear cache when setting new adapter', () => {
423
+ const testData = createTestDataArray(3);
424
+ dataManager.setCachedData('test-key', testData);
425
+
426
+ expect((dataManager as any).cache.size).toBe(1);
427
+
428
+ const newAdapter = createMockAdapter();
429
+ dataManager.setAdapter(newAdapter);
430
+
431
+ expect((dataManager as any).cache.size).toBe(0);
432
+ });
433
+ });
434
+
435
+ describe('Row ID Generation', () => {
436
+ it('should use id field for row identification', () => {
437
+ const item = createTestData({ id: 'test-id' });
438
+ const rowId = (dataManager as any).getRowId(item);
439
+ expect(rowId).toBe('test-id');
440
+ });
441
+
442
+ it('should use key field when id is not available', () => {
443
+ const item = { key: 'test-key', name: 'Test' } as any;
444
+ const rowId = (dataManager as any).getRowId(item);
445
+ expect(rowId).toBe('test-key');
446
+ });
447
+
448
+ it('should use JSON string when neither id nor key is available', () => {
449
+ const item = { name: 'Test', email: 'test@example.com' } as any;
450
+ const rowId = (dataManager as any).getRowId(item);
451
+ expect(rowId).toBe(JSON.stringify(item));
452
+ });
453
+ });
454
+
455
+ describe('Concurrent Operations', () => {
456
+ it('should handle concurrent create operations', async () => {
457
+ const data1 = { name: 'User 1', email: 'user1@example.com' };
458
+ const data2 = { name: 'User 2', email: 'user2@example.com' };
459
+ const created1 = createTestData({ ...data1, id: 'id-1' });
460
+ const created2 = createTestData({ ...data2, id: 'id-2' });
461
+
462
+ vi.mocked(mockAdapter.createData)
463
+ .mockResolvedValueOnce(created1)
464
+ .mockResolvedValueOnce(created2);
465
+
466
+ const [result1, result2] = await Promise.all([
467
+ dataManager.createData(data1),
468
+ dataManager.createData(data2),
469
+ ]);
470
+
471
+ expect(result1).toEqual(created1);
472
+ expect(result2).toEqual(created2);
473
+ expect(dataManager.getData()).toHaveLength(2);
474
+ });
475
+
476
+ it('should handle concurrent update operations', async () => {
477
+ const testData = createTestDataArray(2);
478
+ (dataManager as any).data = testData;
479
+
480
+ vi.mocked(mockAdapter.updateData).mockResolvedValue(undefined);
481
+
482
+ await Promise.all([
483
+ dataManager.updateData('test-id-1', { name: 'Updated 1' }),
484
+ dataManager.updateData('test-id-2', { name: 'Updated 2' }),
485
+ ]);
486
+
487
+ expect(mockAdapter.updateData).toHaveBeenCalledTimes(2);
488
+ expect(dataManager.getData()).toHaveLength(2);
489
+ });
490
+ });
491
+
492
+ describe('Performance and Memory', () => {
493
+ it('should handle large datasets efficiently', async () => {
494
+ const largeDataset = createTestDataArray(1000);
495
+ (dataManager as any).data = largeDataset;
496
+
497
+ expect(dataManager.getData()).toHaveLength(1000);
498
+ expect(dataManager.getData()[0]).toEqual(expect.objectContaining({
499
+ id: 'test-id-1',
500
+ name: 'Test User 1',
501
+ }));
502
+ });
503
+
504
+ it('should not leak memory with repeated operations', async () => {
505
+ const testData = { name: 'Test User', email: 'test@example.com' };
506
+ const createdItem = createTestData(testData);
507
+
508
+ vi.mocked(mockAdapter.createData).mockResolvedValue(createdItem);
509
+
510
+ // Perform multiple operations
511
+ for (let i = 0; i < 100; i++) {
512
+ await dataManager.createData({ ...testData, name: `User ${i}` });
513
+ }
514
+
515
+ expect(dataManager.getData()).toHaveLength(100);
516
+ expect((dataManager as any).cache.size).toBe(0); // Cache should be cleared after each operation
517
+ });
518
+ });
519
+ });