@jmruthers/pace-core 0.6.4 → 0.6.6

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 (387) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +5 -403
  3. package/core-usage-manifest.json +93 -0
  4. package/cursor-rules/00-pace-core-compliance.mdc +128 -26
  5. package/cursor-rules/01-standards-compliance.mdc +49 -8
  6. package/cursor-rules/02-project-structure.mdc +6 -0
  7. package/cursor-rules/03-solid-principles.mdc +2 -0
  8. package/cursor-rules/04-testing-standards.mdc +2 -0
  9. package/cursor-rules/05-bug-reports-and-features.mdc +2 -0
  10. package/cursor-rules/06-code-quality.mdc +2 -0
  11. package/cursor-rules/07-tech-stack-compliance.mdc +2 -0
  12. package/cursor-rules/08-markup-quality.mdc +52 -27
  13. package/cursor-rules/09-rbac-compliance.mdc +462 -0
  14. package/cursor-rules/10-error-handling-patterns.mdc +179 -0
  15. package/cursor-rules/11-performance-optimization.mdc +169 -0
  16. package/cursor-rules/12-ci-cd-integration.mdc +150 -0
  17. package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
  18. package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-2N_tqbfq.d.ts} +1 -1
  19. package/dist/DataTable-LRJL4IRV.js +15 -0
  20. package/dist/{PublicPageProvider-DEMpysFR.d.ts → PublicPageProvider-BBH6Vqg7.d.ts} +72 -139
  21. package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
  22. package/dist/api-Y4MQWOFW.js +4 -0
  23. package/dist/audit-MYQXYZFU.js +3 -0
  24. package/dist/{chunk-J36DSWQK.js → chunk-2HGJFNAH.js} +8 -28
  25. package/dist/{chunk-OEWDTMG7.js → chunk-3O3WHILE.js} +38 -121
  26. package/dist/{chunk-M43Y4SSO.js → chunk-3QC3KRHK.js} +1 -14
  27. package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
  28. package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
  29. package/dist/chunk-4T7OBVTU.js +62 -0
  30. package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
  31. package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
  32. package/dist/{chunk-NN6WWZ5U.js → chunk-7TYHROIV.js} +579 -563
  33. package/dist/{chunk-M7MPQISP.js → chunk-A55DK444.js} +9 -16
  34. package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
  35. package/dist/{chunk-L4OXEN46.js → chunk-BVP2BCJF.js} +2 -16
  36. package/dist/chunk-C7NSAPTL.js +1 -0
  37. package/dist/{chunk-YKRAFF5K.js → chunk-FENMYN2U.js} +73 -149
  38. package/dist/{chunk-AVMLPIM7.js → chunk-FTCRZOG2.js} +284 -432
  39. package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
  40. package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
  41. package/dist/{chunk-I6DAQMWX.js → chunk-LAZMKTTF.js} +930 -891
  42. package/dist/{chunk-5EC5MEWX.js → chunk-MAGBIDNS.js} +77 -222
  43. package/dist/chunk-MBADTM7L.js +64 -0
  44. package/dist/chunk-OHIK3MIO.js +994 -0
  45. package/dist/{chunk-6SOIHG6Z.js → chunk-S7DKJPLT.js} +115 -44
  46. package/dist/{chunk-FMUCXFII.js → chunk-SD6WQY43.js} +1 -5
  47. package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
  48. package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
  49. package/dist/{chunk-FFQEQTNW.js → chunk-UIYSCEV7.js} +134 -45
  50. package/dist/{chunk-3LPHPB62.js → chunk-ZFYPMX46.js} +271 -87
  51. package/dist/{chunk-7JPAB3T5.js → chunk-ZS5VO5JB.js} +1989 -1283
  52. package/dist/components.d.ts +6 -6
  53. package/dist/components.js +57 -267
  54. package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
  55. package/dist/eslint-rules/index.cjs +22 -0
  56. package/dist/eslint-rules/rules/compliance.cjs +348 -0
  57. package/dist/eslint-rules/rules/components.cjs +113 -0
  58. package/dist/eslint-rules/rules/imports.cjs +102 -0
  59. package/dist/eslint-rules/rules/rbac.cjs +790 -0
  60. package/dist/eslint-rules/utils/helpers.cjs +42 -0
  61. package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
  62. package/dist/hooks.d.ts +5 -5
  63. package/dist/hooks.js +62 -270
  64. package/dist/icons/index.d.ts +1 -0
  65. package/dist/icons/index.js +1 -0
  66. package/dist/index.d.ts +36 -26
  67. package/dist/index.js +87 -690
  68. package/dist/providers.d.ts +2 -2
  69. package/dist/providers.js +8 -35
  70. package/dist/rbac/eslint-rules.d.ts +46 -44
  71. package/dist/rbac/eslint-rules.js +7 -4
  72. package/dist/rbac/index.d.ts +124 -594
  73. package/dist/rbac/index.js +14 -207
  74. package/dist/styles/index.js +2 -12
  75. package/dist/theming/runtime.js +3 -19
  76. package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
  77. package/dist/{types-CkbwOr4Y.d.ts → types-B-K_5VnO.d.ts} +4 -0
  78. package/dist/types-t9H8qKRw.d.ts +55 -0
  79. package/dist/types.d.ts +1 -1
  80. package/dist/types.js +7 -94
  81. package/dist/{usePublicRouteParams-i3qtoBgg.d.ts → usePublicRouteParams-COZ28Mvq.d.ts} +9 -9
  82. package/dist/utils.d.ts +24 -117
  83. package/dist/utils.js +54 -392
  84. package/docs/README.md +16 -6
  85. package/docs/api/README.md +4 -402
  86. package/docs/api/modules.md +454 -930
  87. package/docs/api-reference/components.md +3 -1
  88. package/docs/api-reference/deprecated.md +31 -6
  89. package/docs/api-reference/rpc-functions.md +78 -3
  90. package/docs/best-practices/accessibility.md +6 -3
  91. package/docs/getting-started/cursor-rules.md +3 -23
  92. package/docs/getting-started/dependencies.md +650 -0
  93. package/docs/getting-started/installation-guide.md +20 -7
  94. package/docs/getting-started/quick-start.md +23 -12
  95. package/docs/implementation-guides/permission-enforcement.md +4 -0
  96. package/docs/rbac/MIGRATION_GUIDE.md +819 -0
  97. package/docs/rbac/RBAC_CONTRACT.md +724 -0
  98. package/docs/rbac/README.md +12 -3
  99. package/docs/rbac/edge-functions-guide.md +376 -0
  100. package/docs/rbac/secure-client-protection.md +0 -34
  101. package/docs/standards/00-pace-core-compliance.md +967 -0
  102. package/docs/standards/01-standards-compliance.md +188 -0
  103. package/docs/standards/02-project-structure.md +985 -0
  104. package/docs/standards/03-solid-principles.md +39 -0
  105. package/docs/standards/04-testing-standards.md +36 -0
  106. package/docs/standards/05-bug-reports-and-features.md +27 -0
  107. package/docs/standards/{04-code-style-standard.md → 06-code-quality.md} +2 -0
  108. package/docs/standards/07-tech-stack-compliance.md +30 -0
  109. package/docs/standards/08-markup-quality.md +345 -0
  110. package/docs/standards/{07-rbac-and-rls-standard.md → 09-rbac-compliance.md} +149 -54
  111. package/docs/standards/10-error-handling-patterns.md +401 -0
  112. package/docs/standards/11-performance-optimization.md +348 -0
  113. package/docs/standards/12-ci-cd-integration.md +370 -0
  114. package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +192 -0
  115. package/docs/standards/README.md +62 -33
  116. package/docs/troubleshooting/organisation-context-setup.md +42 -19
  117. package/eslint-config-pace-core.cjs +20 -4
  118. package/package.json +31 -21
  119. package/scripts/audit/audit-compliance.cjs +1295 -0
  120. package/scripts/audit/audit-components.cjs +260 -0
  121. package/scripts/audit/audit-dependencies.cjs +395 -0
  122. package/scripts/audit/audit-rbac.cjs +954 -0
  123. package/scripts/audit/audit-standards.cjs +1268 -0
  124. package/scripts/audit/index.cjs +1898 -194
  125. package/scripts/install-cursor-rules.cjs +259 -8
  126. package/scripts/validate-master.js +1 -1
  127. package/src/__tests__/fixtures/supabase.ts +1 -1
  128. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +1 -1
  129. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
  130. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
  131. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +3 -3
  132. package/src/__tests__/helpers/component-test-utils.tsx +1 -1
  133. package/src/__tests__/helpers/supabaseMock.ts +2 -2
  134. package/src/__tests__/public-recipe-view.test.ts +38 -9
  135. package/src/components/Button/Button.tsx +5 -1
  136. package/src/components/ContextSelector/ContextSelector.tsx +42 -39
  137. package/src/components/DataTable/__tests__/keyboard.test.tsx +15 -2
  138. package/src/components/DataTable/components/DataTableBody.tsx +55 -31
  139. package/src/components/DataTable/components/DataTableCore.tsx +186 -13
  140. package/src/components/DataTable/components/DataTableLayout.tsx +30 -5
  141. package/src/components/DataTable/components/EditFields.tsx +23 -3
  142. package/src/components/DataTable/components/EditableRow.tsx +7 -2
  143. package/src/components/DataTable/components/ImportModal.tsx +4 -6
  144. package/src/components/DataTable/components/RowComponent.tsx +12 -0
  145. package/src/components/DataTable/components/ViewRowModal.tsx +4 -4
  146. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +455 -96
  147. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +122 -58
  148. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
  149. package/src/components/DataTable/core/DataTableContext.tsx +1 -1
  150. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
  151. package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
  152. package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
  153. package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
  154. package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
  155. package/src/components/DataTable/types.ts +5 -0
  156. package/src/components/DateTimeField/DateTimeField.tsx +20 -20
  157. package/src/components/DateTimeField/README.md +5 -2
  158. package/src/components/Dialog/Dialog.test.tsx +361 -318
  159. package/src/components/Dialog/Dialog.tsx +1154 -323
  160. package/src/components/Dialog/index.ts +3 -3
  161. package/src/components/FileDisplay/FileDisplay.test.tsx +45 -2
  162. package/src/components/FileDisplay/FileDisplay.tsx +28 -22
  163. package/src/components/Form/Form.test.tsx +9 -10
  164. package/src/components/Form/Form.tsx +369 -9
  165. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +28 -28
  166. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +40 -54
  167. package/src/components/LoginForm/LoginForm.tsx +2 -2
  168. package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
  169. package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
  170. package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
  171. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
  172. package/src/components/PaceAppLayout/PaceAppLayout.tsx +30 -41
  173. package/src/components/PaceAppLayout/README.md +10 -9
  174. package/src/components/PaceAppLayout/test-setup.tsx +40 -31
  175. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
  176. package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
  177. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +61 -0
  178. package/src/components/PasswordChange/PasswordChangeForm.tsx +20 -13
  179. package/src/components/PublicLayout/PublicLayout.test.tsx +7 -3
  180. package/src/components/PublicLayout/PublicPageLayout.tsx +5 -8
  181. package/src/components/Select/Select.tsx +23 -21
  182. package/src/components/Select/types.ts +1 -1
  183. package/src/components/UserMenu/UserMenu.test.tsx +38 -6
  184. package/src/components/UserMenu/UserMenu.tsx +39 -34
  185. package/src/components/index.ts +3 -4
  186. package/src/eslint-rules/index.cjs +22 -0
  187. package/src/eslint-rules/rules/compliance.cjs +348 -0
  188. package/src/eslint-rules/rules/components.cjs +113 -0
  189. package/src/eslint-rules/rules/imports.cjs +102 -0
  190. package/src/eslint-rules/rules/rbac.cjs +790 -0
  191. package/src/eslint-rules/utils/helpers.cjs +42 -0
  192. package/src/eslint-rules/utils/manifest-loader.cjs +75 -0
  193. package/src/hooks/__tests__/hooks.integration.test.tsx +6 -8
  194. package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
  195. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
  196. package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
  197. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
  198. package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
  199. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
  200. package/src/hooks/public/usePublicEvent.ts +62 -190
  201. package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
  202. package/src/hooks/public/usePublicEventLogo.ts +19 -9
  203. package/src/hooks/useAppConfig.ts +26 -24
  204. package/src/hooks/useEventTheme.test.ts +211 -233
  205. package/src/hooks/useEventTheme.ts +19 -28
  206. package/src/hooks/useEvents.ts +11 -7
  207. package/src/hooks/useKeyboardShortcuts.ts +1 -1
  208. package/src/hooks/useOrganisationPermissions.ts +9 -11
  209. package/src/hooks/useOrganisations.ts +13 -7
  210. package/src/hooks/useQueryCache.ts +0 -1
  211. package/src/hooks/useSessionDraft.ts +380 -0
  212. package/src/hooks/useSessionRestoration.ts +3 -1
  213. package/src/icons/index.ts +27 -0
  214. package/src/index.ts +16 -1
  215. package/src/providers/OrganisationProvider.tsx +23 -14
  216. package/src/providers/services/EventServiceProvider.tsx +1 -24
  217. package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
  218. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -0
  219. package/src/rbac/README.md +20 -20
  220. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
  221. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
  222. package/src/rbac/adapters.tsx +7 -295
  223. package/src/rbac/api.test.ts +44 -56
  224. package/src/rbac/api.ts +10 -17
  225. package/src/rbac/cache-invalidation.ts +0 -1
  226. package/src/rbac/compliance/index.ts +10 -0
  227. package/src/rbac/compliance/pattern-detector.ts +553 -0
  228. package/src/rbac/compliance/runtime-compliance.ts +22 -0
  229. package/src/rbac/components/AccessDenied.tsx +150 -0
  230. package/src/rbac/components/NavigationGuard.tsx +12 -20
  231. package/src/rbac/components/PagePermissionGuard.tsx +4 -24
  232. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
  233. package/src/rbac/components/index.ts +3 -41
  234. package/src/rbac/eslint-rules.js +1 -1
  235. package/src/rbac/hooks/index.ts +0 -3
  236. package/src/rbac/hooks/permissions/index.ts +0 -3
  237. package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
  238. package/src/rbac/hooks/usePermissions.ts +0 -3
  239. package/src/rbac/hooks/useRBAC.test.ts +21 -3
  240. package/src/rbac/hooks/useRBAC.ts +4 -3
  241. package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
  242. package/src/rbac/hooks/useResolvedScope.ts +58 -140
  243. package/src/rbac/hooks/useResourcePermissions.test.ts +241 -60
  244. package/src/rbac/hooks/useResourcePermissions.ts +182 -63
  245. package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
  246. package/src/rbac/hooks/useRoleManagement.ts +147 -19
  247. package/src/rbac/hooks/useSecureSupabase.ts +4 -8
  248. package/src/rbac/index.ts +7 -9
  249. package/src/rbac/permissions.ts +17 -17
  250. package/src/rbac/utils/contextValidator.ts +45 -7
  251. package/src/services/AuthService.ts +132 -23
  252. package/src/services/EventService.ts +4 -97
  253. package/src/services/InactivityService.ts +155 -58
  254. package/src/services/OrganisationService.ts +7 -44
  255. package/src/services/__tests__/OrganisationService.test.ts +26 -8
  256. package/src/services/base/BaseService.ts +0 -3
  257. package/src/styles/core.css +4 -0
  258. package/src/types/database.generated.ts +4733 -3809
  259. package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
  260. package/src/utils/context/organisationContext.test.ts +13 -28
  261. package/src/utils/context/organisationContext.ts +21 -52
  262. package/src/utils/dynamic/dynamicUtils.ts +1 -1
  263. package/src/utils/file-reference/index.ts +39 -15
  264. package/src/utils/formatting/formatDateTime.test.ts +3 -2
  265. package/src/utils/formatting/formatTime.test.ts +3 -2
  266. package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
  267. package/src/utils/index.ts +4 -1
  268. package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
  269. package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
  270. package/src/utils/persistence/keyDerivation.ts +304 -0
  271. package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
  272. package/src/utils/security/secureStorage.ts +5 -5
  273. package/src/utils/storage/helpers.ts +3 -3
  274. package/src/utils/supabase/createBaseClient.ts +147 -0
  275. package/src/utils/timezone/timezone.test.ts +1 -2
  276. package/src/utils/timezone/timezone.ts +1 -1
  277. package/src/utils/validation/csrf.ts +4 -4
  278. package/cursor-rules/CHANGELOG.md +0 -119
  279. package/cursor-rules/README.md +0 -192
  280. package/dist/DataTable-E7YQZD7D.js +0 -175
  281. package/dist/DataTable-E7YQZD7D.js.map +0 -1
  282. package/dist/UnifiedAuthProvider-QPXO24B4.js +0 -18
  283. package/dist/UnifiedAuthProvider-QPXO24B4.js.map +0 -1
  284. package/dist/api-6LVZTHDS.js +0 -52
  285. package/dist/api-6LVZTHDS.js.map +0 -1
  286. package/dist/audit-V53FV5AG.js +0 -17
  287. package/dist/audit-V53FV5AG.js.map +0 -1
  288. package/dist/chunk-36LVWXB2.js +0 -227
  289. package/dist/chunk-36LVWXB2.js.map +0 -1
  290. package/dist/chunk-3LPHPB62.js.map +0 -1
  291. package/dist/chunk-5DRSZLL2.js.map +0 -1
  292. package/dist/chunk-5EC5MEWX.js.map +0 -1
  293. package/dist/chunk-63FOKYGO.js.map +0 -1
  294. package/dist/chunk-6SOIHG6Z.js.map +0 -1
  295. package/dist/chunk-7JPAB3T5.js.map +0 -1
  296. package/dist/chunk-ATKZM7RX.js +0 -2053
  297. package/dist/chunk-ATKZM7RX.js.map +0 -1
  298. package/dist/chunk-AVMLPIM7.js.map +0 -1
  299. package/dist/chunk-DGUM43GV.js.map +0 -1
  300. package/dist/chunk-E66EQZE6.js.map +0 -1
  301. package/dist/chunk-FFQEQTNW.js.map +0 -1
  302. package/dist/chunk-FMUCXFII.js.map +0 -1
  303. package/dist/chunk-G37KK66H.js.map +0 -1
  304. package/dist/chunk-I6DAQMWX.js.map +0 -1
  305. package/dist/chunk-J36DSWQK.js.map +0 -1
  306. package/dist/chunk-KQCRWDSA.js +0 -1
  307. package/dist/chunk-KQCRWDSA.js.map +0 -1
  308. package/dist/chunk-L4OXEN46.js.map +0 -1
  309. package/dist/chunk-LMC26NLJ.js +0 -84
  310. package/dist/chunk-LMC26NLJ.js.map +0 -1
  311. package/dist/chunk-M43Y4SSO.js.map +0 -1
  312. package/dist/chunk-M7MPQISP.js.map +0 -1
  313. package/dist/chunk-NN6WWZ5U.js.map +0 -1
  314. package/dist/chunk-OEWDTMG7.js.map +0 -1
  315. package/dist/chunk-PWLANIRT.js.map +0 -1
  316. package/dist/chunk-QXHPKYJV.js.map +0 -1
  317. package/dist/chunk-VBXEHIUJ.js.map +0 -1
  318. package/dist/chunk-YKRAFF5K.js.map +0 -1
  319. package/dist/chunk-ZSAAAMVR.js.map +0 -1
  320. package/dist/components.js.map +0 -1
  321. package/dist/contextValidator-OOPCLPZW.js +0 -9
  322. package/dist/contextValidator-OOPCLPZW.js.map +0 -1
  323. package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
  324. package/dist/hooks.js.map +0 -1
  325. package/dist/index.js.map +0 -1
  326. package/dist/providers.js.map +0 -1
  327. package/dist/rbac/eslint-rules.js.map +0 -1
  328. package/dist/rbac/index.js.map +0 -1
  329. package/dist/styles/index.js.map +0 -1
  330. package/dist/theming/runtime.js.map +0 -1
  331. package/dist/types.js.map +0 -1
  332. package/dist/utils.js.map +0 -1
  333. package/docs/standards/01-architecture-standard.md +0 -44
  334. package/docs/standards/02-api-and-rpc-standard.md +0 -39
  335. package/docs/standards/03-component-standard.md +0 -32
  336. package/docs/standards/05-security-standard.md +0 -44
  337. package/docs/standards/06-testing-and-docs-standard.md +0 -29
  338. package/docs/standards/pace-core-compliance.md +0 -432
  339. package/scripts/audit/core/checks/accessibility.cjs +0 -197
  340. package/scripts/audit/core/checks/api-usage.cjs +0 -191
  341. package/scripts/audit/core/checks/bundle.cjs +0 -142
  342. package/scripts/audit/core/checks/compliance.cjs +0 -2706
  343. package/scripts/audit/core/checks/config.cjs +0 -54
  344. package/scripts/audit/core/checks/coverage.cjs +0 -84
  345. package/scripts/audit/core/checks/dependencies.cjs +0 -994
  346. package/scripts/audit/core/checks/documentation.cjs +0 -268
  347. package/scripts/audit/core/checks/environment.cjs +0 -116
  348. package/scripts/audit/core/checks/error-handling.cjs +0 -340
  349. package/scripts/audit/core/checks/forms.cjs +0 -172
  350. package/scripts/audit/core/checks/heuristics.cjs +0 -68
  351. package/scripts/audit/core/checks/hooks.cjs +0 -334
  352. package/scripts/audit/core/checks/imports.cjs +0 -244
  353. package/scripts/audit/core/checks/performance.cjs +0 -325
  354. package/scripts/audit/core/checks/routes.cjs +0 -117
  355. package/scripts/audit/core/checks/state.cjs +0 -130
  356. package/scripts/audit/core/checks/structure.cjs +0 -65
  357. package/scripts/audit/core/checks/style.cjs +0 -584
  358. package/scripts/audit/core/checks/testing.cjs +0 -122
  359. package/scripts/audit/core/checks/typescript.cjs +0 -61
  360. package/scripts/audit/core/scanner.cjs +0 -199
  361. package/scripts/audit/core/utils.cjs +0 -137
  362. package/scripts/audit/reporters/console.cjs +0 -151
  363. package/scripts/audit/reporters/json.cjs +0 -54
  364. package/scripts/audit/reporters/markdown.cjs +0 -124
  365. package/scripts/audit-consuming-app.cjs +0 -86
  366. package/src/eslint-rules/pace-core-compliance.cjs +0 -510
  367. package/src/eslint-rules/pace-core-compliance.js +0 -638
  368. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
  369. package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
  370. package/src/rbac/components/NavigationProvider.test.tsx +0 -481
  371. package/src/rbac/components/NavigationProvider.tsx +0 -345
  372. package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
  373. package/src/rbac/components/PagePermissionProvider.tsx +0 -279
  374. package/src/rbac/components/PermissionEnforcer.tsx +0 -312
  375. package/src/rbac/components/RoleBasedRouter.tsx +0 -440
  376. package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
  377. package/src/rbac/components/SecureDataProvider.tsx +0 -339
  378. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
  379. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
  380. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
  381. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
  382. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
  383. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
  384. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
  385. package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
  386. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
  387. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
