@jmruthers/pace-core 0.5.118 → 0.5.119

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/{DataTable-ZOAKQ3SU.js → DataTable-BQYGKVHR.js} +6 -6
  2. package/dist/{UnifiedAuthProvider-YFN7YGVN.js → UnifiedAuthProvider-UACKFATV.js} +3 -3
  3. package/dist/{chunk-7OTQLFVI.js → chunk-B4GZ2BXO.js} +3 -3
  4. package/dist/{chunk-KA3PSVNV.js → chunk-BHWIUEYH.js} +2 -1
  5. package/dist/chunk-BHWIUEYH.js.map +1 -0
  6. package/dist/{chunk-LFS45U62.js → chunk-CGURJ27Z.js} +2 -2
  7. package/dist/{chunk-PHDAXDHB.js → chunk-D6BOFXYR.js} +3 -3
  8. package/dist/{chunk-2LM4QQGH.js → chunk-F7COHU5B.js} +8 -8
  9. package/dist/{chunk-P3PUOL6B.js → chunk-FKFHZUGF.js} +4 -4
  10. package/dist/{chunk-UKZWNQMB.js → chunk-NP5VABFV.js} +4 -4
  11. package/dist/{chunk-O3FTRYEU.js → chunk-NZ32EONV.js} +2 -2
  12. package/dist/{chunk-ECOVPXYS.js → chunk-RIEJGKD3.js} +4 -4
  13. package/dist/{chunk-HIWXXDXO.js → chunk-TDNI6ZWL.js} +5 -5
  14. package/dist/{chunk-VN3OOE35.js → chunk-ZYJ6O5CA.js} +2 -2
  15. package/dist/components.js +8 -8
  16. package/dist/hooks.js +7 -7
  17. package/dist/index.js +11 -11
  18. package/dist/providers.js +2 -2
  19. package/dist/rbac/index.js +7 -7
  20. package/dist/utils.js +1 -1
  21. package/docs/api/classes/ColumnFactory.md +1 -1
  22. package/docs/api/classes/ErrorBoundary.md +1 -1
  23. package/docs/api/classes/InvalidScopeError.md +1 -1
  24. package/docs/api/classes/MissingUserContextError.md +1 -1
  25. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  26. package/docs/api/classes/PermissionDeniedError.md +1 -1
  27. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  28. package/docs/api/classes/RBACAuditManager.md +1 -1
  29. package/docs/api/classes/RBACCache.md +1 -1
  30. package/docs/api/classes/RBACEngine.md +1 -1
  31. package/docs/api/classes/RBACError.md +1 -1
  32. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  33. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  34. package/docs/api/classes/StorageUtils.md +1 -1
  35. package/docs/api/enums/FileCategory.md +1 -1
  36. package/docs/api/interfaces/AggregateConfig.md +1 -1
  37. package/docs/api/interfaces/ButtonProps.md +1 -1
  38. package/docs/api/interfaces/CardProps.md +1 -1
  39. package/docs/api/interfaces/ColorPalette.md +1 -1
  40. package/docs/api/interfaces/ColorShade.md +1 -1
  41. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  42. package/docs/api/interfaces/DataRecord.md +1 -1
  43. package/docs/api/interfaces/DataTableAction.md +1 -1
  44. package/docs/api/interfaces/DataTableColumn.md +1 -1
  45. package/docs/api/interfaces/DataTableProps.md +1 -1
  46. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  47. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  48. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  49. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  50. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  51. package/docs/api/interfaces/FileMetadata.md +1 -1
  52. package/docs/api/interfaces/FileReference.md +1 -1
  53. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  54. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  55. package/docs/api/interfaces/FileUploadProps.md +1 -1
  56. package/docs/api/interfaces/FooterProps.md +1 -1
  57. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  58. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  59. package/docs/api/interfaces/InputProps.md +1 -1
  60. package/docs/api/interfaces/LabelProps.md +1 -1
  61. package/docs/api/interfaces/LoginFormProps.md +1 -1
  62. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  63. package/docs/api/interfaces/NavigationContextType.md +1 -1
  64. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  65. package/docs/api/interfaces/NavigationItem.md +1 -1
  66. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  67. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  68. package/docs/api/interfaces/Organisation.md +1 -1
  69. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  70. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  71. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  72. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  73. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  74. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  75. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  76. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  77. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  78. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  79. package/docs/api/interfaces/PaletteData.md +1 -1
  80. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  81. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  82. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  83. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  84. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  85. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  86. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  87. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  88. package/docs/api/interfaces/RBACConfig.md +1 -1
  89. package/docs/api/interfaces/RBACLogger.md +1 -1
  90. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  91. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  92. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  93. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  94. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  95. package/docs/api/interfaces/RouteConfig.md +1 -1
  96. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  97. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  98. package/docs/api/interfaces/StorageConfig.md +1 -1
  99. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  100. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  101. package/docs/api/interfaces/StorageListOptions.md +1 -1
  102. package/docs/api/interfaces/StorageListResult.md +1 -1
  103. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  104. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  105. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  106. package/docs/api/interfaces/StyleImport.md +1 -1
  107. package/docs/api/interfaces/SwitchProps.md +1 -1
  108. package/docs/api/interfaces/ToastActionElement.md +1 -1
  109. package/docs/api/interfaces/ToastProps.md +1 -1
  110. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  111. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  112. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  113. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  114. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  115. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  116. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  117. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  118. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  119. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  120. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  121. package/docs/api/interfaces/UserEventAccess.md +1 -1
  122. package/docs/api/interfaces/UserMenuProps.md +1 -1
  123. package/docs/api/interfaces/UserProfile.md +1 -1
  124. package/docs/api/modules.md +2 -2
  125. package/package.json +1 -1
  126. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +697 -0
  127. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +544 -9
  128. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +1004 -0
  129. package/src/components/DataTable/utils/__tests__/a11yUtils.test.ts +612 -0
  130. package/src/components/DataTable/utils/__tests__/errorHandling.test.ts +266 -0
  131. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +455 -1
  132. package/src/hooks/__tests__/index.unit.test.ts +223 -0
  133. package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +748 -0
  134. package/src/hooks/__tests__/useEvents.unit.test.ts +249 -0
  135. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +1060 -0
  136. package/src/hooks/__tests__/useFileUrl.unit.test.ts +958 -0
  137. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +540 -1
  138. package/src/hooks/__tests__/useIsMobile.unit.test.ts +205 -5
  139. package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +616 -1
  140. package/src/hooks/__tests__/useOrganisations.unit.test.ts +369 -0
  141. package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +608 -0
  142. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +2 -0
  143. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +372 -0
  144. package/src/hooks/__tests__/useToast.unit.test.tsx +431 -30
  145. package/src/hooks/useSecureDataAccess.test.ts +1 -0
  146. package/src/rbac/audit-enhanced.ts +339 -0
  147. package/src/services/EventService.ts +1 -0
  148. package/src/services/__tests__/AuthService.test.ts +473 -0
  149. package/src/services/__tests__/EventService.test.ts +390 -0
  150. package/src/services/__tests__/InactivityService.test.ts +217 -0
  151. package/src/services/__tests__/OrganisationService.test.ts +371 -0
  152. package/dist/chunk-KA3PSVNV.js.map +0 -1
  153. package/src/components/DataTable/utils/debugTools.ts +0 -609
  154. package/src/rbac/testing/index.tsx +0 -340
  155. /package/dist/{DataTable-ZOAKQ3SU.js.map → DataTable-BQYGKVHR.js.map} +0 -0
  156. /package/dist/{UnifiedAuthProvider-YFN7YGVN.js.map → UnifiedAuthProvider-UACKFATV.js.map} +0 -0
  157. /package/dist/{chunk-7OTQLFVI.js.map → chunk-B4GZ2BXO.js.map} +0 -0
  158. /package/dist/{chunk-LFS45U62.js.map → chunk-CGURJ27Z.js.map} +0 -0
  159. /package/dist/{chunk-PHDAXDHB.js.map → chunk-D6BOFXYR.js.map} +0 -0
  160. /package/dist/{chunk-2LM4QQGH.js.map → chunk-F7COHU5B.js.map} +0 -0
  161. /package/dist/{chunk-P3PUOL6B.js.map → chunk-FKFHZUGF.js.map} +0 -0
  162. /package/dist/{chunk-UKZWNQMB.js.map → chunk-NP5VABFV.js.map} +0 -0
  163. /package/dist/{chunk-O3FTRYEU.js.map → chunk-NZ32EONV.js.map} +0 -0
  164. /package/dist/{chunk-ECOVPXYS.js.map → chunk-RIEJGKD3.js.map} +0 -0
  165. /package/dist/{chunk-HIWXXDXO.js.map → chunk-TDNI6ZWL.js.map} +0 -0
  166. /package/dist/{chunk-VN3OOE35.js.map → chunk-ZYJ6O5CA.js.map} +0 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * @file useEvents Hook Unit Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module Hooks/__tests__/useEvents
