@jmruthers/pace-core 0.6.9 → 0.6.10

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 (665) hide show
  1. package/audit-tool/audits/02-project-structure.cjs +62 -0
  2. package/audit-tool/audits/03-architecture.cjs +145 -19
  3. package/audit-tool/audits/04-code-quality.cjs +86 -1
  4. package/audit-tool/audits/06-security-rbac.cjs +109 -11
  5. package/cursor-rules/02-project-structure.mdc +2 -26
  6. package/cursor-rules/05-styling.mdc +84 -6
  7. package/cursor-rules/06-security-rbac.mdc +124 -1
  8. package/dist/{DataTable-SOAFXIWY.js → DataTable-SAXFG4XI.js} +11 -13
  9. package/dist/{AuthService-DmfO5rGS.d.ts → InactivityServiceProvider-DHryoh6K.d.ts} +24 -249
  10. package/dist/UnifiedAuthProvider-BBD2PS3Q.js +7 -0
  11. package/dist/{UnifiedAuthProvider-CKvHP1MK.d.ts → UnifiedAuthProvider-CiBAl9-s.d.ts} +34 -22
  12. package/dist/{api-7P7DI652.js → api-F47QJ7FX.js} +3 -3
  13. package/dist/assets/app-icons/admin_favicon.svg +462 -0
  14. package/dist/assets/app-icons/base_favicon.svg +85 -0
  15. package/dist/assets/app-icons/cake_favicon.svg +68 -0
  16. package/dist/assets/app-icons/core_favicon.svg +256 -0
  17. package/dist/assets/app-icons/gear_favicon.svg +91 -0
  18. package/dist/assets/app-icons/medi_favicon.svg +92 -0
  19. package/dist/assets/app-icons/mint_favicon.svg +83 -0
  20. package/dist/assets/app-icons/pace_favicon.svg +49 -0
  21. package/dist/assets/app-icons/pump_favicon.svg +68 -0
  22. package/dist/assets/app-icons/seed_favicon.svg +91 -0
  23. package/dist/assets/app-icons/team_favicon.svg +67 -0
  24. package/dist/assets/app-icons/trac_favicon.svg +112 -0
  25. package/dist/assets/app-icons/trip_favicon.svg +102 -0
  26. package/dist/audit-Z6ZZBWLU.js +3 -0
  27. package/dist/chunk-3GWSPISD.js +61 -0
  28. package/dist/{chunk-4DDCYDQ3.js → chunk-66R6RLUZ.js} +12 -27
  29. package/dist/{chunk-FYHN4DD5.js → chunk-7YDC7LMU.js} +80 -8
  30. package/dist/{chunk-S7DKJPLT.js → chunk-BCTXBU6U.js} +22 -17
  31. package/dist/{chunk-TTRFSOKR.js → chunk-BTHN5MKC.js} +4 -4
  32. package/dist/{chunk-A3W6LW53.js → chunk-DDMPHZ3D.js} +6 -18
  33. package/dist/{chunk-MPBLMWVR.js → chunk-FBZ7U3ID.js} +140 -92
  34. package/dist/chunk-FN52B75D.js +246 -0
  35. package/dist/{chunk-5W2A3DRC.js → chunk-JJEYZ3DX.js} +5 -4
  36. package/dist/chunk-KPYQWGFQ.js +183 -0
  37. package/dist/{chunk-C7ZQ5O4C.js → chunk-KSNLMI7N.js} +3 -3
  38. package/dist/chunk-KYURMOQM.js +977 -0
  39. package/dist/{chunk-LX6U42O3.js → chunk-LNHFAF4X.js} +160 -58
  40. package/dist/{chunk-J2U36LHD.js → chunk-MPY44PWB.js} +620 -627
  41. package/dist/{chunk-AHU7G2R5.js → chunk-NIU6DPQV.js} +10 -6
  42. package/dist/{chunk-HF6O3O37.js → chunk-RMLY6KB5.js} +1 -1
  43. package/dist/{chunk-6GLLNA6U.js → chunk-SACF5YSM.js} +1 -1
  44. package/dist/{chunk-5HNSDQWH.js → chunk-TFIPNIPE.js} +865 -532
  45. package/dist/{chunk-OJ4SKRSV.js → chunk-UZNAFKGW.js} +25 -5
  46. package/dist/chunk-W46INAVW.js +1216 -0
  47. package/dist/chunk-X5EAU5G7.js +793 -0
  48. package/dist/{chunk-T5CVK4R3.js → chunk-Y4PF6HIM.js} +110 -64
  49. package/dist/components.d.ts +8 -86
  50. package/dist/components.js +21 -55
  51. package/dist/eslint-rules/rules/05-styling.cjs +507 -0
  52. package/dist/eslint-rules/rules/06-security-rbac.cjs +10 -0
  53. package/dist/{event-CW5YB_2p.d.ts → event-WTAQuGcq.d.ts} +1 -1
  54. package/dist/{functions-lBy5L2ry.d.ts → functions-DH45k8ec.d.ts} +1 -1
  55. package/dist/hooks.d.ts +11 -10
  56. package/dist/hooks.js +69 -44
  57. package/dist/index.d.ts +379 -31
  58. package/dist/index.js +46 -32
  59. package/dist/papaparseLoader-WG2UXQ22.js +7 -0
  60. package/dist/providers.d.ts +28 -14
  61. package/dist/providers.js +5 -5
  62. package/dist/rbac/eslint-rules.js +2 -2
  63. package/dist/rbac/index.d.ts +57 -213
  64. package/dist/rbac/index.js +11 -11
  65. package/dist/theming/runtime.d.ts +9 -3
  66. package/dist/theming/runtime.js +2 -2
  67. package/dist/{timezone-0AyangqX.d.ts → timezone-K-ptz3HO.d.ts} +21 -22
  68. package/dist/{types-t9H8qKRw.d.ts → types-BE2sEHKd.d.ts} +1 -1
  69. package/dist/{types-BeoeWV5I.d.ts → types-CvOPXWWZ.d.ts} +6 -5
  70. package/dist/{types-DXstZpNI.d.ts → types-D05dCGma.d.ts} +56 -149
  71. package/dist/types-Dr8sNhER.d.ts +50 -0
  72. package/dist/types.d.ts +4 -4
  73. package/dist/{PublicPageProvider-CIGSujI2.d.ts → usePublicPageContext-vxBlEHO9.d.ts} +294 -151
  74. package/dist/{usePublicRouteParams-DQLrDqDb.d.ts → usePublicRouteParams-G3Ks53mk.d.ts} +7 -6
  75. package/dist/utils.d.ts +300 -136
  76. package/dist/utils.js +42 -41
  77. package/dist/{validation-643vUDZW.d.ts → validation-g5n0hDkh.d.ts} +2 -2
  78. package/docs/api/modules.md +542 -549
  79. package/docs/api-reference/components.md +5 -5
  80. package/docs/implementation-guides/data-tables.md +190 -8
  81. package/docs/rbac/RBAC_CONTRACT.md +0 -12
  82. package/docs/standards/2-project-structure-standards.md +12 -74
  83. package/docs/standards/6-security-rbac-standards.md +222 -7
  84. package/docs/standards/7-api-tech-stack-standards.md +91 -3
  85. package/docs/testing/README.md +10 -0
  86. package/docs/testing/test-setup-for-consumers.md +914 -0
  87. package/eslint-config-pace-core.cjs +4 -0
  88. package/package.json +1 -1
  89. package/scripts/eslint-audit.cjs +110 -11
  90. package/src/__mocks__/lucide-react.ts +0 -2
  91. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +0 -2
  92. package/src/__tests__/index.test.ts +532 -0
  93. package/src/__tests__/integration/UserProfile.test.tsx +1 -1
  94. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +10 -8
  95. package/src/__tests__/rls-policies.test.ts +3 -2
  96. package/src/assets/app-icons/admin_favicon.svg +462 -0
  97. package/src/assets/app-icons/base_favicon.svg +85 -0
  98. package/src/assets/app-icons/cake_favicon.svg +68 -0
  99. package/src/assets/app-icons/core_favicon.svg +256 -0
  100. package/src/assets/app-icons/gear_favicon.svg +91 -0
  101. package/src/assets/app-icons/index.ts +83 -0
  102. package/src/assets/app-icons/medi_favicon.svg +92 -0
  103. package/src/assets/app-icons/mint_favicon.svg +83 -0
  104. package/src/assets/app-icons/pace_favicon.svg +49 -0
  105. package/src/assets/app-icons/pump_favicon.svg +68 -0
  106. package/src/assets/app-icons/seed_favicon.svg +91 -0
  107. package/src/assets/app-icons/team_favicon.svg +67 -0
  108. package/src/assets/app-icons/trac_favicon.svg +112 -0
  109. package/src/assets/app-icons/trip_favicon.svg +102 -0
  110. package/src/components/AddressField/AddressField.test.tsx +378 -3
  111. package/src/components/AddressField/AddressField.tsx +2 -2
  112. package/src/components/AddressField/types.ts +2 -2
  113. package/src/components/Alert/Alert.test.tsx +35 -25
  114. package/src/components/Alert/Alert.tsx +8 -8
  115. package/src/components/AppSwitcher/AppSwitcher.test.tsx +1250 -0
  116. package/src/components/AppSwitcher/AppSwitcher.tsx +315 -0
  117. package/src/components/Avatar/Avatar.test.tsx +11 -1
  118. package/src/components/Avatar/Avatar.tsx +3 -2
  119. package/src/components/Badge/Badge.test.tsx +11 -1
  120. package/src/components/Button/Button.test.tsx +13 -3
  121. package/src/components/Calendar/Calendar.test.tsx +523 -131
  122. package/src/components/Calendar/Calendar.tsx +107 -488
  123. package/src/components/Card/Card.test.tsx +220 -249
  124. package/src/components/Checkbox/Checkbox.test.tsx +58 -174
  125. package/src/components/ContextSelector/ContextSelector.tsx +3 -3
  126. package/src/components/ContextSelector/__tests__/ContextSelector.test.tsx +360 -0
  127. package/src/components/DataTable/DataTable.tsx +2 -2
  128. package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -1
  129. package/src/components/DataTable/__tests__/DataTable.export.test.tsx +2 -2
  130. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +1 -1
  131. package/src/components/DataTable/__tests__/DataTable.select-label-display.test.tsx +16 -14
  132. package/src/components/DataTable/__tests__/DataTable.test.tsx +2 -2
  133. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +1 -1
  134. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +76 -580
  135. package/src/components/DataTable/__tests__/README.md +1 -1
  136. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +1 -1
  137. package/src/components/DataTable/__tests__/keyboard.test.tsx +1 -1
  138. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +1 -3
  139. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +0 -6
  140. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +14 -6
  141. package/src/components/DataTable/components/ActionButtons.tsx +9 -4
  142. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +3 -3
  143. package/src/components/DataTable/components/ColumnFilter.tsx +2 -7
  144. package/src/components/DataTable/components/DataTableCore.tsx +44 -52
  145. package/src/components/DataTable/components/DataTableLayout.tsx +37 -26
  146. package/src/components/DataTable/components/DataTableModals.tsx +118 -30
  147. package/src/components/DataTable/components/DataTableToolbar.tsx +2 -2
  148. package/src/components/DataTable/components/EditFields.tsx +6 -47
  149. package/src/components/DataTable/components/EditableRow.tsx +8 -8
  150. package/src/components/DataTable/components/EmptyState.tsx +6 -3
  151. package/src/components/DataTable/components/FilterRow.tsx +18 -11
  152. package/src/components/DataTable/components/GroupingDropdown.tsx +0 -1
  153. package/src/components/DataTable/components/ImportModal.tsx +305 -133
  154. package/src/components/DataTable/components/LoadingState.tsx +2 -2
  155. package/src/components/DataTable/components/PaginationControls.tsx +0 -4
  156. package/src/components/DataTable/components/RowComponent.tsx +42 -22
  157. package/src/components/DataTable/components/UnifiedTableBody.tsx +52 -12
  158. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +51 -463
  159. package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +122 -116
  160. package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +40 -68
  161. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +9 -137
  162. package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.test.tsx +57 -17
  163. package/src/components/DataTable/components/__tests__/DataTableCore.test.tsx +792 -0
  164. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +24 -65
  165. package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +467 -0
  166. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +8 -125
  167. package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +528 -56
  168. package/src/components/DataTable/components/__tests__/EditFields.test.tsx +526 -0
  169. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +1 -68
  170. package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +8 -25
  171. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +3 -62
  172. package/src/components/DataTable/components/__tests__/GroupingDropdown.test.tsx +9 -14
  173. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +50 -186
  174. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +39 -97
  175. package/src/components/DataTable/components/__tests__/PaginationControls.test.tsx +13 -103
  176. package/src/components/DataTable/components/__tests__/RowComponent.test.tsx +629 -0
  177. package/src/components/DataTable/components/__tests__/SortIndicator.test.tsx +135 -0
  178. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +31 -171
  179. package/src/components/DataTable/components/__tests__/cellValueUtils.test.ts +453 -0
  180. package/src/components/DataTable/components/hooks/useImportModalFocus.test.ts +184 -0
  181. package/src/components/DataTable/components/hooks/usePermissionTracking.test.ts +381 -0
  182. package/src/components/DataTable/context/DataTableContext.tsx +9 -10
  183. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +12 -26
  184. package/src/components/DataTable/core/ColumnFactory.ts +3 -3
  185. package/src/components/DataTable/core/ColumnManager.ts +0 -1
  186. package/src/components/DataTable/core/DataManager.ts +4 -2
  187. package/src/components/DataTable/core/LocalDataAdapter.ts +1 -1
  188. package/src/components/DataTable/core/PluginRegistry.ts +2 -2
  189. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +114 -2
  190. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +103 -5
  191. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +57 -0
  192. package/src/components/DataTable/core/__tests__/DataManager.test.ts +63 -0
  193. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +42 -9
  194. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +29 -7
  195. package/src/components/DataTable/core/__tests__/StateManager.test.ts +58 -4
  196. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +16 -21
  197. package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +93 -4
  198. package/src/components/DataTable/hooks/__tests__/useDataTableConfiguration.test.ts +227 -54
  199. package/src/components/DataTable/hooks/__tests__/useDataTableDataPipeline.test.ts +215 -62
  200. package/src/components/DataTable/hooks/__tests__/useDataTablePermissions.test.ts +217 -39
  201. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +101 -6
  202. package/src/components/DataTable/hooks/__tests__/useEffectiveColumnOrder.test.ts +157 -27
  203. package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +80 -0
  204. package/src/components/DataTable/hooks/__tests__/useKeyboardNavigation.test.ts +787 -0
  205. package/src/components/DataTable/hooks/__tests__/useServerSideDataEffect.test.ts +258 -0
  206. package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +128 -77
  207. package/src/components/DataTable/hooks/__tests__/useTableHandlers.test.ts +440 -0
  208. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +12 -9
  209. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +12 -9
  210. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +1 -1
  211. package/src/components/DataTable/hooks/useDataTablePermissions.ts +11 -22
  212. package/src/components/DataTable/hooks/useDataTableState.ts +20 -24
  213. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +5 -5
  214. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +13 -1
  215. package/src/components/DataTable/hooks/useTableColumns.ts +15 -39
  216. package/src/components/DataTable/hooks/useTableHandlers.ts +8 -20
  217. package/src/components/DataTable/index.ts +24 -2
  218. package/src/components/DataTable/types.ts +6 -3
  219. package/src/components/DataTable/utils/__tests__/a11yUtils.test.ts +3 -67
  220. package/src/components/DataTable/utils/__tests__/aggregationUtils.test.ts +288 -0
  221. package/src/components/DataTable/utils/__tests__/errorHandling.test.ts +3 -60
  222. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +1 -1
  223. package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +9 -21
  224. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +102 -86
  225. package/src/components/DataTable/utils/__tests__/paginationUtils.test.ts +593 -0
  226. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +33 -49
  227. package/src/components/DataTable/utils/__tests__/selectFieldUtils.test.ts +1 -0
  228. package/src/components/DataTable/utils/a11yUtils.ts +1 -1
  229. package/src/components/DataTable/utils/aggregationUtils.ts +5 -5
  230. package/src/components/DataTable/utils/errorHandling.ts +3 -1
  231. package/src/components/DataTable/utils/exportUtils.ts +1 -1
  232. package/src/components/DataTable/utils/flexibleImport.ts +2 -2
  233. package/src/components/DataTable/utils/hierarchicalSorting.ts +3 -3
  234. package/src/components/DataTable/utils/paginationUtils.ts +1 -1
  235. package/src/components/DataTable/utils/performanceUtils.ts +1 -1
  236. package/src/components/DataTable/utils/selectFieldUtils.ts +0 -7
  237. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +17 -24
  238. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +1 -1
  239. package/src/components/DateTimeField/DateTimeField.test.tsx +2 -15
  240. package/src/components/DateTimeField/DateTimeField.tsx +1 -1
  241. package/src/components/Dialog/Dialog.test.tsx +2007 -407
  242. package/src/components/Dialog/Dialog.tsx +97 -192
  243. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +2 -62
  244. package/src/components/ErrorBoundary/ErrorBoundaryContext.context.ts +17 -0
  245. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +2 -45
  246. package/src/components/ErrorBoundary/ErrorBoundaryContext.types.ts +41 -0
  247. package/src/components/ErrorBoundary/index.ts +3 -4
  248. package/src/components/ErrorBoundary/useErrorBoundaryContext.ts +20 -0
  249. package/src/components/FileDisplay/FileDisplay.test.tsx +454 -222
  250. package/src/components/FileDisplay/FileDisplay.tsx +14 -12
  251. package/src/components/FileDisplay/index.tsx +1 -1
  252. package/src/components/FileUpload/FileUpload.test.tsx +54 -18
  253. package/src/components/FileUpload/FileUpload.tsx +10 -7
  254. package/src/components/FileUpload/index.tsx +1 -1
  255. package/src/components/Footer/Footer.test.tsx +33 -114
  256. package/src/components/Form/Form.test.tsx +388 -68
  257. package/src/components/Form/Form.tsx +57 -42
  258. package/src/components/Header/Header.test.tsx +645 -154
  259. package/src/components/Header/Header.tsx +52 -43
  260. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +35 -76
  261. package/src/components/Input/Input.test.tsx +34 -120
  262. package/src/components/Label/Label.test.tsx +47 -46
  263. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +9 -12
  264. package/src/components/LoginForm/LoginForm.test.tsx +0 -1
  265. package/src/components/NavigationMenu/NavigationMenu.test.tsx +1399 -82
  266. package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
  267. package/src/components/NavigationMenu/__tests__/useNavigationFiltering.test.ts +1934 -0
  268. package/src/components/NavigationMenu/useNavigationFiltering.ts +5 -15
  269. package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +1307 -0
  270. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +47 -46
  271. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +81 -38
  272. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +87 -66
  273. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +245 -39
  274. package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -20
  275. package/src/components/PaceAppLayout/README.md +0 -9
  276. package/src/components/PaceAppLayout/test-setup.tsx +15 -9
  277. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +759 -3
  278. package/src/components/PaceLoginPage/PaceLoginPage.tsx +2 -3
  279. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +1 -1
  280. package/src/components/Progress/Progress.test.tsx +127 -1
  281. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +1196 -4
  282. package/src/components/ProtectedRoute/ProtectedRoute.tsx +24 -6
  283. package/src/components/PublicLayout/PublicLayout.test.tsx +1435 -14
  284. package/src/components/PublicLayout/PublicPageContext.ts +28 -0
  285. package/src/components/PublicLayout/PublicPageLayout.tsx +6 -6
  286. package/src/components/PublicLayout/PublicPageProvider.tsx +2 -41
  287. package/src/components/PublicLayout/usePublicPageContext.ts +36 -0
  288. package/src/components/Select/Select.test.tsx +46 -9
  289. package/src/components/Select/Select.tsx +31 -24
  290. package/src/components/Select/__tests__/context.test.tsx +56 -0
  291. package/src/components/Select/hooks/__tests__/useSelectEvents.test.ts +279 -0
  292. package/src/components/Select/hooks/__tests__/useSelectSearch.test.tsx +295 -0
  293. package/src/components/Select/hooks/__tests__/useSelectState.test.ts +254 -0
  294. package/src/components/Select/hooks/useSelectState.ts +16 -16
  295. package/src/components/Select/types.ts +3 -0
  296. package/src/components/Select/utils/__tests__/text.test.tsx +104 -0
  297. package/src/components/SessionRestorationLoader/SessionRestorationLoader.test.tsx +28 -112
  298. package/src/components/Switch/Switch.test.tsx +57 -153
  299. package/src/components/Table/Table.test.tsx +47 -317
  300. package/src/components/Tabs/Tabs.tsx +3 -3
  301. package/src/components/Textarea/Textarea.test.tsx +11 -38
  302. package/src/components/Toast/Toast.test.tsx +78 -569
  303. package/src/components/Tooltip/Tooltip.test.tsx +4 -21
  304. package/src/components/UserMenu/UserMenu.test.tsx +1 -21
  305. package/src/components/UserMenu/UserMenu.tsx +0 -1
  306. package/src/components/__tests__/index.test.ts +346 -0
  307. package/src/components/index.ts +12 -1
  308. package/src/constants/__tests__/performance.test.ts +91 -0
  309. package/src/hooks/__tests__/ServiceHooks.test.tsx +239 -129
  310. package/src/hooks/__tests__/hooks.integration.test.tsx +4 -3
  311. package/src/hooks/__tests__/useApiFetch.unit.test.ts +1 -1
  312. package/src/hooks/__tests__/useAppConfig.unit.test.ts +88 -29
  313. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +282 -98
  314. package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +53 -109
  315. package/src/hooks/__tests__/useDataTableState.test.ts +143 -49
  316. package/src/hooks/__tests__/useDebounce.unit.test.ts +94 -19
  317. package/src/hooks/__tests__/useEvents.unit.test.ts +100 -125
  318. package/src/hooks/__tests__/useFileDisplay.test.ts +540 -0
  319. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +1 -4
  320. package/src/hooks/__tests__/useFileUrl.unit.test.ts +27 -247
  321. package/src/hooks/__tests__/useFileUrlCache.test.ts +246 -56
  322. package/src/hooks/__tests__/useFocusManagement.unit.test.ts +442 -68
  323. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +345 -560
  324. package/src/hooks/__tests__/useFormDialog.test.ts +51 -222
  325. package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +1 -1
  326. package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +1 -4
  327. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +0 -1
  328. package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +1 -1
  329. package/src/hooks/__tests__/usePermissionCache.test.ts +506 -0
  330. package/src/hooks/__tests__/usePreventTabReload.test.ts +255 -36
  331. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +17 -8
  332. package/src/hooks/__tests__/usePublicEvent.test.ts +16 -24
  333. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +12 -4
  334. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +3 -6
  335. package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +1 -2
  336. package/src/hooks/__tests__/useQueryCache.test.ts +313 -66
  337. package/src/hooks/__tests__/useSessionDraft.test.ts +496 -103
  338. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +2 -2
  339. package/src/hooks/__tests__/useStorage.unit.test.ts +72 -102
  340. package/src/hooks/__tests__/useToast.test.ts +413 -0
  341. package/src/hooks/__tests__/useToast.unit.test.tsx +1 -1
  342. package/src/hooks/__tests__/useZodForm.unit.test.tsx +175 -21
  343. package/src/hooks/index.ts +13 -1
  344. package/src/hooks/public/usePublicEvent.test.ts +304 -0
  345. package/src/hooks/public/usePublicEvent.ts +11 -11
  346. package/src/hooks/public/usePublicEventLogo.test.ts +655 -120
  347. package/src/hooks/public/usePublicEventLogo.ts +2 -2
  348. package/src/hooks/public/usePublicFileDisplay.test.ts +723 -0
  349. package/src/hooks/public/usePublicFileDisplay.ts +79 -49
  350. package/src/hooks/public/usePublicRouteParams.test.ts +595 -0
  351. package/src/hooks/public/usePublicRouteParams.ts +2 -2
  352. package/src/hooks/services/useAuthService.ts +1 -1
  353. package/src/hooks/services/useEventService.ts +1 -1
  354. package/src/hooks/useAccessibleApps.test.ts +400 -0
  355. package/src/hooks/useAccessibleApps.ts +264 -0
  356. package/src/hooks/useAddressAutocomplete.test.ts +165 -42
  357. package/src/hooks/useAddressAutocomplete.ts +41 -28
  358. package/src/hooks/useAppConfig.ts +13 -3
  359. package/src/hooks/useDataTablePerformance.ts +13 -12
  360. package/src/hooks/useDataTableState.ts +5 -5
  361. package/src/hooks/useEventTheme.test.ts +66 -17
  362. package/src/hooks/useEventTheme.ts +1 -1
  363. package/src/hooks/useEvents.ts +8 -1
  364. package/src/hooks/useFileDisplay.ts +66 -33
  365. package/src/hooks/useFileReference.test.ts +365 -87
  366. package/src/hooks/useFileReference.ts +2 -6
  367. package/src/hooks/useFileUrlCache.ts +4 -1
  368. package/src/hooks/useFormDialog.ts +2 -2
  369. package/src/hooks/useInactivityTracker.ts +3 -3
  370. package/src/hooks/useOrganisationPermissions.test.ts +1 -2
  371. package/src/hooks/useOrganisationPermissions.ts +1 -4
  372. package/src/hooks/useOrganisationSecurity.test.ts +1 -30
  373. package/src/hooks/useOrganisationSecurity.ts +3 -3
  374. package/src/hooks/useOrganisations.ts +1 -1
  375. package/src/hooks/usePerformanceMonitor.ts +1 -1
  376. package/src/hooks/usePermissionCache.ts +2 -6
  377. package/src/hooks/useQueryCache.ts +7 -7
  378. package/src/hooks/useSessionDraft.ts +14 -11
  379. package/src/hooks/useSessionRestoration.ts +1 -1
  380. package/src/hooks/useStorage.ts +75 -40
  381. package/src/hooks/useToast.ts +2 -2
  382. package/src/hooks/useZodForm.ts +3 -3
  383. package/src/icons/__tests__/index.test.ts +133 -0
  384. package/src/icons/index.ts +1 -1
  385. package/src/index.ts +43 -4
  386. package/src/providers/OrganisationProvider.test.tsx +40 -0
  387. package/src/providers/OrganisationProvider.tsx +5 -5
  388. package/src/providers/UnifiedAuthProvider.smoke.test.tsx +7 -12
  389. package/src/providers/__tests__/AuthProvider.test.tsx +22 -91
  390. package/src/providers/__tests__/EventProvider.test.tsx +16 -80
  391. package/src/providers/__tests__/InactivityProvider.test.tsx +29 -173
  392. package/src/providers/__tests__/OrganisationProvider.test.tsx +4 -5
  393. package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +591 -0
  394. package/src/providers/__tests__/ProviderLifecycle.test.tsx +80 -196
  395. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +40 -133
  396. package/src/providers/__tests__/index.test.ts +138 -0
  397. package/src/providers/services/AuthServiceContext.ts +27 -0
  398. package/src/providers/services/AuthServiceProvider.tsx +81 -20
  399. package/src/providers/services/EventServiceContext.ts +25 -0
  400. package/src/providers/services/EventServiceProvider.tsx +11 -20
  401. package/src/providers/services/InactivityServiceContext.ts +25 -0
  402. package/src/providers/services/InactivityServiceProvider.tsx +7 -17
  403. package/src/providers/services/OrganisationServiceContext.ts +25 -0
  404. package/src/providers/services/OrganisationServiceProvider.tsx +7 -17
  405. package/src/providers/services/UnifiedAuthContext.ts +99 -0
  406. package/src/providers/services/UnifiedAuthProvider.test.tsx +212 -0
  407. package/src/providers/services/UnifiedAuthProvider.tsx +38 -143
  408. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +61 -95
  409. package/src/providers/services/__tests__/AuthServiceProvider.test.tsx +638 -0
  410. package/src/providers/services/__tests__/EventServiceProvider.test.tsx +839 -0
  411. package/src/providers/services/__tests__/InactivityServiceProvider.test.tsx +662 -0
  412. package/src/providers/services/__tests__/OrganisationServiceProvider.test.tsx +440 -0
  413. package/src/providers/services/__tests__/UnifiedAuthProvider.advanced.test.tsx +435 -0
  414. package/src/providers/services/__tests__/UnifiedAuthProvider.appId.test.tsx +408 -0
  415. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +55 -48
  416. package/src/providers/services/__tests__/contexts.test.tsx +281 -0
  417. package/src/providers/services/__tests__/useUnifiedAuth.test.tsx +251 -0
  418. package/src/providers/services/useUnifiedAuth.ts +29 -0
  419. package/src/rbac/README.md +5 -5
  420. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +9 -14
  421. package/src/rbac/__tests__/audit-batched.test.ts +550 -0
  422. package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +1 -14
  423. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +43 -12
  424. package/src/rbac/__tests__/cache-invalidation.test.ts +8 -14
  425. package/src/rbac/__tests__/engine.comprehensive.test.ts +2 -7
  426. package/src/rbac/__tests__/index.test.ts +107 -0
  427. package/src/rbac/__tests__/performance.test.ts +451 -0
  428. package/src/rbac/__tests__/rbac-core.test.tsx +2 -2
  429. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +0 -5
  430. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +1 -7
  431. package/src/rbac/__tests__/rbac-functions.test.ts +0 -1
  432. package/src/rbac/__tests__/rbac-integration.test.ts +0 -1
  433. package/src/rbac/__tests__/scenarios.user-role.test.tsx +21 -32
  434. package/src/rbac/adapters.test.tsx +654 -0
  435. package/src/rbac/adapters.tsx +24 -9
  436. package/src/rbac/api.test.ts +13 -217
  437. package/src/rbac/api.ts +85 -16
  438. package/src/rbac/audit-batched.ts +5 -4
  439. package/src/rbac/audit.test.ts +225 -28
  440. package/src/rbac/audit.ts +22 -17
  441. package/src/rbac/cache-invalidation.ts +18 -15
  442. package/src/rbac/cache.test.ts +123 -63
  443. package/src/rbac/cache.ts +3 -4
  444. package/src/rbac/components/AccessDenied.tsx +20 -18
  445. package/src/rbac/components/NavigationGuard.tsx +10 -8
  446. package/src/rbac/components/PagePermissionGuard.tsx +27 -25
  447. package/src/rbac/components/__tests__/AccessDenied.test.tsx +324 -0
  448. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +242 -71
  449. package/src/rbac/components/__tests__/PagePermissionGuard.performance.test.tsx +20 -37
  450. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +18 -17
  451. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +452 -129
  452. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -13
  453. package/src/rbac/config.test.ts +131 -48
  454. package/src/rbac/config.ts +11 -8
  455. package/src/rbac/docs/event-based-apps.md +26 -13
  456. package/src/rbac/engine.test.ts +496 -146
  457. package/src/rbac/engine.ts +53 -13
  458. package/src/rbac/errors.test.ts +99 -87
  459. package/src/rbac/eslint-rules.js +2 -2
  460. package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +0 -5
  461. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +601 -1
  462. package/src/rbac/hooks/permissions/__tests__/useAccessLevel.test.ts +622 -0
  463. package/src/rbac/hooks/permissions/__tests__/useCan.test.ts +798 -0
  464. package/src/rbac/hooks/permissions/__tests__/useMultiplePermissions.test.ts +843 -0
  465. package/src/rbac/hooks/permissions/__tests__/usePermissions.test.ts +545 -0
  466. package/src/rbac/hooks/permissions/useAccessLevel.ts +7 -8
  467. package/src/rbac/hooks/permissions/useCan.ts +12 -10
  468. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +57 -8
  469. package/src/rbac/hooks/permissions/usePermissions.ts +15 -14
  470. package/src/rbac/hooks/useCan.test.ts +319 -3
  471. package/src/rbac/hooks/usePermissions.test.ts +426 -0
  472. package/src/rbac/hooks/usePermissions.ts +5 -7
  473. package/src/rbac/hooks/useRBAC.test.ts +1669 -2
  474. package/src/rbac/hooks/useRBAC.ts +7 -11
  475. package/src/rbac/hooks/useResolvedScope.test.ts +442 -5
  476. package/src/rbac/hooks/useResolvedScope.ts +4 -1
  477. package/src/rbac/hooks/useResourcePermissions.test.ts +538 -1
  478. package/src/rbac/hooks/useResourcePermissions.ts +9 -7
  479. package/src/rbac/hooks/useRoleManagement.test.ts +659 -1
  480. package/src/rbac/hooks/useRoleManagement.ts +16 -12
  481. package/src/rbac/hooks/useSecureSupabase.ts +11 -12
  482. package/src/rbac/index.ts +32 -32
  483. package/src/rbac/permissions.test.ts +149 -68
  484. package/src/rbac/permissions.ts +0 -3
  485. package/src/rbac/request-deduplication.test.ts +347 -0
  486. package/src/rbac/secureClient.test.ts +112 -159
  487. package/src/rbac/secureClient.ts +46 -26
  488. package/src/rbac/security.test.ts +125 -44
  489. package/src/rbac/security.ts +7 -6
  490. package/src/rbac/types.test.ts +236 -0
  491. package/src/rbac/types.ts +7 -5
  492. package/src/rbac/utils/__tests__/clientSecurity.test.ts +192 -0
  493. package/src/rbac/utils/__tests__/contextValidator.test.ts +1 -3
  494. package/src/rbac/utils/__tests__/deep-equal.test.ts +23 -0
  495. package/src/rbac/utils/__tests__/eventContext.test.ts +10 -57
  496. package/src/rbac/utils/clientSecurity.ts +6 -4
  497. package/src/rbac/utils/contextValidator.ts +1 -2
  498. package/src/rbac/utils/eventContext.ts +2 -2
  499. package/src/services/AuthService.ts +13 -11
  500. package/src/services/EventService.ts +4 -5
  501. package/src/services/OrganisationService.ts +13 -30
  502. package/src/services/__tests__/AuthService.edge-cases.test.ts +746 -0
  503. package/src/services/__tests__/AuthService.restoreSession.test.ts +23 -3
  504. package/src/services/__tests__/AuthService.test.ts +4 -8
  505. package/src/services/__tests__/BaseService.edge-cases.test.ts +506 -0
  506. package/src/services/__tests__/BaseService.test.ts +49 -0
  507. package/src/services/__tests__/EventService.edge-cases.test.ts +633 -0
  508. package/src/services/__tests__/EventService.eventColours.test.ts +0 -12
  509. package/src/services/__tests__/EventService.test.ts +0 -7
  510. package/src/services/__tests__/InactivityService.edge-cases.test.ts +492 -0
  511. package/src/services/__tests__/InactivityService.lifecycle.test.ts +0 -5
  512. package/src/services/__tests__/OrganisationService.edge-cases.test.ts +633 -0
  513. package/src/services/base/BaseService.test.ts +214 -0
  514. package/src/services/interfaces/IOrganisationService.ts +0 -1
  515. package/src/services/interfaces/__tests__/IAuthService.test.ts +190 -0
  516. package/src/services/interfaces/__tests__/IEventService.test.ts +176 -0
  517. package/src/services/interfaces/__tests__/IInactivityService.test.ts +183 -0
  518. package/src/services/interfaces/__tests__/IOrganisationService.test.ts +207 -0
  519. package/src/styles/core.css +1 -0
  520. package/src/theming/__tests__/runtime.test.ts +29 -94
  521. package/src/theming/parseEventColours.ts +18 -9
  522. package/src/theming/runtime.ts +1 -5
  523. package/src/types/__tests__/core.test.ts +397 -0
  524. package/src/types/__tests__/database-generated.test.ts +78 -0
  525. package/src/types/__tests__/file-reference.test.ts +270 -366
  526. package/src/types/__tests__/guards.test.ts +26 -26
  527. package/src/types/__tests__/index.test.ts +265 -0
  528. package/src/types/__tests__/type-validation.test.ts +3 -3
  529. package/src/types/__tests__/validation.test.ts +0 -2
  530. package/src/types/auth.ts +0 -1
  531. package/src/types/event.ts +1 -1
  532. package/src/types/rpc-responses.ts +33 -0
  533. package/src/types/supabase.ts +1 -2
  534. package/src/types/vitest-globals.d.ts +1 -1
  535. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +64 -77
  536. package/src/utils/__tests__/dynamicUtils.unit.test.ts +13 -0
  537. package/src/utils/__tests__/formatDate.unit.test.ts +1 -1
  538. package/src/utils/__tests__/lazyLoad.unit.test.tsx +0 -1
  539. package/src/utils/__tests__/logger.unit.test.ts +1 -1
  540. package/src/utils/__tests__/performanceBenchmark.test.ts +1 -2
  541. package/src/utils/__tests__/performanceBudgets.unit.test.ts +48 -13
  542. package/src/utils/__tests__/request-deduplication.test.ts +349 -0
  543. package/src/utils/__tests__/secureDataAccess.unit.test.ts +0 -1
  544. package/src/utils/__tests__/timezone.test.ts +1 -1
  545. package/src/utils/__tests__/validation.unit.test.ts +1 -2
  546. package/src/utils/__tests__/validationUtils.unit.test.ts +1 -1
  547. package/src/utils/app/appConfig.test.ts +235 -0
  548. package/src/utils/app/appIdResolver.test.ts +188 -20
  549. package/src/utils/app/appNameResolver.test.ts +18 -10
  550. package/src/utils/app/appNameResolver.ts +11 -9
  551. package/src/utils/app/appPortMap.test.ts +125 -0
  552. package/src/utils/app/appPortMap.ts +51 -0
  553. package/src/utils/app/buildAppUrl.test.ts +273 -0
  554. package/src/utils/app/buildAppUrl.ts +114 -0
  555. package/src/utils/audit/audit.test.ts +354 -39
  556. package/src/utils/context/organisationContext.test.ts +10 -4
  557. package/src/utils/context/organisationContext.ts +5 -5
  558. package/src/utils/context/sessionTracking.test.ts +354 -0
  559. package/src/utils/core/__tests__/cn.test.ts +66 -0
  560. package/src/utils/core/__tests__/debugLogger.test.ts +113 -0
  561. package/src/utils/core/__tests__/logger.test.ts +217 -0
  562. package/src/utils/core/debugLogger.ts +15 -8
  563. package/src/utils/core/logger.ts +20 -16
  564. package/src/utils/device/deviceFingerprint.test.ts +8 -5
  565. package/src/utils/device/deviceFingerprint.ts +3 -3
  566. package/src/utils/dynamic/__tests__/dynamicUtils.test.ts +185 -0
  567. package/src/utils/dynamic/__tests__/lazyLoad.test.tsx +156 -0
  568. package/src/utils/dynamic/createLazyComponent.tsx +38 -0
  569. package/src/utils/dynamic/dynamicUtils.ts +6 -6
  570. package/src/utils/dynamic/lazyLoad.tsx +8 -36
  571. package/src/utils/dynamic/papaparseLoader.ts +7 -0
  572. package/src/utils/file-reference/__tests__/file-reference.test.ts +583 -145
  573. package/src/utils/file-reference/index.ts +0 -1
  574. package/src/utils/formatting/formatDate.test.ts +22 -148
  575. package/src/utils/formatting/formatDateTime.test.ts +41 -119
  576. package/src/utils/formatting/formatDateTimeTimezone.test.ts +40 -84
  577. package/src/utils/formatting/formatNumber.test.ts +259 -0
  578. package/src/utils/formatting/formatTime.test.ts +36 -128
  579. package/src/utils/formatting/formatting.ts +1 -1
  580. package/src/utils/google-places/googlePlacesUtils.test.ts +72 -3
  581. package/src/utils/google-places/googlePlacesUtils.ts +15 -2
  582. package/src/utils/google-places/loadGoogleMapsScript.test.ts +58 -1
  583. package/src/utils/google-places/loadGoogleMapsScript.ts +2 -1
  584. package/src/utils/index.ts +52 -11
  585. package/src/utils/location/location.test.ts +18 -115
  586. package/src/utils/performance/__tests__/bundleAnalysis.test.ts +148 -0
  587. package/src/utils/performance/__tests__/performanceBenchmark.test.ts +251 -0
  588. package/src/utils/performance/__tests__/performanceBudgets.test.ts +241 -0
  589. package/src/utils/performance/bundleAnalysis.ts +16 -22
  590. package/src/utils/performance/performanceBenchmark.ts +12 -4
  591. package/src/utils/performance/performanceBudgets.ts +9 -6
  592. package/src/utils/permissions/__tests__/permissionTypes.test.ts +149 -0
  593. package/src/utils/permissions/permissionUtils.test.ts +20 -42
  594. package/src/utils/persistence/__tests__/keyDerivation.test.ts +180 -9
  595. package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +164 -16
  596. package/src/utils/persistence/sensitiveFieldDetection.ts +2 -2
  597. package/src/utils/request-deduplication.ts +6 -4
  598. package/src/utils/security/auth-utils.ts +7 -7
  599. package/src/utils/security/secureDataAccess.test.ts +22 -191
  600. package/src/utils/security/secureErrors.test.ts +163 -0
  601. package/src/utils/security/secureStorage.test.ts +156 -0
  602. package/src/utils/security/secureStorage.ts +1 -1
  603. package/src/utils/security/security.test.ts +204 -0
  604. package/src/utils/security/securityMonitor.test.ts +90 -0
  605. package/src/utils/security/securityMonitor.ts +1 -1
  606. package/src/utils/storage/__tests__/config.unit.test.ts +239 -0
  607. package/src/utils/storage/__tests__/index.unit.test.ts +64 -12
  608. package/src/utils/storage/helpers.test.ts +757 -430
  609. package/src/utils/storage/helpers.ts +1 -2
  610. package/src/utils/storage/{index.ts → storageUtils.ts} +1 -36
  611. package/src/utils/storage/types.ts +2 -2
  612. package/src/utils/supabase/createBaseClient.test.ts +201 -0
  613. package/src/utils/supabase/createBaseClient.ts +2 -1
  614. package/src/utils/timezone/timezone.test.ts +25 -43
  615. package/src/utils/validation/__tests__/common.test.ts +115 -0
  616. package/src/utils/validation/__tests__/csrf.test.ts +65 -0
  617. package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +27 -7
  618. package/src/utils/validation/__tests__/passwordSchema.test.ts +164 -0
  619. package/src/utils/validation/__tests__/schema.test.ts +127 -0
  620. package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +76 -3
  621. package/src/utils/validation/__tests__/user.test.ts +173 -0
  622. package/src/utils/validation/__tests__/validation.test.ts +197 -0
  623. package/src/utils/validation/__tests__/validationUtils.test.ts +265 -43
  624. package/src/utils/validation/htmlSanitization.ts +27 -31
  625. package/src/utils/validation/schema.ts +6 -3
  626. package/src/utils/validation/sqlInjectionProtection.ts +2 -2
  627. package/src/vite-env.d.ts +6 -0
  628. package/dist/DataTable-DRUIgtUH.d.ts +0 -166
  629. package/dist/UnifiedAuthProvider-7SNDOWYD.js +0 -7
  630. package/dist/audit-MYQXYZFU.js +0 -3
  631. package/dist/chunk-7ILTDCL2.js +0 -80
  632. package/dist/chunk-EF2UGZWY.js +0 -611
  633. package/dist/chunk-FEJLJNWA.js +0 -181
  634. package/dist/chunk-GS5672WG.js +0 -2003
  635. package/dist/chunk-S6ZQKDY6.js +0 -62
  636. package/dist/chunk-Z2FNRKF3.js +0 -994
  637. package/dist/useToast-AyaT-x7p.d.ts +0 -68
  638. package/src/components/DataTable/components/index.ts +0 -16
  639. package/src/components/DataTable/core/index.ts +0 -1
  640. package/src/components/DataTable/hooks/index.ts +0 -13
  641. package/src/components/DataTable/utils/index.ts +0 -10
  642. package/src/components/PublicLayout/index.ts +0 -32
  643. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +0 -192
  644. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -741
  645. package/src/hooks/public/index.ts +0 -36
  646. package/src/hooks/usePermissionCache.test.ts +0 -536
  647. package/src/rbac/__tests__/isSuperAdmin.real.test.ts +0 -82
  648. package/src/rbac/audit-enhanced.ts +0 -384
  649. package/src/rbac/compliance/database-validator.ts +0 -165
  650. package/src/rbac/compliance/index.ts +0 -48
  651. package/src/rbac/compliance/pattern-detector.ts +0 -553
  652. package/src/rbac/compliance/quick-fix-suggestions.ts +0 -209
  653. package/src/rbac/compliance/runtime-compliance.ts +0 -99
  654. package/src/rbac/compliance/setup-validator.ts +0 -131
  655. package/src/rbac/components/index.ts +0 -26
  656. package/src/rbac/hooks/index.ts +0 -34
  657. package/src/rbac/hooks/permissions/index.ts +0 -4
  658. package/src/rbac/hooks/useRBAC.simple.test.ts +0 -95
  659. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -490
  660. package/src/utils/app/appNameResolver.simple.test.ts +0 -212
  661. package/src/utils/google-places/index.ts +0 -26
  662. package/src/utils/location/index.ts +0 -16
  663. package/src/utils/storage/__tests__/helpers.unit.test.ts +0 -332
  664. package/src/utils/timezone/index.ts +0 -17
  665. package/src/utils/validation/index.ts +0 -73