@@ -1,555 +0,0 @@
1
- /**
2
- * @file Enhanced Navigation Menu Tests
3
- * @package @jmruthers/pace-core
4
- * @module RBAC/Components/EnhancedNavigationMenu
5
- * @since 2.0.0
6
- *
7
- * Comprehensive tests for the EnhancedNavigationMenu component covering all critical functionality.
8
- */
9
-
10
- import React from 'react';
11
- import { render, screen, waitFor, fireEvent } from '@testing-library/react';
12
- import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
13
- import { EnhancedNavigationMenu } from './EnhancedNavigationMenu';
14
- import { useNavigationPermissions, NavigationItem } from './NavigationProvider';
15
- import { UUID, Scope, Permission } from '../types';
16
-
17
- // Mock the navigation provider
18
- vi.mock('./NavigationProvider', () => ({
19
- useNavigationPermissions: vi.fn(),
20
- NavigationProvider: ({ children }: { children: React.ReactNode }) => <div>{children}</div>
21
- }));
22
-
23
- // Mock the navigation guard
24
- vi.mock('./NavigationGuard', () => ({
25
- default: ({ children, navigationItem, onDenied }: {
26
- children: React.ReactNode;
27
- navigationItem: NavigationItem;
28
- onDenied?: (item: NavigationItem) => void;
29
- }) => {
30
- // Simulate NavigationGuard behavior - call onDenied if user doesn't have permission
31
- React.useEffect(() => {
32
- if (onDenied) {
33
- onDenied(navigationItem);
34
- }
35
- }, [onDenied, navigationItem]);
36
-
37
- return <div data-testid={`nav-guard-${navigationItem.id}`}>{children}</div>;
38
- }
39
- }));
40
-
41
- // Mock data
42
- const mockScope: Scope = {
43
- organisationId: 'org-123' as UUID,
44
- eventId: 'event-456',
45
- appId: 'app-789' as UUID
46
- };
47
-
48
- const mockNavigationItems: NavigationItem[] = [
49
- {
50
- id: 'dashboard',
51
- label: 'Dashboard',
52
- path: '/dashboard',
53
- permissions: ['read:dashboard'] as Permission[],
54
- pageId: 'page-dashboard',
55
- meta: {
56
- icon: 'dashboard-icon',
57
- description: 'Main dashboard',
58
- order: 1
59
- }
60
- },
61
- {
62
- id: 'users',
63
- label: 'Users',
64
- path: '/users',
65
- permissions: ['read:users'] as Permission[],
66
- pageId: 'page-users',
67
- meta: {
68
- icon: 'users-icon',
69
- description: 'User management',
70
- order: 2
71
- }
72
- },
73
- {
74
- id: 'admin',
75
- label: 'Admin',
76
- path: '/admin',
77
- permissions: ['update:admin'] as Permission[],
78
- pageId: 'page-admin',
79
- accessLevel: 'admin',
80
- meta: {
81
- icon: 'admin-icon',
82
- description: 'Administration',
83
- order: 3
84
- }
85
- }
86
- ];
87
-
88
- describe('EnhancedNavigationMenu', () => {
89
- beforeEach(() => {
90
- vi.clearAllMocks();
91
- vi.mocked(useNavigationPermissions).mockReturnValue({
92
- hasNavigationPermission: vi.fn().mockReturnValue(true),
93
- getNavigationPermissions: vi.fn().mockReturnValue({}),
94
- getFilteredNavigationItems: vi.fn().mockImplementation((items) => items), // Return items as-is by default
95
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
96
- clearNavigationAccessHistory: vi.fn(),
97
- isEnabled: true,
98
- isStrictMode: true,
99
- isAuditLogEnabled: true
100
- } as any);
101
- });
102
-
103
- describe('Rendering', () => {
104
- it('renders navigation items correctly', () => {
105
- render(
106
- <EnhancedNavigationMenu items={mockNavigationItems} />
107
- );
108
-
109
- expect(screen.getByText('Dashboard')).toBeInTheDocument();
110
- expect(screen.getByText('Users')).toBeInTheDocument();
111
- expect(screen.getByText('Admin')).toBeInTheDocument();
112
- });
113
-
114
- it('renders with custom className', () => {
115
- const { container } = render(
116
- <EnhancedNavigationMenu
117
- items={mockNavigationItems}
118
- className="custom-nav-menu"
119
- />
120
- );
121
-
122
- expect(container.firstChild).toHaveClass('custom-nav-menu');
123
- });
124
-
125
- it('renders with custom item className', () => {
126
- render(
127
- <EnhancedNavigationMenu
128
- items={mockNavigationItems}
129
- itemClassName="custom-nav-item"
130
- />
131
- );
132
-
133
- const navItems = screen.getAllByRole('button');
134
- navItems.forEach(item => {
135
- expect(item).toHaveClass('custom-nav-item');
136
- });
137
- });
138
-
139
- it('renders with custom active item className', () => {
140
- render(
141
- <EnhancedNavigationMenu
142
- items={mockNavigationItems}
143
- activeItemClassName="custom-active-item"
144
- activePath="/dashboard"
145
- />
146
- );
147
-
148
- const activeItem = screen.getByText('Dashboard').closest('button');
149
- expect(activeItem).toHaveClass('custom-active-item');
150
- });
151
-
152
- it('renders with custom disabled item className', () => {
153
- vi.mocked(useNavigationPermissions).mockReturnValue({
154
- hasNavigationPermission: vi.fn().mockReturnValue(false),
155
- getNavigationPermissions: vi.fn().mockReturnValue({}),
156
- getFilteredNavigationItems: vi.fn().mockReturnValue(mockNavigationItems),
157
- validateNavigationItem: vi.fn().mockReturnValue(true),
158
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
159
- clearNavigationAccessHistory: vi.fn(),
160
- isEnabled: true,
161
- isStrictMode: true,
162
- isAuditLogEnabled: true
163
- } as any);
164
-
165
- render(
166
- <EnhancedNavigationMenu
167
- items={mockNavigationItems}
168
- disabledItemClassName="custom-disabled-item"
169
- />
170
- );
171
-
172
- const buttons = screen.getAllByRole('button');
173
- buttons.forEach(button => {
174
- expect(button).toHaveClass('custom-disabled-item');
175
- });
176
- });
177
- });
178
-
179
- describe('Permission Filtering', () => {
180
- it('filters navigation items based on permissions', () => {
181
- const filteredItems = [mockNavigationItems[0], mockNavigationItems[1]]; // Only dashboard and users
182
- vi.mocked(useNavigationPermissions).mockReturnValue({
183
- hasNavigationPermission: vi.fn().mockReturnValue(true),
184
- getNavigationPermissions: vi.fn().mockReturnValue({}),
185
- getFilteredNavigationItems: vi.fn().mockReturnValue(filteredItems),
186
- validateNavigationItem: vi.fn().mockReturnValue(true),
187
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
188
- clearNavigationAccessHistory: vi.fn(),
189
- isEnabled: true,
190
- isStrictMode: true,
191
- isAuditLogEnabled: true
192
- } as any);
193
-
194
- render(
195
- <EnhancedNavigationMenu items={mockNavigationItems} />
196
- );
197
-
198
- expect(screen.getByText('Dashboard')).toBeInTheDocument();
199
- expect(screen.getByText('Users')).toBeInTheDocument();
200
- expect(screen.queryByText('Admin')).not.toBeInTheDocument();
201
- });
202
-
203
- it('hides unauthorized items when hideUnauthorizedItems is true', () => {
204
- vi.mocked(useNavigationPermissions).mockReturnValue({
205
- hasNavigationPermission: vi.fn()
206
- .mockReturnValueOnce(true) // dashboard
207
- .mockReturnValueOnce(true) // users
208
- .mockReturnValueOnce(false), // admin
209
- getNavigationPermissions: vi.fn().mockReturnValue({}),
210
- getFilteredNavigationItems: vi.fn().mockImplementation((items) =>
211
- items.filter(item => item.id !== 'admin') // Filter out admin item
212
- ),
213
- validateNavigationItem: vi.fn().mockReturnValue(true),
214
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
215
- clearNavigationAccessHistory: vi.fn(),
216
- isEnabled: true,
217
- isStrictMode: true,
218
- isAuditLogEnabled: true
219
- } as any);
220
-
221
- render(
222
- <EnhancedNavigationMenu
223
- items={mockNavigationItems}
224
- hideUnauthorizedItems={true}
225
- />
226
- );
227
-
228
- expect(screen.getByText('Dashboard')).toBeInTheDocument();
229
- expect(screen.getByText('Users')).toBeInTheDocument();
230
- expect(screen.queryByText('Admin')).not.toBeInTheDocument();
231
- });
232
-
233
- it('shows unauthorized items as disabled when hideUnauthorizedItems is false', () => {
234
- vi.mocked(useNavigationPermissions).mockReturnValue({
235
- hasNavigationPermission: vi.fn()
236
- .mockReturnValueOnce(true) // dashboard
237
- .mockReturnValueOnce(true) // users
238
- .mockReturnValueOnce(false), // admin
239
- getNavigationPermissions: vi.fn().mockReturnValue({}),
240
- getFilteredNavigationItems: vi.fn().mockReturnValue(mockNavigationItems),
241
- validateNavigationItem: vi.fn().mockReturnValue(true),
242
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
243
- clearNavigationAccessHistory: vi.fn(),
244
- isEnabled: true,
245
- isStrictMode: true,
246
- isAuditLogEnabled: true
247
- } as any);
248
-
249
- render(
250
- <EnhancedNavigationMenu
251
- items={mockNavigationItems}
252
- hideUnauthorizedItems={false}
253
- />
254
- );
255
-
256
- expect(screen.getByText('Dashboard')).toBeInTheDocument();
257
- expect(screen.getByText('Users')).toBeInTheDocument();
258
- expect(screen.getByText('Admin')).toBeInTheDocument();
259
- });
260
- });
261
-
262
- describe('Custom Rendering', () => {
263
- it('uses custom render function for navigation items', () => {
264
- const customRenderItem = vi.fn((item: NavigationItem, isAuthorized: boolean) => (
265
- <div key={item.id} data-testid={`custom-${item.id}`}>
266
- {item.label} - {isAuthorized ? 'Authorized' : 'Unauthorized'}
267
- </div>
268
- ));
269
-
270
- render(
271
- <EnhancedNavigationMenu
272
- items={mockNavigationItems}
273
- renderItem={customRenderItem}
274
- />
275
- );
276
-
277
- expect(customRenderItem).toHaveBeenCalledTimes(3);
278
- expect(screen.getByTestId('custom-dashboard')).toBeInTheDocument();
279
- expect(screen.getByTestId('custom-users')).toBeInTheDocument();
280
- expect(screen.getByTestId('custom-admin')).toBeInTheDocument();
281
- });
282
-
283
- it('passes correct parameters to custom render function', () => {
284
- const customRenderItem = vi.fn((item: NavigationItem, isAuthorized: boolean) => (
285
- <div key={item.id}>{item.label}</div>
286
- ));
287
-
288
- render(
289
- <EnhancedNavigationMenu
290
- items={mockNavigationItems}
291
- renderItem={customRenderItem}
292
- />
293
- );
294
-
295
- expect(customRenderItem).toHaveBeenCalledWith(mockNavigationItems[0], true);
296
- expect(customRenderItem).toHaveBeenCalledWith(mockNavigationItems[1], true);
297
- expect(customRenderItem).toHaveBeenCalledWith(mockNavigationItems[2], true);
298
- });
299
- });
300
-
301
- describe('Event Handling', () => {
302
- it('calls onItemClick when navigation item is clicked', () => {
303
- const onItemClick = vi.fn();
304
-
305
- render(
306
- <EnhancedNavigationMenu
307
- items={mockNavigationItems}
308
- onItemClick={onItemClick}
309
- />
310
- );
311
-
312
- const dashboardLink = screen.getByText('Dashboard').closest('button');
313
- fireEvent.click(dashboardLink!);
314
-
315
- expect(onItemClick).toHaveBeenCalledWith(mockNavigationItems[0]);
316
- });
317
-
318
- it('calls onNavigationAccess when navigation access is attempted', () => {
319
- const onNavigationAccess = vi.fn();
320
- vi.mocked(useNavigationPermissions).mockReturnValue({
321
- hasNavigationPermission: vi.fn().mockReturnValue(true),
322
- getNavigationPermissions: vi.fn().mockReturnValue({}),
323
- getFilteredNavigationItems: vi.fn().mockReturnValue(mockNavigationItems),
324
- validateNavigationItem: vi.fn().mockReturnValue(true),
325
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
326
- clearNavigationAccessHistory: vi.fn(),
327
- isEnabled: true,
328
- isStrictMode: true,
329
- isAuditLogEnabled: true
330
- } as any);
331
-
332
- render(
333
- <EnhancedNavigationMenu
334
- items={mockNavigationItems}
335
- onNavigationAccess={onNavigationAccess}
336
- />
337
- );
338
-
339
- // Click on a navigation item to trigger the event
340
- const dashboardButton = screen.getByText('Dashboard').closest('button');
341
- fireEvent.click(dashboardButton!);
342
-
343
- expect(onNavigationAccess).toHaveBeenCalled();
344
- });
345
-
346
- it('calls onStrictModeViolation when strict mode is violated', () => {
347
- const onStrictModeViolation = vi.fn();
348
- vi.mocked(useNavigationPermissions).mockReturnValue({
349
- hasNavigationPermission: vi.fn().mockReturnValue(false),
350
- getNavigationPermissions: vi.fn().mockReturnValue({}),
351
- getFilteredNavigationItems: vi.fn().mockReturnValue(mockNavigationItems),
352
- validateNavigationItem: vi.fn().mockReturnValue(true),
353
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
354
- clearNavigationAccessHistory: vi.fn(),
355
- isEnabled: true,
356
- isStrictMode: true,
357
- isAuditLogEnabled: true
358
- } as any);
359
-
360
- render(
361
- <EnhancedNavigationMenu
362
- items={mockNavigationItems}
363
- onStrictModeViolation={onStrictModeViolation}
364
- strictMode={true}
365
- />
366
- );
367
-
368
- // The NavigationGuard should be configured with the onStrictModeViolation handler
369
- // Since the user doesn't have permission, the button should be disabled
370
- const dashboardButton = screen.getByText('Dashboard').closest('button');
371
- expect(dashboardButton).toBeDisabled();
372
-
373
- // The NavigationGuard should call onStrictModeViolation when it detects unauthorized access
374
- // This happens during the component render, not on click
375
- expect(onStrictModeViolation).toHaveBeenCalled();
376
- });
377
- });
378
-
379
- describe('Loading and Error States', () => {
380
- it('renders loading state when permissions are being checked', () => {
381
- vi.mocked(useNavigationPermissions).mockReturnValue({
382
- hasNavigationPermission: vi.fn().mockReturnValue(false),
383
- getNavigationPermissions: vi.fn().mockReturnValue({}),
384
- getFilteredNavigationItems: vi.fn().mockReturnValue([]),
385
- validateNavigationItem: vi.fn().mockReturnValue(true),
386
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
387
- clearNavigationAccessHistory: vi.fn(),
388
- isEnabled: true,
389
- isStrictMode: true,
390
- isAuditLogEnabled: true
391
- } as any);
392
-
393
- render(
394
- <EnhancedNavigationMenu
395
- items={mockNavigationItems}
396
- />
397
- );
398
-
399
- // When no items are returned, the component renders an empty nav
400
- expect(screen.getByRole('navigation')).toBeInTheDocument();
401
- });
402
-
403
- it('renders error state when permission check fails', () => {
404
- vi.mocked(useNavigationPermissions).mockReturnValue({
405
- hasNavigationPermission: vi.fn().mockImplementation(() => {
406
- throw new Error('Permission check failed');
407
- }),
408
- getNavigationPermissions: vi.fn().mockReturnValue({}),
409
- getFilteredNavigationItems: vi.fn().mockReturnValue([]),
410
- validateNavigationItem: vi.fn().mockReturnValue(true),
411
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
412
- clearNavigationAccessHistory: vi.fn(),
413
- isEnabled: true,
414
- isStrictMode: true,
415
- isAuditLogEnabled: true
416
- } as any);
417
-
418
- render(
419
- <EnhancedNavigationMenu
420
- items={mockNavigationItems}
421
- />
422
- );
423
-
424
- // When permission check fails, the component should still render
425
- expect(screen.getByRole('navigation')).toBeInTheDocument();
426
- });
427
-
428
- it('renders empty state when no navigation items are available', () => {
429
- vi.mocked(useNavigationPermissions).mockReturnValue({
430
- hasNavigationPermission: vi.fn().mockReturnValue(false),
431
- getNavigationPermissions: vi.fn().mockReturnValue({}),
432
- getFilteredNavigationItems: vi.fn().mockReturnValue([]),
433
- validateNavigationItem: vi.fn().mockReturnValue(true),
434
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
435
- clearNavigationAccessHistory: vi.fn(),
436
- isEnabled: true,
437
- isStrictMode: true,
438
- isAuditLogEnabled: true
439
- } as any);
440
-
441
- render(
442
- <EnhancedNavigationMenu
443
- items={[]}
444
- />
445
- );
446
-
447
- // When no items are provided, the component renders an empty nav
448
- expect(screen.getByRole('navigation')).toBeInTheDocument();
449
- });
450
- });
451
-
452
- describe('Accessibility', () => {
453
- it('renders navigation with proper ARIA attributes', () => {
454
- render(
455
- <EnhancedNavigationMenu
456
- items={mockNavigationItems}
457
- />
458
- );
459
-
460
- const nav = screen.getByRole('navigation');
461
- expect(nav).toBeInTheDocument();
462
- });
463
-
464
- it('renders navigation items with proper accessibility attributes', () => {
465
- render(
466
- <EnhancedNavigationMenu items={mockNavigationItems} />
467
- );
468
-
469
- const buttons = screen.getAllByRole('button');
470
- buttons.forEach(button => {
471
- expect(button).not.toBeDisabled();
472
- });
473
- });
474
-
475
- it('handles keyboard navigation correctly', () => {
476
- const onItemClick = vi.fn();
477
-
478
- render(
479
- <EnhancedNavigationMenu
480
- items={mockNavigationItems}
481
- onItemClick={onItemClick}
482
- />
483
- );
484
-
485
- const dashboardLink = screen.getByText('Dashboard').closest('button');
486
- fireEvent.click(dashboardLink!);
487
-
488
- expect(onItemClick).toHaveBeenCalledWith(mockNavigationItems[0]);
489
- });
490
- });
491
-
492
- describe('Performance', () => {
493
- it('memoizes filtered navigation items', () => {
494
- const getFilteredNavigationItems = vi.fn().mockReturnValue(mockNavigationItems);
495
- vi.mocked(useNavigationPermissions).mockReturnValue({
496
- hasNavigationPermission: vi.fn().mockReturnValue(true),
497
- getNavigationPermissions: vi.fn().mockReturnValue({}),
498
- getFilteredNavigationItems,
499
- validateNavigationItem: vi.fn().mockReturnValue(true),
500
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
501
- clearNavigationAccessHistory: vi.fn(),
502
- isEnabled: true,
503
- isStrictMode: true,
504
- isAuditLogEnabled: true
505
- } as any);
506
-
507
- const { rerender } = render(
508
- <EnhancedNavigationMenu items={mockNavigationItems} />
509
- );
510
-
511
- const initialCallCount = getFilteredNavigationItems.mock.calls.length;
512
-
513
- // Re-render with same props
514
- rerender(
515
- <EnhancedNavigationMenu items={mockNavigationItems} />
516
- );
517
-
518
- // Should not call filterNavigationItems again due to memoization
519
- expect(getFilteredNavigationItems).toHaveBeenCalledTimes(initialCallCount);
520
- });
521
- });
522
-
523
- describe('Integration with NavigationProvider', () => {
524
- it('integrates with useNavigationPermissions hook', () => {
525
- render(
526
- <EnhancedNavigationMenu items={mockNavigationItems} />
527
- );
528
-
529
- expect(vi.mocked(useNavigationPermissions)).toHaveBeenCalled();
530
- });
531
-
532
- it('uses filtered navigation items from provider', () => {
533
- const filteredItems = [mockNavigationItems[0]];
534
- vi.mocked(useNavigationPermissions).mockReturnValue({
535
- hasNavigationPermission: vi.fn().mockReturnValue(true),
536
- getNavigationPermissions: vi.fn().mockReturnValue({}),
537
- getFilteredNavigationItems: vi.fn().mockReturnValue(filteredItems),
538
- validateNavigationItem: vi.fn().mockReturnValue(true),
539
- getNavigationAccessHistory: vi.fn().mockReturnValue([]),
540
- clearNavigationAccessHistory: vi.fn(),
541
- isEnabled: true,
542
- isStrictMode: true,
543
- isAuditLogEnabled: true
544
- } as any);
545
-
546
- render(
547
- <EnhancedNavigationMenu items={mockNavigationItems} />
548
- );
549
-
550
- expect(screen.getByText('Dashboard')).toBeInTheDocument();
551
- expect(screen.queryByText('Users')).not.toBeInTheDocument();
552
- expect(screen.queryByText('Admin')).not.toBeInTheDocument();
553
- });
554
- });
555
- });