5
+ * @since 0.1.0
6
+ *
7
+ * Comprehensive tests for the useEvents hook covering all critical functionality.
8
+ */
9
+
10
+ import { renderHook, act } from '@testing-library/react';
11
+ import { vi, describe, it, expect, beforeEach } from 'vitest';
12
+ import { useEvents } from '../useEvents';
13
+ import { Event } from '../../types/unified';
14
+
15
+ // Mock useEventService
16
+ const mockEventService = {
17
+ getEvents: vi.fn(() => []),
18
+ getSelectedEvent: vi.fn(() => null),
19
+ isLoading: vi.fn(() => false),
20
+ getError: vi.fn(() => null),
21
+ setSelectedEvent: vi.fn(),
22
+ refreshEvents: vi.fn().mockResolvedValue(undefined),
23
+ subscribe: vi.fn(() => vi.fn()), // Returns unsubscribe function
24
+ };
25
+
26
+ vi.mock('../services/useEventService', () => ({
27
+ useEventService: vi.fn(() => mockEventService),
28
+ }));
29
+
30
+ describe('useEvents', () => {
31
+ beforeEach(() => {
32
+ vi.clearAllMocks();
33
+ mockEventService.getEvents.mockReturnValue([]);
34
+ mockEventService.getSelectedEvent.mockReturnValue(null);
35
+ mockEventService.isLoading.mockReturnValue(false);
36
+ mockEventService.getError.mockReturnValue(null);
37
+ mockEventService.refreshEvents.mockResolvedValue(undefined);
38
+ });
39
+
40
+ describe('Initialization', () => {
41
+ it('returns event context with default values', () => {
42
+ const { result } = renderHook(() => useEvents());
43
+
44
+ expect(result.current.events).toEqual([]);
45
+ expect(result.current.selectedEvent).toBeNull();
46
+ expect(result.current.isLoading).toBe(false);
47
+ expect(result.current.error).toBeNull();
48
+ expect(typeof result.current.setSelectedEvent).toBe('function');
49
+ expect(typeof result.current.refreshEvents).toBe('function');
50
+ });
51
+
52
+ it('calls useEventService to get event service', () => {
53
+ const { useEventService } = require('../services/useEventService');
54
+
55
+ renderHook(() => useEvents());
56
+
57
+ expect(useEventService).toHaveBeenCalled();
58
+ });
59
+ });
60
+
61
+ describe('Event State Access', () => {
62
+ it('returns events from event service', () => {
63
+ const mockEvents: Event[] = [
64
+ {
65
+ id: 'event-1',
66
+ event_id: 'event-1',
67
+ event_name: 'Test Event 1',
68
+ event_date: '2025-01-01T00:00:00Z',
69
+ event_venue: 'Test Venue',
70
+ event_participants: 100,
71
+ event_colours: '#FF0000',
72
+ event_logo: '',
73
+ organisation_id: 'org-1',
74
+ is_visible: true,
75
+ name: 'Test Event 1',
76
+ start_date: '2025-01-01T00:00:00Z',
77
+ },
78
+ {
79
+ id: 'event-2',
80
+ event_id: 'event-2',
81
+ event_name: 'Test Event 2',
82
+ event_date: '2025-02-01T00:00:00Z',
83
+ event_venue: 'Test Venue 2',
84
+ event_participants: 200,
85
+ event_colours: '#00FF00',
86
+ event_logo: '',
87
+ organisation_id: 'org-1',
88
+ is_visible: true,
89
+ name: 'Test Event 2',
90
+ start_date: '2025-02-01T00:00:00Z',
91
+ },
92
+ ];
93
+
94
+ mockEventService.getEvents.mockReturnValue(mockEvents);
95
+
96
+ const { result } = renderHook(() => useEvents());
97
+
98
+ expect(result.current.events).toEqual(mockEvents);
99
+ expect(result.current.events).toHaveLength(2);
100
+ });
101
+
102
+ it('returns selected event from event service', () => {
103
+ const mockSelectedEvent: Event = {
104
+ id: 'event-1',
105
+ event_id: 'event-1',
106
+ event_name: 'Selected Event',
107
+ event_date: '2025-01-01T00:00:00Z',
108
+ event_venue: 'Test Venue',
109
+ event_participants: 100,
110
+ event_colours: '#FF0000',
111
+ event_logo: '',
112
+ organisation_id: 'org-1',
113
+ is_visible: true,
114
+ name: 'Selected Event',
115
+ start_date: '2025-01-01T00:00:00Z',
116
+ };
117
+
118
+ mockEventService.getSelectedEvent.mockReturnValue(mockSelectedEvent);
119
+
120
+ const { result } = renderHook(() => useEvents());
121
+
122
+ expect(result.current.selectedEvent).toEqual(mockSelectedEvent);
123
+ });
124
+
125
+ it('returns loading state from event service', () => {
126
+ mockEventService.isLoading.mockReturnValue(true);
127
+
128
+ const { result } = renderHook(() => useEvents());
129
+
130
+ expect(result.current.isLoading).toBe(true);
131
+ });
132
+
133
+ it('returns error from event service', () => {
134
+ const mockError = new Error('Failed to load events');
135
+ mockEventService.getError.mockReturnValue(mockError);
136
+
137
+ const { result } = renderHook(() => useEvents());
138
+
139
+ expect(result.current.error).toEqual(mockError);
140
+ });
141
+ });
142
+
143
+ describe('Event Selection', () => {
144
+ it('calls setSelectedEvent on event service when setSelectedEvent is called', () => {
145
+ const mockEvent: Event = {
146
+ id: 'event-1',
147
+ event_id: 'event-1',
148
+ event_name: 'Test Event',
149
+ event_date: '2025-01-01T00:00:00Z',
150
+ event_venue: 'Test Venue',
151
+ event_participants: 100,
152
+ event_colours: '#FF0000',
153
+ event_logo: '',
154
+ organisation_id: 'org-1',
155
+ is_visible: true,
156
+ name: 'Test Event',
157
+ start_date: '2025-01-01T00:00:00Z',
158
+ };
159
+
160
+ const { result } = renderHook(() => useEvents());
161
+
162
+ act(() => {
163
+ result.current.setSelectedEvent(mockEvent);
164
+ });
165
+
166
+ expect(mockEventService.setSelectedEvent).toHaveBeenCalledWith(mockEvent);
167
+ expect(mockEventService.setSelectedEvent).toHaveBeenCalledTimes(1);
168
+ });
169
+
170
+ it('calls setSelectedEvent with null when clearing selection', () => {
171
+ const { result } = renderHook(() => useEvents());
172
+
173
+ act(() => {
174
+ result.current.setSelectedEvent(null);
175
+ });
176
+
177
+ expect(mockEventService.setSelectedEvent).toHaveBeenCalledWith(null);
178
+ expect(mockEventService.setSelectedEvent).toHaveBeenCalledTimes(1);
179
+ });
180
+ });
181
+
182
+ describe('Event Refresh', () => {
183
+ it('calls refreshEvents on event service when refreshEvents is called', async () => {
184
+ const { result } = renderHook(() => useEvents());
185
+
186
+ await act(async () => {
187
+ await result.current.refreshEvents();
188
+ });
189
+
190
+ expect(mockEventService.refreshEvents).toHaveBeenCalledTimes(1);
191
+ });
192
+
193
+ it('handles refreshEvents promise resolution', async () => {
194
+ mockEventService.refreshEvents.mockResolvedValue(undefined);
195
+
196
+ const { result } = renderHook(() => useEvents());
197
+
198
+ await act(async () => {
199
+ await expect(result.current.refreshEvents()).resolves.toBeUndefined();
200
+ });
201
+ });
202
+
203
+ it('handles refreshEvents promise rejection', async () => {
204
+ const mockError = new Error('Refresh failed');
205
+ mockEventService.refreshEvents.mockRejectedValue(mockError);
206
+
207
+ const { result } = renderHook(() => useEvents());
208
+
209
+ await act(async () => {
210
+ await expect(result.current.refreshEvents()).rejects.toThrow('Refresh failed');
211
+ });
212
+ });
213
+ });
214
+
215
+ describe('Reactive Updates', () => {
216
+ it('updates when event service state changes', () => {
217
+ const mockEvents: Event[] = [
218
+ {
219
+ id: 'event-1',
220
+ event_id: 'event-1',
221
+ event_name: 'Test Event',
222
+ event_date: '2025-01-01T00:00:00Z',
223
+ event_venue: 'Test Venue',
224
+ event_participants: 100,
225
+ event_colours: '#FF0000',
226
+ event_logo: '',
227
+ organisation_id: 'org-1',
228
+ is_visible: true,
229
+ name: 'Test Event',
230
+ start_date: '2025-01-01T00:00:00Z',
231
+ },
232
+ ];
233
+
234
+ const { result, rerender } = renderHook(() => useEvents());
235
+
236
+ // Initial state
237
+ expect(result.current.events).toEqual([]);
238
+
239
+ // Update mock and rerender
240
+ mockEventService.getEvents.mockReturnValue(mockEvents);
241
+ rerender();
242
+
243
+ // Note: In real usage, the subscription would trigger updates
244
+ // This test verifies the hook structure
245
+ expect(mockEventService.getEvents).toHaveBeenCalled();
246
+ });
247
+ });
248
+ });
249
+