@@ -0,0 +1,349 @@
1
+ /**
2
+ * @file Request Deduplication Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module Utils/__tests__
5
+ * @since 2.0.0
6
+ */
7
+
8
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
9
+ import {
10
+ generateRequestKey,
11
+ getOrCreateRequest,
12
+ clearInFlightRequests,
13
+ getInFlightRequestStats,
14
+ deduplicatedQuery,
15
+ } from '../request-deduplication';
16
+
17
+ describe('Request Deduplication', () => {
18
+ beforeEach(() => {
19
+ clearInFlightRequests();
20
+ vi.clearAllMocks();
21
+ });
22
+
23
+ describe('generateRequestKey', () => {
24
+ it('generates key from method and table', () => {
25
+ const key = generateRequestKey('GET', 'users');
26
+ expect(key).toBe('GET:users::*');
27
+ });
28
+
29
+ it('generates key with filters', () => {
30
+ const key = generateRequestKey('GET', 'users', { user_id: '123' });
31
+ expect(key).toBe('GET:users:{"user_id":"123"}:*');
32
+ });
33
+
34
+ it('generates key with select columns', () => {
35
+ const key = generateRequestKey('GET', 'users', undefined, 'id, name');
36
+ expect(key).toBe('GET:users::id, name');
37
+ });
38
+
39
+ it('generates key with filters and select', () => {
40
+ const key = generateRequestKey('GET', 'users', { user_id: '123' }, 'id, name');
41
+ expect(key).toBe('GET:users:{"user_id":"123"}:id, name');
42
+ });
43
+
44
+ it('generates consistent keys for same parameters', () => {
45
+ const key1 = generateRequestKey('GET', 'users', { user_id: '123' }, 'id, name');
46
+ const key2 = generateRequestKey('GET', 'users', { user_id: '123' }, 'id, name');
47
+ expect(key1).toBe(key2);
48
+ });
49
+
50
+ it('generates different keys for different filters', () => {
51
+ const key1 = generateRequestKey('GET', 'users', { user_id: '123' });
52
+ const key2 = generateRequestKey('GET', 'users', { user_id: '456' });
53
+ expect(key1).not.toBe(key2);
54
+ });
55
+
56
+ it('generates different keys for different methods', () => {
57
+ const key1 = generateRequestKey('GET', 'users');
58
+ const key2 = generateRequestKey('POST', 'users');
59
+ expect(key1).not.toBe(key2);
60
+ });
61
+
62
+ it('handles complex filter objects', () => {
63
+ const filters = {
64
+ user_id: '123',
65
+ status: 'active',
66
+ tags: ['tag1', 'tag2'],
67
+ };
68
+ const key = generateRequestKey('GET', 'users', filters);
69
+ expect(key).toContain('GET:users:');
70
+ expect(key).toContain('user_id');
71
+ expect(key).toContain('status');
72
+ });
73
+
74
+ it('handles empty filters object', () => {
75
+ const key = generateRequestKey('GET', 'users', {});
76
+ expect(key).toBe('GET:users:{}:*');
77
+ });
78
+
79
+ it('uses default select when not provided', () => {
80
+ const key = generateRequestKey('GET', 'users');
81
+ expect(key).toContain(':*');
82
+ });
83
+ });
84
+
85
+ describe('getOrCreateRequest', () => {
86
+ it('creates new request when key does not exist', async () => {
87
+ const requestFn = vi.fn().mockResolvedValue('result');
88
+ const result = await getOrCreateRequest('test-key', requestFn);
89
+
90
+ expect(result).toBe('result');
91
+ expect(requestFn).toHaveBeenCalledTimes(1);
92
+ });
93
+
94
+ it('reuses existing request when key exists', async () => {
95
+ const requestFn = vi.fn().mockResolvedValue('result');
96
+
97
+ const promise1 = getOrCreateRequest('test-key', requestFn);
98
+ const promise2 = getOrCreateRequest('test-key', requestFn);
99
+
100
+ const [result1, result2] = await Promise.all([promise1, promise2]);
101
+
102
+ expect(result1).toBe('result');
103
+ expect(result2).toBe('result');
104
+ expect(requestFn).toHaveBeenCalledTimes(1); // Only called once due to deduplication
105
+ });
106
+
107
+ it('removes request from cache after successful completion', async () => {
108
+ const requestFn = vi.fn().mockResolvedValue('result');
109
+
110
+ await getOrCreateRequest('test-key', requestFn);
111
+
112
+ const stats = getInFlightRequestStats();
113
+ expect(stats.count).toBe(0);
114
+ expect(stats.keys).not.toContain('test-key');
115
+ });
116
+
117
+ it('removes request from cache after error', async () => {
118
+ const requestFn = vi.fn().mockRejectedValue(new Error('Request failed'));
119
+
120
+ await expect(getOrCreateRequest('test-key', requestFn)).rejects.toThrow('Request failed');
121
+
122
+ const stats = getInFlightRequestStats();
123
+ expect(stats.count).toBe(0);
124
+ expect(stats.keys).not.toContain('test-key');
125
+ });
126
+
127
+ it('propagates errors correctly', async () => {
128
+ const error = new Error('Request failed');
129
+ const requestFn = vi.fn().mockRejectedValue(error);
130
+
131
+ await expect(getOrCreateRequest('test-key', requestFn)).rejects.toThrow('Request failed');
132
+ });
133
+
134
+ it('handles concurrent requests with same key', async () => {
135
+ let callCount = 0;
136
+ const requestFn = vi.fn().mockImplementation(async () => {
137
+ callCount++;
138
+ await new Promise(resolve => setTimeout(resolve, 10));
139
+ return `result-${callCount}`;
140
+ });
141
+
142
+ const promises = [
143
+ getOrCreateRequest('test-key', requestFn),
144
+ getOrCreateRequest('test-key', requestFn),
145
+ getOrCreateRequest('test-key', requestFn),
146
+ ];
147
+
148
+ const results = await Promise.all(promises);
149
+
150
+ // All should get the same result (first one)
151
+ expect(results[0]).toBe('result-1');
152
+ expect(results[1]).toBe('result-1');
153
+ expect(results[2]).toBe('result-1');
154
+ expect(requestFn).toHaveBeenCalledTimes(1);
155
+ });
156
+
157
+ it('handles different keys independently', async () => {
158
+ const requestFn1 = vi.fn().mockResolvedValue('result1');
159
+ const requestFn2 = vi.fn().mockResolvedValue('result2');
160
+
161
+ const [result1, result2] = await Promise.all([
162
+ getOrCreateRequest('key1', requestFn1),
163
+ getOrCreateRequest('key2', requestFn2),
164
+ ]);
165
+
166
+ expect(result1).toBe('result1');
167
+ expect(result2).toBe('result2');
168
+ expect(requestFn1).toHaveBeenCalledTimes(1);
169
+ expect(requestFn2).toHaveBeenCalledTimes(1);
170
+ });
171
+
172
+ it('handles async request functions', async () => {
173
+ const requestFn = vi.fn().mockImplementation(async () => {
174
+ await new Promise(resolve => setTimeout(resolve, 50));
175
+ return 'async-result';
176
+ });
177
+
178
+ const result = await getOrCreateRequest('test-key', requestFn);
179
+ expect(result).toBe('async-result');
180
+ });
181
+ });
182
+
183
+ describe('clearInFlightRequests', () => {
184
+ it('clears all in-flight requests', async () => {
185
+ const requestFn = vi.fn().mockImplementation(async () => {
186
+ await new Promise(resolve => setTimeout(resolve, 100));
187
+ return 'result';
188
+ });
189
+
190
+ // Start a request but don't wait for it
191
+ getOrCreateRequest('test-key', requestFn);
192
+
193
+ // Verify request is in-flight
194
+ let stats = getInFlightRequestStats();
195
+ expect(stats.count).toBe(1);
196
+
197
+ // Clear all requests
198
+ clearInFlightRequests();
199
+
200
+ // Verify cache is empty
201
+ stats = getInFlightRequestStats();
202
+ expect(stats.count).toBe(0);
203
+ expect(stats.keys).toEqual([]);
204
+ });
205
+
206
+ it('can be called multiple times safely', () => {
207
+ clearInFlightRequests();
208
+ clearInFlightRequests();
209
+ clearInFlightRequests();
210
+
211
+ const stats = getInFlightRequestStats();
212
+ expect(stats.count).toBe(0);
213
+ });
214
+
215
+ it('clears requests even when they are in progress', async () => {
216
+ const requestFn = vi.fn().mockImplementation(async () => {
217
+ await new Promise(resolve => setTimeout(resolve, 100));
218
+ return 'result';
219
+ });
220
+
221
+ getOrCreateRequest('test-key', requestFn);
222
+
223
+ clearInFlightRequests();
224
+
225
+ const stats = getInFlightRequestStats();
226
+ expect(stats.count).toBe(0);
227
+ });
228
+ });
229
+
230
+ describe('getInFlightRequestStats', () => {
231
+ it('returns empty stats when no requests in flight', () => {
232
+ const stats = getInFlightRequestStats();
233
+ expect(stats.count).toBe(0);
234
+ expect(stats.keys).toEqual([]);
235
+ });
236
+
237
+ it('returns correct count for in-flight requests', async () => {
238
+ const requestFn = vi.fn().mockImplementation(async () => {
239
+ await new Promise(resolve => setTimeout(resolve, 100));
240
+ return 'result';
241
+ });
242
+
243
+ getOrCreateRequest('key1', requestFn);
244
+ getOrCreateRequest('key2', requestFn);
245
+
246
+ const stats = getInFlightRequestStats();
247
+ expect(stats.count).toBe(2);
248
+ expect(stats.keys).toContain('key1');
249
+ expect(stats.keys).toContain('key2');
250
+ });
251
+
252
+ it('returns all request keys', async () => {
253
+ const requestFn = vi.fn().mockImplementation(async () => {
254
+ await new Promise(resolve => setTimeout(resolve, 100));
255
+ return 'result';
256
+ });
257
+
258
+ getOrCreateRequest('key1', requestFn);
259
+ getOrCreateRequest('key2', requestFn);
260
+ getOrCreateRequest('key3', requestFn);
261
+
262
+ const stats = getInFlightRequestStats();
263
+ expect(stats.keys).toHaveLength(3);
264
+ expect(stats.keys.sort()).toEqual(['key1', 'key2', 'key3'].sort());
265
+ });
266
+
267
+ it('updates stats as requests complete', async () => {
268
+ const requestFn = vi.fn().mockResolvedValue('result');
269
+
270
+ getOrCreateRequest('key1', requestFn);
271
+ getOrCreateRequest('key2', requestFn);
272
+
273
+ let stats = getInFlightRequestStats();
274
+ expect(stats.count).toBe(2);
275
+
276
+ await Promise.all([
277
+ getOrCreateRequest('key1', requestFn),
278
+ getOrCreateRequest('key2', requestFn),
279
+ ]);
280
+
281
+ stats = getInFlightRequestStats();
282
+ expect(stats.count).toBe(0);
283
+ });
284
+ });
285
+
286
+ describe('deduplicatedQuery', () => {
287
+ it('generates key and calls getOrCreateRequest', async () => {
288
+ const mockSupabase = {} as any;
289
+ const filters = { user_id: '123' };
290
+ const select = 'id, name';
291
+ const requestFn = vi.fn().mockResolvedValue('result');
292
+
293
+ const result = await deduplicatedQuery(mockSupabase, 'users', filters, select, requestFn);
294
+
295
+ expect(result).toBe('result');
296
+ expect(requestFn).toHaveBeenCalledTimes(1);
297
+ });
298
+
299
+ it('uses correct key format for deduplication', async () => {
300
+ const mockSupabase = {} as any;
301
+ const filters = { user_id: '123' };
302
+ const select = 'id, name';
303
+ const requestFn = vi.fn().mockResolvedValue('result');
304
+
305
+ // Call twice with same parameters
306
+ const promise1 = deduplicatedQuery(mockSupabase, 'users', filters, select, requestFn);
307
+ const promise2 = deduplicatedQuery(mockSupabase, 'users', filters, select, requestFn);
308
+
309
+ await Promise.all([promise1, promise2]);
310
+
311
+ // Should only call requestFn once due to deduplication
312
+ expect(requestFn).toHaveBeenCalledTimes(1);
313
+ });
314
+
315
+ it('handles different filters as separate requests', async () => {
316
+ const mockSupabase = {} as any;
317
+ const requestFn = vi.fn().mockResolvedValue('result');
318
+
319
+ await Promise.all([
320
+ deduplicatedQuery(mockSupabase, 'users', { user_id: '123' }, '*', requestFn),
321
+ deduplicatedQuery(mockSupabase, 'users', { user_id: '456' }, '*', requestFn),
322
+ ]);
323
+
324
+ expect(requestFn).toHaveBeenCalledTimes(2);
325
+ });
326
+
327
+ it('handles different tables as separate requests', async () => {
328
+ const mockSupabase = {} as any;
329
+ const requestFn = vi.fn().mockResolvedValue('result');
330
+
331
+ await Promise.all([
332
+ deduplicatedQuery(mockSupabase, 'users', {}, '*', requestFn),
333
+ deduplicatedQuery(mockSupabase, 'events', {}, '*', requestFn),
334
+ ]);
335
+
336
+ expect(requestFn).toHaveBeenCalledTimes(2);
337
+ });
338
+
339
+ it('propagates errors from request function', async () => {
340
+ const mockSupabase = {} as any;
341
+ const error = new Error('Query failed');
342
+ const requestFn = vi.fn().mockRejectedValue(error);
343
+
344
+ await expect(
345
+ deduplicatedQuery(mockSupabase, 'users', {}, '*', requestFn)
346
+ ).rejects.toThrow('Query failed');
347
+ });
348
+ });
349
+ });
@@ -7,7 +7,6 @@
7
7
 
