@jmruthers/pace-core 0.2.7 → 0.5.1
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/dist/{DataTable-EEUDXPE5.js → DataTable-GX3XERFJ.js} +8 -4
- package/dist/{DataTable-C1AEm9Cx.d.ts → DataTable-ltTFXHS3.d.ts} +3 -1
- package/dist/{chunk-VYG4AXYW.js → chunk-5EL3KHOQ.js} +2 -2
- package/dist/{chunk-ETEJVKYK.js → chunk-6CR3MRZN.js} +1426 -62
- package/dist/chunk-6CR3MRZN.js.map +1 -0
- package/dist/chunk-AUE24LVR.js +268 -0
- package/dist/chunk-AUE24LVR.js.map +1 -0
- package/dist/chunk-COBPIXXQ.js +379 -0
- package/dist/chunk-COBPIXXQ.js.map +1 -0
- package/dist/{chunk-EWKPTNPO.js → chunk-GSNM5D6H.js} +388 -86
- package/dist/chunk-GSNM5D6H.js.map +1 -0
- package/dist/{chunk-2V3Y6YBC.js → chunk-OEGRKULD.js} +1 -42
- package/dist/chunk-OEGRKULD.js.map +1 -0
- package/dist/chunk-OYRY44Q2.js +62 -0
- package/dist/chunk-OYRY44Q2.js.map +1 -0
- package/dist/{chunk-RRUYHORU.js → chunk-T3XIA4AJ.js} +297 -433
- package/dist/chunk-T3XIA4AJ.js.map +1 -0
- package/dist/{chunk-HEMJ4SUJ.js → chunk-TGDCLPP2.js} +11 -7
- package/dist/{chunk-HEMJ4SUJ.js.map → chunk-TGDCLPP2.js.map} +1 -1
- package/dist/{chunk-HNDFPXUU.js → chunk-U6JDHVC2.js} +6 -4
- package/dist/{chunk-HNDFPXUU.js.map → chunk-U6JDHVC2.js.map} +1 -1
- package/dist/{chunk-TIVL4UQ7.js → chunk-XJK2J4N6.js} +6 -4
- package/dist/{chunk-TIVL4UQ7.js.map → chunk-XJK2J4N6.js.map} +1 -1
- package/dist/components.d.ts +2 -2
- package/dist/components.js +21 -20
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +7 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +26 -25
- package/dist/index.js.map +1 -1
- package/dist/providers.js +8 -7
- package/dist/rbac/index.d.ts +806 -806
- package/dist/rbac/index.js +937 -1179
- package/dist/rbac/index.js.map +1 -1
- package/dist/{types-DiRQsGJs.d.ts → types-BRDU7N6w.d.ts} +12 -1
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +6 -6
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +4 -4
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +21 -8
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +46 -33
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +2 -2
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +3 -3
- package/package.json +5 -2
- package/src/__tests__/REBUILD_PLAN.md +223 -0
- package/src/__tests__/TESTING_GUIDELINES.md +341 -0
- package/src/__tests__/fixtures/mocks.ts +93 -0
- package/src/__tests__/helpers/component-test-utils.tsx +145 -0
- package/src/__tests__/helpers/test-utils.tsx +117 -0
- package/src/__tests__/integration/UserProfile.test.tsx +128 -0
- package/src/__tests__/setup.ts +37 -225
- package/src/__tests__/templates/component.test.template.tsx +97 -75
- package/src/__tests__/templates/hook.test.template.ts +173 -0
- package/src/__tests__/types/test.types.ts +106 -0
- package/src/components/Alert/Alert.test.tsx +496 -0
- package/src/components/Avatar/Avatar.test.tsx +484 -0
- package/src/components/Button/Button.test.tsx +662 -0
- package/src/components/Card/Card.test.tsx +593 -0
- package/src/components/Checkbox/Checkbox.test.tsx +461 -0
- package/src/components/DataTable/DataTable.tsx +9 -1
- package/src/components/DataTable/components/AccessDeniedPage.tsx +168 -0
- package/src/components/DataTable/components/ActionButtons.tsx +18 -1
- package/src/components/DataTable/components/DataTableCore.tsx +97 -11
- package/src/components/DataTable/components/DataTableToolbar.tsx +22 -10
- package/src/components/DataTable/components/UnifiedTableBody.tsx +33 -4
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -0
- package/src/components/DataTable/examples/HierarchicalExample.tsx +3 -0
- package/src/components/DataTable/examples/InitialPageSizeExample.tsx +3 -0
- package/src/components/DataTable/examples/PerformanceExample.tsx +3 -0
- package/src/components/DataTable/types.ts +39 -1
- package/src/components/Dialog/Dialog.test.tsx +1139 -0
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +752 -0
- package/src/components/FileUpload/FileUpload.test.tsx +665 -0
- package/src/hooks/useCounter.test.ts +135 -0
- package/src/rbac/index.ts +3 -3
- package/dist/chunk-2V3Y6YBC.js.map +0 -1
- package/dist/chunk-BEZRLNK3.js +0 -1744
- package/dist/chunk-BEZRLNK3.js.map +0 -1
- package/dist/chunk-ETEJVKYK.js.map +0 -1
- package/dist/chunk-EWKPTNPO.js.map +0 -1
- package/dist/chunk-OHXGNT3K.js +0 -21
- package/dist/chunk-OHXGNT3K.js.map +0 -1
- package/dist/chunk-RRUYHORU.js.map +0 -1
- package/src/__tests__/README.md +0 -404
- package/src/__tests__/debug-provider.unit.test.tsx +0 -67
- package/src/__tests__/e2e/workflows.test.tsx +0 -373
- package/src/__tests__/hybridPermissions.unit.test.tsx +0 -474
- package/src/__tests__/index.integration.test.ts +0 -491
- package/src/__tests__/mocks/MockAuthProvider-standalone.tsx +0 -47
- package/src/__tests__/mocks/MockAuthProvider.tsx +0 -63
- package/src/__tests__/mocks/enhancedSupabaseMock.ts +0 -252
- package/src/__tests__/mocks/index.test.ts +0 -23
- package/src/__tests__/mocks/index.ts +0 -16
- package/src/__tests__/mocks/mockAuth.ts +0 -155
- package/src/__tests__/mocks/mockSupabase.ts +0 -83
- package/src/__tests__/mocks/mockSupabaseClient.ts +0 -63
- package/src/__tests__/mocks/providers.tsx +0 -22
- package/src/__tests__/patterns/__tests__/testPatterns.test.ts +0 -394
- package/src/__tests__/patterns/testPatterns.ts +0 -124
- package/src/__tests__/performance/componentPerformance.performance.test.ts +0 -27
- package/src/__tests__/performance/index.ts +0 -24
- package/src/__tests__/performance/performanceValidation.performance.test.ts +0 -15
- package/src/__tests__/security/security.unit.test.tsx +0 -7
- package/src/__tests__/security/securityValidation.security.test.tsx +0 -153
- package/src/__tests__/setupTests.d.ts +0 -1
- package/src/__tests__/shared/componentTestUtils.tsx +0 -475
- package/src/__tests__/shared/errorHandlingTestUtils.ts +0 -107
- package/src/__tests__/shared/index.ts +0 -81
- package/src/__tests__/shared/integrationTestUtils.tsx +0 -375
- package/src/__tests__/shared/performanceTestUtils.tsx +0 -476
- package/src/__tests__/shared/testUtils.optimized.tsx +0 -685
- package/src/__tests__/simple.test.tsx +0 -20
- package/src/__tests__/test-utils/dataFactories.ts +0 -60
- package/src/__tests__/test-utils/index.ts +0 -6
- package/src/__tests__/typeSafety.unit.test.ts +0 -65
- package/src/__tests__/unifiedAuth.unit.test.tsx +0 -151
- package/src/__tests__/utils/accessibilityHelpers.ts +0 -254
- package/src/__tests__/utils/assertions.ts +0 -50
- package/src/__tests__/utils/deterministicHelpers.ts +0 -31
- package/src/__tests__/utils/edgeCaseConfig.test.ts +0 -75
- package/src/__tests__/utils/edgeCaseConfig.ts +0 -98
- package/src/__tests__/utils/mockHelpers.ts +0 -149
- package/src/__tests__/utils/mockLoader.ts +0 -101
- package/src/__tests__/utils/performanceHelpers.ts +0 -55
- package/src/__tests__/utils/performanceTestHelpers.ts +0 -68
- package/src/__tests__/utils/testDataFactories.ts +0 -28
- package/src/__tests__/utils/testIsolation.ts +0 -67
- package/src/__tests__/utils/visualTestHelpers.ts +0 -20
- package/src/__tests__/visual/__snapshots__/componentSnapshots.visual.test.tsx.snap +0 -68
- package/src/__tests__/visual/__snapshots__/componentVisuals.visual.test.tsx.snap +0 -14
- package/src/__tests__/visual/__snapshots__/visualRegression.test.tsx.snap +0 -217
- package/src/__tests__/visual/__snapshots__/visualRegression.visual.test.tsx.snap +0 -24
- package/src/__tests__/visual/componentSnapshots.visual.test.tsx +0 -33
- package/src/__tests__/visual/componentVisuals.visual.test.tsx +0 -12
- package/src/__tests__/visual/visualRegression.visual.test.tsx +0 -20
- package/src/components/Alert/__tests__/Alert.unit.test.tsx +0 -381
- package/src/components/Avatar/__tests__/Avatar.unit.test.tsx +0 -232
- package/src/components/Button/__tests__/Button.accessibility.test.tsx +0 -131
- package/src/components/Button/__tests__/Button.comprehensive.test.tsx +0 -721
- package/src/components/Button/__tests__/Button.unit.test.tsx +0 -189
- package/src/components/Button/__tests__/EventSelector.integration.test.tsx +0 -285
- package/src/components/Card/__tests__/Card.accessibility.test.tsx +0 -394
- package/src/components/Card/__tests__/Card.comprehensive.test.tsx +0 -599
- package/src/components/Card/__tests__/Card.integration.test.tsx +0 -673
- package/src/components/Card/__tests__/Card.performance.test.tsx +0 -546
- package/src/components/Card/__tests__/Card.unit.test.tsx +0 -330
- package/src/components/Card/__tests__/Card.visual.test.tsx +0 -599
- package/src/components/Card/__tests__/README.md +0 -211
- package/src/components/Checkbox/__tests__/Checkbox.unit.test.tsx +0 -520
- package/src/components/DataTable/__tests__/DataTable.errorHandling.test.tsx +0 -251
- package/src/components/DataTable/__tests__/DataTable.hierarchical.test.tsx +0 -680
- package/src/components/DataTable/__tests__/DataTable.infinite-loop.test.tsx +0 -323
- package/src/components/DataTable/__tests__/DataTable.integration.test.tsx +0 -716
- package/src/components/DataTable/__tests__/DataTable.performance.test.tsx +0 -589
- package/src/components/DataTable/__tests__/DataTable.permissions.test.tsx +0 -316
- package/src/components/DataTable/__tests__/DataTable.regressionFixes.test.tsx +0 -546
- package/src/components/DataTable/__tests__/DataTable.selection.controlled.test.tsx +0 -386
- package/src/components/DataTable/__tests__/DataTable.selection.test.tsx +0 -338
- package/src/components/DataTable/__tests__/DataTable.sorting.test.tsx +0 -321
- package/src/components/DataTable/__tests__/DataTable.userWorkflows.test.tsx +0 -320
- package/src/components/DataTable/__tests__/DataTable.workflowValidation.test.tsx +0 -583
- package/src/components/DataTable/__tests__/DataTable.workflows.test.tsx +0 -711
- package/src/components/DataTable/__tests__/performance-regression.test.tsx +0 -777
- package/src/components/DataTable/__tests__/performance.test.tsx +0 -365
- package/src/components/DataTable/components/__tests__/ActionButtons.unit.test.tsx +0 -150
- package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +0 -224
- package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.unit.test.tsx +0 -244
- package/src/components/DataTable/components/__tests__/DataTable.accessibility.test.tsx +0 -629
- package/src/components/DataTable/components/__tests__/DataTable.integration.test.tsx +0 -470
- package/src/components/DataTable/components/__tests__/DataTable.performance.test.tsx +0 -160
- package/src/components/DataTable/components/__tests__/DataTable.real.test.tsx +0 -251
- package/src/components/DataTable/components/__tests__/DataTable.security.test.tsx +0 -171
- package/src/components/DataTable/components/__tests__/DataTable.unit.test.tsx +0 -290
- package/src/components/DataTable/components/__tests__/DataTableBody.unit.test.tsx +0 -147
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.unit.test.tsx +0 -182
- package/src/components/DataTable/components/__tests__/DataTableModals.unit.test.tsx +0 -123
- package/src/components/DataTable/components/__tests__/EditableRow.unit.test.tsx +0 -660
- package/src/components/DataTable/components/__tests__/EmptyState.unit.test.tsx +0 -256
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -498
- package/src/components/DataTable/components/__tests__/FilterRow.unit.test.tsx +0 -112
- package/src/components/DataTable/components/__tests__/FilteringToggle.unit.test.tsx +0 -133
- package/src/components/DataTable/components/__tests__/GroupHeader.unit.test.tsx +0 -172
- package/src/components/DataTable/components/__tests__/GroupingDropdown.unit.test.tsx +0 -222
- package/src/components/DataTable/components/__tests__/ImportModal.unit.test.tsx +0 -780
- package/src/components/DataTable/components/__tests__/LoadingState.unit.test.tsx +0 -65
- package/src/components/DataTable/components/__tests__/PaginationControls.unit.test.tsx +0 -634
- package/src/components/DataTable/components/__tests__/StateComponents.unit.test.tsx +0 -48
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.hierarchical.test.tsx +0 -541
- package/src/components/DataTable/components/__tests__/ViewRowModal.unit.test.tsx +0 -228
- package/src/components/DataTable/components/__tests__/VirtualizedDataTable.unit.test.tsx +0 -568
- package/src/components/DataTable/core/__tests__/ActionManager.unit.test.ts +0 -405
- package/src/components/DataTable/core/__tests__/ArchitectureIntegration.unit.test.tsx +0 -445
- package/src/components/DataTable/core/__tests__/ColumnFactory.unit.test.ts +0 -288
- package/src/components/DataTable/core/__tests__/ColumnManager.unit.test.ts +0 -623
- package/src/components/DataTable/core/__tests__/DataManager.unit.test.ts +0 -431
- package/src/components/DataTable/core/__tests__/DataTableContext.unit.test.tsx +0 -433
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.unit.test.ts +0 -422
- package/src/components/DataTable/core/__tests__/PluginRegistry.unit.test.tsx +0 -207
- package/src/components/DataTable/core/__tests__/StateManager.unit.test.ts +0 -278
- package/src/components/DataTable/examples/__tests__/PerformanceExample.unit.test.tsx +0 -281
- package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.unit.test.ts +0 -407
- package/src/components/DataTable/hooks/__tests__/useColumnReordering.unit.test.ts +0 -679
- package/src/components/DataTable/utils/__tests__/debugTools.unit.test.ts +0 -267
- package/src/components/DataTable/utils/__tests__/errorHandling.unit.test.ts +0 -467
- package/src/components/DataTable/utils/__tests__/exportUtils.unit.test.ts +0 -380
- package/src/components/DataTable/utils/__tests__/flexibleImport.unit.test.ts +0 -233
- package/src/components/DataTable/utils/__tests__/performanceUtils.unit.test.ts +0 -414
- package/src/components/Dialog/__tests__/Dialog.accessibility.test.tsx +0 -521
- package/src/components/Dialog/__tests__/Dialog.auto-size.example.tsx +0 -157
- package/src/components/Dialog/__tests__/Dialog.enhanced.test.tsx +0 -538
- package/src/components/Dialog/__tests__/Dialog.unit.test.tsx +0 -1373
- package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +0 -151
- package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +0 -611
- package/src/components/ErrorBoundary/__tests__/ErrorBoundary.accessibility.test.tsx +0 -517
- package/src/components/ErrorBoundary/__tests__/ErrorBoundary.integration.test.tsx +0 -572
- package/src/components/ErrorBoundary/__tests__/ErrorBoundary.unit.test.tsx +0 -579
- package/src/components/EventSelector/__tests__/EventSelector.test.tsx +0 -528
- package/src/components/FileUpload/__tests__/FileUpload.integration.test.tsx +0 -992
- package/src/components/FileUpload/__tests__/FileUpload.real.test.tsx +0 -927
- package/src/components/FileUpload/__tests__/FileUpload.test.tsx +0 -855
- package/src/components/FileUpload/__tests__/FileUpload.unit.test.tsx +0 -1311
- package/src/components/FileUpload/__tests__/FileUpload.unmocked.test.tsx +0 -937
- package/src/components/Footer/__tests__/Footer.accessibility.test.tsx +0 -359
- package/src/components/Footer/__tests__/Footer.integration.test.tsx +0 -353
- package/src/components/Footer/__tests__/Footer.performance.test.tsx +0 -309
- package/src/components/Footer/__tests__/Footer.unit.test.tsx +0 -309
- package/src/components/Footer/__tests__/Footer.visual.test.tsx +0 -335
- package/src/components/Form/__tests__/Form.accessibility.test.tsx +0 -820
- package/src/components/Form/__tests__/Form.unit.test.tsx +0 -305
- package/src/components/Form/__tests__/FormErrorSummary.unit.test.tsx +0 -285
- package/src/components/Form/__tests__/FormFieldset.unit.test.tsx +0 -241
- package/src/components/Header/__tests__/Header.accessibility.test.tsx +0 -382
- package/src/components/Header/__tests__/Header.comprehensive.test.tsx +0 -509
- package/src/components/Header/__tests__/Header.unit.test.tsx +0 -335
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +0 -196
- package/src/components/InactivityWarningModal/__tests__/InactivityWarningModal.unit.test.tsx +0 -224
- package/src/components/Input/__tests__/Input.accessibility.test.tsx +0 -632
- package/src/components/Input/__tests__/Input.unit.test.tsx +0 -1121
- package/src/components/Label/__tests__/Label.accessibility.test.tsx +0 -239
- package/src/components/Label/__tests__/Label.unit.test.tsx +0 -331
- package/src/components/LoadingSpinner/__tests__/LoadingSpinner.accessibility.test.tsx +0 -116
- package/src/components/LoadingSpinner/__tests__/LoadingSpinner.unit.test.tsx +0 -144
- package/src/components/LoginForm/__tests__/LoginForm.accessibility.test.tsx +0 -201
- package/src/components/LoginForm/__tests__/LoginForm.unit.test.tsx +0 -119
- package/src/components/NavigationMenu/__tests__/NavigationMenu.accessibility.test.tsx +0 -378
- package/src/components/NavigationMenu/__tests__/NavigationMenu.enhanced.test.tsx +0 -768
- package/src/components/NavigationMenu/__tests__/NavigationMenu.integration.test.tsx +0 -576
- package/src/components/NavigationMenu/__tests__/NavigationMenu.performance.test.tsx +0 -585
- package/src/components/NavigationMenu/__tests__/NavigationMenu.real.component.test.tsx +0 -783
- package/src/components/NavigationMenu/__tests__/NavigationMenu.security.enhanced.test.tsx +0 -810
- package/src/components/NavigationMenu/__tests__/NavigationMenu.security.test.tsx +0 -494
- package/src/components/NavigationMenu/__tests__/NavigationMenu.unit.test.tsx +0 -331
- package/src/components/NavigationMenu/__tests__/NavigationMenu.userWorkflows.test.tsx +0 -347
- package/src/components/NavigationMenu/__tests__/NavigationMenu.workflows.test.tsx +0 -584
- package/src/components/OrganisationSelector/__tests__/OrganisationSelector.unit.test.tsx +0 -664
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +0 -288
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -893
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +0 -629
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -782
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -904
- package/src/components/PaceLoginPage/__tests__/PaceLoginPage.accessibility.test.tsx +0 -463
- package/src/components/PaceLoginPage/__tests__/PaceLoginPage.integration.test.tsx +0 -586
- package/src/components/PaceLoginPage/__tests__/PaceLoginPage.unit.test.tsx +0 -533
- package/src/components/PasswordReset/__tests__/PasswordChangeForm.accessibility.test.tsx +0 -408
- package/src/components/PasswordReset/__tests__/PasswordChangeForm.unit.test.tsx +0 -561
- package/src/components/PasswordReset/__tests__/PasswordReset.integration.test.tsx +0 -304
- package/src/components/PasswordReset/__tests__/PasswordResetForm.accessibility.test.tsx +0 -20
- package/src/components/PasswordReset/__tests__/PasswordResetForm.unit.test.tsx +0 -523
- package/src/components/PasswordReset/__tests__/__mocks__/UnifiedAuthProvider.ts +0 -29
- package/src/components/Print/__tests__/Print.comprehensive.test.tsx +0 -331
- package/src/components/PrintButton/__tests__/PrintButton.unit.test.tsx +0 -429
- package/src/components/PrintButton/__tests__/PrintButtonGroup.unit.test.tsx +0 -277
- package/src/components/PrintButton/__tests__/PrintToolbar.unit.test.tsx +0 -264
- package/src/components/PrintCard/__tests__/PrintCard.unit.test.tsx +0 -233
- package/src/components/PrintCard/__tests__/PrintCardContent.test.tsx +0 -284
- package/src/components/PrintCard/__tests__/PrintCardGrid.unit.test.tsx +0 -214
- package/src/components/PrintCard/__tests__/PrintCardImage.unit.test.tsx +0 -264
- package/src/components/PrintDataTable/__tests__/PrintDataTable.unit.test.tsx +0 -361
- package/src/components/PrintDataTable/__tests__/PrintTableGroup.unit.test.tsx +0 -314
- package/src/components/PrintDataTable/__tests__/PrintTableRow.unit.test.tsx +0 -362
- package/src/components/PrintFooter/__tests__/PrintFooter.unit.test.tsx +0 -500
- package/src/components/PrintFooter/__tests__/PrintFooterContent.unit.test.tsx +0 -321
- package/src/components/PrintFooter/__tests__/PrintFooterInfo.unit.test.tsx +0 -335
- package/src/components/PrintFooter/__tests__/PrintPageNumber.unit.test.tsx +0 -340
- package/src/components/PrintGrid/__tests__/PrintGrid.unit.test.tsx +0 -340
- package/src/components/PrintGrid/__tests__/PrintGridBreakpoint.unit.test.tsx +0 -261
- package/src/components/PrintGrid/__tests__/PrintGridContainer.unit.test.tsx +0 -338
- package/src/components/PrintGrid/__tests__/PrintGridItem.unit.test.tsx +0 -338
- package/src/components/PrintHeader/__tests__/PrintCoverHeader.unit.test.tsx +0 -309
- package/src/components/PrintHeader/__tests__/PrintHeader.unit.test.tsx +0 -202
- package/src/components/PrintLayout/__tests__/PrintLayout.unit.test.tsx +0 -238
- package/src/components/PrintPageBreak/__tests__/PrintPageBreak.unit.test.tsx +0 -263
- package/src/components/PrintPageBreak/__tests__/PrintPageBreakGroup.unit.test.tsx +0 -239
- package/src/components/PrintPageBreak/__tests__/PrintPageBreakIndicator.unit.test.tsx +0 -235
- package/src/components/PrintSection/__tests__/PrintColumn.unit.test.tsx +0 -385
- package/src/components/PrintSection/__tests__/PrintDivider.unit.test.tsx +0 -373
- package/src/components/PrintSection/__tests__/PrintSection.unit.test.tsx +0 -390
- package/src/components/PrintSection/__tests__/PrintSectionContent.unit.test.tsx +0 -321
- package/src/components/PrintSection/__tests__/PrintSectionHeader.unit.test.tsx +0 -334
- package/src/components/PrintText/__tests__/PrintText.unit.test.tsx +0 -351
- package/src/components/Progress/__tests__/Progress.accessibility.test.tsx +0 -240
- package/src/components/Progress/__tests__/Progress.unit.test.tsx +0 -242
- package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +0 -761
- package/src/components/PublicLayout/__tests__/PublicErrorBoundary.simplified.test.tsx +0 -228
- package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +0 -228
- package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +0 -459
- package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +0 -362
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +0 -522
- package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +0 -599
- package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +0 -513
- package/src/components/RBAC/__tests__/PagePermissionGuard.unit.test.tsx +0 -683
- package/src/components/RBAC/__tests__/RBAC.integration.test.tsx +0 -573
- package/src/components/RBAC/__tests__/RBACGuard.unit.test.tsx +0 -467
- package/src/components/RBAC/__tests__/RBACProvider.accessibility.test.tsx +0 -475
- package/src/components/RBAC/__tests__/RBACProvider.advanced.test.tsx +0 -569
- package/src/components/RBAC/__tests__/RBACProvider.integration.test.tsx +0 -352
- package/src/components/RBAC/__tests__/RBACProvider.unit.test.tsx +0 -128
- package/src/components/RBAC/__tests__/RoleBasedContent.unit.test.tsx +0 -657
- package/src/components/Select/__tests__/SearchableSelect.unit.test.tsx +0 -437
- package/src/components/Select/__tests__/Select.accessibility.test.tsx +0 -1202
- package/src/components/Select/__tests__/Select.actual.test.tsx +0 -774
- package/src/components/Select/__tests__/Select.comprehensive.test.tsx +0 -837
- package/src/components/Select/__tests__/Select.enhanced.test.tsx +0 -1101
- package/src/components/Select/__tests__/Select.integration.test.tsx +0 -772
- package/src/components/Select/__tests__/Select.performance.test.tsx +0 -695
- package/src/components/Select/__tests__/Select.real-world.test.tsx +0 -1046
- package/src/components/Select/__tests__/Select.search-algorithms.test.tsx +0 -968
- package/src/components/Select/__tests__/Select.unit.test.tsx +0 -647
- package/src/components/Select/__tests__/Select.utils.test.tsx +0 -890
- package/src/components/Table/__tests__/Table.accessibility.test.tsx +0 -233
- package/src/components/Table/__tests__/Table.unit.test.tsx +0 -235
- package/src/components/Toast/__tests__/Toast.accessibility.test.tsx +0 -238
- package/src/components/Toast/__tests__/Toast.integration.test.tsx +0 -699
- package/src/components/Toast/__tests__/Toast.unit.test.tsx +0 -750
- package/src/components/Tooltip/__tests__/Tooltip.accessibility.test.tsx +0 -121
- package/src/components/Tooltip/__tests__/Tooltip.unit.test.tsx +0 -185
- package/src/components/UserMenu/__tests__/UserMenu.accessibility.test.tsx +0 -139
- package/src/components/UserMenu/__tests__/UserMenu.integration.test.tsx +0 -188
- package/src/components/UserMenu/__tests__/UserMenu.unit.test.tsx +0 -458
- package/src/components/__tests__/EdgeCaseTesting.enhanced.test.tsx +0 -524
- package/src/components/__tests__/ErrorTesting.enhanced.test.tsx +0 -455
- package/src/components/__tests__/SuperAdminGuard.test.tsx +0 -456
- package/src/components/__tests__/SuperAdminGuard.unit.test.tsx +0 -456
- package/src/components/examples/__tests__/PermissionExample.unit.test.tsx +0 -360
- package/src/hooks/__tests__/hooks.integration.test.tsx +0 -575
- package/src/hooks/__tests__/useApiFetch.unit.test.ts +0 -115
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +0 -133
- package/src/hooks/__tests__/useDebounce.unit.test.ts +0 -82
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +0 -293
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +0 -385
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +0 -286
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +0 -838
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -627
- package/src/hooks/__tests__/useRBAC.unit.test.ts +0 -911
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -537
- package/src/hooks/__tests__/useToast.unit.test.tsx +0 -62
- package/src/hooks/__tests__/useZodForm.unit.test.tsx +0 -37
- package/src/hooks/public/__tests__/usePublicEvent.test.tsx +0 -397
- package/src/hooks/public/__tests__/usePublicEventLogo.test.tsx +0 -690
- package/src/hooks/public/__tests__/usePublicRouteParams.test.tsx +0 -449
- package/src/providers/__tests__/EventProvider.unit.test.tsx +0 -768
- package/src/providers/__tests__/OrganisationProvider.basic.test.tsx +0 -116
- package/src/providers/__tests__/OrganisationProvider.unit.test.tsx +0 -1312
- package/src/providers/__tests__/UnifiedAuthProvider.inactivity.test.tsx +0 -601
- package/src/providers/__tests__/UnifiedAuthProvider.unit.test.tsx +0 -683
- package/src/providers/__tests__/index.unit.test.ts +0 -78
- package/src/rbac/__tests__/PagePermissionGuard.test.tsx +0 -673
- package/src/rbac/__tests__/README.md +0 -170
- package/src/rbac/__tests__/RoleBasedRouter.test.tsx +0 -709
- package/src/rbac/__tests__/TestContext.tsx +0 -72
- package/src/rbac/__tests__/__mocks__/cache.ts +0 -144
- package/src/rbac/__tests__/__mocks__/supabase.ts +0 -152
- package/src/rbac/__tests__/adapters-hooks-comprehensive.test.tsx +0 -782
- package/src/rbac/__tests__/adapters-hooks.test.tsx +0 -561
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +0 -963
- package/src/rbac/__tests__/adapters.test.tsx +0 -444
- package/src/rbac/__tests__/api.test.ts +0 -620
- package/src/rbac/__tests__/audit-observability-comprehensive.test.ts +0 -792
- package/src/rbac/__tests__/audit-observability.test.ts +0 -549
- package/src/rbac/__tests__/audit.test.ts +0 -616
- package/src/rbac/__tests__/build-contract-compliance-simple.test.ts +0 -230
- package/src/rbac/__tests__/cache-invalidation-comprehensive.test.ts +0 -889
- package/src/rbac/__tests__/cache-invalidation.test.ts +0 -457
- package/src/rbac/__tests__/cache.test.ts +0 -458
- package/src/rbac/__tests__/components-navigation-guard.enhanced.test.tsx +0 -859
- package/src/rbac/__tests__/components-navigation-guard.test.tsx +0 -895
- package/src/rbac/__tests__/components-navigation-provider.test.tsx +0 -692
- package/src/rbac/__tests__/components-page-permission-guard.test.tsx +0 -673
- package/src/rbac/__tests__/components-page-permission-provider.test.tsx +0 -614
- package/src/rbac/__tests__/components-permission-enforcer.enhanced.fixed.test.tsx +0 -836
- package/src/rbac/__tests__/components-permission-enforcer.enhanced.test.tsx +0 -837
- package/src/rbac/__tests__/components-permission-enforcer.test.tsx +0 -825
- package/src/rbac/__tests__/components-role-based-router.test.tsx +0 -709
- package/src/rbac/__tests__/components-secure-data-provider.test.tsx +0 -607
- package/src/rbac/__tests__/config.test.ts +0 -583
- package/src/rbac/__tests__/core-logic-unit.test.ts +0 -190
- package/src/rbac/__tests__/core-permission-logic-comprehensive.test.ts +0 -1467
- package/src/rbac/__tests__/core-permission-logic-fixed.test.ts +0 -151
- package/src/rbac/__tests__/core-permission-logic-simple.test.ts +0 -968
- package/src/rbac/__tests__/core-permission-logic.test.ts +0 -966
- package/src/rbac/__tests__/edge-cases-comprehensive.test.ts +0 -988
- package/src/rbac/__tests__/edge-cases.test.ts +0 -654
- package/src/rbac/__tests__/engine.test.ts +0 -361
- package/src/rbac/__tests__/engine.unit.test.ts +0 -361
- package/src/rbac/__tests__/hooks.enhanced.test.tsx +0 -979
- package/src/rbac/__tests__/hooks.fixed.test.tsx +0 -475
- package/src/rbac/__tests__/hooks.test.tsx +0 -385
- package/src/rbac/__tests__/index.test.ts +0 -269
- package/src/rbac/__tests__/integration.enhanced.test.tsx +0 -824
- package/src/rbac/__tests__/page-permission-guard-super-admin.test.tsx +0 -261
- package/src/rbac/__tests__/performance.enhanced.test.tsx +0 -724
- package/src/rbac/__tests__/permissions.test.ts +0 -383
- package/src/rbac/__tests__/requires-event.test.ts +0 -330
- package/src/rbac/__tests__/scope-isolation-comprehensive.test.ts +0 -1349
- package/src/rbac/__tests__/scope-isolation.test.ts +0 -755
- package/src/rbac/__tests__/secure-client-rls-comprehensive.test.ts +0 -592
- package/src/rbac/__tests__/secure-client-rls.test.ts +0 -377
- package/src/rbac/__tests__/security.test.ts +0 -296
- package/src/rbac/__tests__/setup.ts +0 -228
- package/src/rbac/__tests__/test-utils-enhanced.tsx +0 -400
- package/src/rbac/__tests__/types.test.ts +0 -685
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -631
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -667
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -647
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -496
- package/src/rbac/testing/__tests__/index.test.tsx +0 -342
- package/src/rbac/utils/__tests__/eventContext.test.ts +0 -428
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -428
- package/src/styles/__tests__/styles.unit.test.ts +0 -164
- package/src/test-dom-cleanup.test.tsx +0 -38
- package/src/theming/__tests__/README.md +0 -335
- package/src/theming/__tests__/runtime.accessibility.test.ts +0 -474
- package/src/theming/__tests__/runtime.error.test.ts +0 -616
- package/src/theming/__tests__/runtime.integration.test.ts +0 -376
- package/src/theming/__tests__/runtime.performance.test.ts +0 -411
- package/src/theming/__tests__/runtime.unit.test.ts +0 -470
- package/src/types/__tests__/database.unit.test.ts +0 -489
- package/src/types/__tests__/guards.unit.test.ts +0 -146
- package/src/types/__tests__/index.unit.test.ts +0 -77
- package/src/types/__tests__/organisation.unit.test.ts +0 -713
- package/src/types/__tests__/rbac.unit.test.ts +0 -621
- package/src/types/__tests__/security.unit.test.ts +0 -347
- package/src/types/__tests__/supabase.unit.test.ts +0 -658
- package/src/types/__tests__/theme.unit.test.ts +0 -218
- package/src/types/__tests__/unified.unit.test.ts +0 -537
- package/src/types/__tests__/validation.unit.test.ts +0 -616
- package/src/utils/__tests__/appConfig.unit.test.ts +0 -55
- package/src/utils/__tests__/appNameResolver.unit.test.ts +0 -137
- package/src/utils/__tests__/audit.unit.test.ts +0 -69
- package/src/utils/__tests__/auth-utils.unit.test.ts +0 -70
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +0 -317
- package/src/utils/__tests__/cn.unit.test.ts +0 -34
- package/src/utils/__tests__/deviceFingerprint.unit.test.ts +0 -480
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +0 -322
- package/src/utils/__tests__/formatDate.unit.test.ts +0 -109
- package/src/utils/__tests__/formatting.unit.test.ts +0 -66
- package/src/utils/__tests__/index.unit.test.ts +0 -251
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +0 -304
- package/src/utils/__tests__/organisationContext.unit.test.ts +0 -192
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +0 -259
- package/src/utils/__tests__/permissionTypes.unit.test.ts +0 -250
- package/src/utils/__tests__/permissionUtils.unit.test.ts +0 -362
- package/src/utils/__tests__/sanitization.unit.test.ts +0 -346
- package/src/utils/__tests__/schemaUtils.unit.test.ts +0 -441
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +0 -334
- package/src/utils/__tests__/secureErrors.unit.test.ts +0 -377
- package/src/utils/__tests__/secureStorage.unit.test.ts +0 -293
- package/src/utils/__tests__/security.unit.test.ts +0 -127
- package/src/utils/__tests__/securityMonitor.unit.test.ts +0 -280
- package/src/utils/__tests__/sessionTracking.unit.test.ts +0 -370
- package/src/utils/__tests__/validation.unit.test.ts +0 -84
- package/src/utils/__tests__/validationUtils.unit.test.ts +0 -571
- package/src/utils/print/__tests__/PrintDataProcessor.unit.test.ts +0 -219
- package/src/utils/print/__tests__/usePrintOptimization.unit.test.tsx +0 -353
- package/src/utils/storage/__tests__/config.unit.test.ts +0 -206
- package/src/utils/storage/__tests__/helpers.unit.test.ts +0 -648
- package/src/utils/storage/__tests__/index.unit.test.ts +0 -167
- package/src/utils/storage/__tests__/types.unit.test.ts +0 -441
- package/src/validation/__tests__/common.unit.test.ts +0 -101
- package/src/validation/__tests__/csrf.unit.test.ts +0 -302
- package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -98
- package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -466
- /package/dist/{DataTable-EEUDXPE5.js.map → DataTable-GX3XERFJ.js.map} +0 -0
- /package/dist/{chunk-VYG4AXYW.js.map → chunk-5EL3KHOQ.js.map} +0 -0
|
@@ -0,0 +1,1139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Dialog Component Tests
|
|
3
|
+
* @description Comprehensive tests for Dialog component system
|
|
4
|
+
* @package @jmruthers/pace-core
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { screen, waitFor } from '@testing-library/react';
|
|
9
|
+
import userEvent from '@testing-library/user-event';
|
|
10
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
11
|
+
import {
|
|
12
|
+
Dialog,
|
|
13
|
+
DialogTrigger,
|
|
14
|
+
DialogContent,
|
|
15
|
+
DialogHeader,
|
|
16
|
+
DialogTitle,
|
|
17
|
+
DialogDescription,
|
|
18
|
+
DialogBody,
|
|
19
|
+
DialogFooter,
|
|
20
|
+
DialogClose,
|
|
21
|
+
DialogOverlay,
|
|
22
|
+
DialogPortal
|
|
23
|
+
} from './Dialog';
|
|
24
|
+
import { renderWithProviders } from '../../__tests__/helpers/test-utils';
|
|
25
|
+
|
|
26
|
+
// Mock lodash debounce to avoid timing issues in tests
|
|
27
|
+
vi.mock('lodash', () => ({
|
|
28
|
+
debounce: (fn: Function) => fn
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
describe('Dialog Component System', () => {
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
vi.clearAllMocks();
|
|
34
|
+
// Mock console methods to avoid noise in tests
|
|
35
|
+
vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
36
|
+
vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('Dialog Root Component', () => {
|
|
40
|
+
it('renders with default props', () => {
|
|
41
|
+
renderWithProviders(
|
|
42
|
+
<Dialog>
|
|
43
|
+
<DialogTrigger asChild>
|
|
44
|
+
<button>Open Dialog</button>
|
|
45
|
+
</DialogTrigger>
|
|
46
|
+
<DialogContent>
|
|
47
|
+
<DialogHeader>
|
|
48
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
49
|
+
</DialogHeader>
|
|
50
|
+
</DialogContent>
|
|
51
|
+
</Dialog>
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
expect(screen.getByRole('button', { name: 'Open Dialog' })).toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('handles open state changes', async () => {
|
|
58
|
+
const user = userEvent.setup();
|
|
59
|
+
|
|
60
|
+
renderWithProviders(
|
|
61
|
+
<Dialog>
|
|
62
|
+
<DialogTrigger asChild>
|
|
63
|
+
<button>Open Dialog</button>
|
|
64
|
+
</DialogTrigger>
|
|
65
|
+
<DialogContent>
|
|
66
|
+
<DialogHeader>
|
|
67
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
68
|
+
</DialogHeader>
|
|
69
|
+
</DialogContent>
|
|
70
|
+
</Dialog>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const trigger = screen.getByRole('button', { name: 'Open Dialog' });
|
|
74
|
+
await user.click(trigger);
|
|
75
|
+
|
|
76
|
+
await waitFor(() => {
|
|
77
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('DialogTrigger Component', () => {
|
|
83
|
+
it('renders as child element when asChild is true', () => {
|
|
84
|
+
renderWithProviders(
|
|
85
|
+
<Dialog>
|
|
86
|
+
<DialogTrigger asChild>
|
|
87
|
+
<button>Custom Trigger</button>
|
|
88
|
+
</DialogTrigger>
|
|
89
|
+
<DialogContent>
|
|
90
|
+
<DialogHeader>
|
|
91
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
92
|
+
</DialogHeader>
|
|
93
|
+
</DialogContent>
|
|
94
|
+
</Dialog>
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
expect(screen.getByRole('button', { name: 'Custom Trigger' })).toBeInTheDocument();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('renders as button when asChild is false', () => {
|
|
101
|
+
renderWithProviders(
|
|
102
|
+
<Dialog>
|
|
103
|
+
<DialogTrigger>Default Trigger</DialogTrigger>
|
|
104
|
+
<DialogContent>
|
|
105
|
+
<DialogHeader>
|
|
106
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
107
|
+
</DialogHeader>
|
|
108
|
+
</DialogContent>
|
|
109
|
+
</Dialog>
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
expect(screen.getByRole('button', { name: 'Default Trigger' })).toBeInTheDocument();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('opens dialog when clicked', async () => {
|
|
116
|
+
const user = userEvent.setup();
|
|
117
|
+
|
|
118
|
+
renderWithProviders(
|
|
119
|
+
<Dialog>
|
|
120
|
+
<DialogTrigger asChild>
|
|
121
|
+
<button>Open Dialog</button>
|
|
122
|
+
</DialogTrigger>
|
|
123
|
+
<DialogContent>
|
|
124
|
+
<DialogHeader>
|
|
125
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
126
|
+
</DialogHeader>
|
|
127
|
+
</DialogContent>
|
|
128
|
+
</Dialog>
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
const trigger = screen.getByRole('button', { name: 'Open Dialog' });
|
|
132
|
+
await user.click(trigger);
|
|
133
|
+
|
|
134
|
+
await waitFor(() => {
|
|
135
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('DialogContent Component', () => {
|
|
141
|
+
it('renders with default props', async () => {
|
|
142
|
+
const user = userEvent.setup();
|
|
143
|
+
|
|
144
|
+
renderWithProviders(
|
|
145
|
+
<Dialog>
|
|
146
|
+
<DialogTrigger asChild>
|
|
147
|
+
<button>Open Dialog</button>
|
|
148
|
+
</DialogTrigger>
|
|
149
|
+
<DialogContent>
|
|
150
|
+
<DialogHeader>
|
|
151
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
152
|
+
</DialogHeader>
|
|
153
|
+
</DialogContent>
|
|
154
|
+
</Dialog>
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
158
|
+
|
|
159
|
+
await waitFor(() => {
|
|
160
|
+
const dialog = screen.getByRole('dialog');
|
|
161
|
+
expect(dialog).toBeInTheDocument();
|
|
162
|
+
expect(dialog).toHaveClass('max-w-md'); // Default size
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('renders with different size variants', async () => {
|
|
167
|
+
const user = userEvent.setup();
|
|
168
|
+
|
|
169
|
+
const { rerender } = renderWithProviders(
|
|
170
|
+
<Dialog>
|
|
171
|
+
<DialogTrigger asChild>
|
|
172
|
+
<button>Open Dialog</button>
|
|
173
|
+
</DialogTrigger>
|
|
174
|
+
<DialogContent size="sm">
|
|
175
|
+
<DialogHeader>
|
|
176
|
+
<DialogTitle>Small Dialog</DialogTitle>
|
|
177
|
+
</DialogHeader>
|
|
178
|
+
</DialogContent>
|
|
179
|
+
</Dialog>
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
183
|
+
|
|
184
|
+
await waitFor(() => {
|
|
185
|
+
expect(screen.getByRole('dialog')).toHaveClass('max-w-sm');
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Test other sizes - close dialog first
|
|
189
|
+
await user.click(screen.getByRole('button', { name: 'Close' }));
|
|
190
|
+
|
|
191
|
+
await waitFor(() => {
|
|
192
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const sizes = ['md', 'lg', 'xl', 'full', 'auto'] as const;
|
|
196
|
+
for (const size of sizes) {
|
|
197
|
+
rerender(
|
|
198
|
+
<Dialog>
|
|
199
|
+
<DialogTrigger asChild>
|
|
200
|
+
<button>Open Dialog</button>
|
|
201
|
+
</DialogTrigger>
|
|
202
|
+
<DialogContent size={size}>
|
|
203
|
+
<DialogHeader>
|
|
204
|
+
<DialogTitle>{size} Dialog</DialogTitle>
|
|
205
|
+
</DialogHeader>
|
|
206
|
+
</DialogContent>
|
|
207
|
+
</Dialog>
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
211
|
+
|
|
212
|
+
await waitFor(() => {
|
|
213
|
+
const dialog = screen.getByRole('dialog');
|
|
214
|
+
if (size === 'full') {
|
|
215
|
+
expect(dialog).toHaveClass('max-w-full', 'h-full');
|
|
216
|
+
} else if (size === 'auto') {
|
|
217
|
+
expect(dialog).toHaveClass('w-fit', 'max-w-[90vw]');
|
|
218
|
+
} else {
|
|
219
|
+
expect(dialog).toHaveClass(`max-w-${size}`);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Close dialog for next iteration
|
|
224
|
+
await user.click(screen.getByRole('button', { name: 'Close' }));
|
|
225
|
+
await waitFor(() => {
|
|
226
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('shows close button by default', async () => {
|
|
232
|
+
const user = userEvent.setup();
|
|
233
|
+
|
|
234
|
+
renderWithProviders(
|
|
235
|
+
<Dialog>
|
|
236
|
+
<DialogTrigger asChild>
|
|
237
|
+
<button>Open Dialog</button>
|
|
238
|
+
</DialogTrigger>
|
|
239
|
+
<DialogContent>
|
|
240
|
+
<DialogHeader>
|
|
241
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
242
|
+
</DialogHeader>
|
|
243
|
+
</DialogContent>
|
|
244
|
+
</Dialog>
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
248
|
+
|
|
249
|
+
await waitFor(() => {
|
|
250
|
+
expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument();
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('hides close button when showCloseButton is false', async () => {
|
|
255
|
+
const user = userEvent.setup();
|
|
256
|
+
|
|
257
|
+
renderWithProviders(
|
|
258
|
+
<Dialog>
|
|
259
|
+
<DialogTrigger asChild>
|
|
260
|
+
<button>Open Dialog</button>
|
|
261
|
+
</DialogTrigger>
|
|
262
|
+
<DialogContent showCloseButton={false}>
|
|
263
|
+
<DialogHeader>
|
|
264
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
265
|
+
</DialogHeader>
|
|
266
|
+
</DialogContent>
|
|
267
|
+
</Dialog>
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
271
|
+
|
|
272
|
+
await waitFor(() => {
|
|
273
|
+
expect(screen.queryByRole('button', { name: 'Close' })).not.toBeInTheDocument();
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('handles custom className', async () => {
|
|
278
|
+
const user = userEvent.setup();
|
|
279
|
+
|
|
280
|
+
renderWithProviders(
|
|
281
|
+
<Dialog>
|
|
282
|
+
<DialogTrigger asChild>
|
|
283
|
+
<button>Open Dialog</button>
|
|
284
|
+
</DialogTrigger>
|
|
285
|
+
<DialogContent className="custom-dialog">
|
|
286
|
+
<DialogHeader>
|
|
287
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
288
|
+
</DialogHeader>
|
|
289
|
+
</DialogContent>
|
|
290
|
+
</Dialog>
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
294
|
+
|
|
295
|
+
await waitFor(() => {
|
|
296
|
+
expect(screen.getByRole('dialog')).toHaveClass('custom-dialog');
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('handles preventCloseOnEscape', async () => {
|
|
301
|
+
const user = userEvent.setup();
|
|
302
|
+
|
|
303
|
+
renderWithProviders(
|
|
304
|
+
<Dialog>
|
|
305
|
+
<DialogTrigger asChild>
|
|
306
|
+
<button>Open Dialog</button>
|
|
307
|
+
</DialogTrigger>
|
|
308
|
+
<DialogContent preventCloseOnEscape>
|
|
309
|
+
<DialogHeader>
|
|
310
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
311
|
+
</DialogHeader>
|
|
312
|
+
</DialogContent>
|
|
313
|
+
</Dialog>
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
317
|
+
|
|
318
|
+
await waitFor(() => {
|
|
319
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// Try to close with Escape key
|
|
323
|
+
await user.keyboard('{Escape}');
|
|
324
|
+
|
|
325
|
+
// Dialog should still be open
|
|
326
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
it('handles preventCloseOnOutsideClick', async () => {
|
|
330
|
+
const user = userEvent.setup();
|
|
331
|
+
|
|
332
|
+
renderWithProviders(
|
|
333
|
+
<Dialog>
|
|
334
|
+
<DialogTrigger asChild>
|
|
335
|
+
<button>Open Dialog</button>
|
|
336
|
+
</DialogTrigger>
|
|
337
|
+
<DialogContent preventCloseOnOutsideClick>
|
|
338
|
+
<DialogHeader>
|
|
339
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
340
|
+
</DialogHeader>
|
|
341
|
+
</DialogContent>
|
|
342
|
+
</Dialog>
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
346
|
+
|
|
347
|
+
await waitFor(() => {
|
|
348
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// Click outside the dialog
|
|
352
|
+
await user.click(document.body);
|
|
353
|
+
|
|
354
|
+
// Dialog should still be open
|
|
355
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it('closes when close button is clicked', async () => {
|
|
359
|
+
const user = userEvent.setup();
|
|
360
|
+
|
|
361
|
+
renderWithProviders(
|
|
362
|
+
<Dialog>
|
|
363
|
+
<DialogTrigger asChild>
|
|
364
|
+
<button>Open Dialog</button>
|
|
365
|
+
</DialogTrigger>
|
|
366
|
+
<DialogContent>
|
|
367
|
+
<DialogHeader>
|
|
368
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
369
|
+
</DialogHeader>
|
|
370
|
+
</DialogContent>
|
|
371
|
+
</Dialog>
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
375
|
+
|
|
376
|
+
await waitFor(() => {
|
|
377
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
await user.click(screen.getByRole('button', { name: 'Close' }));
|
|
381
|
+
|
|
382
|
+
await waitFor(() => {
|
|
383
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
describe('DialogHeader Component', () => {
|
|
389
|
+
it('renders with default props', async () => {
|
|
390
|
+
const user = userEvent.setup();
|
|
391
|
+
|
|
392
|
+
renderWithProviders(
|
|
393
|
+
<Dialog>
|
|
394
|
+
<DialogTrigger asChild>
|
|
395
|
+
<button>Open Dialog</button>
|
|
396
|
+
</DialogTrigger>
|
|
397
|
+
<DialogContent>
|
|
398
|
+
<DialogHeader>
|
|
399
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
400
|
+
<DialogDescription>Test description</DialogDescription>
|
|
401
|
+
</DialogHeader>
|
|
402
|
+
</DialogContent>
|
|
403
|
+
</Dialog>
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
407
|
+
|
|
408
|
+
await waitFor(() => {
|
|
409
|
+
const header = screen.getByRole('banner');
|
|
410
|
+
expect(header).toBeInTheDocument();
|
|
411
|
+
expect(header).toHaveClass('flex', 'flex-col', 'space-y-1.5');
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
it('renders with sticky behavior', async () => {
|
|
416
|
+
const user = userEvent.setup();
|
|
417
|
+
|
|
418
|
+
renderWithProviders(
|
|
419
|
+
<Dialog>
|
|
420
|
+
<DialogTrigger asChild>
|
|
421
|
+
<button>Open Dialog</button>
|
|
422
|
+
</DialogTrigger>
|
|
423
|
+
<DialogContent enableScrolling>
|
|
424
|
+
<DialogHeader sticky>
|
|
425
|
+
<DialogTitle>Sticky Header</DialogTitle>
|
|
426
|
+
</DialogHeader>
|
|
427
|
+
</DialogContent>
|
|
428
|
+
</Dialog>
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
432
|
+
|
|
433
|
+
await waitFor(() => {
|
|
434
|
+
const header = screen.getByRole('banner');
|
|
435
|
+
expect(header).toHaveClass('sticky', 'top-0', 'z-10');
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
it('handles custom className', async () => {
|
|
440
|
+
const user = userEvent.setup();
|
|
441
|
+
|
|
442
|
+
renderWithProviders(
|
|
443
|
+
<Dialog>
|
|
444
|
+
<DialogTrigger asChild>
|
|
445
|
+
<button>Open Dialog</button>
|
|
446
|
+
</DialogTrigger>
|
|
447
|
+
<DialogContent>
|
|
448
|
+
<DialogHeader className="custom-header">
|
|
449
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
450
|
+
</DialogHeader>
|
|
451
|
+
</DialogContent>
|
|
452
|
+
</Dialog>
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
456
|
+
|
|
457
|
+
await waitFor(() => {
|
|
458
|
+
expect(screen.getByRole('banner')).toHaveClass('custom-header');
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
describe('DialogTitle Component', () => {
|
|
464
|
+
it('renders with text content', async () => {
|
|
465
|
+
const user = userEvent.setup();
|
|
466
|
+
|
|
467
|
+
renderWithProviders(
|
|
468
|
+
<Dialog>
|
|
469
|
+
<DialogTrigger asChild>
|
|
470
|
+
<button>Open Dialog</button>
|
|
471
|
+
</DialogTrigger>
|
|
472
|
+
<DialogContent>
|
|
473
|
+
<DialogHeader>
|
|
474
|
+
<DialogTitle>Test Dialog Title</DialogTitle>
|
|
475
|
+
</DialogHeader>
|
|
476
|
+
</DialogContent>
|
|
477
|
+
</Dialog>
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
481
|
+
|
|
482
|
+
await waitFor(() => {
|
|
483
|
+
const title = screen.getByRole('heading', { level: 2 }); // Radix UI uses h2
|
|
484
|
+
expect(title).toBeInTheDocument();
|
|
485
|
+
expect(title).toHaveTextContent('Test Dialog Title');
|
|
486
|
+
expect(title).toHaveClass('text-lg', 'font-semibold');
|
|
487
|
+
});
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it('renders with HTML content', async () => {
|
|
491
|
+
const user = userEvent.setup();
|
|
492
|
+
|
|
493
|
+
renderWithProviders(
|
|
494
|
+
<Dialog>
|
|
495
|
+
<DialogTrigger asChild>
|
|
496
|
+
<button>Open Dialog</button>
|
|
497
|
+
</DialogTrigger>
|
|
498
|
+
<DialogContent>
|
|
499
|
+
<DialogHeader>
|
|
500
|
+
<DialogTitle htmlContent="<strong>Bold Title</strong> with <em>emphasis</em>">
|
|
501
|
+
Fallback Title
|
|
502
|
+
</DialogTitle>
|
|
503
|
+
</DialogHeader>
|
|
504
|
+
</DialogContent>
|
|
505
|
+
</Dialog>
|
|
506
|
+
);
|
|
507
|
+
|
|
508
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
509
|
+
|
|
510
|
+
await waitFor(() => {
|
|
511
|
+
const title = screen.getByRole('heading', { level: 2 }); // Radix UI uses h2
|
|
512
|
+
expect(title).toBeInTheDocument();
|
|
513
|
+
expect(title).toHaveTextContent('Bold Title with emphasis');
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
it('handles custom className', async () => {
|
|
518
|
+
const user = userEvent.setup();
|
|
519
|
+
|
|
520
|
+
renderWithProviders(
|
|
521
|
+
<Dialog>
|
|
522
|
+
<DialogTrigger asChild>
|
|
523
|
+
<button>Open Dialog</button>
|
|
524
|
+
</DialogTrigger>
|
|
525
|
+
<DialogContent>
|
|
526
|
+
<DialogHeader>
|
|
527
|
+
<DialogTitle className="custom-title">Test Title</DialogTitle>
|
|
528
|
+
</DialogHeader>
|
|
529
|
+
</DialogContent>
|
|
530
|
+
</Dialog>
|
|
531
|
+
);
|
|
532
|
+
|
|
533
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
534
|
+
|
|
535
|
+
await waitFor(() => {
|
|
536
|
+
expect(screen.getByRole('heading', { level: 2 })).toHaveClass('custom-title');
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
describe('DialogDescription Component', () => {
|
|
542
|
+
it('renders with text content', async () => {
|
|
543
|
+
const user = userEvent.setup();
|
|
544
|
+
|
|
545
|
+
renderWithProviders(
|
|
546
|
+
<Dialog>
|
|
547
|
+
<DialogTrigger asChild>
|
|
548
|
+
<button>Open Dialog</button>
|
|
549
|
+
</DialogTrigger>
|
|
550
|
+
<DialogContent>
|
|
551
|
+
<DialogHeader>
|
|
552
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
553
|
+
<DialogDescription>This is a test description</DialogDescription>
|
|
554
|
+
</DialogHeader>
|
|
555
|
+
</DialogContent>
|
|
556
|
+
</Dialog>
|
|
557
|
+
);
|
|
558
|
+
|
|
559
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
560
|
+
|
|
561
|
+
await waitFor(() => {
|
|
562
|
+
const description = screen.getByText('This is a test description');
|
|
563
|
+
expect(description).toBeInTheDocument();
|
|
564
|
+
expect(description).toHaveClass('text-sm', 'text-muted-foreground');
|
|
565
|
+
});
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
it('renders with HTML content', async () => {
|
|
569
|
+
const user = userEvent.setup();
|
|
570
|
+
|
|
571
|
+
renderWithProviders(
|
|
572
|
+
<Dialog>
|
|
573
|
+
<DialogTrigger asChild>
|
|
574
|
+
<button>Open Dialog</button>
|
|
575
|
+
</DialogTrigger>
|
|
576
|
+
<DialogContent>
|
|
577
|
+
<DialogHeader>
|
|
578
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
579
|
+
<DialogDescription htmlContent="<strong>Bold description</strong> with <em>emphasis</em>">
|
|
580
|
+
Fallback description
|
|
581
|
+
</DialogDescription>
|
|
582
|
+
</DialogHeader>
|
|
583
|
+
</DialogContent>
|
|
584
|
+
</Dialog>
|
|
585
|
+
);
|
|
586
|
+
|
|
587
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
588
|
+
|
|
589
|
+
await waitFor(() => {
|
|
590
|
+
// The text is split across multiple elements, so we check for parts
|
|
591
|
+
expect(screen.getByText('Bold description')).toBeInTheDocument();
|
|
592
|
+
expect(screen.getByText('emphasis')).toBeInTheDocument();
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
describe('DialogBody Component', () => {
|
|
598
|
+
it('renders with React children', async () => {
|
|
599
|
+
const user = userEvent.setup();
|
|
600
|
+
|
|
601
|
+
renderWithProviders(
|
|
602
|
+
<Dialog>
|
|
603
|
+
<DialogTrigger asChild>
|
|
604
|
+
<button>Open Dialog</button>
|
|
605
|
+
</DialogTrigger>
|
|
606
|
+
<DialogContent>
|
|
607
|
+
<DialogHeader>
|
|
608
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
609
|
+
</DialogHeader>
|
|
610
|
+
<DialogBody>
|
|
611
|
+
<section>
|
|
612
|
+
<h2>Content Section</h2>
|
|
613
|
+
<p>This is the main content of the dialog.</p>
|
|
614
|
+
</section>
|
|
615
|
+
</DialogBody>
|
|
616
|
+
</DialogContent>
|
|
617
|
+
</Dialog>
|
|
618
|
+
);
|
|
619
|
+
|
|
620
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
621
|
+
|
|
622
|
+
await waitFor(() => {
|
|
623
|
+
const body = screen.getByRole('main');
|
|
624
|
+
expect(body).toBeInTheDocument();
|
|
625
|
+
expect(body).toHaveClass('flex-1', 'overflow-y-auto');
|
|
626
|
+
expect(screen.getByText('Content Section')).toBeInTheDocument();
|
|
627
|
+
expect(screen.getByText('This is the main content of the dialog.')).toBeInTheDocument();
|
|
628
|
+
});
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
it('renders with HTML content', async () => {
|
|
632
|
+
const user = userEvent.setup();
|
|
633
|
+
|
|
634
|
+
renderWithProviders(
|
|
635
|
+
<Dialog>
|
|
636
|
+
<DialogTrigger asChild>
|
|
637
|
+
<button>Open Dialog</button>
|
|
638
|
+
</DialogTrigger>
|
|
639
|
+
<DialogContent>
|
|
640
|
+
<DialogHeader>
|
|
641
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
642
|
+
</DialogHeader>
|
|
643
|
+
<DialogBody
|
|
644
|
+
htmlContent="<h2>HTML Content</h2><p>This is <strong>HTML content</strong> rendered safely.</p>"
|
|
645
|
+
allowHtml={true}
|
|
646
|
+
/>
|
|
647
|
+
</DialogContent>
|
|
648
|
+
</Dialog>
|
|
649
|
+
);
|
|
650
|
+
|
|
651
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
652
|
+
|
|
653
|
+
await waitFor(() => {
|
|
654
|
+
const body = screen.getByRole('main');
|
|
655
|
+
expect(body).toBeInTheDocument();
|
|
656
|
+
expect(screen.getByText('HTML Content')).toBeInTheDocument();
|
|
657
|
+
// The text is split across multiple elements, so we check for parts
|
|
658
|
+
expect(screen.getByText('HTML content')).toBeInTheDocument();
|
|
659
|
+
expect(screen.getByText(/safely/)).toBeInTheDocument();
|
|
660
|
+
});
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
it('handles custom maxHeight', async () => {
|
|
664
|
+
const user = userEvent.setup();
|
|
665
|
+
|
|
666
|
+
renderWithProviders(
|
|
667
|
+
<Dialog>
|
|
668
|
+
<DialogTrigger asChild>
|
|
669
|
+
<button>Open Dialog</button>
|
|
670
|
+
</DialogTrigger>
|
|
671
|
+
<DialogContent>
|
|
672
|
+
<DialogHeader>
|
|
673
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
674
|
+
</DialogHeader>
|
|
675
|
+
<DialogBody maxHeight="200px">
|
|
676
|
+
<section>
|
|
677
|
+
<p>Content with custom max height</p>
|
|
678
|
+
</section>
|
|
679
|
+
</DialogBody>
|
|
680
|
+
</DialogContent>
|
|
681
|
+
</Dialog>
|
|
682
|
+
);
|
|
683
|
+
|
|
684
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
685
|
+
|
|
686
|
+
await waitFor(() => {
|
|
687
|
+
const body = screen.getByRole('main');
|
|
688
|
+
expect(body).toBeInTheDocument();
|
|
689
|
+
// Check that the style attribute contains the max-height
|
|
690
|
+
expect(body.getAttribute('style')).toContain('max-height: 200px');
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
it('handles custom className', async () => {
|
|
695
|
+
const user = userEvent.setup();
|
|
696
|
+
|
|
697
|
+
renderWithProviders(
|
|
698
|
+
<Dialog>
|
|
699
|
+
<DialogTrigger asChild>
|
|
700
|
+
<button>Open Dialog</button>
|
|
701
|
+
</DialogTrigger>
|
|
702
|
+
<DialogContent>
|
|
703
|
+
<DialogHeader>
|
|
704
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
705
|
+
</DialogHeader>
|
|
706
|
+
<DialogBody className="custom-body">
|
|
707
|
+
<section>
|
|
708
|
+
<p>Content with custom class</p>
|
|
709
|
+
</section>
|
|
710
|
+
</DialogBody>
|
|
711
|
+
</DialogContent>
|
|
712
|
+
</Dialog>
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
716
|
+
|
|
717
|
+
await waitFor(() => {
|
|
718
|
+
expect(screen.getByRole('main')).toHaveClass('custom-body');
|
|
719
|
+
});
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
describe('DialogFooter Component', () => {
|
|
724
|
+
it('renders with default props', async () => {
|
|
725
|
+
const user = userEvent.setup();
|
|
726
|
+
|
|
727
|
+
renderWithProviders(
|
|
728
|
+
<Dialog>
|
|
729
|
+
<DialogTrigger asChild>
|
|
730
|
+
<button>Open Dialog</button>
|
|
731
|
+
</DialogTrigger>
|
|
732
|
+
<DialogContent>
|
|
733
|
+
<DialogHeader>
|
|
734
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
735
|
+
</DialogHeader>
|
|
736
|
+
<DialogFooter>
|
|
737
|
+
<button>Cancel</button>
|
|
738
|
+
<button>Save</button>
|
|
739
|
+
</DialogFooter>
|
|
740
|
+
</DialogContent>
|
|
741
|
+
</Dialog>
|
|
742
|
+
);
|
|
743
|
+
|
|
744
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
745
|
+
|
|
746
|
+
await waitFor(() => {
|
|
747
|
+
const footer = screen.getByRole('contentinfo');
|
|
748
|
+
expect(footer).toBeInTheDocument();
|
|
749
|
+
expect(footer).toHaveClass('flex', 'flex-col-reverse', 'sm:flex-row');
|
|
750
|
+
expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument();
|
|
751
|
+
expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument();
|
|
752
|
+
});
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
it('renders with sticky behavior', async () => {
|
|
756
|
+
const user = userEvent.setup();
|
|
757
|
+
|
|
758
|
+
renderWithProviders(
|
|
759
|
+
<Dialog>
|
|
760
|
+
<DialogTrigger asChild>
|
|
761
|
+
<button>Open Dialog</button>
|
|
762
|
+
</DialogTrigger>
|
|
763
|
+
<DialogContent enableScrolling>
|
|
764
|
+
<DialogHeader>
|
|
765
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
766
|
+
</DialogHeader>
|
|
767
|
+
<DialogFooter sticky>
|
|
768
|
+
<button>Save</button>
|
|
769
|
+
</DialogFooter>
|
|
770
|
+
</DialogContent>
|
|
771
|
+
</Dialog>
|
|
772
|
+
);
|
|
773
|
+
|
|
774
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
775
|
+
|
|
776
|
+
await waitFor(() => {
|
|
777
|
+
const footer = screen.getByRole('contentinfo');
|
|
778
|
+
expect(footer).toHaveClass('sticky', 'bottom-0', 'z-10');
|
|
779
|
+
});
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
it('handles custom className', async () => {
|
|
783
|
+
const user = userEvent.setup();
|
|
784
|
+
|
|
785
|
+
renderWithProviders(
|
|
786
|
+
<Dialog>
|
|
787
|
+
<DialogTrigger asChild>
|
|
788
|
+
<button>Open Dialog</button>
|
|
789
|
+
</DialogTrigger>
|
|
790
|
+
<DialogContent>
|
|
791
|
+
<DialogHeader>
|
|
792
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
793
|
+
</DialogHeader>
|
|
794
|
+
<DialogFooter className="custom-footer">
|
|
795
|
+
<button>Save</button>
|
|
796
|
+
</DialogFooter>
|
|
797
|
+
</DialogContent>
|
|
798
|
+
</Dialog>
|
|
799
|
+
);
|
|
800
|
+
|
|
801
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
802
|
+
|
|
803
|
+
await waitFor(() => {
|
|
804
|
+
expect(screen.getByRole('contentinfo')).toHaveClass('custom-footer');
|
|
805
|
+
});
|
|
806
|
+
});
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
describe('DialogClose Component', () => {
|
|
810
|
+
it('closes dialog when clicked', async () => {
|
|
811
|
+
const user = userEvent.setup();
|
|
812
|
+
|
|
813
|
+
renderWithProviders(
|
|
814
|
+
<Dialog>
|
|
815
|
+
<DialogTrigger asChild>
|
|
816
|
+
<button>Open Dialog</button>
|
|
817
|
+
</DialogTrigger>
|
|
818
|
+
<DialogContent>
|
|
819
|
+
<DialogHeader>
|
|
820
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
821
|
+
</DialogHeader>
|
|
822
|
+
<DialogFooter>
|
|
823
|
+
<DialogClose asChild>
|
|
824
|
+
<button>Close Dialog</button>
|
|
825
|
+
</DialogClose>
|
|
826
|
+
</DialogFooter>
|
|
827
|
+
</DialogContent>
|
|
828
|
+
</Dialog>
|
|
829
|
+
);
|
|
830
|
+
|
|
831
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
832
|
+
|
|
833
|
+
await waitFor(() => {
|
|
834
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
await user.click(screen.getByRole('button', { name: 'Close Dialog' }));
|
|
838
|
+
|
|
839
|
+
await waitFor(() => {
|
|
840
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
841
|
+
});
|
|
842
|
+
});
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
describe('Accessibility', () => {
|
|
846
|
+
it('has proper ARIA attributes', async () => {
|
|
847
|
+
const user = userEvent.setup();
|
|
848
|
+
|
|
849
|
+
renderWithProviders(
|
|
850
|
+
<Dialog>
|
|
851
|
+
<DialogTrigger asChild>
|
|
852
|
+
<button>Open Dialog</button>
|
|
853
|
+
</DialogTrigger>
|
|
854
|
+
<DialogContent>
|
|
855
|
+
<DialogHeader>
|
|
856
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
857
|
+
<DialogDescription>Test description</DialogDescription>
|
|
858
|
+
</DialogHeader>
|
|
859
|
+
</DialogContent>
|
|
860
|
+
</Dialog>
|
|
861
|
+
);
|
|
862
|
+
|
|
863
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
864
|
+
|
|
865
|
+
await waitFor(() => {
|
|
866
|
+
const dialog = screen.getByRole('dialog');
|
|
867
|
+
expect(dialog).toBeInTheDocument();
|
|
868
|
+
// Radix UI Dialog doesn't set aria-modal directly, it's handled internally
|
|
869
|
+
expect(dialog).toHaveAttribute('role', 'dialog');
|
|
870
|
+
});
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
it('supports keyboard navigation', async () => {
|
|
874
|
+
const user = userEvent.setup();
|
|
875
|
+
|
|
876
|
+
renderWithProviders(
|
|
877
|
+
<Dialog>
|
|
878
|
+
<DialogTrigger asChild>
|
|
879
|
+
<button>Open Dialog</button>
|
|
880
|
+
</DialogTrigger>
|
|
881
|
+
<DialogContent>
|
|
882
|
+
<DialogHeader>
|
|
883
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
884
|
+
</DialogHeader>
|
|
885
|
+
<DialogBody>
|
|
886
|
+
<button>Focusable Button</button>
|
|
887
|
+
</DialogBody>
|
|
888
|
+
</DialogContent>
|
|
889
|
+
</Dialog>
|
|
890
|
+
);
|
|
891
|
+
|
|
892
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
893
|
+
|
|
894
|
+
await waitFor(() => {
|
|
895
|
+
const dialog = screen.getByRole('dialog');
|
|
896
|
+
expect(dialog).toBeInTheDocument();
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
// Tab navigation should work within the dialog
|
|
900
|
+
// Note: Focus management is handled by Radix UI, so we just verify the button exists
|
|
901
|
+
expect(screen.getByRole('button', { name: 'Focusable Button' })).toBeInTheDocument();
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
it('closes on Escape key', async () => {
|
|
905
|
+
const user = userEvent.setup();
|
|
906
|
+
|
|
907
|
+
renderWithProviders(
|
|
908
|
+
<Dialog>
|
|
909
|
+
<DialogTrigger asChild>
|
|
910
|
+
<button>Open Dialog</button>
|
|
911
|
+
</DialogTrigger>
|
|
912
|
+
<DialogContent>
|
|
913
|
+
<DialogHeader>
|
|
914
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
915
|
+
</DialogHeader>
|
|
916
|
+
</DialogContent>
|
|
917
|
+
</Dialog>
|
|
918
|
+
);
|
|
919
|
+
|
|
920
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
921
|
+
|
|
922
|
+
await waitFor(() => {
|
|
923
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
924
|
+
});
|
|
925
|
+
|
|
926
|
+
await user.keyboard('{Escape}');
|
|
927
|
+
|
|
928
|
+
await waitFor(() => {
|
|
929
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
930
|
+
});
|
|
931
|
+
});
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
describe('Scrolling Behavior', () => {
|
|
935
|
+
it('enables scrolling when enableScrolling is true', async () => {
|
|
936
|
+
const user = userEvent.setup();
|
|
937
|
+
|
|
938
|
+
renderWithProviders(
|
|
939
|
+
<Dialog>
|
|
940
|
+
<DialogTrigger asChild>
|
|
941
|
+
<button>Open Dialog</button>
|
|
942
|
+
</DialogTrigger>
|
|
943
|
+
<DialogContent enableScrolling>
|
|
944
|
+
<DialogHeader>
|
|
945
|
+
<DialogTitle>Scrollable Dialog</DialogTitle>
|
|
946
|
+
</DialogHeader>
|
|
947
|
+
<DialogBody>
|
|
948
|
+
<section>
|
|
949
|
+
{Array.from({ length: 20 }, (_, i) => (
|
|
950
|
+
<p key={i}>Content item {i + 1}</p>
|
|
951
|
+
))}
|
|
952
|
+
</section>
|
|
953
|
+
</DialogBody>
|
|
954
|
+
<DialogFooter>
|
|
955
|
+
<button>Save</button>
|
|
956
|
+
</DialogFooter>
|
|
957
|
+
</DialogContent>
|
|
958
|
+
</Dialog>
|
|
959
|
+
);
|
|
960
|
+
|
|
961
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
962
|
+
|
|
963
|
+
await waitFor(() => {
|
|
964
|
+
const dialog = screen.getByRole('dialog');
|
|
965
|
+
expect(dialog).toHaveClass('flex', 'flex-col', 'overflow-hidden');
|
|
966
|
+
const body = screen.getByRole('main');
|
|
967
|
+
expect(body).toHaveClass('overflow-y-auto');
|
|
968
|
+
});
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
it('handles sticky header and footer', async () => {
|
|
972
|
+
const user = userEvent.setup();
|
|
973
|
+
|
|
974
|
+
renderWithProviders(
|
|
975
|
+
<Dialog>
|
|
976
|
+
<DialogTrigger asChild>
|
|
977
|
+
<button>Open Dialog</button>
|
|
978
|
+
</DialogTrigger>
|
|
979
|
+
<DialogContent enableScrolling>
|
|
980
|
+
<DialogHeader sticky>
|
|
981
|
+
<DialogTitle>Sticky Header</DialogTitle>
|
|
982
|
+
</DialogHeader>
|
|
983
|
+
<DialogBody>
|
|
984
|
+
<section>
|
|
985
|
+
{Array.from({ length: 20 }, (_, i) => (
|
|
986
|
+
<p key={i}>Content item {i + 1}</p>
|
|
987
|
+
))}
|
|
988
|
+
</section>
|
|
989
|
+
</DialogBody>
|
|
990
|
+
<DialogFooter sticky>
|
|
991
|
+
<button>Sticky Footer</button>
|
|
992
|
+
</DialogFooter>
|
|
993
|
+
</DialogContent>
|
|
994
|
+
</Dialog>
|
|
995
|
+
);
|
|
996
|
+
|
|
997
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
998
|
+
|
|
999
|
+
await waitFor(() => {
|
|
1000
|
+
const header = screen.getByRole('banner');
|
|
1001
|
+
const footer = screen.getByRole('contentinfo');
|
|
1002
|
+
expect(header).toHaveClass('sticky', 'top-0');
|
|
1003
|
+
expect(footer).toHaveClass('sticky', 'bottom-0');
|
|
1004
|
+
});
|
|
1005
|
+
});
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
describe('Error Handling', () => {
|
|
1009
|
+
it('handles missing children gracefully', () => {
|
|
1010
|
+
renderWithProviders(
|
|
1011
|
+
<Dialog>
|
|
1012
|
+
<DialogTrigger asChild>
|
|
1013
|
+
<button>Open Dialog</button>
|
|
1014
|
+
</DialogTrigger>
|
|
1015
|
+
<DialogContent>
|
|
1016
|
+
<DialogHeader>
|
|
1017
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
1018
|
+
</DialogHeader>
|
|
1019
|
+
<DialogBody />
|
|
1020
|
+
</DialogContent>
|
|
1021
|
+
</Dialog>
|
|
1022
|
+
);
|
|
1023
|
+
|
|
1024
|
+
expect(screen.getByRole('button', { name: 'Open Dialog' })).toBeInTheDocument();
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
it('handles invalid props gracefully', () => {
|
|
1028
|
+
// @ts-expect-error Testing invalid prop
|
|
1029
|
+
renderWithProviders(
|
|
1030
|
+
<Dialog invalidProp="test">
|
|
1031
|
+
<DialogTrigger asChild>
|
|
1032
|
+
<button>Open Dialog</button>
|
|
1033
|
+
</DialogTrigger>
|
|
1034
|
+
<DialogContent>
|
|
1035
|
+
<DialogHeader>
|
|
1036
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
1037
|
+
</DialogHeader>
|
|
1038
|
+
</DialogContent>
|
|
1039
|
+
</Dialog>
|
|
1040
|
+
);
|
|
1041
|
+
|
|
1042
|
+
expect(screen.getByRole('button', { name: 'Open Dialog' })).toBeInTheDocument();
|
|
1043
|
+
});
|
|
1044
|
+
|
|
1045
|
+
it('handles HTML sanitization errors gracefully', async () => {
|
|
1046
|
+
const user = userEvent.setup();
|
|
1047
|
+
|
|
1048
|
+
renderWithProviders(
|
|
1049
|
+
<Dialog>
|
|
1050
|
+
<DialogTrigger asChild>
|
|
1051
|
+
<button>Open Dialog</button>
|
|
1052
|
+
</DialogTrigger>
|
|
1053
|
+
<DialogContent>
|
|
1054
|
+
<DialogHeader>
|
|
1055
|
+
<DialogTitle>Test Dialog</DialogTitle>
|
|
1056
|
+
</DialogHeader>
|
|
1057
|
+
<DialogBody
|
|
1058
|
+
htmlContent="<script>alert('xss')</script><p>Safe content</p>"
|
|
1059
|
+
allowHtml={true}
|
|
1060
|
+
/>
|
|
1061
|
+
</DialogContent>
|
|
1062
|
+
</Dialog>
|
|
1063
|
+
);
|
|
1064
|
+
|
|
1065
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
1066
|
+
|
|
1067
|
+
await waitFor(() => {
|
|
1068
|
+
// Script should be removed, safe content should remain
|
|
1069
|
+
expect(screen.getByText('Safe content')).toBeInTheDocument();
|
|
1070
|
+
expect(screen.queryByText("alert('xss')")).not.toBeInTheDocument();
|
|
1071
|
+
});
|
|
1072
|
+
});
|
|
1073
|
+
});
|
|
1074
|
+
|
|
1075
|
+
describe('Integration', () => {
|
|
1076
|
+
it('works with forms', async () => {
|
|
1077
|
+
const user = userEvent.setup();
|
|
1078
|
+
const handleSubmit = vi.fn((e) => e.preventDefault());
|
|
1079
|
+
|
|
1080
|
+
renderWithProviders(
|
|
1081
|
+
<Dialog>
|
|
1082
|
+
<DialogTrigger asChild>
|
|
1083
|
+
<button>Open Dialog</button>
|
|
1084
|
+
</DialogTrigger>
|
|
1085
|
+
<DialogContent>
|
|
1086
|
+
<DialogHeader>
|
|
1087
|
+
<DialogTitle>Form Dialog</DialogTitle>
|
|
1088
|
+
</DialogHeader>
|
|
1089
|
+
<DialogBody>
|
|
1090
|
+
<form onSubmit={handleSubmit}>
|
|
1091
|
+
<input type="text" placeholder="Enter name" />
|
|
1092
|
+
<button type="submit">Submit</button>
|
|
1093
|
+
</form>
|
|
1094
|
+
</DialogBody>
|
|
1095
|
+
</DialogContent>
|
|
1096
|
+
</Dialog>
|
|
1097
|
+
);
|
|
1098
|
+
|
|
1099
|
+
await user.click(screen.getByRole('button', { name: 'Open Dialog' }));
|
|
1100
|
+
|
|
1101
|
+
await waitFor(() => {
|
|
1102
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
1103
|
+
});
|
|
1104
|
+
|
|
1105
|
+
await user.click(screen.getByRole('button', { name: 'Submit' }));
|
|
1106
|
+
expect(handleSubmit).toHaveBeenCalledTimes(1);
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
it('works with multiple dialogs', () => {
|
|
1110
|
+
renderWithProviders(
|
|
1111
|
+
<div>
|
|
1112
|
+
<Dialog>
|
|
1113
|
+
<DialogTrigger asChild>
|
|
1114
|
+
<button>Open Dialog 1</button>
|
|
1115
|
+
</DialogTrigger>
|
|
1116
|
+
<DialogContent>
|
|
1117
|
+
<DialogHeader>
|
|
1118
|
+
<DialogTitle>Dialog 1</DialogTitle>
|
|
1119
|
+
</DialogHeader>
|
|
1120
|
+
</DialogContent>
|
|
1121
|
+
</Dialog>
|
|
1122
|
+
<Dialog>
|
|
1123
|
+
<DialogTrigger asChild>
|
|
1124
|
+
<button>Open Dialog 2</button>
|
|
1125
|
+
</DialogTrigger>
|
|
1126
|
+
<DialogContent>
|
|
1127
|
+
<DialogHeader>
|
|
1128
|
+
<DialogTitle>Dialog 2</DialogTitle>
|
|
1129
|
+
</DialogHeader>
|
|
1130
|
+
</DialogContent>
|
|
1131
|
+
</Dialog>
|
|
1132
|
+
</div>
|
|
1133
|
+
);
|
|
1134
|
+
|
|
1135
|
+
expect(screen.getByRole('button', { name: 'Open Dialog 1' })).toBeInTheDocument();
|
|
1136
|
+
expect(screen.getByRole('button', { name: 'Open Dialog 2' })).toBeInTheDocument();
|
|
1137
|
+
});
|
|
1138
|
+
});
|
|
1139
|
+
});
|