@jmruthers/pace-core 0.6.5 → 0.6.7
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/CHANGELOG.md +104 -0
- package/README.md +5 -403
- package/audit-tool/00-dependencies.cjs +394 -0
- package/audit-tool/audits/01-pace-core-compliance.cjs +556 -0
- package/audit-tool/audits/02-project-structure.cjs +255 -0
- package/audit-tool/audits/03-architecture.cjs +196 -0
- package/audit-tool/audits/04-code-quality.cjs +149 -0
- package/audit-tool/audits/05-styling.cjs +224 -0
- package/audit-tool/audits/06-security-rbac.cjs +544 -0
- package/audit-tool/audits/07-api-tech-stack.cjs +301 -0
- package/audit-tool/audits/08-testing-documentation.cjs +202 -0
- package/audit-tool/audits/09-operations.cjs +208 -0
- package/audit-tool/index.cjs +291 -0
- package/audit-tool/utils/code-utils.cjs +218 -0
- package/audit-tool/utils/file-utils.cjs +230 -0
- package/audit-tool/utils/report-utils.cjs +241 -0
- package/core-usage-manifest.json +93 -0
- package/cursor-rules/00-standards-overview.mdc +156 -0
- package/cursor-rules/01-pace-core-compliance.mdc +586 -0
- package/cursor-rules/02-project-structure.mdc +42 -4
- package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +126 -10
- package/cursor-rules/04-code-quality.mdc +419 -0
- package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +104 -34
- package/cursor-rules/06-security-rbac.mdc +518 -0
- package/cursor-rules/07-api-tech-stack.mdc +377 -0
- package/cursor-rules/08-testing-documentation.mdc +324 -0
- package/cursor-rules/09-operations.mdc +365 -0
- package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
- package/dist/DataTable-7PMH7XN7.js +15 -0
- package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
- package/dist/{PublicPageProvider-QTFVrL-Z.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +33 -72
- package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
- package/dist/api-Y4MQWOFW.js +4 -0
- package/dist/audit-MYQXYZFU.js +3 -0
- package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
- package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
- package/dist/{chunk-UPPMRMYG.js → chunk-5X4QLXRG.js} +73 -151
- package/dist/chunk-6F3IILHI.js +62 -0
- package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
- package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
- package/dist/{chunk-FMUCXFII.js → chunk-7ILTDCL2.js} +9 -5
- package/dist/{chunk-M43Y4SSO.js → chunk-A3W6LW53.js} +15 -13
- package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
- package/dist/{chunk-HU2C6SSC.js → chunk-BM4CQ5P3.js} +606 -559
- package/dist/chunk-C7NSAPTL.js +1 -0
- package/dist/{chunk-J36DSWQK.js → chunk-FEJLJNWA.js} +7 -41
- package/dist/{chunk-IHB5DR3H.js → chunk-FTCRZOG2.js} +188 -387
- package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
- package/dist/chunk-GHYHJTYV.js +994 -0
- package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
- package/dist/{chunk-FFQEQTNW.js → chunk-IUBRCBSY.js} +134 -45
- package/dist/{chunk-6COVEUS7.js → chunk-JGWDVX64.js} +983 -1034
- package/dist/{chunk-RGAWHO7N.js → chunk-L4XMVJKY.js} +77 -222
- package/dist/chunk-MBADTM7L.js +64 -0
- package/dist/{chunk-M7MPQISP.js → chunk-OJ4SKRSV.js} +3 -16
- package/dist/{chunk-IVOFDYWT.js → chunk-Q7Q7V5NV.js} +2109 -1604
- package/dist/{chunk-JGRYX5UX.js → chunk-S7DKJPLT.js} +29 -58
- package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
- package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
- package/dist/{chunk-NTM7ZSB6.js → chunk-VBCS3DUA.js} +261 -168
- package/dist/{chunk-EFN2EIMK.js → chunk-ZFYPMX46.js} +271 -87
- package/dist/{chunk-L4OXEN46.js → chunk-ZKAWKYT4.js} +10 -24
- package/dist/components.d.ts +7 -5
- package/dist/components.js +46 -257
- package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
- package/dist/eslint-rules/index.cjs +35 -0
- package/{src/eslint-rules/pace-core-compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +234 -235
- package/dist/eslint-rules/rules/04-code-quality.cjs +290 -0
- package/dist/eslint-rules/rules/05-styling.cjs +61 -0
- package/dist/eslint-rules/rules/06-security-rbac.cjs +806 -0
- package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
- package/dist/eslint-rules/rules/08-testing.cjs +94 -0
- package/dist/eslint-rules/utils/helpers.cjs +42 -0
- package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
- package/dist/hooks.d.ts +6 -6
- package/dist/hooks.js +62 -172
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.d.ts +12 -11
- package/dist/index.js +67 -660
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +8 -35
- package/dist/rbac/eslint-rules.d.ts +46 -44
- package/dist/rbac/eslint-rules.js +7 -4
- package/dist/rbac/index.d.ts +109 -586
- package/dist/rbac/index.js +14 -207
- package/dist/styles/index.js +2 -12
- package/dist/theming/runtime.d.ts +14 -1
- package/dist/theming/runtime.js +3 -19
- package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
- package/dist/{types-CkbwOr4Y.d.ts → types-DXstZpNI.d.ts} +4 -17
- package/dist/types-t9H8qKRw.d.ts +55 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +7 -94
- package/dist/{usePublicRouteParams-ClnV4tnv.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +20 -20
- package/dist/utils.d.ts +24 -117
- package/dist/utils.js +54 -392
- package/docs/README.md +17 -7
- package/docs/api/README.md +4 -402
- package/docs/api/modules.md +301 -871
- package/docs/api-reference/components.md +21 -21
- package/docs/api-reference/deprecated.md +31 -6
- package/docs/api-reference/hooks.md +80 -80
- package/docs/api-reference/rpc-functions.md +78 -3
- package/docs/api-reference/types.md +1 -1
- package/docs/api-reference/utilities.md +1 -1
- package/docs/architecture/README.md +1 -1
- package/docs/core-concepts/events.md +3 -3
- package/docs/core-concepts/organisations.md +6 -6
- package/docs/core-concepts/permissions.md +6 -6
- package/docs/documentation-index.md +12 -18
- package/docs/getting-started/cursor-rules.md +3 -23
- package/docs/getting-started/dependencies.md +650 -0
- package/docs/getting-started/documentation-index.md +1 -1
- package/docs/getting-started/examples/README.md +4 -4
- package/docs/getting-started/examples/full-featured-app.md +1 -1
- package/docs/getting-started/faq.md +2 -2
- package/docs/getting-started/installation-guide.md +20 -7
- package/docs/getting-started/quick-reference.md +4 -4
- package/docs/getting-started/quick-start.md +23 -12
- package/docs/implementation-guides/authentication.md +15 -15
- package/docs/implementation-guides/component-styling.md +1 -1
- package/docs/implementation-guides/data-tables.md +126 -33
- package/docs/implementation-guides/datatable-rbac-usage.md +1 -1
- package/docs/implementation-guides/dynamic-colors.md +3 -3
- package/docs/implementation-guides/file-upload-storage.md +2 -2
- package/docs/implementation-guides/hierarchical-datatable.md +40 -60
- package/docs/implementation-guides/inactivity-tracking.md +3 -3
- package/docs/implementation-guides/large-datasets.md +3 -2
- package/docs/implementation-guides/organisation-security.md +2 -2
- package/docs/implementation-guides/performance.md +2 -2
- package/docs/implementation-guides/permission-enforcement.md +5 -1
- package/docs/migration/V0.3.44_organisation-context-timing-fix.md +1 -1
- package/docs/migration/V0.4.0_rbac-migration.md +6 -6
- package/docs/rbac/MIGRATION_GUIDE.md +819 -0
- package/docs/rbac/RBAC_CONTRACT.md +724 -0
- package/docs/rbac/README.md +17 -8
- package/docs/rbac/advanced-patterns.md +6 -6
- package/docs/rbac/api-reference.md +20 -20
- package/docs/rbac/edge-functions-guide.md +376 -0
- package/docs/rbac/event-based-apps.md +3 -3
- package/docs/rbac/examples.md +41 -41
- package/docs/rbac/getting-started.md +37 -37
- package/docs/rbac/performance.md +1 -1
- package/docs/rbac/quick-start.md +52 -52
- package/docs/rbac/secure-client-protection.md +1 -35
- package/docs/rbac/troubleshooting.md +1 -1
- package/docs/security/README.md +5 -5
- package/docs/standards/0-standards-overview.md +220 -0
- package/docs/standards/1-pace-core-compliance-standards.md +986 -0
- package/docs/standards/2-project-structure-standards.md +949 -0
- package/docs/standards/3-architecture-standards.md +606 -0
- package/docs/standards/4-code-quality-standards.md +728 -0
- package/docs/standards/5-styling-standards.md +348 -0
- package/docs/standards/{07-rbac-and-rls-standard.md → 6-security-rbac-standards.md} +269 -66
- package/docs/standards/7-api-tech-stack-standards.md +662 -0
- package/docs/standards/8-testing-documentation-standards.md +401 -0
- package/docs/standards/9-operations-standards.md +1102 -0
- package/docs/standards/README.md +185 -57
- package/docs/troubleshooting/README.md +4 -4
- package/docs/troubleshooting/common-issues.md +2 -2
- package/docs/troubleshooting/debugging.md +9 -9
- package/docs/troubleshooting/migration.md +4 -4
- package/docs/troubleshooting/organisation-context-setup.md +42 -19
- package/eslint-config-pace-core.cjs +33 -6
- package/package.json +35 -23
- package/scripts/install-cursor-rules.cjs +25 -6
- package/scripts/install-eslint-config.cjs +284 -0
- package/src/__tests__/fixtures/supabase.ts +1 -1
- package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +3 -3
- package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
- package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +13 -13
- package/src/__tests__/helpers/component-test-utils.tsx +1 -1
- package/src/__tests__/helpers/supabaseMock.ts +2 -2
- package/src/__tests__/integration/UserProfile.test.tsx +14 -14
- package/src/__tests__/public-recipe-view.test.ts +38 -9
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -6
- package/src/__tests__/templates/accessibility.test.template.tsx +9 -9
- package/src/__tests__/templates/component.test.template.tsx +18 -15
- package/src/components/Button/Button.tsx +5 -1
- package/src/components/Calendar/Calendar.tsx +201 -47
- package/src/components/ContextSelector/ContextSelector.tsx +106 -119
- package/src/components/DataTable/AUDIT_REPORT.md +293 -0
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +10 -2
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +10 -4
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +9 -9
- package/src/components/DataTable/components/ColumnFilter.tsx +63 -74
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +43 -41
- package/src/components/DataTable/components/DataTableCore.tsx +186 -13
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +9 -11
- package/src/components/DataTable/components/DataTableLayout.tsx +35 -21
- package/src/components/DataTable/components/EditFields.tsx +23 -3
- package/src/components/DataTable/components/EditableRow.tsx +12 -9
- package/src/components/DataTable/components/EmptyState.tsx +10 -9
- package/src/components/DataTable/components/FilterRow.tsx +2 -4
- package/src/components/DataTable/components/ImportModal.tsx +124 -126
- package/src/components/DataTable/components/LoadingState.tsx +5 -6
- package/src/components/DataTable/components/RowComponent.tsx +12 -0
- package/src/components/DataTable/components/SortIndicator.tsx +50 -0
- package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +4 -4
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +23 -82
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +37 -9
- package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +7 -4
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +12 -4
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +41 -27
- package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
- package/src/components/DataTable/components/index.ts +2 -1
- package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
- package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
- package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
- package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
- package/src/components/DataTable/types.ts +5 -18
- package/src/components/DataTable/utils/a11yUtils.ts +17 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +2 -1
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +11 -15
- package/src/components/DateTimeField/DateTimeField.tsx +10 -9
- package/src/components/Dialog/Dialog.test.tsx +128 -104
- package/src/components/Dialog/Dialog.tsx +742 -24
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
- package/src/components/FileDisplay/FileDisplay.test.tsx +4 -2
- package/src/components/FileDisplay/FileDisplay.tsx +23 -17
- package/src/components/FileUpload/FileUpload.test.tsx +52 -14
- package/src/components/FileUpload/FileUpload.tsx +112 -130
- package/src/components/Form/Form.test.tsx +6 -8
- package/src/components/Form/Form.tsx +365 -4
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
- package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +11 -15
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
- package/src/components/Progress/Progress.tsx +2 -4
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
- package/src/components/Select/Select.tsx +109 -98
- package/src/components/Select/types.ts +4 -1
- package/src/components/UserMenu/UserMenu.tsx +9 -6
- package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
- package/src/hooks/__tests__/hooks.integration.test.tsx +55 -57
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
- package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
- package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
- package/src/hooks/public/usePublicEvent.ts +67 -195
- package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
- package/src/hooks/public/usePublicEventLogo.ts +24 -14
- package/src/hooks/public/usePublicFileDisplay.ts +2 -2
- package/src/hooks/public/usePublicRouteParams.ts +5 -5
- package/src/hooks/useAppConfig.ts +28 -26
- package/src/hooks/useEventTheme.test.ts +217 -239
- package/src/hooks/useEventTheme.ts +16 -28
- package/src/hooks/useFileDisplay.ts +2 -2
- package/src/hooks/useOrganisationPermissions.ts +5 -7
- package/src/hooks/useQueryCache.ts +0 -1
- package/src/hooks/useSessionDraft.ts +380 -0
- package/src/hooks/useSessionRestoration.ts +3 -1
- package/src/icons/index.ts +27 -0
- package/src/index.ts +5 -0
- package/src/providers/OrganisationProvider.tsx +23 -14
- package/src/providers/UnifiedAuthProvider.smoke.test.tsx +21 -21
- package/src/providers/__tests__/AuthProvider.test.tsx +21 -21
- package/src/providers/__tests__/EventProvider.test.tsx +61 -61
- package/src/providers/__tests__/InactivityProvider.test.tsx +56 -56
- package/src/providers/__tests__/OrganisationProvider.test.tsx +75 -75
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +37 -37
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +103 -103
- package/src/providers/services/EventServiceProvider.tsx +1 -24
- package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +13 -10
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
- package/src/rbac/adapters.tsx +7 -295
- package/src/rbac/api.test.ts +44 -56
- package/src/rbac/api.ts +10 -17
- package/src/rbac/cache-invalidation.ts +0 -1
- package/src/rbac/compliance/index.ts +10 -0
- package/src/rbac/compliance/pattern-detector.ts +553 -0
- package/src/rbac/compliance/runtime-compliance.ts +22 -0
- package/src/rbac/components/AccessDenied.tsx +150 -0
- package/src/rbac/components/NavigationGuard.tsx +12 -20
- package/src/rbac/components/PagePermissionGuard.tsx +4 -24
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
- package/src/rbac/components/index.ts +3 -41
- package/src/rbac/eslint-rules.js +1 -1
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/permissions/index.ts +0 -3
- package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
- package/src/rbac/hooks/usePermissions.ts +0 -3
- package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
- package/src/rbac/hooks/useResolvedScope.ts +58 -140
- package/src/rbac/hooks/useResourcePermissions.test.ts +124 -38
- package/src/rbac/hooks/useResourcePermissions.ts +139 -48
- package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
- package/src/rbac/hooks/useRoleManagement.ts +147 -19
- package/src/rbac/hooks/useSecureSupabase.ts +4 -8
- package/src/rbac/index.ts +7 -9
- package/src/rbac/utils/contextValidator.ts +9 -7
- package/src/services/AuthService.ts +130 -18
- package/src/services/EventService.ts +4 -97
- package/src/services/InactivityService.ts +16 -0
- package/src/services/OrganisationService.ts +7 -44
- package/src/services/__tests__/OrganisationService.test.ts +26 -8
- package/src/services/base/BaseService.ts +0 -3
- package/src/styles/core.css +7 -0
- package/src/theming/__tests__/parseEventColours.test.ts +9 -3
- package/src/theming/parseEventColours.ts +22 -10
- package/src/types/database.generated.ts +4733 -3809
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
- package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
- package/src/utils/context/organisationContext.test.ts +13 -28
- package/src/utils/context/organisationContext.ts +21 -52
- package/src/utils/dynamic/dynamicUtils.ts +1 -1
- package/src/utils/file-reference/index.ts +39 -15
- package/src/utils/formatting/formatDateTime.test.ts +3 -2
- package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
- package/src/utils/index.ts +4 -1
- package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
- package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
- package/src/utils/persistence/keyDerivation.ts +304 -0
- package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
- package/src/utils/security/secureStorage.ts +5 -5
- package/src/utils/storage/README.md +1 -1
- package/src/utils/storage/helpers.ts +3 -3
- package/src/utils/supabase/createBaseClient.ts +147 -0
- package/src/utils/timezone/timezone.test.ts +1 -2
- package/src/utils/timezone/timezone.ts +1 -1
- package/src/utils/validation/csrf.ts +4 -4
- package/cursor-rules/00-pace-core-compliance.mdc +0 -331
- package/cursor-rules/01-standards-compliance.mdc +0 -244
- package/cursor-rules/04-testing-standards.mdc +0 -268
- package/cursor-rules/05-bug-reports-and-features.mdc +0 -246
- package/cursor-rules/06-code-quality.mdc +0 -309
- package/cursor-rules/07-tech-stack-compliance.mdc +0 -214
- package/cursor-rules/CHANGELOG.md +0 -119
- package/cursor-rules/README.md +0 -192
- package/dist/DataTable-AOVNCPTX.js +0 -175
- package/dist/DataTable-AOVNCPTX.js.map +0 -1
- package/dist/UnifiedAuthProvider-4SBX4LU5.js +0 -18
- package/dist/UnifiedAuthProvider-4SBX4LU5.js.map +0 -1
- package/dist/api-O6HTBX5Y.js +0 -52
- package/dist/api-O6HTBX5Y.js.map +0 -1
- package/dist/audit-V53FV5AG.js +0 -17
- package/dist/audit-V53FV5AG.js.map +0 -1
- package/dist/chunk-5DRSZLL2.js.map +0 -1
- package/dist/chunk-63FOKYGO.js.map +0 -1
- package/dist/chunk-6COVEUS7.js.map +0 -1
- package/dist/chunk-AFVQODI2.js +0 -263
- package/dist/chunk-AFVQODI2.js.map +0 -1
- package/dist/chunk-DGUM43GV.js.map +0 -1
- package/dist/chunk-E66EQZE6.js.map +0 -1
- package/dist/chunk-EFN2EIMK.js.map +0 -1
- package/dist/chunk-FFQEQTNW.js.map +0 -1
- package/dist/chunk-FMUCXFII.js.map +0 -1
- package/dist/chunk-G37KK66H.js.map +0 -1
- package/dist/chunk-G7QEZTYQ.js +0 -2053
- package/dist/chunk-G7QEZTYQ.js.map +0 -1
- package/dist/chunk-HU2C6SSC.js.map +0 -1
- package/dist/chunk-IHB5DR3H.js.map +0 -1
- package/dist/chunk-IVOFDYWT.js.map +0 -1
- package/dist/chunk-J36DSWQK.js.map +0 -1
- package/dist/chunk-JGRYX5UX.js.map +0 -1
- package/dist/chunk-KQCRWDSA.js +0 -1
- package/dist/chunk-KQCRWDSA.js.map +0 -1
- package/dist/chunk-L4OXEN46.js.map +0 -1
- package/dist/chunk-LMC26NLJ.js +0 -84
- package/dist/chunk-LMC26NLJ.js.map +0 -1
- package/dist/chunk-M43Y4SSO.js.map +0 -1
- package/dist/chunk-M7MPQISP.js.map +0 -1
- package/dist/chunk-NTM7ZSB6.js.map +0 -1
- package/dist/chunk-PWLANIRT.js.map +0 -1
- package/dist/chunk-QXHPKYJV.js.map +0 -1
- package/dist/chunk-RGAWHO7N.js.map +0 -1
- package/dist/chunk-UPPMRMYG.js.map +0 -1
- package/dist/chunk-VBXEHIUJ.js.map +0 -1
- package/dist/chunk-ZSAAAMVR.js.map +0 -1
- package/dist/components.js.map +0 -1
- package/dist/contextValidator-5OGXSPKS.js +0 -9
- package/dist/contextValidator-5OGXSPKS.js.map +0 -1
- package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
- package/dist/hooks.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/providers.js.map +0 -1
- package/dist/rbac/eslint-rules.js.map +0 -1
- package/dist/rbac/index.js.map +0 -1
- package/dist/styles/index.js.map +0 -1
- package/dist/theming/runtime.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.js.map +0 -1
- package/docs/best-practices/README.md +0 -472
- package/docs/best-practices/accessibility.md +0 -601
- package/docs/best-practices/common-patterns.md +0 -516
- package/docs/best-practices/deployment.md +0 -1103
- package/docs/best-practices/performance.md +0 -1328
- package/docs/best-practices/security.md +0 -940
- package/docs/best-practices/testing.md +0 -1034
- package/docs/rbac/compliance/compliance-guide.md +0 -544
- package/docs/standards/01-architecture-standard.md +0 -44
- package/docs/standards/02-api-and-rpc-standard.md +0 -39
- package/docs/standards/03-component-standard.md +0 -32
- package/docs/standards/04-code-style-standard.md +0 -32
- package/docs/standards/05-security-standard.md +0 -44
- package/docs/standards/06-testing-and-docs-standard.md +0 -29
- package/docs/standards/pace-core-compliance.md +0 -432
- package/scripts/audit/core/checks/accessibility.cjs +0 -197
- package/scripts/audit/core/checks/api-usage.cjs +0 -191
- package/scripts/audit/core/checks/bundle.cjs +0 -142
- package/scripts/audit/core/checks/compliance.cjs +0 -2706
- package/scripts/audit/core/checks/config.cjs +0 -54
- package/scripts/audit/core/checks/coverage.cjs +0 -84
- package/scripts/audit/core/checks/dependencies.cjs +0 -994
- package/scripts/audit/core/checks/documentation.cjs +0 -268
- package/scripts/audit/core/checks/environment.cjs +0 -116
- package/scripts/audit/core/checks/error-handling.cjs +0 -340
- package/scripts/audit/core/checks/forms.cjs +0 -172
- package/scripts/audit/core/checks/heuristics.cjs +0 -68
- package/scripts/audit/core/checks/hooks.cjs +0 -334
- package/scripts/audit/core/checks/imports.cjs +0 -244
- package/scripts/audit/core/checks/performance.cjs +0 -325
- package/scripts/audit/core/checks/routes.cjs +0 -117
- package/scripts/audit/core/checks/state.cjs +0 -130
- package/scripts/audit/core/checks/structure.cjs +0 -65
- package/scripts/audit/core/checks/style.cjs +0 -584
- package/scripts/audit/core/checks/testing.cjs +0 -122
- package/scripts/audit/core/checks/typescript.cjs +0 -61
- package/scripts/audit/core/scanner.cjs +0 -199
- package/scripts/audit/core/utils.cjs +0 -137
- package/scripts/audit/index.cjs +0 -223
- package/scripts/audit/reporters/console.cjs +0 -151
- package/scripts/audit/reporters/json.cjs +0 -54
- package/scripts/audit/reporters/markdown.cjs +0 -124
- package/scripts/audit-consuming-app.cjs +0 -86
- package/src/components/DataTable/components/DataTableBody.tsx +0 -454
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -156
- package/src/components/DataTable/components/ExpandButton.tsx +0 -113
- package/src/components/DataTable/components/GroupHeader.tsx +0 -54
- package/src/components/DataTable/components/ViewRowModal.tsx +0 -68
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -525
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -462
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +0 -393
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +0 -476
- package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +0 -128
- package/src/components/DataTable/core/DataTableContext.tsx +0 -216
- package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +0 -136
- package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +0 -570
- package/src/components/DataTable/hooks/useColumnReordering.ts +0 -123
- package/src/components/DataTable/utils/debugTools.ts +0 -514
- package/src/eslint-rules/pace-core-compliance.js +0 -638
- package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
- package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
- package/src/rbac/components/NavigationProvider.test.tsx +0 -481
- package/src/rbac/components/NavigationProvider.tsx +0 -345
- package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
- package/src/rbac/components/PagePermissionProvider.tsx +0 -279
- package/src/rbac/components/PermissionEnforcer.tsx +0 -312
- package/src/rbac/components/RoleBasedRouter.tsx +0 -440
- package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
- package/src/rbac/components/SecureDataProvider.tsx +0 -339
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
- package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
|
@@ -77,21 +77,21 @@ const DebouncedSearch = () => {
|
|
|
77
77
|
}, [debouncedSearchTerm]);
|
|
78
78
|
|
|
79
79
|
return (
|
|
80
|
-
<
|
|
80
|
+
<section>
|
|
81
81
|
<Input
|
|
82
82
|
data-testid="search-input"
|
|
83
83
|
value={searchTerm}
|
|
84
84
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
85
85
|
placeholder="Search..."
|
|
86
86
|
/>
|
|
87
|
-
<
|
|
88
|
-
<
|
|
89
|
-
<
|
|
87
|
+
<p data-testid="search-term">Current: {searchTerm}</p>
|
|
88
|
+
<p data-testid="debounced-term">Debounced: {debouncedSearchTerm}</p>
|
|
89
|
+
<section data-testid="results">
|
|
90
90
|
{searchResults.map((result, index) => (
|
|
91
|
-
<
|
|
91
|
+
<p key={index} data-testid={`result-${index}`}>{result}</p>
|
|
92
92
|
))}
|
|
93
|
-
</
|
|
94
|
-
</
|
|
93
|
+
</section>
|
|
94
|
+
</section>
|
|
95
95
|
);
|
|
96
96
|
};
|
|
97
97
|
|
|
@@ -100,17 +100,17 @@ const ResponsiveComponent = () => {
|
|
|
100
100
|
const isMobile = useIsMobile();
|
|
101
101
|
|
|
102
102
|
return (
|
|
103
|
-
<
|
|
104
|
-
<
|
|
103
|
+
<section>
|
|
104
|
+
<p data-testid="device-type">
|
|
105
105
|
{isMobile ? 'Mobile' : 'Desktop'}
|
|
106
|
-
</
|
|
106
|
+
</p>
|
|
107
107
|
<Button
|
|
108
108
|
data-testid="responsive-button"
|
|
109
109
|
className={isMobile ? 'mobile-button' : 'desktop-button'}
|
|
110
110
|
>
|
|
111
111
|
{isMobile ? 'Mobile Action' : 'Desktop Action'}
|
|
112
112
|
</Button>
|
|
113
|
-
</
|
|
113
|
+
</section>
|
|
114
114
|
);
|
|
115
115
|
};
|
|
116
116
|
|
|
@@ -138,7 +138,7 @@ const ValidatedForm = ({ onSubmit }: ValidatedFormProps = {}) => {
|
|
|
138
138
|
onSubmit={handleSubmit}
|
|
139
139
|
>
|
|
140
140
|
{(methods) => (
|
|
141
|
-
<ValidatedFormFields methods={methods} />
|
|
141
|
+
<ValidatedFormFields methods={methods as any} />
|
|
142
142
|
)}
|
|
143
143
|
</Form>
|
|
144
144
|
);
|
|
@@ -151,27 +151,27 @@ const ValidatedFormFields = ({ methods }: { methods: ReturnType<typeof useForm>
|
|
|
151
151
|
|
|
152
152
|
return (
|
|
153
153
|
<>
|
|
154
|
-
<
|
|
154
|
+
<section>
|
|
155
155
|
<Input
|
|
156
156
|
{...methods.register('name')}
|
|
157
157
|
data-testid="name-input"
|
|
158
158
|
placeholder="Name"
|
|
159
159
|
/>
|
|
160
160
|
{errors.name && (
|
|
161
|
-
<
|
|
161
|
+
<p data-testid="name-error">{String(errors.name.message)}</p>
|
|
162
162
|
)}
|
|
163
|
-
</
|
|
164
|
-
<
|
|
163
|
+
</section>
|
|
164
|
+
<section>
|
|
165
165
|
<Input
|
|
166
166
|
{...methods.register('email')}
|
|
167
167
|
data-testid="email-input"
|
|
168
168
|
placeholder="Email"
|
|
169
169
|
/>
|
|
170
170
|
{errors.email && (
|
|
171
|
-
<
|
|
171
|
+
<p data-testid="email-error">{String(errors.email.message)}</p>
|
|
172
172
|
)}
|
|
173
|
-
</
|
|
174
|
-
<
|
|
173
|
+
</section>
|
|
174
|
+
<section>
|
|
175
175
|
<Input
|
|
176
176
|
{...methods.register('age', { valueAsNumber: true })}
|
|
177
177
|
data-testid="age-input"
|
|
@@ -179,9 +179,9 @@ const ValidatedFormFields = ({ methods }: { methods: ReturnType<typeof useForm>
|
|
|
179
179
|
placeholder="Age"
|
|
180
180
|
/>
|
|
181
181
|
{errors.age && (
|
|
182
|
-
<
|
|
182
|
+
<p data-testid="age-error">{String(errors.age.message)}</p>
|
|
183
183
|
)}
|
|
184
|
-
</
|
|
184
|
+
</section>
|
|
185
185
|
<Button type="submit" data-testid="submit-button">
|
|
186
186
|
Submit
|
|
187
187
|
</Button>
|
|
@@ -211,20 +211,20 @@ const KeyboardShortcutsComponent = () => {
|
|
|
211
211
|
useKeyboardShortcuts(shortcuts);
|
|
212
212
|
|
|
213
213
|
return (
|
|
214
|
-
<
|
|
214
|
+
<section>
|
|
215
215
|
<Button onClick={() => setIsModalOpen(true)} data-testid="open-modal">
|
|
216
216
|
Open Modal
|
|
217
217
|
</Button>
|
|
218
218
|
{isModalOpen && (
|
|
219
|
-
<
|
|
220
|
-
<
|
|
219
|
+
<section data-testid="modal">
|
|
220
|
+
<p>Modal Content</p>
|
|
221
221
|
<Button onClick={() => setIsModalOpen(false)} data-testid="close-modal">
|
|
222
222
|
Close
|
|
223
223
|
</Button>
|
|
224
|
-
</
|
|
224
|
+
</section>
|
|
225
225
|
)}
|
|
226
|
-
<
|
|
227
|
-
</
|
|
226
|
+
<p data-testid="saved-status">{savedData}</p>
|
|
227
|
+
</section>
|
|
228
228
|
);
|
|
229
229
|
};
|
|
230
230
|
|
|
@@ -238,13 +238,13 @@ const FocusManagementComponent = () => {
|
|
|
238
238
|
});
|
|
239
239
|
|
|
240
240
|
return (
|
|
241
|
-
<
|
|
241
|
+
<section ref={focusManager.containerRef}>
|
|
242
242
|
<Button data-testid="first-button">First Button</Button>
|
|
243
243
|
<Input data-testid="first-input" placeholder="First Input" />
|
|
244
244
|
<Button data-testid="second-button">Second Button</Button>
|
|
245
245
|
<Input data-testid="second-input" placeholder="Second Input" />
|
|
246
246
|
<Button data-testid="last-button">Last Button</Button>
|
|
247
|
-
</
|
|
247
|
+
</section>
|
|
248
248
|
);
|
|
249
249
|
};
|
|
250
250
|
|
|
@@ -257,10 +257,10 @@ const PerformanceTestComponent = () => {
|
|
|
257
257
|
});
|
|
258
258
|
|
|
259
259
|
return (
|
|
260
|
-
<
|
|
260
|
+
<section data-testid="performance-component">
|
|
261
261
|
<h1>Performance Test Component</h1>
|
|
262
262
|
<p>This component is being monitored for performance.</p>
|
|
263
|
-
</
|
|
263
|
+
</section>
|
|
264
264
|
);
|
|
265
265
|
};
|
|
266
266
|
|
|
@@ -269,19 +269,19 @@ const DataTableStateComponent = () => {
|
|
|
269
269
|
const tableState = useDataTableState({ initialPageSize: 10, data: [] });
|
|
270
270
|
|
|
271
271
|
return (
|
|
272
|
-
<
|
|
273
|
-
<
|
|
272
|
+
<section>
|
|
273
|
+
<p data-testid="sorting-state">
|
|
274
274
|
Sorting: {JSON.stringify(tableState.state.sorting)}
|
|
275
|
-
</
|
|
276
|
-
<
|
|
275
|
+
</p>
|
|
276
|
+
<p data-testid="filters-state">
|
|
277
277
|
Filters: {JSON.stringify(tableState.state.columnFilters)}
|
|
278
|
-
</
|
|
279
|
-
<
|
|
278
|
+
</p>
|
|
279
|
+
<p data-testid="page-state">
|
|
280
280
|
Page: {tableState.state.pageIndex + 1} of {Math.ceil(100 / tableState.state.pageSize)}
|
|
281
|
-
</
|
|
282
|
-
<
|
|
281
|
+
</p>
|
|
282
|
+
<p data-testid="selected-rows">
|
|
283
283
|
Selected: {tableState.state.selectedRows.length} rows
|
|
284
|
-
</
|
|
284
|
+
</p>
|
|
285
285
|
<Button
|
|
286
286
|
onClick={() => tableState.actions.setSorting([{ id: 'name', desc: false }])}
|
|
287
287
|
data-testid="sort-name"
|
|
@@ -294,7 +294,7 @@ const DataTableStateComponent = () => {
|
|
|
294
294
|
>
|
|
295
295
|
Filter Active
|
|
296
296
|
</Button>
|
|
297
|
-
</
|
|
297
|
+
</section>
|
|
298
298
|
);
|
|
299
299
|
};
|
|
300
300
|
|
|
@@ -332,7 +332,7 @@ describe('Hooks Integration', () => {
|
|
|
332
332
|
await user.type(searchInput, 'abc');
|
|
333
333
|
|
|
334
334
|
// Should not show results immediately
|
|
335
|
-
expect(screen.queryByTestId('result-0')).
|
|
335
|
+
expect(screen.queryByTestId('result-0')).toBeNull();
|
|
336
336
|
|
|
337
337
|
// Wait for final debounced value
|
|
338
338
|
await waitFor(() => {
|
|
@@ -402,11 +402,11 @@ describe('Hooks Integration', () => {
|
|
|
402
402
|
const emailError = screen.queryByTestId('email-error');
|
|
403
403
|
const ageError = screen.queryByTestId('age-error');
|
|
404
404
|
|
|
405
|
-
expect(nameError).
|
|
405
|
+
expect(nameError).toBeDefined();
|
|
406
406
|
expect(nameError).toHaveTextContent('Name must be at least 2 characters');
|
|
407
|
-
expect(emailError).
|
|
407
|
+
expect(emailError).toBeDefined();
|
|
408
408
|
expect(emailError).toHaveTextContent('Invalid email address');
|
|
409
|
-
expect(ageError).
|
|
409
|
+
expect(ageError).toBeDefined();
|
|
410
410
|
expect(ageError).toHaveTextContent('Must be at least 18 years old');
|
|
411
411
|
}, { timeout: 5000 });
|
|
412
412
|
});
|
|
@@ -433,15 +433,13 @@ describe('Hooks Integration', () => {
|
|
|
433
433
|
});
|
|
434
434
|
|
|
435
435
|
// Assert that onSubmit was called with the correct form data
|
|
436
|
+
// Note: Form component only passes data, not methods (react-hook-form behavior)
|
|
436
437
|
await waitFor(() => {
|
|
437
|
-
expect(mockOnSubmit).toHaveBeenCalledWith(
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
},
|
|
443
|
-
expect.any(Object) // Form methods object
|
|
444
|
-
);
|
|
438
|
+
expect(mockOnSubmit).toHaveBeenCalledWith({
|
|
439
|
+
name: 'John Doe',
|
|
440
|
+
email: 'john@example.com',
|
|
441
|
+
age: 25,
|
|
442
|
+
});
|
|
445
443
|
});
|
|
446
444
|
});
|
|
447
445
|
});
|
|
@@ -453,13 +451,13 @@ describe('Hooks Integration', () => {
|
|
|
453
451
|
const openButton = screen.getByTestId('open-modal');
|
|
454
452
|
fireEvent.click(openButton);
|
|
455
453
|
|
|
456
|
-
expect(screen.getByTestId('modal')).
|
|
454
|
+
expect(screen.getByTestId('modal')).toBeDefined();
|
|
457
455
|
|
|
458
456
|
// Test Escape key
|
|
459
457
|
fireEvent.keyDown(document, { key: 'Escape' });
|
|
460
458
|
|
|
461
459
|
await waitFor(() => {
|
|
462
|
-
expect(screen.queryByTestId('modal')).
|
|
460
|
+
expect(screen.queryByTestId('modal')).toBeNull();
|
|
463
461
|
});
|
|
464
462
|
});
|
|
465
463
|
|
|
@@ -514,7 +512,7 @@ describe('Hooks Integration', () => {
|
|
|
514
512
|
|
|
515
513
|
renderWithProviders(<PerformanceTestComponent />);
|
|
516
514
|
|
|
517
|
-
expect(screen.getByTestId('performance-component')).
|
|
515
|
+
expect(screen.getByTestId('performance-component')).toBeDefined();
|
|
518
516
|
|
|
519
517
|
// Simulate slow render
|
|
520
518
|
mockPerformance.now.mockReturnValueOnce(0);
|
|
@@ -531,7 +529,7 @@ describe('Hooks Integration', () => {
|
|
|
531
529
|
// Note: This test may need to be updated based on how useComponentPerformance is used
|
|
532
530
|
// The Logger mock should be checked if logging is enabled
|
|
533
531
|
// For now, we verify the component renders without errors
|
|
534
|
-
expect(screen.getByTestId('performance-component')).
|
|
532
|
+
expect(screen.getByTestId('performance-component')).toBeDefined();
|
|
535
533
|
});
|
|
536
534
|
});
|
|
537
535
|
|
|
@@ -2,18 +2,87 @@ import { renderHook } from '@testing-library/react';
|
|
|
2
2
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { useAppConfig } from '../useAppConfig';
|
|
5
|
+
import { UnifiedAuthContext } from '../../providers/services/UnifiedAuthProvider';
|
|
5
6
|
|
|
6
7
|
// Declare mock functions
|
|
7
8
|
const mockUseIsPublicPage = vi.fn();
|
|
8
9
|
const mockUseUnifiedAuthFn = vi.fn();
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
// Helper to create a minimal auth context value
|
|
12
|
+
const createAuthValue = (overrides: any = {}) => ({
|
|
13
|
+
appName: 'PACE',
|
|
14
|
+
user: null,
|
|
15
|
+
session: null,
|
|
16
|
+
isAuthenticated: false,
|
|
17
|
+
authLoading: false,
|
|
18
|
+
authError: null,
|
|
19
|
+
supabase: null,
|
|
20
|
+
appId: undefined,
|
|
21
|
+
selectedOrganisation: null,
|
|
22
|
+
selectedOrganisationId: null,
|
|
23
|
+
organisations: [],
|
|
24
|
+
userMemberships: [],
|
|
25
|
+
organisationLoading: false,
|
|
26
|
+
organisationError: null,
|
|
27
|
+
hasValidOrganisationContext: false,
|
|
28
|
+
isContextReady: false,
|
|
29
|
+
switchOrganisation: vi.fn(),
|
|
30
|
+
getUserRole: vi.fn(),
|
|
31
|
+
validateOrganisationAccess: vi.fn(),
|
|
32
|
+
refreshOrganisations: vi.fn(),
|
|
33
|
+
ensureOrganisationContext: vi.fn(),
|
|
34
|
+
isOrganisationSecure: vi.fn(),
|
|
35
|
+
getPrimaryOrganisation: vi.fn(),
|
|
36
|
+
events: [],
|
|
37
|
+
selectedEvent: null,
|
|
38
|
+
selectedEventId: null,
|
|
39
|
+
eventLoading: false,
|
|
40
|
+
eventError: null,
|
|
41
|
+
setSelectedEvent: vi.fn(),
|
|
42
|
+
refreshEvents: vi.fn(),
|
|
43
|
+
showInactivityWarning: false,
|
|
44
|
+
inactivityTimeRemaining: 0,
|
|
45
|
+
isIdle: false,
|
|
46
|
+
timeRemaining: 0,
|
|
47
|
+
showWarning: false,
|
|
48
|
+
isTracking: false,
|
|
49
|
+
resetActivity: vi.fn(),
|
|
50
|
+
startTracking: vi.fn(),
|
|
51
|
+
stopTracking: vi.fn(),
|
|
52
|
+
handleIdleLogout: vi.fn(),
|
|
53
|
+
handleStaySignedIn: vi.fn(),
|
|
54
|
+
handleSignOutNow: vi.fn(),
|
|
55
|
+
signIn: vi.fn(),
|
|
56
|
+
signUp: vi.fn(),
|
|
57
|
+
signOut: vi.fn(),
|
|
58
|
+
resetPassword: vi.fn(),
|
|
59
|
+
updatePassword: vi.fn(),
|
|
60
|
+
refreshSession: vi.fn(),
|
|
61
|
+
isLoading: false,
|
|
62
|
+
hasErrors: false,
|
|
63
|
+
sessionRestoration: {
|
|
64
|
+
isRestoring: false,
|
|
65
|
+
restorationComplete: false,
|
|
66
|
+
restorationError: null,
|
|
67
|
+
},
|
|
68
|
+
sessionRestorationTimedOut: false,
|
|
69
|
+
sessionRestorationTimeoutMs: 0,
|
|
70
|
+
...overrides,
|
|
15
71
|
});
|
|
16
72
|
|
|
73
|
+
// Helper to create a wrapper component that provides UnifiedAuthContext
|
|
74
|
+
const createAuthWrapper = (authValue: any) => {
|
|
75
|
+
return ({ children }: { children: React.ReactNode }) => {
|
|
76
|
+
return React.createElement(
|
|
77
|
+
UnifiedAuthContext.Provider,
|
|
78
|
+
{
|
|
79
|
+
value: authValue,
|
|
80
|
+
},
|
|
81
|
+
children
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
17
86
|
vi.mock('../../components/PublicLayout/PublicPageProvider', async (importOriginal) => {
|
|
18
87
|
const actual = await importOriginal<typeof import('../../components/PublicLayout/PublicPageProvider')>();
|
|
19
88
|
return {
|
|
@@ -22,7 +91,6 @@ vi.mock('../../components/PublicLayout/PublicPageProvider', async (importOrigina
|
|
|
22
91
|
};
|
|
23
92
|
});
|
|
24
93
|
|
|
25
|
-
import { useUnifiedAuth as actualUseUnifiedAuth } from '../../providers/services/UnifiedAuthProvider';
|
|
26
94
|
import { useIsPublicPage as actualUseIsPublicPage } from '../../components/PublicLayout/PublicPageProvider';
|
|
27
95
|
import { PublicPageContext } from '../../components/PublicLayout/PublicPageProvider';
|
|
28
96
|
|
|
@@ -31,25 +99,28 @@ describe('useAppConfig Hook', () => {
|
|
|
31
99
|
const originalUseContext = React.useContext;
|
|
32
100
|
const originalEnv = import.meta.env;
|
|
33
101
|
|
|
102
|
+
// Store the real UnifiedAuthContext for comparison
|
|
103
|
+
const realUnifiedAuthContext = UnifiedAuthContext;
|
|
104
|
+
|
|
34
105
|
beforeEach(() => {
|
|
35
106
|
// Set up the mocks to use our mock functions
|
|
36
107
|
vi.mocked(actualUseIsPublicPage).mockImplementation(mockUseIsPublicPage);
|
|
37
108
|
|
|
38
|
-
// Mock useContext to return
|
|
39
|
-
// This ensures the hook
|
|
109
|
+
// Mock useContext to return values for UnifiedAuthContext and PublicPageContext
|
|
110
|
+
// This ensures the hook gets the correct values
|
|
40
111
|
vi.spyOn(React, 'useContext').mockImplementation((context) => {
|
|
41
|
-
// Check if this is the
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
112
|
+
// Check if this is the UnifiedAuthContext (use the real one from the import)
|
|
113
|
+
if (context === realUnifiedAuthContext) {
|
|
114
|
+
// Return the value from mockUseUnifiedAuthFn if it's set, otherwise return null
|
|
115
|
+
const mockValue = mockUseUnifiedAuthFn();
|
|
116
|
+
return mockValue !== undefined ? mockValue : null;
|
|
117
|
+
}
|
|
118
|
+
// Check if this is the PublicPageContext
|
|
119
|
+
if (context === PublicPageContext) {
|
|
120
|
+
// Return undefined to simulate no provider
|
|
121
|
+
return undefined;
|
|
52
122
|
}
|
|
123
|
+
// For other contexts, use original implementation
|
|
53
124
|
return originalUseContext(context);
|
|
54
125
|
});
|
|
55
126
|
|
|
@@ -136,21 +207,23 @@ describe('useAppConfig Hook', () => {
|
|
|
136
207
|
|
|
137
208
|
it('should return configuration from UnifiedAuthProvider when available', () => {
|
|
138
209
|
const mockAppName = 'AuthApp';
|
|
210
|
+
|
|
211
|
+
// Ensure we're not in public page mode
|
|
212
|
+
mockUseIsPublicPage.mockReturnValue(false);
|
|
139
213
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const { result } = renderHook(() => useAppConfig());
|
|
214
|
+
// Use wrapper to provide UnifiedAuthContext
|
|
215
|
+
const authValue = createAuthValue({ appName: mockAppName });
|
|
216
|
+
const wrapper = createAuthWrapper(authValue);
|
|
217
|
+
const { result } = renderHook(() => useAppConfig(), { wrapper });
|
|
145
218
|
|
|
146
219
|
expect(result.current.isLoading).toBe(false);
|
|
147
220
|
expect(result.current.appName).toBe('AuthApp');
|
|
148
221
|
});
|
|
149
222
|
|
|
150
223
|
it('should handle UnifiedAuthProvider error and return fallback', () => {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
224
|
+
// Since useAppConfig now uses useContext directly, missing provider returns null
|
|
225
|
+
// Mock useContext to return null for UnifiedAuthContext (simulating missing provider)
|
|
226
|
+
mockUseUnifiedAuthFn.mockReturnValue(null as any);
|
|
154
227
|
|
|
155
228
|
const { result } = renderHook(() => useAppConfig());
|
|
156
229
|
|
|
@@ -159,9 +232,9 @@ describe('useAppConfig Hook', () => {
|
|
|
159
232
|
});
|
|
160
233
|
|
|
161
234
|
it('should handle different types of errors from UnifiedAuthProvider', () => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
235
|
+
// Since useAppConfig now uses useContext directly, missing provider returns null
|
|
236
|
+
// Mock useContext to return null for UnifiedAuthContext (simulating missing provider)
|
|
237
|
+
mockUseUnifiedAuthFn.mockReturnValue(null as any);
|
|
165
238
|
|
|
166
239
|
const { result } = renderHook(() => useAppConfig());
|
|
167
240
|
|
|
@@ -170,9 +243,9 @@ describe('useAppConfig Hook', () => {
|
|
|
170
243
|
});
|
|
171
244
|
|
|
172
245
|
it('should handle non-Error exceptions from UnifiedAuthProvider', () => {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
246
|
+
// Since useAppConfig now uses useContext directly, missing provider returns null
|
|
247
|
+
// Mock useContext to return null for UnifiedAuthContext (simulating missing provider)
|
|
248
|
+
mockUseUnifiedAuthFn.mockReturnValue(null as any);
|
|
176
249
|
|
|
177
250
|
const { result } = renderHook(() => useAppConfig());
|
|
178
251
|
|
|
@@ -197,52 +270,43 @@ describe('useAppConfig Hook', () => {
|
|
|
197
270
|
it('should memoize authenticated configuration based on dependencies', () => {
|
|
198
271
|
mockUseIsPublicPage.mockReturnValue(false);
|
|
199
272
|
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
appName: mockAppName,
|
|
204
|
-
} as any);
|
|
205
|
-
|
|
206
|
-
const { result, rerender } = renderHook(() => useAppConfig());
|
|
273
|
+
const authValue1 = createAuthValue({ appName: 'TestApp' });
|
|
274
|
+
const wrapper1 = createAuthWrapper(authValue1);
|
|
275
|
+
const { result, rerender } = renderHook(() => useAppConfig(), { wrapper: wrapper1 });
|
|
207
276
|
|
|
208
277
|
const firstResult = result.current;
|
|
278
|
+
expect(firstResult.appName).toBe('TestApp');
|
|
209
279
|
|
|
210
280
|
// Rerender with same props
|
|
211
281
|
rerender();
|
|
212
|
-
|
|
213
282
|
expect(result.current).toBe(firstResult);
|
|
214
283
|
|
|
215
|
-
// Rerender with different appName
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
284
|
+
// Rerender with different appName - need new wrapper with new value
|
|
285
|
+
const authValue2 = createAuthValue({ appName: 'DifferentApp' });
|
|
286
|
+
const wrapper2 = createAuthWrapper(authValue2);
|
|
287
|
+
const { result: result2 } = renderHook(() => useAppConfig(), { wrapper: wrapper2 });
|
|
219
288
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
expect(result.current).not.toBe(firstResult);
|
|
223
|
-
expect(result.current.appName).toBe('DifferentApp');
|
|
289
|
+
expect(result2.current).not.toBe(firstResult);
|
|
290
|
+
expect(result2.current.appName).toBe('DifferentApp');
|
|
224
291
|
});
|
|
225
292
|
|
|
226
293
|
it('should memoize authenticated configuration based on appName changes', () => {
|
|
227
294
|
mockUseIsPublicPage.mockReturnValue(false);
|
|
228
295
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const { result, rerender } = renderHook(() => useAppConfig());
|
|
296
|
+
const authValue1 = createAuthValue({ appName: 'App1' });
|
|
297
|
+
const wrapper1 = createAuthWrapper(authValue1);
|
|
298
|
+
const { result, rerender } = renderHook(() => useAppConfig(), { wrapper: wrapper1 });
|
|
234
299
|
|
|
235
300
|
const firstResult = result.current;
|
|
301
|
+
expect(firstResult.appName).toBe('App1');
|
|
236
302
|
|
|
237
|
-
// Rerender with different appName
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
303
|
+
// Rerender with different appName - need new wrapper with new value
|
|
304
|
+
const authValue2 = createAuthValue({ appName: 'App2' });
|
|
305
|
+
const wrapper2 = createAuthWrapper(authValue2);
|
|
306
|
+
const { result: result2 } = renderHook(() => useAppConfig(), { wrapper: wrapper2 });
|
|
241
307
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
expect(result.current).not.toBe(firstResult);
|
|
245
|
-
expect(result.current.appName).toBe('App2');
|
|
308
|
+
expect(result2.current).not.toBe(firstResult);
|
|
309
|
+
expect(result2.current.appName).toBe('App2');
|
|
246
310
|
});
|
|
247
311
|
});
|
|
248
312
|
|
|
@@ -259,11 +323,9 @@ describe('useAppConfig Hook', () => {
|
|
|
259
323
|
|
|
260
324
|
// Test authenticated page context separately
|
|
261
325
|
mockUseIsPublicPage.mockReturnValue(false);
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const { result: authResult } = renderHook(() => useAppConfig());
|
|
326
|
+
const authValue = createAuthValue({ appName: 'AuthApp' });
|
|
327
|
+
const authWrapper = createAuthWrapper(authValue);
|
|
328
|
+
const { result: authResult } = renderHook(() => useAppConfig(), { wrapper: authWrapper });
|
|
267
329
|
|
|
268
330
|
expect(authResult.current.appName).toBe('AuthApp');
|
|
269
331
|
});
|