8
8
  import { describe, it, expect, vi, beforeEach } from 'vitest';
9
9
  import { createSecureDataAccess } from '../security/secureDataAccess';
10
- import type { SupabaseClient } from '@supabase/supabase-js';
11
10
  import { testDataGenerators } from '../../__tests__/helpers/test-utils';
12
11
 
13
12
  // Create a proper mock for Supabase query chain
@@ -18,7 +18,7 @@ import {
18
18
  fromZonedTime,
19
19
  roundToNearestMinutes,
20
20
  getTimeZoneDifference
21
- } from '../timezone';
21
+ } from '../timezone/timezone';
22
22
 
23
23
  describe('Timezone Utilities', () => {
24
24
  describe('formatInTimeZone', () => {
@@ -10,7 +10,7 @@ import {
10
10
  matchesPattern,
11
11
  deepMerge,
12
12
  isObject
13
- } from '../validation';
13
+ } from '../validation/validation';
14
14
 
15
15
  describe('validation utilities', () => {
16
16
  describe('isValidEmail', () => {
@@ -137,7 +137,6 @@ describe('validation utilities', () => {
137
137
  it('invalidates dates with invalid day', () => {
138
138
  // Note: JavaScript Date is permissive, but some invalid dates will be detected
139
139
  // Dates like '2023-01-32' may roll over to next month, so we check actual behavior
140
- const invalidDay = new Date('2023-01-32');
141
140
  // If the date rolls over, it's technically valid from Date's perspective
142
141
  // So we test with truly invalid formats instead
143
142
  expect(isValidDate('not-a-date-format')).toBe(false);
@@ -13,7 +13,7 @@ import {
13
13
  // Mock sanitization functions
14
14
  vi.mock('../validation/sanitization', () => ({
15
15
  sanitizeUserInput: vi.fn((input: string) => `sanitized_${input}`),
16
- sanitizeFormData: vi.fn((data: unknown, schema: z.ZodSchema, rules?: Record<string, any>) => {
16
+ sanitizeFormData: vi.fn((data: unknown, schema: z.ZodSchema, _rules?: Record<string, any>) => {
17
17
  // Try to parse with the schema to determine success
18
18
  try {
19
19
  const result = schema.parse(data);
@@ -0,0 +1,235 @@
1
+ /**
2
+ * @file App Config Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module Utils/AppConfig
5
+ * @since 0.1.0
6
+ *
7
+ * Comprehensive tests for app configuration utility functions covering:
8
+ * - Configuration setting and retrieval
9
+ * - Fallback behavior
10
+ * - Default values
11
+ * - Edge cases
12
+ */
13
+
14
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
15
+ import {
16
+ setAppConfig,
17
+ getAppConfig,
18
+ getCurrentAppName,
19
+ getCurrentAppId
20
+ } from './appConfig';
21
+
22
+ // Following testing standards: use timeout parameter to prevent hanging
23
+ const TEST_TIMEOUT = 10000; // 10 seconds per test
24
+
25
+ describe('App Config', () => {
26
+ beforeEach(() => {
27
+ // Clear app config before each test
28
+ // We need to access the internal state to reset it
29
+ // Since the module uses a closure, we'll set a new config to clear it
30
+ setAppConfig({ appName: 'PACE', appId: 'PACE' });
31
+ // Then clear it by setting to a known state
32
+ vi.clearAllMocks();
33
+ });
34
+
35
+ describe('setAppConfig', () => {
36
+ it('sets the app configuration', () => {
37
+ const config = { appName: 'TEST_APP', appId: 'test-app-id' };
38
+ setAppConfig(config);
39
+
40
+ const result = getAppConfig();
41
+ expect(result).toEqual(config);
42
+ }, TEST_TIMEOUT);
43
+
44
+ it('overwrites previous configuration', () => {
45
+ setAppConfig({ appName: 'APP1', appId: 'app1-id' });
46
+ setAppConfig({ appName: 'APP2', appId: 'app2-id' });
47
+
48
+ const result = getAppConfig();
49
+ expect(result).toEqual({ appName: 'APP2', appId: 'app2-id' });
50
+ }, TEST_TIMEOUT);
51
+
52
+ it('handles configuration with same appName and appId', () => {
53
+ const config = { appName: 'SAME', appId: 'SAME' };
54
+ setAppConfig(config);
55
+
56
+ const result = getAppConfig();
57
+ expect(result).toEqual(config);
58
+ }, TEST_TIMEOUT);
59
+
60
+ it('handles configuration with different appName and appId', () => {
61
+ const config = { appName: 'MyApp', appId: 'my-app-id-123' };
62
+ setAppConfig(config);
63
+
64
+ const result = getAppConfig();
65
+ expect(result).toEqual(config);
66
+ }, TEST_TIMEOUT);
67
+ });
68
+
69
+ describe('getAppConfig', () => {
70
+ it('returns the current app configuration when set', () => {
71
+ const config = { appName: 'TEST_APP', appId: 'test-app-id' };
72
+ setAppConfig(config);
73
+
74
+ const result = getAppConfig();
75
+ expect(result).toEqual(config);
76
+ }, TEST_TIMEOUT);
77
+
78
+ it('returns fallback configuration when not set', () => {
79
+ // Clear config by setting a known state, then test fallback
80
+ // The fallback uses import.meta.env.REACT_APP_NAME or 'PACE'
81
+ const result = getAppConfig();
82
+
83
+ expect(result).toBeDefined();
84
+ expect(result).toHaveProperty('appName');
85
+ expect(result).toHaveProperty('appId');
86
+ expect(typeof result.appName).toBe('string');
87
+ expect(typeof result.appId).toBe('string');
88
+ }, TEST_TIMEOUT);
89
+
90
+ it('uses REACT_APP_NAME from environment when available', () => {
91
+ // Note: import.meta.env is read-only in Vite, so we can't easily test this
92
+ // But we can verify the structure is correct
93
+ const result = getAppConfig();
94
+
95
+ expect(result.appName).toBeTruthy();
96
+ expect(result.appId).toBeTruthy();
97
+ }, TEST_TIMEOUT);
98
+
99
+ it('uses PACE as default when REACT_APP_NAME is not available', () => {
100
+ // The function falls back to 'PACE' if REACT_APP_NAME is not set
101
+ // Since we can't easily control import.meta.env, we verify the structure
102
+ const result = getAppConfig();
103
+
104
+ // Should have appName and appId
105
+ expect(result.appName).toBeDefined();
106
+ expect(result.appId).toBeDefined();
107
+ // appId should match appName in fallback case
108
+ expect(result.appId).toBe(result.appName);
109
+ }, TEST_TIMEOUT);
110
+ });
111
+
112
+ describe('getCurrentAppName', () => {
113
+ it('returns the app name from configuration', () => {
114
+ setAppConfig({ appName: 'MY_APP', appId: 'my-app-id' });
115
+
116
+ const result = getCurrentAppName();
117
+ expect(result).toBe('MY_APP');
118
+ }, TEST_TIMEOUT);
119
+
120
+ it('returns fallback app name when configuration is not set', () => {
121
+ // Clear config and test fallback
122
+ const result = getCurrentAppName();
123
+
124
+ expect(result).toBeDefined();
125
+ expect(typeof result).toBe('string');
126
+ expect(result.length).toBeGreaterThan(0);
127
+ }, TEST_TIMEOUT);
128
+
129
+ it('returns updated app name after configuration change', () => {
130
+ setAppConfig({ appName: 'APP1', appId: 'app1-id' });
131
+ expect(getCurrentAppName()).toBe('APP1');
132
+
133
+ setAppConfig({ appName: 'APP2', appId: 'app2-id' });
134
+ expect(getCurrentAppName()).toBe('APP2');
135
+ }, TEST_TIMEOUT);
136
+ });
137
+
138
+ describe('getCurrentAppId', () => {
139
+ it('returns the app ID from configuration', () => {
140
+ setAppConfig({ appName: 'MY_APP', appId: 'my-app-id' });
141
+
142
+ const result = getCurrentAppId();
143
+ expect(result).toBe('my-app-id');
144
+ }, TEST_TIMEOUT);
145
+
146
+ it('returns fallback app ID when configuration is not set', () => {
147
+ // Clear config and test fallback
148
+ const result = getCurrentAppId();
149
+
150
+ expect(result).toBeDefined();
151
+ expect(typeof result).toBe('string');
152
+ expect(result.length).toBeGreaterThan(0);
153
+ }, TEST_TIMEOUT);
154
+
155
+ it('returns updated app ID after configuration change', () => {
156
+ setAppConfig({ appName: 'APP1', appId: 'app1-id' });
157
+ expect(getCurrentAppId()).toBe('app1-id');
158
+
159
+ setAppConfig({ appName: 'APP2', appId: 'app2-id' });
160
+ expect(getCurrentAppId()).toBe('app2-id');
161
+ }, TEST_TIMEOUT);
162
+
163
+ it('can have different appName and appId', () => {
164
+ setAppConfig({ appName: 'MyApp', appId: 'different-id' });
165
+
166
+ expect(getCurrentAppName()).toBe('MyApp');
167
+ expect(getCurrentAppId()).toBe('different-id');
168
+ expect(getCurrentAppName()).not.toBe(getCurrentAppId());
169
+ }, TEST_TIMEOUT);
170
+ });
171
+
172
+ describe('Integration', () => {
173
+ it('maintains consistent state across multiple calls', () => {
174
+ const config = { appName: 'CONSISTENT', appId: 'consistent-id' };
175
+ setAppConfig(config);
176
+
177
+ expect(getAppConfig()).toEqual(config);
178
+ expect(getCurrentAppName()).toBe('CONSISTENT');
179
+ expect(getCurrentAppId()).toBe('consistent-id');
180
+
181
+ // Multiple calls should return same values
182
+ expect(getAppConfig()).toEqual(config);
183
+ expect(getCurrentAppName()).toBe('CONSISTENT');
184
+ expect(getCurrentAppId()).toBe('consistent-id');
185
+ }, TEST_TIMEOUT);
186
+
187
+ it('handles rapid configuration changes', () => {
188
+ const configs = [
189
+ { appName: 'APP1', appId: 'app1' },
190
+ { appName: 'APP2', appId: 'app2' },
191
+ { appName: 'APP3', appId: 'app3' }
192
+ ];
193
+
194
+ configs.forEach((config, _index) => {
195
+ setAppConfig(config);
196
+ expect(getCurrentAppName()).toBe(config.appName);
197
+ expect(getCurrentAppId()).toBe(config.appId);
198
+ });
199
+ }, TEST_TIMEOUT);
200
+ });
201
+
202
+ describe('Edge Cases', () => {
203
+ it('handles empty string app name', () => {
204
+ setAppConfig({ appName: '', appId: 'id' });
205
+
206
+ expect(getCurrentAppName()).toBe('');
207
+ expect(getCurrentAppId()).toBe('id');
208
+ }, TEST_TIMEOUT);
209
+
210
+ it('handles empty string app ID', () => {
211
+ setAppConfig({ appName: 'APP', appId: '' });
212
+
213
+ expect(getCurrentAppName()).toBe('APP');
214
+ expect(getCurrentAppId()).toBe('');
215
+ }, TEST_TIMEOUT);
216
+
217
+ it('handles very long app names and IDs', () => {
218
+ const longName = 'A'.repeat(1000);
219
+ const longId = 'B'.repeat(1000);
220
+
221
+ setAppConfig({ appName: longName, appId: longId });
222
+
223
+ expect(getCurrentAppName()).toBe(longName);
224
+ expect(getCurrentAppId()).toBe(longId);
225
+ }, TEST_TIMEOUT);
226
+
227
+ it('handles special characters in app name and ID', () => {
228
+ const config = { appName: 'APP-123_test@domain', appId: 'app-123_test@domain' };
229
+ setAppConfig(config);
230
+
231
+ expect(getCurrentAppName()).toBe('APP-123_test@domain');
232
+ expect(getCurrentAppId()).toBe('app-123_test@domain');
233
+ }, TEST_TIMEOUT);
234
+ });
235
+ });