@jmruthers/pace-core 0.5.73 → 0.5.75
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-INW5YIFV.js → DataTable-HWZQGASI.js} +8 -8
- package/dist/{PublicLoadingSpinner-DLpF5bbs.d.ts → PublicLoadingSpinner-BKNBT6b6.d.ts} +2 -2
- package/dist/RBACService-C4udt_Zp.d.ts +528 -0
- package/dist/{UnifiedAuthProvider-6SYT5WFN.js → UnifiedAuthProvider-3NKDOSOK.js} +6 -4
- package/dist/UnifiedAuthProvider-Bj6YCf7c.d.ts +113 -0
- package/dist/{chunk-2PRPDH66.js → chunk-2CHATWBF.js} +5 -7
- package/dist/chunk-2CHATWBF.js.map +1 -0
- package/dist/{chunk-43C63KLH.js → chunk-2DFZ432F.js} +496 -30
- package/dist/chunk-2DFZ432F.js.map +1 -0
- package/dist/{chunk-M4UMXYNK.js → chunk-33PHABLB.js} +36 -3
- package/dist/chunk-33PHABLB.js.map +1 -0
- package/dist/chunk-5F3NDPJV.js +232 -0
- package/dist/chunk-5F3NDPJV.js.map +1 -0
- package/dist/chunk-A4FUBC7B.js +17 -0
- package/dist/chunk-A4FUBC7B.js.map +1 -0
- package/dist/{chunk-SMJZMKYN.js → chunk-A6HBIY5P.js} +2 -11
- package/dist/{chunk-SMJZMKYN.js.map → chunk-A6HBIY5P.js.map} +1 -1
- package/dist/{chunk-GBC5PC3N.js → chunk-CY3AHGO4.js} +6256 -1937
- package/dist/chunk-CY3AHGO4.js.map +1 -0
- package/dist/{chunk-BYG6OSTC.js → chunk-DAXLNIDY.js} +48 -50
- package/dist/chunk-DAXLNIDY.js.map +1 -0
- package/dist/{chunk-VKOCWWVY.js → chunk-L3RV2ALE.js} +1 -6
- package/dist/{chunk-VKOCWWVY.js.map → chunk-L3RV2ALE.js.map} +1 -1
- package/dist/chunk-LW7MMEAQ.js +59 -0
- package/dist/chunk-LW7MMEAQ.js.map +1 -0
- package/dist/{chunk-LANO5IFV.js → chunk-NTNILOBC.js} +7 -9
- package/dist/chunk-NTNILOBC.js.map +1 -0
- package/dist/chunk-PYUXFQJ3.js +11 -0
- package/dist/chunk-PYUXFQJ3.js.map +1 -0
- package/dist/chunk-URUTVZ7N.js +27 -0
- package/dist/chunk-URUTVZ7N.js.map +1 -0
- package/dist/chunk-WN6XJWOS.js +2468 -0
- package/dist/chunk-WN6XJWOS.js.map +1 -0
- package/dist/{chunk-3SP4P7NS.js → chunk-XLZ7U46Z.js} +59 -1
- package/dist/chunk-XLZ7U46Z.js.map +1 -0
- package/dist/{chunk-UC2BWIK7.js → chunk-ZTT2AXMX.js} +9 -14
- package/dist/chunk-ZTT2AXMX.js.map +1 -0
- package/dist/components.d.ts +4 -5
- package/dist/components.js +32 -39
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +3 -3
- package/dist/hooks.js +9 -8
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +156 -10
- package/dist/index.js +188 -93
- package/dist/index.js.map +1 -1
- package/dist/{organisation-t-vvQC3g.d.ts → organisation-BtshODVF.d.ts} +4 -3
- package/dist/providers.d.ts +27 -38
- package/dist/providers.js +33 -23
- package/dist/rbac/index.d.ts +61 -5
- package/dist/rbac/index.js +13 -14
- package/dist/styles/index.js +2 -2
- package/dist/theming/runtime.js +1 -3
- package/dist/types.d.ts +3 -3
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/{unified-CMPjE_fv.d.ts → unified-CM7T0aTK.d.ts} +1 -1
- package/dist/useInactivityTracker-MRUU55XI.js +10 -0
- package/dist/useInactivityTracker-MRUU55XI.js.map +1 -0
- package/dist/{usePublicRouteParams-Ua1Vz-HG.d.ts → usePublicRouteParams-B-CumWRc.d.ts} +3 -3
- package/dist/utils.js +7 -9
- package/dist/utils.js.map +1 -1
- package/dist/validation.d.ts +1 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +3 -3
- package/docs/api/interfaces/CardProps.md +2 -2
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +2 -2
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.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 +2 -2
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +28 -17
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +2 -2
- 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/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.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 +2 -2
- 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/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +5 -11
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.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/SwitchProps.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 +524 -440
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +14 -14
- 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 +11 -11
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +179 -52
- package/docs/architecture/services.md +30 -32
- package/docs/breaking-changes.md +2 -5
- package/docs/implementation-guides/data-tables.md +82 -1
- package/docs/migration/service-architecture.md +121 -260
- package/docs/rbac/README-rbac-rls-integration.md +48 -38
- package/{src/rbac/examples → examples/RBAC}/CompleteRBACExample.tsx +3 -2
- package/{src/rbac/examples → examples/RBAC}/EventBasedApp.tsx +5 -4
- package/{src/components/examples → examples/RBAC}/PermissionExample.tsx +7 -6
- package/examples/RBAC/__tests__/PermissionExample.test.tsx +150 -0
- package/examples/RBAC/index.ts +13 -0
- package/examples/README.md +37 -0
- package/examples/index.ts +22 -0
- package/{src/examples → examples/public-pages}/CorrectPublicPageImplementation.tsx +1 -1
- package/{src/examples → examples/public-pages}/PublicEventPage.tsx +1 -1
- package/{src/examples → examples/public-pages}/PublicPageApp.tsx +1 -1
- package/{src/examples → examples/public-pages}/PublicPageUsageExample.tsx +1 -1
- package/examples/public-pages/__tests__/PublicPageUsageExample.test.tsx +159 -0
- package/examples/public-pages/index.ts +14 -0
- package/package.json +22 -18
- package/src/__tests__/TEST_GUIDE_CURSOR.md +650 -9
- package/src/__tests__/helpers/README.md +255 -0
- package/src/__tests__/helpers/index.ts +62 -0
- package/src/__tests__/helpers/supabaseMock.ts +27 -3
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -8
- package/src/components/DataTable/components/DataTableCore.tsx +37 -3
- package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +55 -0
- package/src/components/DataTable/core/ColumnManager.ts +10 -0
- package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +254 -0
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +193 -0
- package/src/components/DataTable/examples/__tests__/HierarchicalExample.test.tsx +45 -0
- package/src/components/DataTable/examples/__tests__/PerformanceExample.test.tsx +117 -0
- package/src/components/Dialog/Dialog.tsx +2 -2
- package/src/components/Dialog/examples/__tests__/HtmlDialogExample.test.tsx +71 -0
- package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +122 -0
- package/src/components/EventSelector/EventSelector.tsx +1 -1
- package/src/components/Header/Header.test.tsx +35 -1
- package/src/components/Header/Header.tsx +3 -1
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -3
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +24 -4
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +3 -2
- package/src/components/Toast/Toast.test.tsx +1 -1
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/hooks/__tests__/useFocusManagement.unit.test.ts +220 -0
- package/src/hooks/__tests__/useIsMobile.unit.test.ts +117 -0
- package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +295 -0
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +29 -19
- package/src/hooks/__tests__/useRBAC.unit.test.ts +7 -3
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +115 -19
- package/src/hooks/useEventTheme.test.ts +350 -0
- package/src/hooks/useEventTheme.ts +1 -1
- package/src/hooks/useEvents.ts +61 -0
- package/src/hooks/useOrganisationSecurity.test.ts +4 -4
- package/src/hooks/useOrganisationSecurity.ts +2 -2
- package/src/hooks/useOrganisations.ts +64 -0
- package/src/hooks/useSecureDataAccess.test.ts +9 -5
- package/src/hooks/useSecureDataAccess.ts +2 -2
- package/src/index.ts +18 -3
- package/src/providers/AuthProvider.tsx +8 -292
- package/src/providers/EventProvider.tsx +15 -425
- package/src/providers/InactivityProvider.tsx +8 -231
- package/src/providers/OrganisationProvider.test.simple.tsx +3 -2
- package/src/providers/OrganisationProvider.tsx +11 -890
- package/src/providers/UnifiedAuthProvider.tsx +8 -320
- package/src/providers/__tests__/AuthProvider.test.tsx +18 -17
- package/src/providers/__tests__/EventProvider.test.tsx +253 -2
- package/src/providers/__tests__/InactivityProvider.test-helper.tsx +65 -0
- package/src/providers/__tests__/InactivityProvider.test.tsx +46 -114
- package/src/providers/__tests__/OrganisationProvider.test.tsx +313 -3
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +383 -2
- package/src/providers/index.ts +8 -7
- package/src/providers/services/EventServiceProvider.tsx +3 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +3 -0
- package/src/rbac/hooks/usePermissions.test.ts +296 -0
- package/src/rbac/hooks/useRBAC.test.ts +9 -5
- package/src/rbac/hooks/useRBAC.ts +3 -3
- package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +688 -0
- package/src/rbac/providers/__tests__/RBACProvider.test.tsx +507 -0
- package/src/services/AuthService.ts +19 -4
- package/src/services/__tests__/AuthService.test.ts +288 -0
- package/src/styles/core.css +2 -0
- package/src/types/__tests__/guards.test.ts +246 -0
- package/src/types/guards.ts +1 -0
- package/src/types/organisation.ts +3 -2
- package/src/validation/__tests__/sanitization.unit.test.ts +250 -0
- package/src/validation/__tests__/schemaUtils.unit.test.ts +451 -0
- package/src/validation/__tests__/user.unit.test.ts +440 -0
- package/dist/RBACProvider-BO4ilsQB.d.ts +0 -63
- package/dist/UnifiedAuthProvider-D02AMXgO.d.ts +0 -103
- package/dist/chunk-2PRPDH66.js.map +0 -1
- package/dist/chunk-3SP4P7NS.js.map +0 -1
- package/dist/chunk-43C63KLH.js.map +0 -1
- package/dist/chunk-5A4RL4BC.js +0 -5670
- package/dist/chunk-5A4RL4BC.js.map +0 -1
- package/dist/chunk-BYG6OSTC.js.map +0 -1
- package/dist/chunk-CDDYJCYU.js +0 -79
- package/dist/chunk-CDDYJCYU.js.map +0 -1
- package/dist/chunk-F24P24TZ.js +0 -17
- package/dist/chunk-F24P24TZ.js.map +0 -1
- package/dist/chunk-GBC5PC3N.js.map +0 -1
- package/dist/chunk-LANO5IFV.js.map +0 -1
- package/dist/chunk-M4UMXYNK.js.map +0 -1
- package/dist/chunk-RJNE764D.js +0 -953
- package/dist/chunk-RJNE764D.js.map +0 -1
- package/dist/chunk-UC2BWIK7.js.map +0 -1
- package/dist/rbac/cli/policy-manager.js +0 -278
- package/dist/rbac/cli/policy-manager.js.map +0 -1
- package/docs/api/interfaces/EventContextType.md +0 -96
- package/docs/api/interfaces/EventProviderProps.md +0 -19
- package/src/providers/OrganisationProvider.test.tsx +0 -164
- package/src/providers/UnifiedAuthProvider.test.tsx +0 -124
- package/src/providers/__tests__/AuthProvider.test.tsx.backup +0 -771
- package/src/providers/__tests__/EventProvider.test.tsx.backup +0 -824
- package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +0 -820
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +0 -911
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +0 -166
- package/src/rbac/cli/__tests__/policy-manager.test.ts +0 -339
- package/src/rbac/cli/policy-manager.ts +0 -443
- package/dist/{DataTable-INW5YIFV.js.map → DataTable-HWZQGASI.js.map} +0 -0
- package/dist/{UnifiedAuthProvider-6SYT5WFN.js.map → UnifiedAuthProvider-3NKDOSOK.js.map} +0 -0
- package/dist/{validation-PM_iOaTI.d.ts → validation-D8VcbTzC.d.ts} +2 -2
- /package/src/utils/{appNameResolver.test.ts.backup → appNameResolver.test 2.ts} +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file useIsMobile Hook Unit Tests
|
|
3
|
+
* @package @jmruthers/pace-core
|
|
4
|
+
* @module Hooks/__tests__/useIsMobile
|
|
5
|
+
* @since 0.4.0
|
|
6
|
+
*
|
|
7
|
+
* Comprehensive tests for the useIsMobile hook covering all critical functionality.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { renderHook } from '@testing-library/react';
|
|
11
|
+
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
|
12
|
+
import { useIsMobile } from '../useIsMobile';
|
|
13
|
+
|
|
14
|
+
describe('useIsMobile', () => {
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
vi.clearAllMocks();
|
|
17
|
+
// Reset window properties for each test
|
|
18
|
+
Object.defineProperty(window, 'innerWidth', {
|
|
19
|
+
writable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
value: 1024
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('Initial detection', () => {
|
|
26
|
+
it('detects mobile viewport initially', () => {
|
|
27
|
+
window.innerWidth = 500;
|
|
28
|
+
|
|
29
|
+
const mql = {
|
|
30
|
+
matches: true,
|
|
31
|
+
media: '(max-width: 767px)',
|
|
32
|
+
onchange: null,
|
|
33
|
+
addEventListener: vi.fn(),
|
|
34
|
+
removeEventListener: vi.fn(),
|
|
35
|
+
addListener: vi.fn(),
|
|
36
|
+
removeListener: vi.fn(),
|
|
37
|
+
dispatchEvent: vi.fn()
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
window.matchMedia = vi.fn(() => mql) as any;
|
|
41
|
+
|
|
42
|
+
const { result } = renderHook(() => useIsMobile());
|
|
43
|
+
|
|
44
|
+
expect(result.current).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('detects desktop viewport initially', () => {
|
|
48
|
+
window.innerWidth = 1200;
|
|
49
|
+
|
|
50
|
+
const mql = {
|
|
51
|
+
matches: false,
|
|
52
|
+
media: '(max-width: 767px)',
|
|
53
|
+
onchange: null,
|
|
54
|
+
addEventListener: vi.fn(),
|
|
55
|
+
removeEventListener: vi.fn(),
|
|
56
|
+
addListener: vi.fn(),
|
|
57
|
+
removeListener: vi.fn(),
|
|
58
|
+
dispatchEvent: vi.fn()
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
window.matchMedia = vi.fn(() => mql) as any;
|
|
62
|
+
|
|
63
|
+
const { result } = renderHook(() => useIsMobile());
|
|
64
|
+
|
|
65
|
+
expect(result.current).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('Event listener management', () => {
|
|
70
|
+
it('registers event listener for media query changes', () => {
|
|
71
|
+
const addEventListener = vi.fn();
|
|
72
|
+
const removeEventListener = vi.fn();
|
|
73
|
+
|
|
74
|
+
const mql = {
|
|
75
|
+
matches: false,
|
|
76
|
+
media: '(max-width: 767px)',
|
|
77
|
+
onchange: null,
|
|
78
|
+
addEventListener,
|
|
79
|
+
removeEventListener,
|
|
80
|
+
addListener: vi.fn(),
|
|
81
|
+
removeListener: vi.fn(),
|
|
82
|
+
dispatchEvent: vi.fn()
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
window.matchMedia = vi.fn(() => mql) as any;
|
|
86
|
+
|
|
87
|
+
const { unmount } = renderHook(() => useIsMobile());
|
|
88
|
+
|
|
89
|
+
expect(addEventListener).toHaveBeenCalledWith('change', expect.any(Function));
|
|
90
|
+
|
|
91
|
+
unmount();
|
|
92
|
+
|
|
93
|
+
expect(removeEventListener).toHaveBeenCalledWith('change', expect.any(Function));
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('Hook returns boolean', () => {
|
|
98
|
+
it('returns a boolean value', () => {
|
|
99
|
+
const mql = {
|
|
100
|
+
matches: false,
|
|
101
|
+
media: '(max-width: 767px)',
|
|
102
|
+
onchange: null,
|
|
103
|
+
addEventListener: vi.fn(),
|
|
104
|
+
removeEventListener: vi.fn(),
|
|
105
|
+
addListener: vi.fn(),
|
|
106
|
+
removeListener: vi.fn(),
|
|
107
|
+
dispatchEvent: vi.fn()
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
window.matchMedia = vi.fn(() => mql) as any;
|
|
111
|
+
|
|
112
|
+
const { result } = renderHook(() => useIsMobile());
|
|
113
|
+
|
|
114
|
+
expect(typeof result.current).toBe('boolean');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file useKeyboardShortcuts Hook Unit Tests
|
|
3
|
+
* @package @jmruthers/pace-core
|
|
4
|
+
* @module Hooks/__tests__/useKeyboardShortcuts
|
|
5
|
+
* @since 0.4.0
|
|
6
|
+
*
|
|
7
|
+
* Comprehensive tests for the useKeyboardShortcuts hook covering all critical functionality.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { renderHook } from '@testing-library/react';
|
|
11
|
+
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
12
|
+
import { useKeyboardShortcuts } from '../useKeyboardShortcuts';
|
|
13
|
+
import { fireEvent } from '@testing-library/react';
|
|
14
|
+
|
|
15
|
+
describe('useKeyboardShortcuts', () => {
|
|
16
|
+
let mockElement: HTMLElement;
|
|
17
|
+
let addEventListenerSpy: ReturnType<typeof vi.spyOn>;
|
|
18
|
+
let removeEventListenerSpy: ReturnType<typeof vi.spyOn>;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
mockElement = document.createElement('div');
|
|
22
|
+
addEventListenerSpy = vi.spyOn(document, 'addEventListener');
|
|
23
|
+
removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(() => {
|
|
27
|
+
addEventListenerSpy.mockRestore();
|
|
28
|
+
removeEventListenerSpy.mockRestore();
|
|
29
|
+
vi.clearAllMocks();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('Event listener registration', () => {
|
|
33
|
+
it('registers keydown event listener on document', () => {
|
|
34
|
+
const shortcuts = [
|
|
35
|
+
{
|
|
36
|
+
key: 'Escape',
|
|
37
|
+
handler: vi.fn()
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
42
|
+
|
|
43
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('keydown', expect.any(Function));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('unregisters event listener on unmount', () => {
|
|
47
|
+
const shortcuts = [
|
|
48
|
+
{
|
|
49
|
+
key: 'Escape',
|
|
50
|
+
handler: vi.fn()
|
|
51
|
+
}
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const { unmount } = renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
55
|
+
unmount();
|
|
56
|
+
|
|
57
|
+
expect(removeEventListenerSpy).toHaveBeenCalled();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('registers listener on custom element', () => {
|
|
61
|
+
const mockAddEventListener = vi.fn();
|
|
62
|
+
const mockRemoveEventListener = vi.fn();
|
|
63
|
+
|
|
64
|
+
const customElement = {
|
|
65
|
+
addEventListener: mockAddEventListener,
|
|
66
|
+
removeEventListener: mockRemoveEventListener
|
|
67
|
+
} as any;
|
|
68
|
+
|
|
69
|
+
const shortcuts = [
|
|
70
|
+
{
|
|
71
|
+
key: 'Escape',
|
|
72
|
+
handler: vi.fn()
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
renderHook(() => useKeyboardShortcuts(shortcuts, { element: customElement }));
|
|
77
|
+
|
|
78
|
+
expect(mockAddEventListener).toHaveBeenCalledWith('keydown', expect.any(Function));
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('Keyboard shortcut handling', () => {
|
|
83
|
+
it('triggers handler when Escape key is pressed', () => {
|
|
84
|
+
const handler = vi.fn();
|
|
85
|
+
const shortcuts = [
|
|
86
|
+
{
|
|
87
|
+
key: 'Escape',
|
|
88
|
+
handler
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
93
|
+
|
|
94
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape' });
|
|
95
|
+
document.dispatchEvent(event);
|
|
96
|
+
|
|
97
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
98
|
+
expect(handler).toHaveBeenCalledWith(expect.objectContaining({ key: 'Escape' }));
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('does not trigger handler for wrong key', () => {
|
|
102
|
+
const handler = vi.fn();
|
|
103
|
+
const shortcuts = [
|
|
104
|
+
{
|
|
105
|
+
key: 'Escape',
|
|
106
|
+
handler
|
|
107
|
+
}
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
111
|
+
|
|
112
|
+
const event = new KeyboardEvent('keydown', { key: 'Enter' });
|
|
113
|
+
document.dispatchEvent(event);
|
|
114
|
+
|
|
115
|
+
expect(handler).not.toHaveBeenCalled();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('triggers handler for Enter key', () => {
|
|
119
|
+
const handler = vi.fn();
|
|
120
|
+
const shortcuts = [
|
|
121
|
+
{
|
|
122
|
+
key: 'Enter',
|
|
123
|
+
handler
|
|
124
|
+
}
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
128
|
+
|
|
129
|
+
const event = new KeyboardEvent('keydown', { key: 'Enter' });
|
|
130
|
+
document.dispatchEvent(event);
|
|
131
|
+
|
|
132
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('handles multiple shortcuts and triggers the first matching one', () => {
|
|
136
|
+
const handler1 = vi.fn();
|
|
137
|
+
const handler2 = vi.fn();
|
|
138
|
+
|
|
139
|
+
const shortcuts = [
|
|
140
|
+
{
|
|
141
|
+
key: 'Escape',
|
|
142
|
+
handler: handler1
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
key: 'Escape',
|
|
146
|
+
handler: handler2
|
|
147
|
+
}
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
151
|
+
|
|
152
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape' });
|
|
153
|
+
document.dispatchEvent(event);
|
|
154
|
+
|
|
155
|
+
expect(handler1).toHaveBeenCalledTimes(1);
|
|
156
|
+
expect(handler2).not.toHaveBeenCalled();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('Modifier key combinations', () => {
|
|
161
|
+
it('handles Ctrl+key combination', () => {
|
|
162
|
+
const handler = vi.fn();
|
|
163
|
+
const shortcuts = [
|
|
164
|
+
{
|
|
165
|
+
key: 'ctrl+s',
|
|
166
|
+
handler
|
|
167
|
+
}
|
|
168
|
+
];
|
|
169
|
+
|
|
170
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
171
|
+
|
|
172
|
+
const event = new KeyboardEvent('keydown', {
|
|
173
|
+
key: 's',
|
|
174
|
+
ctrlKey: true,
|
|
175
|
+
bubbles: true
|
|
176
|
+
});
|
|
177
|
+
document.dispatchEvent(event);
|
|
178
|
+
|
|
179
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('does not trigger when modifiers do not match', () => {
|
|
183
|
+
const handler = vi.fn();
|
|
184
|
+
const shortcuts = [
|
|
185
|
+
{
|
|
186
|
+
key: 'ctrl+s',
|
|
187
|
+
handler
|
|
188
|
+
}
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
192
|
+
|
|
193
|
+
const event = new KeyboardEvent('keydown', {
|
|
194
|
+
key: 's',
|
|
195
|
+
ctrlKey: false,
|
|
196
|
+
bubbles: true
|
|
197
|
+
});
|
|
198
|
+
document.dispatchEvent(event);
|
|
199
|
+
|
|
200
|
+
expect(handler).not.toHaveBeenCalled();
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe('Options', () => {
|
|
205
|
+
it('does not register listeners when disabled', () => {
|
|
206
|
+
const shortcuts = [
|
|
207
|
+
{
|
|
208
|
+
key: 'Escape',
|
|
209
|
+
handler: vi.fn()
|
|
210
|
+
}
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
renderHook(() => useKeyboardShortcuts(shortcuts, { enabled: false }));
|
|
214
|
+
|
|
215
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape' });
|
|
216
|
+
document.dispatchEvent(event);
|
|
217
|
+
|
|
218
|
+
expect(addEventListenerSpy).not.toHaveBeenCalled();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('skips disabled shortcuts', () => {
|
|
222
|
+
const handler = vi.fn();
|
|
223
|
+
const shortcuts = [
|
|
224
|
+
{
|
|
225
|
+
key: 'Escape',
|
|
226
|
+
handler,
|
|
227
|
+
enabled: false
|
|
228
|
+
}
|
|
229
|
+
];
|
|
230
|
+
|
|
231
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
232
|
+
|
|
233
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape' });
|
|
234
|
+
document.dispatchEvent(event);
|
|
235
|
+
|
|
236
|
+
expect(handler).not.toHaveBeenCalled();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('calls preventDefault when option is set', () => {
|
|
240
|
+
const handler = vi.fn();
|
|
241
|
+
const shortcuts = [
|
|
242
|
+
{
|
|
243
|
+
key: 'Escape',
|
|
244
|
+
handler,
|
|
245
|
+
preventDefault: true
|
|
246
|
+
}
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
250
|
+
|
|
251
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape', cancelable: true });
|
|
252
|
+
document.dispatchEvent(event);
|
|
253
|
+
|
|
254
|
+
expect(handler).toHaveBeenCalled();
|
|
255
|
+
// Note: preventDefault() is called on the event object by the handler
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
describe('Case insensitivity', () => {
|
|
260
|
+
it('handles lowercase key correctly', () => {
|
|
261
|
+
const handler = vi.fn();
|
|
262
|
+
const shortcuts = [
|
|
263
|
+
{
|
|
264
|
+
key: 'escape',
|
|
265
|
+
handler
|
|
266
|
+
}
|
|
267
|
+
];
|
|
268
|
+
|
|
269
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
270
|
+
|
|
271
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape' });
|
|
272
|
+
document.dispatchEvent(event);
|
|
273
|
+
|
|
274
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('handles uppercase key correctly', () => {
|
|
278
|
+
const handler = vi.fn();
|
|
279
|
+
const shortcuts = [
|
|
280
|
+
{
|
|
281
|
+
key: 'ESCAPE',
|
|
282
|
+
handler
|
|
283
|
+
}
|
|
284
|
+
];
|
|
285
|
+
|
|
286
|
+
renderHook(() => useKeyboardShortcuts(shortcuts));
|
|
287
|
+
|
|
288
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape' });
|
|
289
|
+
document.dispatchEvent(event);
|
|
290
|
+
|
|
291
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { renderHook, act } from '@testing-library/react';
|
|
2
2
|
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
|
3
3
|
import { useOrganisationSecurity } from '../useOrganisationSecurity';
|
|
4
|
-
import { useUnifiedAuth } from '../../providers
|
|
5
|
-
import { useOrganisations } from '../../
|
|
4
|
+
import { useUnifiedAuth } from '../../providers';
|
|
5
|
+
import { useOrganisations } from '../../hooks/useOrganisations';
|
|
6
6
|
// Mock dependencies
|
|
7
|
-
vi.mock('../../providers
|
|
8
|
-
vi.
|
|
7
|
+
vi.mock('../../providers', () => ({
|
|
8
|
+
useUnifiedAuth: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
vi.mock('../../providers/services/UnifiedAuthProvider', () => ({
|
|
12
|
+
useUnifiedAuth: vi.fn(),
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
vi.mock('../../hooks/useOrganisations', () => ({
|
|
16
|
+
useOrganisations: vi.fn(),
|
|
17
|
+
}));
|
|
9
18
|
|
|
10
19
|
// Mock the RBAC API
|
|
11
20
|
vi.mock('../../rbac/api', () => ({
|
|
@@ -45,16 +54,17 @@ describe('useOrganisationSecurity', () => {
|
|
|
45
54
|
it('should detect super admin from user metadata', () => {
|
|
46
55
|
const mockUser = {
|
|
47
56
|
id: 'user-123',
|
|
48
|
-
user_metadata: { globalRole: 'super_admin' }
|
|
57
|
+
user_metadata: { globalRole: 'super_admin' },
|
|
58
|
+
app_metadata: { globalRole: 'super_admin' }
|
|
49
59
|
};
|
|
50
60
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
51
61
|
...mockUseUnifiedAuth,
|
|
52
62
|
user: mockUser
|
|
53
63
|
} as any);
|
|
54
|
-
// Global role now derived from user metadata directly
|
|
55
64
|
|
|
56
65
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
57
|
-
|
|
66
|
+
|
|
67
|
+
console.log('User metadata:', result.current);
|
|
58
68
|
expect(result.current.superAdminContext.isSuperAdmin).toBe(true);
|
|
59
69
|
expect(result.current.superAdminContext.hasGlobalAccess).toBe(true);
|
|
60
70
|
expect(result.current.superAdminContext.canManageAllOrganisations).toBe(true);
|
|
@@ -98,7 +108,8 @@ describe('useOrganisationSecurity', () => {
|
|
|
98
108
|
it('should return true for super admin', async () => {
|
|
99
109
|
const mockUser = {
|
|
100
110
|
id: 'user-123',
|
|
101
|
-
user_metadata: { globalRole: 'super_admin' }
|
|
111
|
+
user_metadata: { globalRole: 'super_admin' },
|
|
112
|
+
app_metadata: { globalRole: 'super_admin' }
|
|
102
113
|
};
|
|
103
114
|
const mockSession = { access_token: 'test-token' };
|
|
104
115
|
const mockSupabase = { from: vi.fn() };
|
|
@@ -109,7 +120,6 @@ describe('useOrganisationSecurity', () => {
|
|
|
109
120
|
session: mockSession,
|
|
110
121
|
supabase: mockSupabase
|
|
111
122
|
} as any);
|
|
112
|
-
// Global role now derived from user metadata directly
|
|
113
123
|
|
|
114
124
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
115
125
|
|
|
@@ -213,13 +223,13 @@ describe('useOrganisationSecurity', () => {
|
|
|
213
223
|
it('should return true for super admin regardless of role', () => {
|
|
214
224
|
const mockUser = {
|
|
215
225
|
id: 'user-123',
|
|
216
|
-
user_metadata: { globalRole: 'super_admin' }
|
|
226
|
+
user_metadata: { globalRole: 'super_admin' },
|
|
227
|
+
app_metadata: { globalRole: 'super_admin' }
|
|
217
228
|
};
|
|
218
229
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
219
230
|
...mockUseUnifiedAuth,
|
|
220
231
|
user: mockUser
|
|
221
232
|
} as any);
|
|
222
|
-
// Global role now derived from user metadata directly
|
|
223
233
|
|
|
224
234
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
225
235
|
|
|
@@ -273,13 +283,13 @@ describe('useOrganisationSecurity', () => {
|
|
|
273
283
|
it('should return true for super admin', () => {
|
|
274
284
|
const mockUser = {
|
|
275
285
|
id: 'user-123',
|
|
276
|
-
user_metadata: { globalRole: 'super_admin' }
|
|
286
|
+
user_metadata: { globalRole: 'super_admin' },
|
|
287
|
+
app_metadata: { globalRole: 'super_admin' }
|
|
277
288
|
};
|
|
278
289
|
vi.mocked(useUnifiedAuth).mockReturnValue({
|
|
279
290
|
...mockUseUnifiedAuth,
|
|
280
291
|
user: mockUser
|
|
281
292
|
} as any);
|
|
282
|
-
// Global role now derived from user metadata directly
|
|
283
293
|
|
|
284
294
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
285
295
|
|
|
@@ -331,7 +341,8 @@ describe('useOrganisationSecurity', () => {
|
|
|
331
341
|
it('should return true for super admin', async () => {
|
|
332
342
|
const mockUser = {
|
|
333
343
|
id: 'user-123',
|
|
334
|
-
user_metadata: { globalRole: 'super_admin' }
|
|
344
|
+
user_metadata: { globalRole: 'super_admin' },
|
|
345
|
+
app_metadata: { globalRole: 'super_admin' }
|
|
335
346
|
};
|
|
336
347
|
const mockSupabase = { rpc: vi.fn() };
|
|
337
348
|
|
|
@@ -340,7 +351,6 @@ describe('useOrganisationSecurity', () => {
|
|
|
340
351
|
user: mockUser,
|
|
341
352
|
supabase: mockSupabase
|
|
342
353
|
} as any);
|
|
343
|
-
// Global role now derived from user metadata directly
|
|
344
354
|
|
|
345
355
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
346
356
|
|
|
@@ -476,7 +486,8 @@ describe('useOrganisationSecurity', () => {
|
|
|
476
486
|
it('should return all permissions for super admin', async () => {
|
|
477
487
|
const mockUser = {
|
|
478
488
|
id: 'user-123',
|
|
479
|
-
user_metadata: { globalRole: 'super_admin' }
|
|
489
|
+
user_metadata: { globalRole: 'super_admin' },
|
|
490
|
+
app_metadata: { globalRole: 'super_admin' }
|
|
480
491
|
};
|
|
481
492
|
const mockSupabase = { rpc: vi.fn() };
|
|
482
493
|
|
|
@@ -485,7 +496,6 @@ describe('useOrganisationSecurity', () => {
|
|
|
485
496
|
user: mockUser,
|
|
486
497
|
supabase: mockSupabase
|
|
487
498
|
} as any);
|
|
488
|
-
// Global role now derived from user metadata directly
|
|
489
499
|
|
|
490
500
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
491
501
|
|
|
@@ -744,7 +754,8 @@ describe('useOrganisationSecurity', () => {
|
|
|
744
754
|
it('should return true for super admin', async () => {
|
|
745
755
|
const mockUser = {
|
|
746
756
|
id: 'user-123',
|
|
747
|
-
user_metadata: { globalRole: 'super_admin' }
|
|
757
|
+
user_metadata: { globalRole: 'super_admin' },
|
|
758
|
+
app_metadata: { globalRole: 'super_admin' }
|
|
748
759
|
};
|
|
749
760
|
const mockSupabase = { from: vi.fn() };
|
|
750
761
|
|
|
@@ -753,7 +764,6 @@ describe('useOrganisationSecurity', () => {
|
|
|
753
764
|
user: mockUser,
|
|
754
765
|
supabase: mockSupabase
|
|
755
766
|
} as any);
|
|
756
|
-
// Global role now derived from user metadata directly
|
|
757
767
|
|
|
758
768
|
const { result } = renderHook(() => useOrganisationSecurity());
|
|
759
769
|
|
|
@@ -8,15 +8,19 @@ const mockUseUnifiedAuth = vi.fn();
|
|
|
8
8
|
const mockUseOrganisations = vi.fn();
|
|
9
9
|
const mockUseEvents = vi.fn();
|
|
10
10
|
|
|
11
|
-
vi.mock('../../providers
|
|
11
|
+
vi.mock('../../providers', () => ({
|
|
12
12
|
useUnifiedAuth: () => mockUseUnifiedAuth()
|
|
13
13
|
}));
|
|
14
14
|
|
|
15
|
-
vi.mock('../../providers/
|
|
15
|
+
vi.mock('../../providers/services/UnifiedAuthProvider', () => ({
|
|
16
|
+
useUnifiedAuth: () => mockUseUnifiedAuth()
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
vi.mock('../../hooks/useOrganisations', () => ({
|
|
16
20
|
useOrganisations: () => mockUseOrganisations()
|
|
17
21
|
}));
|
|
18
22
|
|
|
19
|
-
vi.mock('../../
|
|
23
|
+
vi.mock('../../hooks/useEvents', () => ({
|
|
20
24
|
useEvents: () => mockUseEvents()
|
|
21
25
|
}));
|
|
22
26
|
|