@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.
- package/audit-tool/audits/02-project-structure.cjs +62 -0
- package/audit-tool/audits/03-architecture.cjs +145 -19
- package/audit-tool/audits/04-code-quality.cjs +86 -1
- package/audit-tool/audits/06-security-rbac.cjs +109 -11
- package/cursor-rules/02-project-structure.mdc +2 -26
- package/cursor-rules/05-styling.mdc +84 -6
- package/cursor-rules/06-security-rbac.mdc +124 -1
- package/dist/{DataTable-SOAFXIWY.js → DataTable-SAXFG4XI.js} +11 -13
- package/dist/{AuthService-DmfO5rGS.d.ts → InactivityServiceProvider-DHryoh6K.d.ts} +24 -249
- package/dist/UnifiedAuthProvider-BBD2PS3Q.js +7 -0
- package/dist/{UnifiedAuthProvider-CKvHP1MK.d.ts → UnifiedAuthProvider-CiBAl9-s.d.ts} +34 -22
- package/dist/{api-7P7DI652.js → api-F47QJ7FX.js} +3 -3
- package/dist/assets/app-icons/admin_favicon.svg +462 -0
- package/dist/assets/app-icons/base_favicon.svg +85 -0
- package/dist/assets/app-icons/cake_favicon.svg +68 -0
- package/dist/assets/app-icons/core_favicon.svg +256 -0
- package/dist/assets/app-icons/gear_favicon.svg +91 -0
- package/dist/assets/app-icons/medi_favicon.svg +92 -0
- package/dist/assets/app-icons/mint_favicon.svg +83 -0
- package/dist/assets/app-icons/pace_favicon.svg +49 -0
- package/dist/assets/app-icons/pump_favicon.svg +68 -0
- package/dist/assets/app-icons/seed_favicon.svg +91 -0
- package/dist/assets/app-icons/team_favicon.svg +67 -0
- package/dist/assets/app-icons/trac_favicon.svg +112 -0
- package/dist/assets/app-icons/trip_favicon.svg +102 -0
- package/dist/audit-Z6ZZBWLU.js +3 -0
- package/dist/chunk-3GWSPISD.js +61 -0
- package/dist/{chunk-4DDCYDQ3.js → chunk-66R6RLUZ.js} +12 -27
- package/dist/{chunk-FYHN4DD5.js → chunk-7YDC7LMU.js} +80 -8
- package/dist/{chunk-S7DKJPLT.js → chunk-BCTXBU6U.js} +22 -17
- package/dist/{chunk-TTRFSOKR.js → chunk-BTHN5MKC.js} +4 -4
- package/dist/{chunk-A3W6LW53.js → chunk-DDMPHZ3D.js} +6 -18
- package/dist/{chunk-MPBLMWVR.js → chunk-FBZ7U3ID.js} +140 -92
- package/dist/chunk-FN52B75D.js +246 -0
- package/dist/{chunk-5W2A3DRC.js → chunk-JJEYZ3DX.js} +5 -4
- package/dist/chunk-KPYQWGFQ.js +183 -0
- package/dist/{chunk-C7ZQ5O4C.js → chunk-KSNLMI7N.js} +3 -3
- package/dist/chunk-KYURMOQM.js +977 -0
- package/dist/{chunk-LX6U42O3.js → chunk-LNHFAF4X.js} +160 -58
- package/dist/{chunk-J2U36LHD.js → chunk-MPY44PWB.js} +620 -627
- package/dist/{chunk-AHU7G2R5.js → chunk-NIU6DPQV.js} +10 -6
- package/dist/{chunk-HF6O3O37.js → chunk-RMLY6KB5.js} +1 -1
- package/dist/{chunk-6GLLNA6U.js → chunk-SACF5YSM.js} +1 -1
- package/dist/{chunk-5HNSDQWH.js → chunk-TFIPNIPE.js} +865 -532
- package/dist/{chunk-OJ4SKRSV.js → chunk-UZNAFKGW.js} +25 -5
- package/dist/chunk-W46INAVW.js +1216 -0
- package/dist/chunk-X5EAU5G7.js +793 -0
- package/dist/{chunk-T5CVK4R3.js → chunk-Y4PF6HIM.js} +110 -64
- package/dist/components.d.ts +8 -86
- package/dist/components.js +21 -55
- package/dist/eslint-rules/rules/05-styling.cjs +507 -0
- package/dist/eslint-rules/rules/06-security-rbac.cjs +10 -0
- package/dist/{event-CW5YB_2p.d.ts → event-WTAQuGcq.d.ts} +1 -1
- package/dist/{functions-lBy5L2ry.d.ts → functions-DH45k8ec.d.ts} +1 -1
- package/dist/hooks.d.ts +11 -10
- package/dist/hooks.js +69 -44
- package/dist/index.d.ts +379 -31
- package/dist/index.js +46 -32
- package/dist/papaparseLoader-WG2UXQ22.js +7 -0
- package/dist/providers.d.ts +28 -14
- package/dist/providers.js +5 -5
- package/dist/rbac/eslint-rules.js +2 -2
- package/dist/rbac/index.d.ts +57 -213
- package/dist/rbac/index.js +11 -11
- package/dist/theming/runtime.d.ts +9 -3
- package/dist/theming/runtime.js +2 -2
- package/dist/{timezone-0AyangqX.d.ts → timezone-K-ptz3HO.d.ts} +21 -22
- package/dist/{types-t9H8qKRw.d.ts → types-BE2sEHKd.d.ts} +1 -1
- package/dist/{types-BeoeWV5I.d.ts → types-CvOPXWWZ.d.ts} +6 -5
- package/dist/{types-DXstZpNI.d.ts → types-D05dCGma.d.ts} +56 -149
- package/dist/types-Dr8sNhER.d.ts +50 -0
- package/dist/types.d.ts +4 -4
- package/dist/{PublicPageProvider-CIGSujI2.d.ts → usePublicPageContext-vxBlEHO9.d.ts} +294 -151
- package/dist/{usePublicRouteParams-DQLrDqDb.d.ts → usePublicRouteParams-G3Ks53mk.d.ts} +7 -6
- package/dist/utils.d.ts +300 -136
- package/dist/utils.js +42 -41
- package/dist/{validation-643vUDZW.d.ts → validation-g5n0hDkh.d.ts} +2 -2
- package/docs/api/modules.md +542 -549
- package/docs/api-reference/components.md +5 -5
- package/docs/implementation-guides/data-tables.md +190 -8
- package/docs/rbac/RBAC_CONTRACT.md +0 -12
- package/docs/standards/2-project-structure-standards.md +12 -74
- package/docs/standards/6-security-rbac-standards.md +222 -7
- package/docs/standards/7-api-tech-stack-standards.md +91 -3
- package/docs/testing/README.md +10 -0
- package/docs/testing/test-setup-for-consumers.md +914 -0
- package/eslint-config-pace-core.cjs +4 -0
- package/package.json +1 -1
- package/scripts/eslint-audit.cjs +110 -11
- package/src/__mocks__/lucide-react.ts +0 -2
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +0 -2
- package/src/__tests__/index.test.ts +532 -0
- package/src/__tests__/integration/UserProfile.test.tsx +1 -1
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +10 -8
- package/src/__tests__/rls-policies.test.ts +3 -2
- package/src/assets/app-icons/admin_favicon.svg +462 -0
- package/src/assets/app-icons/base_favicon.svg +85 -0
- package/src/assets/app-icons/cake_favicon.svg +68 -0
- package/src/assets/app-icons/core_favicon.svg +256 -0
- package/src/assets/app-icons/gear_favicon.svg +91 -0
- package/src/assets/app-icons/index.ts +83 -0
- package/src/assets/app-icons/medi_favicon.svg +92 -0
- package/src/assets/app-icons/mint_favicon.svg +83 -0
- package/src/assets/app-icons/pace_favicon.svg +49 -0
- package/src/assets/app-icons/pump_favicon.svg +68 -0
- package/src/assets/app-icons/seed_favicon.svg +91 -0
- package/src/assets/app-icons/team_favicon.svg +67 -0
- package/src/assets/app-icons/trac_favicon.svg +112 -0
- package/src/assets/app-icons/trip_favicon.svg +102 -0
- package/src/components/AddressField/AddressField.test.tsx +378 -3
- package/src/components/AddressField/AddressField.tsx +2 -2
- package/src/components/AddressField/types.ts +2 -2
- package/src/components/Alert/Alert.test.tsx +35 -25
- package/src/components/Alert/Alert.tsx +8 -8
- package/src/components/AppSwitcher/AppSwitcher.test.tsx +1250 -0
- package/src/components/AppSwitcher/AppSwitcher.tsx +315 -0
- package/src/components/Avatar/Avatar.test.tsx +11 -1
- package/src/components/Avatar/Avatar.tsx +3 -2
- package/src/components/Badge/Badge.test.tsx +11 -1
- package/src/components/Button/Button.test.tsx +13 -3
- package/src/components/Calendar/Calendar.test.tsx +523 -131
- package/src/components/Calendar/Calendar.tsx +107 -488
- package/src/components/Card/Card.test.tsx +220 -249
- package/src/components/Checkbox/Checkbox.test.tsx +58 -174
- package/src/components/ContextSelector/ContextSelector.tsx +3 -3
- package/src/components/ContextSelector/__tests__/ContextSelector.test.tsx +360 -0
- package/src/components/DataTable/DataTable.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -1
- package/src/components/DataTable/__tests__/DataTable.export.test.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +1 -1
- package/src/components/DataTable/__tests__/DataTable.select-label-display.test.tsx +16 -14
- package/src/components/DataTable/__tests__/DataTable.test.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +1 -1
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +76 -580
- package/src/components/DataTable/__tests__/README.md +1 -1
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +1 -1
- package/src/components/DataTable/__tests__/keyboard.test.tsx +1 -1
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +1 -3
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +0 -6
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +14 -6
- package/src/components/DataTable/components/ActionButtons.tsx +9 -4
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +3 -3
- package/src/components/DataTable/components/ColumnFilter.tsx +2 -7
- package/src/components/DataTable/components/DataTableCore.tsx +44 -52
- package/src/components/DataTable/components/DataTableLayout.tsx +37 -26
- package/src/components/DataTable/components/DataTableModals.tsx +118 -30
- package/src/components/DataTable/components/DataTableToolbar.tsx +2 -2
- package/src/components/DataTable/components/EditFields.tsx +6 -47
- package/src/components/DataTable/components/EditableRow.tsx +8 -8
- package/src/components/DataTable/components/EmptyState.tsx +6 -3
- package/src/components/DataTable/components/FilterRow.tsx +18 -11
- package/src/components/DataTable/components/GroupingDropdown.tsx +0 -1
- package/src/components/DataTable/components/ImportModal.tsx +305 -133
- package/src/components/DataTable/components/LoadingState.tsx +2 -2
- package/src/components/DataTable/components/PaginationControls.tsx +0 -4
- package/src/components/DataTable/components/RowComponent.tsx +42 -22
- package/src/components/DataTable/components/UnifiedTableBody.tsx +52 -12
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +51 -463
- package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +122 -116
- package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +40 -68
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +9 -137
- package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.test.tsx +57 -17
- package/src/components/DataTable/components/__tests__/DataTableCore.test.tsx +792 -0
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +24 -65
- package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +467 -0
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +8 -125
- package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +528 -56
- package/src/components/DataTable/components/__tests__/EditFields.test.tsx +526 -0
- package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +1 -68
- package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +8 -25
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +3 -62
- package/src/components/DataTable/components/__tests__/GroupingDropdown.test.tsx +9 -14
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +50 -186
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +39 -97
- package/src/components/DataTable/components/__tests__/PaginationControls.test.tsx +13 -103
- package/src/components/DataTable/components/__tests__/RowComponent.test.tsx +629 -0
- package/src/components/DataTable/components/__tests__/SortIndicator.test.tsx +135 -0
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +31 -171
- package/src/components/DataTable/components/__tests__/cellValueUtils.test.ts +453 -0
- package/src/components/DataTable/components/hooks/useImportModalFocus.test.ts +184 -0
- package/src/components/DataTable/components/hooks/usePermissionTracking.test.ts +381 -0
- package/src/components/DataTable/context/DataTableContext.tsx +9 -10
- package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +12 -26
- package/src/components/DataTable/core/ColumnFactory.ts +3 -3
- package/src/components/DataTable/core/ColumnManager.ts +0 -1
- package/src/components/DataTable/core/DataManager.ts +4 -2
- package/src/components/DataTable/core/LocalDataAdapter.ts +1 -1
- package/src/components/DataTable/core/PluginRegistry.ts +2 -2
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +114 -2
- package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +103 -5
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +57 -0
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +63 -0
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +42 -9
- package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +29 -7
- package/src/components/DataTable/core/__tests__/StateManager.test.ts +58 -4
- package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +16 -21
- package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +93 -4
- package/src/components/DataTable/hooks/__tests__/useDataTableConfiguration.test.ts +227 -54
- package/src/components/DataTable/hooks/__tests__/useDataTableDataPipeline.test.ts +215 -62
- package/src/components/DataTable/hooks/__tests__/useDataTablePermissions.test.ts +217 -39
- package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +101 -6
- package/src/components/DataTable/hooks/__tests__/useEffectiveColumnOrder.test.ts +157 -27
- package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +80 -0
- package/src/components/DataTable/hooks/__tests__/useKeyboardNavigation.test.ts +787 -0
- package/src/components/DataTable/hooks/__tests__/useServerSideDataEffect.test.ts +258 -0
- package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +128 -77
- package/src/components/DataTable/hooks/__tests__/useTableHandlers.test.ts +440 -0
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +12 -9
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +12 -9
- package/src/components/DataTable/hooks/useDataTableConfiguration.ts +1 -1
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +11 -22
- package/src/components/DataTable/hooks/useDataTableState.ts +20 -24
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +5 -5
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +13 -1
- package/src/components/DataTable/hooks/useTableColumns.ts +15 -39
- package/src/components/DataTable/hooks/useTableHandlers.ts +8 -20
- package/src/components/DataTable/index.ts +24 -2
- package/src/components/DataTable/types.ts +6 -3
- package/src/components/DataTable/utils/__tests__/a11yUtils.test.ts +3 -67
- package/src/components/DataTable/utils/__tests__/aggregationUtils.test.ts +288 -0
- package/src/components/DataTable/utils/__tests__/errorHandling.test.ts +3 -60
- package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +1 -1
- package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +9 -21
- package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +102 -86
- package/src/components/DataTable/utils/__tests__/paginationUtils.test.ts +593 -0
- package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +33 -49
- package/src/components/DataTable/utils/__tests__/selectFieldUtils.test.ts +1 -0
- package/src/components/DataTable/utils/a11yUtils.ts +1 -1
- package/src/components/DataTable/utils/aggregationUtils.ts +5 -5
- package/src/components/DataTable/utils/errorHandling.ts +3 -1
- package/src/components/DataTable/utils/exportUtils.ts +1 -1
- package/src/components/DataTable/utils/flexibleImport.ts +2 -2
- package/src/components/DataTable/utils/hierarchicalSorting.ts +3 -3
- package/src/components/DataTable/utils/paginationUtils.ts +1 -1
- package/src/components/DataTable/utils/performanceUtils.ts +1 -1
- package/src/components/DataTable/utils/selectFieldUtils.ts +0 -7
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +17 -24
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +1 -1
- package/src/components/DateTimeField/DateTimeField.test.tsx +2 -15
- package/src/components/DateTimeField/DateTimeField.tsx +1 -1
- package/src/components/Dialog/Dialog.test.tsx +2007 -407
- package/src/components/Dialog/Dialog.tsx +97 -192
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +2 -62
- package/src/components/ErrorBoundary/ErrorBoundaryContext.context.ts +17 -0
- package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +2 -45
- package/src/components/ErrorBoundary/ErrorBoundaryContext.types.ts +41 -0
- package/src/components/ErrorBoundary/index.ts +3 -4
- package/src/components/ErrorBoundary/useErrorBoundaryContext.ts +20 -0
- package/src/components/FileDisplay/FileDisplay.test.tsx +454 -222
- package/src/components/FileDisplay/FileDisplay.tsx +14 -12
- package/src/components/FileDisplay/index.tsx +1 -1
- package/src/components/FileUpload/FileUpload.test.tsx +54 -18
- package/src/components/FileUpload/FileUpload.tsx +10 -7
- package/src/components/FileUpload/index.tsx +1 -1
- package/src/components/Footer/Footer.test.tsx +33 -114
- package/src/components/Form/Form.test.tsx +388 -68
- package/src/components/Form/Form.tsx +57 -42
- package/src/components/Header/Header.test.tsx +645 -154
- package/src/components/Header/Header.tsx +52 -43
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +35 -76
- package/src/components/Input/Input.test.tsx +34 -120
- package/src/components/Label/Label.test.tsx +47 -46
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +9 -12
- package/src/components/LoginForm/LoginForm.test.tsx +0 -1
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +1399 -82
- package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
- package/src/components/NavigationMenu/__tests__/useNavigationFiltering.test.ts +1934 -0
- package/src/components/NavigationMenu/useNavigationFiltering.ts +5 -15
- package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +1307 -0
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +47 -46
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +81 -38
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +87 -66
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +245 -39
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -20
- package/src/components/PaceAppLayout/README.md +0 -9
- package/src/components/PaceAppLayout/test-setup.tsx +15 -9
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +759 -3
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +2 -3
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +1 -1
- package/src/components/Progress/Progress.test.tsx +127 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +1196 -4
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +24 -6
- package/src/components/PublicLayout/PublicLayout.test.tsx +1435 -14
- package/src/components/PublicLayout/PublicPageContext.ts +28 -0
- package/src/components/PublicLayout/PublicPageLayout.tsx +6 -6
- package/src/components/PublicLayout/PublicPageProvider.tsx +2 -41
- package/src/components/PublicLayout/usePublicPageContext.ts +36 -0
- package/src/components/Select/Select.test.tsx +46 -9
- package/src/components/Select/Select.tsx +31 -24
- package/src/components/Select/__tests__/context.test.tsx +56 -0
- package/src/components/Select/hooks/__tests__/useSelectEvents.test.ts +279 -0
- package/src/components/Select/hooks/__tests__/useSelectSearch.test.tsx +295 -0
- package/src/components/Select/hooks/__tests__/useSelectState.test.ts +254 -0
- package/src/components/Select/hooks/useSelectState.ts +16 -16
- package/src/components/Select/types.ts +3 -0
- package/src/components/Select/utils/__tests__/text.test.tsx +104 -0
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.test.tsx +28 -112
- package/src/components/Switch/Switch.test.tsx +57 -153
- package/src/components/Table/Table.test.tsx +47 -317
- package/src/components/Tabs/Tabs.tsx +3 -3
- package/src/components/Textarea/Textarea.test.tsx +11 -38
- package/src/components/Toast/Toast.test.tsx +78 -569
- package/src/components/Tooltip/Tooltip.test.tsx +4 -21
- package/src/components/UserMenu/UserMenu.test.tsx +1 -21
- package/src/components/UserMenu/UserMenu.tsx +0 -1
- package/src/components/__tests__/index.test.ts +346 -0
- package/src/components/index.ts +12 -1
- package/src/constants/__tests__/performance.test.ts +91 -0
- package/src/hooks/__tests__/ServiceHooks.test.tsx +239 -129
- package/src/hooks/__tests__/hooks.integration.test.tsx +4 -3
- package/src/hooks/__tests__/useApiFetch.unit.test.ts +1 -1
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +88 -29
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +282 -98
- package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +53 -109
- package/src/hooks/__tests__/useDataTableState.test.ts +143 -49
- package/src/hooks/__tests__/useDebounce.unit.test.ts +94 -19
- package/src/hooks/__tests__/useEvents.unit.test.ts +100 -125
- package/src/hooks/__tests__/useFileDisplay.test.ts +540 -0
- package/src/hooks/__tests__/useFileDisplay.unit.test.ts +1 -4
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +27 -247
- package/src/hooks/__tests__/useFileUrlCache.test.ts +246 -56
- package/src/hooks/__tests__/useFocusManagement.unit.test.ts +442 -68
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +345 -560
- package/src/hooks/__tests__/useFormDialog.test.ts +51 -222
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +1 -1
- package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +1 -4
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +0 -1
- package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +1 -1
- package/src/hooks/__tests__/usePermissionCache.test.ts +506 -0
- package/src/hooks/__tests__/usePreventTabReload.test.ts +255 -36
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +17 -8
- package/src/hooks/__tests__/usePublicEvent.test.ts +16 -24
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +12 -4
- package/src/hooks/__tests__/usePublicFileDisplay.test.ts +3 -6
- package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +1 -2
- package/src/hooks/__tests__/useQueryCache.test.ts +313 -66
- package/src/hooks/__tests__/useSessionDraft.test.ts +496 -103
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +2 -2
- package/src/hooks/__tests__/useStorage.unit.test.ts +72 -102
- package/src/hooks/__tests__/useToast.test.ts +413 -0
- package/src/hooks/__tests__/useToast.unit.test.tsx +1 -1
- package/src/hooks/__tests__/useZodForm.unit.test.tsx +175 -21
- package/src/hooks/index.ts +13 -1
- package/src/hooks/public/usePublicEvent.test.ts +304 -0
- package/src/hooks/public/usePublicEvent.ts +11 -11
- package/src/hooks/public/usePublicEventLogo.test.ts +655 -120
- package/src/hooks/public/usePublicEventLogo.ts +2 -2
- package/src/hooks/public/usePublicFileDisplay.test.ts +723 -0
- package/src/hooks/public/usePublicFileDisplay.ts +79 -49
- package/src/hooks/public/usePublicRouteParams.test.ts +595 -0
- package/src/hooks/public/usePublicRouteParams.ts +2 -2
- package/src/hooks/services/useAuthService.ts +1 -1
- package/src/hooks/services/useEventService.ts +1 -1
- package/src/hooks/useAccessibleApps.test.ts +400 -0
- package/src/hooks/useAccessibleApps.ts +264 -0
- package/src/hooks/useAddressAutocomplete.test.ts +165 -42
- package/src/hooks/useAddressAutocomplete.ts +41 -28
- package/src/hooks/useAppConfig.ts +13 -3
- package/src/hooks/useDataTablePerformance.ts +13 -12
- package/src/hooks/useDataTableState.ts +5 -5
- package/src/hooks/useEventTheme.test.ts +66 -17
- package/src/hooks/useEventTheme.ts +1 -1
- package/src/hooks/useEvents.ts +8 -1
- package/src/hooks/useFileDisplay.ts +66 -33
- package/src/hooks/useFileReference.test.ts +365 -87
- package/src/hooks/useFileReference.ts +2 -6
- package/src/hooks/useFileUrlCache.ts +4 -1
- package/src/hooks/useFormDialog.ts +2 -2
- package/src/hooks/useInactivityTracker.ts +3 -3
- package/src/hooks/useOrganisationPermissions.test.ts +1 -2
- package/src/hooks/useOrganisationPermissions.ts +1 -4
- package/src/hooks/useOrganisationSecurity.test.ts +1 -30
- package/src/hooks/useOrganisationSecurity.ts +3 -3
- package/src/hooks/useOrganisations.ts +1 -1
- package/src/hooks/usePerformanceMonitor.ts +1 -1
- package/src/hooks/usePermissionCache.ts +2 -6
- package/src/hooks/useQueryCache.ts +7 -7
- package/src/hooks/useSessionDraft.ts +14 -11
- package/src/hooks/useSessionRestoration.ts +1 -1
- package/src/hooks/useStorage.ts +75 -40
- package/src/hooks/useToast.ts +2 -2
- package/src/hooks/useZodForm.ts +3 -3
- package/src/icons/__tests__/index.test.ts +133 -0
- package/src/icons/index.ts +1 -1
- package/src/index.ts +43 -4
- package/src/providers/OrganisationProvider.test.tsx +40 -0
- package/src/providers/OrganisationProvider.tsx +5 -5
- package/src/providers/UnifiedAuthProvider.smoke.test.tsx +7 -12
- package/src/providers/__tests__/AuthProvider.test.tsx +22 -91
- package/src/providers/__tests__/EventProvider.test.tsx +16 -80
- package/src/providers/__tests__/InactivityProvider.test.tsx +29 -173
- package/src/providers/__tests__/OrganisationProvider.test.tsx +4 -5
- package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +591 -0
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +80 -196
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +40 -133
- package/src/providers/__tests__/index.test.ts +138 -0
- package/src/providers/services/AuthServiceContext.ts +27 -0
- package/src/providers/services/AuthServiceProvider.tsx +81 -20
- package/src/providers/services/EventServiceContext.ts +25 -0
- package/src/providers/services/EventServiceProvider.tsx +11 -20
- package/src/providers/services/InactivityServiceContext.ts +25 -0
- package/src/providers/services/InactivityServiceProvider.tsx +7 -17
- package/src/providers/services/OrganisationServiceContext.ts +25 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +7 -17
- package/src/providers/services/UnifiedAuthContext.ts +99 -0
- package/src/providers/services/UnifiedAuthProvider.test.tsx +212 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +38 -143
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +61 -95
- package/src/providers/services/__tests__/AuthServiceProvider.test.tsx +638 -0
- package/src/providers/services/__tests__/EventServiceProvider.test.tsx +839 -0
- package/src/providers/services/__tests__/InactivityServiceProvider.test.tsx +662 -0
- package/src/providers/services/__tests__/OrganisationServiceProvider.test.tsx +440 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.advanced.test.tsx +435 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.appId.test.tsx +408 -0
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +55 -48
- package/src/providers/services/__tests__/contexts.test.tsx +281 -0
- package/src/providers/services/__tests__/useUnifiedAuth.test.tsx +251 -0
- package/src/providers/services/useUnifiedAuth.ts +29 -0
- package/src/rbac/README.md +5 -5
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +9 -14
- package/src/rbac/__tests__/audit-batched.test.ts +550 -0
- package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +1 -14
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +43 -12
- package/src/rbac/__tests__/cache-invalidation.test.ts +8 -14
- package/src/rbac/__tests__/engine.comprehensive.test.ts +2 -7
- package/src/rbac/__tests__/index.test.ts +107 -0
- package/src/rbac/__tests__/performance.test.ts +451 -0
- package/src/rbac/__tests__/rbac-core.test.tsx +2 -2
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +0 -5
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +1 -7
- package/src/rbac/__tests__/rbac-functions.test.ts +0 -1
- package/src/rbac/__tests__/rbac-integration.test.ts +0 -1
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +21 -32
- package/src/rbac/adapters.test.tsx +654 -0
- package/src/rbac/adapters.tsx +24 -9
- package/src/rbac/api.test.ts +13 -217
- package/src/rbac/api.ts +85 -16
- package/src/rbac/audit-batched.ts +5 -4
- package/src/rbac/audit.test.ts +225 -28
- package/src/rbac/audit.ts +22 -17
- package/src/rbac/cache-invalidation.ts +18 -15
- package/src/rbac/cache.test.ts +123 -63
- package/src/rbac/cache.ts +3 -4
- package/src/rbac/components/AccessDenied.tsx +20 -18
- package/src/rbac/components/NavigationGuard.tsx +10 -8
- package/src/rbac/components/PagePermissionGuard.tsx +27 -25
- package/src/rbac/components/__tests__/AccessDenied.test.tsx +324 -0
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +242 -71
- package/src/rbac/components/__tests__/PagePermissionGuard.performance.test.tsx +20 -37
- package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +18 -17
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +452 -129
- package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -13
- package/src/rbac/config.test.ts +131 -48
- package/src/rbac/config.ts +11 -8
- package/src/rbac/docs/event-based-apps.md +26 -13
- package/src/rbac/engine.test.ts +496 -146
- package/src/rbac/engine.ts +53 -13
- package/src/rbac/errors.test.ts +99 -87
- package/src/rbac/eslint-rules.js +2 -2
- package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +0 -5
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +601 -1
- package/src/rbac/hooks/permissions/__tests__/useAccessLevel.test.ts +622 -0
- package/src/rbac/hooks/permissions/__tests__/useCan.test.ts +798 -0
- package/src/rbac/hooks/permissions/__tests__/useMultiplePermissions.test.ts +843 -0
- package/src/rbac/hooks/permissions/__tests__/usePermissions.test.ts +545 -0
- package/src/rbac/hooks/permissions/useAccessLevel.ts +7 -8
- package/src/rbac/hooks/permissions/useCan.ts +12 -10
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +57 -8
- package/src/rbac/hooks/permissions/usePermissions.ts +15 -14
- package/src/rbac/hooks/useCan.test.ts +319 -3
- package/src/rbac/hooks/usePermissions.test.ts +426 -0
- package/src/rbac/hooks/usePermissions.ts +5 -7
- package/src/rbac/hooks/useRBAC.test.ts +1669 -2
- package/src/rbac/hooks/useRBAC.ts +7 -11
- package/src/rbac/hooks/useResolvedScope.test.ts +442 -5
- package/src/rbac/hooks/useResolvedScope.ts +4 -1
- package/src/rbac/hooks/useResourcePermissions.test.ts +538 -1
- package/src/rbac/hooks/useResourcePermissions.ts +9 -7
- package/src/rbac/hooks/useRoleManagement.test.ts +659 -1
- package/src/rbac/hooks/useRoleManagement.ts +16 -12
- package/src/rbac/hooks/useSecureSupabase.ts +11 -12
- package/src/rbac/index.ts +32 -32
- package/src/rbac/permissions.test.ts +149 -68
- package/src/rbac/permissions.ts +0 -3
- package/src/rbac/request-deduplication.test.ts +347 -0
- package/src/rbac/secureClient.test.ts +112 -159
- package/src/rbac/secureClient.ts +46 -26
- package/src/rbac/security.test.ts +125 -44
- package/src/rbac/security.ts +7 -6
- package/src/rbac/types.test.ts +236 -0
- package/src/rbac/types.ts +7 -5
- package/src/rbac/utils/__tests__/clientSecurity.test.ts +192 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +1 -3
- package/src/rbac/utils/__tests__/deep-equal.test.ts +23 -0
- package/src/rbac/utils/__tests__/eventContext.test.ts +10 -57
- package/src/rbac/utils/clientSecurity.ts +6 -4
- package/src/rbac/utils/contextValidator.ts +1 -2
- package/src/rbac/utils/eventContext.ts +2 -2
- package/src/services/AuthService.ts +13 -11
- package/src/services/EventService.ts +4 -5
- package/src/services/OrganisationService.ts +13 -30
- package/src/services/__tests__/AuthService.edge-cases.test.ts +746 -0
- package/src/services/__tests__/AuthService.restoreSession.test.ts +23 -3
- package/src/services/__tests__/AuthService.test.ts +4 -8
- package/src/services/__tests__/BaseService.edge-cases.test.ts +506 -0
- package/src/services/__tests__/BaseService.test.ts +49 -0
- package/src/services/__tests__/EventService.edge-cases.test.ts +633 -0
- package/src/services/__tests__/EventService.eventColours.test.ts +0 -12
- package/src/services/__tests__/EventService.test.ts +0 -7
- package/src/services/__tests__/InactivityService.edge-cases.test.ts +492 -0
- package/src/services/__tests__/InactivityService.lifecycle.test.ts +0 -5
- package/src/services/__tests__/OrganisationService.edge-cases.test.ts +633 -0
- package/src/services/base/BaseService.test.ts +214 -0
- package/src/services/interfaces/IOrganisationService.ts +0 -1
- package/src/services/interfaces/__tests__/IAuthService.test.ts +190 -0
- package/src/services/interfaces/__tests__/IEventService.test.ts +176 -0
- package/src/services/interfaces/__tests__/IInactivityService.test.ts +183 -0
- package/src/services/interfaces/__tests__/IOrganisationService.test.ts +207 -0
- package/src/styles/core.css +1 -0
- package/src/theming/__tests__/runtime.test.ts +29 -94
- package/src/theming/parseEventColours.ts +18 -9
- package/src/theming/runtime.ts +1 -5
- package/src/types/__tests__/core.test.ts +397 -0
- package/src/types/__tests__/database-generated.test.ts +78 -0
- package/src/types/__tests__/file-reference.test.ts +270 -366
- package/src/types/__tests__/guards.test.ts +26 -26
- package/src/types/__tests__/index.test.ts +265 -0
- package/src/types/__tests__/type-validation.test.ts +3 -3
- package/src/types/__tests__/validation.test.ts +0 -2
- package/src/types/auth.ts +0 -1
- package/src/types/event.ts +1 -1
- package/src/types/rpc-responses.ts +33 -0
- package/src/types/supabase.ts +1 -2
- package/src/types/vitest-globals.d.ts +1 -1
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +64 -77
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +13 -0
- package/src/utils/__tests__/formatDate.unit.test.ts +1 -1
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +0 -1
- package/src/utils/__tests__/logger.unit.test.ts +1 -1
- package/src/utils/__tests__/performanceBenchmark.test.ts +1 -2
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +48 -13
- package/src/utils/__tests__/request-deduplication.test.ts +349 -0
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +0 -1
- package/src/utils/__tests__/timezone.test.ts +1 -1
- package/src/utils/__tests__/validation.unit.test.ts +1 -2
- package/src/utils/__tests__/validationUtils.unit.test.ts +1 -1
- package/src/utils/app/appConfig.test.ts +235 -0
- package/src/utils/app/appIdResolver.test.ts +188 -20
- package/src/utils/app/appNameResolver.test.ts +18 -10
- package/src/utils/app/appNameResolver.ts +11 -9
- package/src/utils/app/appPortMap.test.ts +125 -0
- package/src/utils/app/appPortMap.ts +51 -0
- package/src/utils/app/buildAppUrl.test.ts +273 -0
- package/src/utils/app/buildAppUrl.ts +114 -0
- package/src/utils/audit/audit.test.ts +354 -39
- package/src/utils/context/organisationContext.test.ts +10 -4
- package/src/utils/context/organisationContext.ts +5 -5
- package/src/utils/context/sessionTracking.test.ts +354 -0
- package/src/utils/core/__tests__/cn.test.ts +66 -0
- package/src/utils/core/__tests__/debugLogger.test.ts +113 -0
- package/src/utils/core/__tests__/logger.test.ts +217 -0
- package/src/utils/core/debugLogger.ts +15 -8
- package/src/utils/core/logger.ts +20 -16
- package/src/utils/device/deviceFingerprint.test.ts +8 -5
- package/src/utils/device/deviceFingerprint.ts +3 -3
- package/src/utils/dynamic/__tests__/dynamicUtils.test.ts +185 -0
- package/src/utils/dynamic/__tests__/lazyLoad.test.tsx +156 -0
- package/src/utils/dynamic/createLazyComponent.tsx +38 -0
- package/src/utils/dynamic/dynamicUtils.ts +6 -6
- package/src/utils/dynamic/lazyLoad.tsx +8 -36
- package/src/utils/dynamic/papaparseLoader.ts +7 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +583 -145
- package/src/utils/file-reference/index.ts +0 -1
- package/src/utils/formatting/formatDate.test.ts +22 -148
- package/src/utils/formatting/formatDateTime.test.ts +41 -119
- package/src/utils/formatting/formatDateTimeTimezone.test.ts +40 -84
- package/src/utils/formatting/formatNumber.test.ts +259 -0
- package/src/utils/formatting/formatTime.test.ts +36 -128
- package/src/utils/formatting/formatting.ts +1 -1
- package/src/utils/google-places/googlePlacesUtils.test.ts +72 -3
- package/src/utils/google-places/googlePlacesUtils.ts +15 -2
- package/src/utils/google-places/loadGoogleMapsScript.test.ts +58 -1
- package/src/utils/google-places/loadGoogleMapsScript.ts +2 -1
- package/src/utils/index.ts +52 -11
- package/src/utils/location/location.test.ts +18 -115
- package/src/utils/performance/__tests__/bundleAnalysis.test.ts +148 -0
- package/src/utils/performance/__tests__/performanceBenchmark.test.ts +251 -0
- package/src/utils/performance/__tests__/performanceBudgets.test.ts +241 -0
- package/src/utils/performance/bundleAnalysis.ts +16 -22
- package/src/utils/performance/performanceBenchmark.ts +12 -4
- package/src/utils/performance/performanceBudgets.ts +9 -6
- package/src/utils/permissions/__tests__/permissionTypes.test.ts +149 -0
- package/src/utils/permissions/permissionUtils.test.ts +20 -42
- package/src/utils/persistence/__tests__/keyDerivation.test.ts +180 -9
- package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +164 -16
- package/src/utils/persistence/sensitiveFieldDetection.ts +2 -2
- package/src/utils/request-deduplication.ts +6 -4
- package/src/utils/security/auth-utils.ts +7 -7
- package/src/utils/security/secureDataAccess.test.ts +22 -191
- package/src/utils/security/secureErrors.test.ts +163 -0
- package/src/utils/security/secureStorage.test.ts +156 -0
- package/src/utils/security/secureStorage.ts +1 -1
- package/src/utils/security/security.test.ts +204 -0
- package/src/utils/security/securityMonitor.test.ts +90 -0
- package/src/utils/security/securityMonitor.ts +1 -1
- package/src/utils/storage/__tests__/config.unit.test.ts +239 -0
- package/src/utils/storage/__tests__/index.unit.test.ts +64 -12
- package/src/utils/storage/helpers.test.ts +757 -430
- package/src/utils/storage/helpers.ts +1 -2
- package/src/utils/storage/{index.ts → storageUtils.ts} +1 -36
- package/src/utils/storage/types.ts +2 -2
- package/src/utils/supabase/createBaseClient.test.ts +201 -0
- package/src/utils/supabase/createBaseClient.ts +2 -1
- package/src/utils/timezone/timezone.test.ts +25 -43
- package/src/utils/validation/__tests__/common.test.ts +115 -0
- package/src/utils/validation/__tests__/csrf.test.ts +65 -0
- package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +27 -7
- package/src/utils/validation/__tests__/passwordSchema.test.ts +164 -0
- package/src/utils/validation/__tests__/schema.test.ts +127 -0
- package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +76 -3
- package/src/utils/validation/__tests__/user.test.ts +173 -0
- package/src/utils/validation/__tests__/validation.test.ts +197 -0
- package/src/utils/validation/__tests__/validationUtils.test.ts +265 -43
- package/src/utils/validation/htmlSanitization.ts +27 -31
- package/src/utils/validation/schema.ts +6 -3
- package/src/utils/validation/sqlInjectionProtection.ts +2 -2
- package/src/vite-env.d.ts +6 -0
- package/dist/DataTable-DRUIgtUH.d.ts +0 -166
- package/dist/UnifiedAuthProvider-7SNDOWYD.js +0 -7
- package/dist/audit-MYQXYZFU.js +0 -3
- package/dist/chunk-7ILTDCL2.js +0 -80
- package/dist/chunk-EF2UGZWY.js +0 -611
- package/dist/chunk-FEJLJNWA.js +0 -181
- package/dist/chunk-GS5672WG.js +0 -2003
- package/dist/chunk-S6ZQKDY6.js +0 -62
- package/dist/chunk-Z2FNRKF3.js +0 -994
- package/dist/useToast-AyaT-x7p.d.ts +0 -68
- package/src/components/DataTable/components/index.ts +0 -16
- package/src/components/DataTable/core/index.ts +0 -1
- package/src/components/DataTable/hooks/index.ts +0 -13
- package/src/components/DataTable/utils/index.ts +0 -10
- package/src/components/PublicLayout/index.ts +0 -32
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +0 -192
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -741
- package/src/hooks/public/index.ts +0 -36
- package/src/hooks/usePermissionCache.test.ts +0 -536
- package/src/rbac/__tests__/isSuperAdmin.real.test.ts +0 -82
- package/src/rbac/audit-enhanced.ts +0 -384
- package/src/rbac/compliance/database-validator.ts +0 -165
- package/src/rbac/compliance/index.ts +0 -48
- package/src/rbac/compliance/pattern-detector.ts +0 -553
- package/src/rbac/compliance/quick-fix-suggestions.ts +0 -209
- package/src/rbac/compliance/runtime-compliance.ts +0 -99
- package/src/rbac/compliance/setup-validator.ts +0 -131
- package/src/rbac/components/index.ts +0 -26
- package/src/rbac/hooks/index.ts +0 -34
- package/src/rbac/hooks/permissions/index.ts +0 -4
- package/src/rbac/hooks/useRBAC.simple.test.ts +0 -95
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -490
- package/src/utils/app/appNameResolver.simple.test.ts +0 -212
- package/src/utils/google-places/index.ts +0 -26
- package/src/utils/location/index.ts +0 -16
- package/src/utils/storage/__tests__/helpers.unit.test.ts +0 -332
- package/src/utils/timezone/index.ts +0 -17
- package/src/utils/validation/index.ts +0 -73
|
@@ -1,8 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file PaceAppLayout Security Tests
|
|
3
|
+
* @package @jmruthers/pace-core
|
|
4
|
+
* @module Components/PaceAppLayout/Security
|
|
5
|
+
* @since 0.1.0
|
|
6
|
+
*
|
|
7
|
+
* Comprehensive security tests for PaceAppLayout component covering:
|
|
8
|
+
* - Permission enforcement and access control
|
|
9
|
+
* - Input validation and sanitization
|
|
10
|
+
* - Session security and data isolation
|
|
11
|
+
* - Error handling security
|
|
12
|
+
* - Privilege escalation prevention
|
|
13
|
+
*/
|
|
14
|
+
|
|
1
15
|
import React from 'react';
|
|
2
16
|
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
3
17
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
4
18
|
import '@testing-library/jest-dom';
|
|
5
|
-
import { BrowserRouter
|
|
19
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
6
20
|
|
|
7
21
|
// Mock React Router hooks
|
|
8
22
|
const mockNavigate = vi.fn();
|
|
@@ -185,6 +199,7 @@ vi.mock('../../hooks/useEventTheme', () => ({
|
|
|
185
199
|
|
|
186
200
|
// Define mocks using vi.hoisted() so they're available in hoisted vi.mock factories
|
|
187
201
|
// Note: Cannot export hoisted variables directly, so we define them and access directly in tests
|
|
202
|
+
// CRITICAL: All mocks must resolve immediately to prevent test hanging
|
|
188
203
|
const mockIsPermitted = vi.hoisted(() => vi.fn().mockResolvedValue(true));
|
|
189
204
|
const mockCheckPermission = vi.hoisted(() => vi.fn().mockResolvedValue(true));
|
|
190
205
|
const mockIsSuperAdmin = vi.hoisted(() => vi.fn().mockResolvedValue(false));
|
|
@@ -274,6 +289,7 @@ vi.mock('@supabase/supabase-js', () => {
|
|
|
274
289
|
|
|
275
290
|
// Mock the new RBAC system for security testing
|
|
276
291
|
// Reference hoisted mocks - they're available when factory runs
|
|
292
|
+
// CRITICAL: All async mocks must resolve immediately to prevent test hanging
|
|
277
293
|
vi.mock('../../rbac/api', () => {
|
|
278
294
|
return {
|
|
279
295
|
isPermitted: mockIsPermitted,
|
|
@@ -281,14 +297,20 @@ vi.mock('../../rbac/api', () => {
|
|
|
281
297
|
getPermissionMap: vi.fn().mockResolvedValue({}),
|
|
282
298
|
getAccessLevel: vi.fn().mockResolvedValue('viewer'),
|
|
283
299
|
isSuperAdmin: mockIsSuperAdmin,
|
|
284
|
-
setupRBAC: vi.fn(),
|
|
300
|
+
setupRBAC: vi.fn().mockResolvedValue(undefined),
|
|
285
301
|
};
|
|
286
302
|
});
|
|
287
303
|
|
|
288
|
-
// Mock RBAC hooks -
|
|
289
|
-
vi.mock('../../rbac/hooks', () => ({
|
|
304
|
+
// Mock RBAC hooks - mock individual files since barrel was removed
|
|
305
|
+
vi.mock('../../rbac/hooks/useRBAC', () => ({
|
|
290
306
|
useRBAC: mockUseRBAC,
|
|
307
|
+
}));
|
|
308
|
+
|
|
309
|
+
vi.mock('../../rbac/hooks/usePermissions', () => ({
|
|
291
310
|
useCan: mockUseCan,
|
|
311
|
+
}));
|
|
312
|
+
|
|
313
|
+
vi.mock('../../rbac/hooks/useResolvedScope', () => ({
|
|
292
314
|
useResolvedScope: vi.fn(() => ({
|
|
293
315
|
resolvedScope: { organisationId: 'org-123', eventId: 'event-123', appId: 'app-123' },
|
|
294
316
|
isLoading: false,
|
|
@@ -378,17 +400,18 @@ const TestWrapper = ({ children }: { children: React.ReactNode }) => (
|
|
|
378
400
|
describe('PaceAppLayout Security', () => {
|
|
379
401
|
beforeEach(async () => {
|
|
380
402
|
vi.clearAllMocks();
|
|
381
|
-
vi.resetModules()
|
|
403
|
+
// Remove vi.resetModules() - it can cause hanging and mock issues
|
|
382
404
|
mockCheckPermission.mockClear();
|
|
383
405
|
mockCheckPermission.mockResolvedValue(true);
|
|
384
406
|
mockIsPermitted.mockClear();
|
|
385
407
|
mockIsPermitted.mockResolvedValue(true);
|
|
386
408
|
|
|
387
|
-
//
|
|
409
|
+
// CRITICAL: Ensure all async mocks resolve immediately to prevent hanging
|
|
410
|
+
// Reset super admin mock - must resolve immediately
|
|
388
411
|
mockIsSuperAdmin.mockClear();
|
|
389
412
|
mockIsSuperAdmin.mockResolvedValue(false);
|
|
390
413
|
|
|
391
|
-
// Reset RBAC hook mocks
|
|
414
|
+
// Reset RBAC hook mocks - must return immediately (not async)
|
|
392
415
|
mockHasPermissionRBAC.mockClear();
|
|
393
416
|
mockHasPermissionRBAC.mockResolvedValue(true);
|
|
394
417
|
mockUseCan.mockReturnValue({
|
|
@@ -410,7 +433,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
410
433
|
permissionMap: {},
|
|
411
434
|
});
|
|
412
435
|
|
|
413
|
-
// Reset the mocked function
|
|
436
|
+
// Reset the mocked function - must resolve immediately
|
|
414
437
|
const { isPermitted } = await import('../../rbac/api');
|
|
415
438
|
vi.mocked(isPermitted).mockClear();
|
|
416
439
|
vi.mocked(isPermitted).mockResolvedValue(true);
|
|
@@ -428,8 +451,15 @@ describe('PaceAppLayout Security', () => {
|
|
|
428
451
|
});
|
|
429
452
|
});
|
|
430
453
|
|
|
454
|
+
afterEach(() => {
|
|
455
|
+
// Clear all timers to prevent hanging
|
|
456
|
+
vi.clearAllTimers();
|
|
457
|
+
// Ensure all mocks are reset
|
|
458
|
+
vi.clearAllMocks();
|
|
459
|
+
});
|
|
460
|
+
|
|
431
461
|
describe('Permission Enforcement', () => {
|
|
432
|
-
it('enforces permissions when enabled', async () => {
|
|
462
|
+
it('enforces permissions when enabled', { timeout: 10000 }, async () => {
|
|
433
463
|
render(
|
|
434
464
|
<TestWrapper>
|
|
435
465
|
<PaceAppLayout appName="Test App" enforcePermissions={true} />
|
|
@@ -441,7 +471,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
441
471
|
await waitFor(() => {
|
|
442
472
|
expect(screen.getByTestId('mock-header')).toBeInTheDocument();
|
|
443
473
|
expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
|
|
444
|
-
});
|
|
474
|
+
}, { timeout: 5000 });
|
|
445
475
|
});
|
|
446
476
|
|
|
447
477
|
it('prevents access when user lacks permission', { timeout: 3000 }, async () => {
|
|
@@ -465,19 +495,16 @@ describe('PaceAppLayout Security', () => {
|
|
|
465
495
|
// Wait for super admin check to complete and component to re-render
|
|
466
496
|
await waitFor(() => {
|
|
467
497
|
expect(mockIsSuperAdmin).toHaveBeenCalled();
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
// Wait a bit for the component to process the super admin check result
|
|
471
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
498
|
+
}, { timeout: 5000 });
|
|
472
499
|
|
|
473
|
-
//
|
|
500
|
+
// Wait for the component to process the super admin check result and show access denied
|
|
474
501
|
await waitFor(() => {
|
|
475
502
|
expect(screen.getByText('Access Denied')).toBeInTheDocument();
|
|
476
503
|
expect(screen.getByText("You don't have permission to access this page.")).toBeInTheDocument();
|
|
477
|
-
});
|
|
504
|
+
}, { timeout: 5000 });
|
|
478
505
|
});
|
|
479
506
|
|
|
480
|
-
it('enforces route-specific permissions', async () => {
|
|
507
|
+
it('enforces route-specific permissions', { timeout: 10000 }, async () => {
|
|
481
508
|
const routePermissions: Record<string, Operation> = {
|
|
482
509
|
'/admin': 'delete',
|
|
483
510
|
'/dashboard': 'read'
|
|
@@ -498,7 +525,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
498
525
|
await waitFor(() => {
|
|
499
526
|
expect(screen.getByTestId('mock-header')).toBeInTheDocument();
|
|
500
527
|
expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
|
|
501
|
-
});
|
|
528
|
+
}, { timeout: 5000 });
|
|
502
529
|
});
|
|
503
530
|
|
|
504
531
|
it('handles permission check failures securely', { timeout: 3000 }, async () => {
|
|
@@ -522,19 +549,17 @@ describe('PaceAppLayout Security', () => {
|
|
|
522
549
|
// Wait for super admin check to complete and component to re-render
|
|
523
550
|
await waitFor(() => {
|
|
524
551
|
expect(mockIsSuperAdmin).toHaveBeenCalled();
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
// Wait a bit for the component to process the super admin check result
|
|
528
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
552
|
+
}, { timeout: 5000 });
|
|
529
553
|
|
|
554
|
+
// Wait for the component to process the super admin check result and show error
|
|
530
555
|
await waitFor(() => {
|
|
531
556
|
// When permission check throws an error, should show Permission Error page
|
|
532
557
|
expect(screen.getByText('Permission Error')).toBeInTheDocument();
|
|
533
558
|
expect(screen.getByText('Permission check failed')).toBeInTheDocument();
|
|
534
|
-
});
|
|
559
|
+
}, { timeout: 5000 });
|
|
535
560
|
});
|
|
536
561
|
|
|
537
|
-
it('prevents bypassing permission checks', async () => {
|
|
562
|
+
it('prevents bypassing permission checks', { timeout: 10000 }, async () => {
|
|
538
563
|
// Test that permission checks cannot be bypassed by manipulating props
|
|
539
564
|
const { rerender } = render(
|
|
540
565
|
<TestWrapper>
|
|
@@ -546,7 +571,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
546
571
|
// With permission enforcement enabled, the component should render normally
|
|
547
572
|
expect(screen.getByTestId('mock-header')).toBeInTheDocument();
|
|
548
573
|
expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
|
|
549
|
-
});
|
|
574
|
+
}, { timeout: 5000 });
|
|
550
575
|
|
|
551
576
|
// Try to bypass by changing props
|
|
552
577
|
mockIsPermitted.mockClear();
|
|
@@ -582,10 +607,10 @@ describe('PaceAppLayout Security', () => {
|
|
|
582
607
|
// With permission enforcement enabled, the component should render normally
|
|
583
608
|
expect(screen.getByTestId('mock-header')).toBeInTheDocument();
|
|
584
609
|
expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
|
|
585
|
-
});
|
|
610
|
+
}, { timeout: 5000 });
|
|
586
611
|
});
|
|
587
612
|
|
|
588
|
-
it('prevents navigation to unauthorized routes', () => {
|
|
613
|
+
it('prevents navigation to unauthorized routes', { timeout: 10000 }, () => {
|
|
589
614
|
render(
|
|
590
615
|
<TestWrapper>
|
|
591
616
|
<PaceAppLayout appName="Test App" />
|
|
@@ -597,7 +622,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
597
622
|
expect(mockNavigate).toHaveBeenCalledWith('/admin');
|
|
598
623
|
});
|
|
599
624
|
|
|
600
|
-
it('handles navigation items without proper href securely', () => {
|
|
625
|
+
it('handles navigation items without proper href securely', { timeout: 10000 }, () => {
|
|
601
626
|
const customNavItems = [
|
|
602
627
|
{ id: 'malicious', label: 'Malicious', href: 'javascript:alert("xss")' },
|
|
603
628
|
{ id: 'safe', label: 'Safe', href: '/safe' }
|
|
@@ -615,7 +640,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
615
640
|
});
|
|
616
641
|
|
|
617
642
|
describe('Authentication Security', () => {
|
|
618
|
-
it('handles authentication securely', async () => {
|
|
643
|
+
it('handles authentication securely', { timeout: 10000 }, async () => {
|
|
619
644
|
render(
|
|
620
645
|
<TestWrapper>
|
|
621
646
|
<PaceAppLayout appName="Test App" />
|
|
@@ -626,10 +651,10 @@ describe('PaceAppLayout Security', () => {
|
|
|
626
651
|
|
|
627
652
|
await waitFor(() => {
|
|
628
653
|
expect(mockSignOut).toHaveBeenCalled();
|
|
629
|
-
});
|
|
654
|
+
}, { timeout: 5000 });
|
|
630
655
|
});
|
|
631
656
|
|
|
632
|
-
it('handles password changes securely', async () => {
|
|
657
|
+
it('handles password changes securely', { timeout: 10000 }, async () => {
|
|
633
658
|
render(
|
|
634
659
|
<TestWrapper>
|
|
635
660
|
<PaceAppLayout appName="Test App" />
|
|
@@ -640,10 +665,10 @@ describe('PaceAppLayout Security', () => {
|
|
|
640
665
|
|
|
641
666
|
await waitFor(() => {
|
|
642
667
|
expect(mockUpdatePassword).toHaveBeenCalledWith('newpassword123');
|
|
643
|
-
});
|
|
668
|
+
}, { timeout: 5000 });
|
|
644
669
|
});
|
|
645
670
|
|
|
646
|
-
it('prevents authentication bypass', async () => {
|
|
671
|
+
it('prevents authentication bypass', { timeout: 10000 }, async () => {
|
|
647
672
|
// Test that authentication cannot be bypassed
|
|
648
673
|
const { rerender } = render(
|
|
649
674
|
<TestWrapper>
|
|
@@ -670,7 +695,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
670
695
|
});
|
|
671
696
|
|
|
672
697
|
describe('Data Isolation', () => {
|
|
673
|
-
it('isolates user data between different users', () => {
|
|
698
|
+
it('isolates user data between different users', { timeout: 10000 }, () => {
|
|
674
699
|
const user1 = {
|
|
675
700
|
id: 'user-1',
|
|
676
701
|
email: 'user1@example.com',
|
|
@@ -711,7 +736,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
711
736
|
Object.assign(mockUser, originalMock);
|
|
712
737
|
});
|
|
713
738
|
|
|
714
|
-
it('isolates organisation context', () => {
|
|
739
|
+
it('isolates organisation context', { timeout: 10000 }, () => {
|
|
715
740
|
const org1 = {
|
|
716
741
|
id: 'org-1',
|
|
717
742
|
name: 'Organisation 1',
|
|
@@ -760,7 +785,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
760
785
|
});
|
|
761
786
|
|
|
762
787
|
describe('Input Validation', () => {
|
|
763
|
-
it('validates appName input securely', () => {
|
|
788
|
+
it('validates appName input securely', { timeout: 10000 }, () => {
|
|
764
789
|
// Test with potentially malicious app names
|
|
765
790
|
const maliciousAppNames = [
|
|
766
791
|
'<script>alert("xss")</script>',
|
|
@@ -782,7 +807,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
782
807
|
});
|
|
783
808
|
});
|
|
784
809
|
|
|
785
|
-
it('validates navigation items securely', () => {
|
|
810
|
+
it('validates navigation items securely', { timeout: 10000 }, () => {
|
|
786
811
|
const maliciousNavItems = [
|
|
787
812
|
{ id: 'malicious1', label: '<script>alert("xss")</script>', href: '/safe' },
|
|
788
813
|
{ id: 'malicious2', label: 'Safe', href: 'javascript:alert("xss")' },
|
|
@@ -799,8 +824,8 @@ describe('PaceAppLayout Security', () => {
|
|
|
799
824
|
expect(screen.getByTestId('mock-header')).toBeInTheDocument();
|
|
800
825
|
});
|
|
801
826
|
|
|
802
|
-
it('validates custom components securely', () => {
|
|
803
|
-
const
|
|
827
|
+
it('validates custom components securely', { timeout: 10000 }, () => {
|
|
828
|
+
const _MaliciousComponent = () => {
|
|
804
829
|
// Simulate a component that might try to execute malicious code
|
|
805
830
|
React.useEffect(() => {
|
|
806
831
|
// This would be dangerous in a real scenario
|
|
@@ -813,7 +838,6 @@ describe('PaceAppLayout Security', () => {
|
|
|
813
838
|
<TestWrapper>
|
|
814
839
|
<PaceAppLayout
|
|
815
840
|
appName="Test App"
|
|
816
|
-
customLogo={<MaliciousComponent />}
|
|
817
841
|
/>
|
|
818
842
|
</TestWrapper>
|
|
819
843
|
);
|
|
@@ -824,7 +848,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
824
848
|
});
|
|
825
849
|
|
|
826
850
|
describe('Error Handling Security', () => {
|
|
827
|
-
it('handles authentication errors securely', async () => {
|
|
851
|
+
it('handles authentication errors securely', { timeout: 10000 }, async () => {
|
|
828
852
|
mockSignOut.mockResolvedValue({ error: { message: 'Authentication failed' } });
|
|
829
853
|
mockUpdatePassword.mockResolvedValue({ error: { message: 'Password update failed' } });
|
|
830
854
|
|
|
@@ -840,7 +864,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
840
864
|
await waitFor(() => {
|
|
841
865
|
expect(mockSignOut).toHaveBeenCalled();
|
|
842
866
|
expect(mockUpdatePassword).toHaveBeenCalled();
|
|
843
|
-
});
|
|
867
|
+
}, { timeout: 5000 });
|
|
844
868
|
});
|
|
845
869
|
|
|
846
870
|
it('handles permission errors securely', { timeout: 3000 }, async () => {
|
|
@@ -864,14 +888,12 @@ describe('PaceAppLayout Security', () => {
|
|
|
864
888
|
// Wait for super admin check to complete and component to re-render
|
|
865
889
|
await waitFor(() => {
|
|
866
890
|
expect(mockIsSuperAdmin).toHaveBeenCalled();
|
|
867
|
-
});
|
|
868
|
-
|
|
869
|
-
// Wait a bit for the component to process the super admin check result
|
|
870
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
891
|
+
}, { timeout: 5000 });
|
|
871
892
|
|
|
893
|
+
// Wait for the component to process the super admin check result and show access denied
|
|
872
894
|
await waitFor(() => {
|
|
873
895
|
expect(screen.getByText('Access Denied')).toBeInTheDocument();
|
|
874
|
-
});
|
|
896
|
+
}, { timeout: 5000 });
|
|
875
897
|
});
|
|
876
898
|
|
|
877
899
|
it('prevents information leakage in error messages', { timeout: 3000 }, async () => {
|
|
@@ -902,21 +924,19 @@ describe('PaceAppLayout Security', () => {
|
|
|
902
924
|
// Wait for super admin check to complete and component to re-render
|
|
903
925
|
await waitFor(() => {
|
|
904
926
|
expect(mockIsSuperAdmin).toHaveBeenCalled();
|
|
905
|
-
});
|
|
906
|
-
|
|
907
|
-
// Wait a bit for the component to process the super admin check result
|
|
908
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
927
|
+
}, { timeout: 5000 });
|
|
909
928
|
|
|
929
|
+
// Wait for the component to process the super admin check result and show error
|
|
910
930
|
await waitFor(() => {
|
|
911
931
|
expect(screen.getByText('Permission Error')).toBeInTheDocument();
|
|
912
932
|
// Should not expose sensitive information
|
|
913
933
|
expect(screen.queryByText('password=secret123')).not.toBeInTheDocument();
|
|
914
|
-
});
|
|
934
|
+
}, { timeout: 5000 });
|
|
915
935
|
});
|
|
916
936
|
});
|
|
917
937
|
|
|
918
938
|
describe('Session Security', () => {
|
|
919
|
-
it('handles session expiration securely', async () => {
|
|
939
|
+
it('handles session expiration securely', { timeout: 10000 }, async () => {
|
|
920
940
|
// Mock user becoming null (session expired) by temporarily overriding the mock
|
|
921
941
|
const originalUser = mockUser;
|
|
922
942
|
Object.assign(mockUser, { ...mockUser, id: null });
|
|
@@ -934,7 +954,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
934
954
|
Object.assign(mockUser, originalUser);
|
|
935
955
|
});
|
|
936
956
|
|
|
937
|
-
it('handles organisation context loss securely', () => {
|
|
957
|
+
it('handles organisation context loss securely', { timeout: 10000 }, () => {
|
|
938
958
|
// Mock organisation context becoming invalid
|
|
939
959
|
vi.doMock('../../../providers/OrganisationProvider', () => ({
|
|
940
960
|
OrganisationProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
|
|
@@ -957,7 +977,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
957
977
|
});
|
|
958
978
|
|
|
959
979
|
describe('Access Control', () => {
|
|
960
|
-
it('enforces proper access control levels', async () => {
|
|
980
|
+
it('enforces proper access control levels', { timeout: 10000 }, async () => {
|
|
961
981
|
const routePermissions: Record<string, Operation> = {
|
|
962
982
|
'/test-path': 'read',
|
|
963
983
|
'/dashboard': 'read',
|
|
@@ -984,7 +1004,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
984
1004
|
// With proper access control levels, the component should render normally
|
|
985
1005
|
expect(screen.getByTestId('mock-header')).toBeInTheDocument();
|
|
986
1006
|
expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
|
|
987
|
-
});
|
|
1007
|
+
}, { timeout: 5000 });
|
|
988
1008
|
});
|
|
989
1009
|
|
|
990
1010
|
it('allows super admin to bypass all permission checks', { timeout: 3000 }, async () => {
|
|
@@ -1017,7 +1037,7 @@ describe('PaceAppLayout Security', () => {
|
|
|
1017
1037
|
expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
|
|
1018
1038
|
// Should NOT show access denied
|
|
1019
1039
|
expect(screen.queryByText('Access Denied')).not.toBeInTheDocument();
|
|
1020
|
-
});
|
|
1040
|
+
}, { timeout: 5000 });
|
|
1021
1041
|
});
|
|
1022
1042
|
|
|
1023
1043
|
it('does not log strict mode violations for super admins', { timeout: 5000 }, async () => {
|
|
@@ -1052,18 +1072,21 @@ describe('PaceAppLayout Security', () => {
|
|
|
1052
1072
|
// Wait for super admin check to complete
|
|
1053
1073
|
await waitFor(() => {
|
|
1054
1074
|
expect(mockIsSuperAdmin).toHaveBeenCalled();
|
|
1055
|
-
});
|
|
1075
|
+
}, { timeout: 5000 });
|
|
1056
1076
|
|
|
1057
1077
|
// Wait for component to fully render (super admin should bypass checks)
|
|
1058
1078
|
await waitFor(() => {
|
|
1059
1079
|
expect(screen.getByTestId('mock-header')).toBeInTheDocument();
|
|
1060
|
-
});
|
|
1080
|
+
}, { timeout: 5000 });
|
|
1061
1081
|
|
|
1062
1082
|
// Clear any violations that might have been logged before super admin check completed
|
|
1063
1083
|
consoleSpy.mockClear();
|
|
1064
1084
|
|
|
1065
|
-
// Wait
|
|
1066
|
-
await
|
|
1085
|
+
// Wait for all useEffects to complete after super admin check
|
|
1086
|
+
await waitFor(() => {
|
|
1087
|
+
// Component should be fully rendered
|
|
1088
|
+
expect(screen.getByTestId('mock-header')).toBeInTheDocument();
|
|
1089
|
+
}, { timeout: 1000 });
|
|
1067
1090
|
|
|
1068
1091
|
// Should not log strict mode violations for super admins after super admin check completes
|
|
1069
1092
|
// The violation check should be skipped because isSuperAdminUser is true
|
|
@@ -1115,16 +1138,14 @@ describe('PaceAppLayout Security', () => {
|
|
|
1115
1138
|
// Wait for super admin check to complete and component to re-render
|
|
1116
1139
|
await waitFor(() => {
|
|
1117
1140
|
expect(mockIsSuperAdmin).toHaveBeenCalled();
|
|
1118
|
-
});
|
|
1119
|
-
|
|
1120
|
-
// Wait a bit for the component to process the super admin check result
|
|
1121
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
1141
|
+
}, { timeout: 5000 });
|
|
1122
1142
|
|
|
1143
|
+
// Wait for the component to process the super admin check result and show access denied
|
|
1123
1144
|
await waitFor(() => {
|
|
1124
1145
|
// With privilege escalation prevention, should show access denied for admin
|
|
1125
1146
|
expect(screen.getByText('Access Denied')).toBeInTheDocument();
|
|
1126
1147
|
expect(screen.getByText("You don't have permission to access this page.")).toBeInTheDocument();
|
|
1127
|
-
});
|
|
1148
|
+
}, { timeout: 5000 });
|
|
1128
1149
|
});
|
|
1129
1150
|
});
|
|
1130
1151
|
});
|