@jmruthers/pace-core 0.5.165 → 0.5.166
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-HAATGNJY.js → DataTable-Z6IYTME3.js} +3 -3
- package/dist/{chunk-DDB2M4XO.js → chunk-5PH366QI.js} +2 -2
- package/dist/{chunk-GFSYFEVZ.js → chunk-BPIFVNEO.js} +24 -24
- package/dist/chunk-BPIFVNEO.js.map +1 -0
- package/dist/{chunk-Q4NUEMNV.js → chunk-JIRBF5HR.js} +6 -20
- package/dist/chunk-JIRBF5HR.js.map +1 -0
- package/dist/{chunk-23YYDN24.js → chunk-SVMR7EVX.js} +2 -2
- package/dist/components.js +3 -3
- package/dist/index.js +4 -4
- package/dist/rbac/index.d.ts +10 -3
- package/dist/rbac/index.js +2 -2
- package/dist/utils.js +1 -1
- package/docs/api/modules.md +17 -10
- package/package.json +1 -1
- package/src/__tests__/hooks/usePermissions.test.ts +12 -9
- package/src/components/NavigationMenu/NavigationMenu.tsx +4 -22
- package/src/hooks/__tests__/ServiceHooks.test.tsx +2 -2
- package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +32 -34
- package/src/rbac/hooks/usePermissions.test.ts +34 -32
- package/src/rbac/hooks/usePermissions.ts +41 -28
- package/dist/chunk-GFSYFEVZ.js.map +0 -1
- package/dist/chunk-Q4NUEMNV.js.map +0 -1
- /package/dist/{DataTable-HAATGNJY.js.map → DataTable-Z6IYTME3.js.map} +0 -0
- /package/dist/{chunk-DDB2M4XO.js.map → chunk-5PH366QI.js.map} +0 -0
- /package/dist/{chunk-23YYDN24.js.map → chunk-SVMR7EVX.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useCan,
|
|
3
3
|
useResolvedScope
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BPIFVNEO.js";
|
|
5
5
|
import {
|
|
6
6
|
toast,
|
|
7
7
|
useDataTablePerformance
|
|
@@ -12726,4 +12726,4 @@ lodash/lodash.js:
|
|
|
12726
12726
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
12727
12727
|
*)
|
|
12728
12728
|
*/
|
|
12729
|
-
//# sourceMappingURL=chunk-
|
|
12729
|
+
//# sourceMappingURL=chunk-SVMR7EVX.js.map
|
package/dist/components.js
CHANGED
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
useFileReferenceForRecord,
|
|
58
58
|
useFilesByCategory,
|
|
59
59
|
usePublicPageContext as usePublicPageContext2
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-JIRBF5HR.js";
|
|
61
61
|
import {
|
|
62
62
|
Alert,
|
|
63
63
|
AlertDescription,
|
|
@@ -98,8 +98,8 @@ import {
|
|
|
98
98
|
TooltipProvider,
|
|
99
99
|
TooltipRoot,
|
|
100
100
|
TooltipTrigger
|
|
101
|
-
} from "./chunk-
|
|
102
|
-
import "./chunk-
|
|
101
|
+
} from "./chunk-SVMR7EVX.js";
|
|
102
|
+
import "./chunk-BPIFVNEO.js";
|
|
103
103
|
import "./chunk-BVYWGZVV.js";
|
|
104
104
|
import "./chunk-SBVILCCA.js";
|
|
105
105
|
import {
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
withAccessLevelGuard,
|
|
31
31
|
withPermissionGuard,
|
|
32
32
|
withRoleGuard
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-5PH366QI.js";
|
|
34
34
|
import {
|
|
35
35
|
init_useInactivityTracker,
|
|
36
36
|
useInactivityTracker
|
|
@@ -96,7 +96,7 @@ import {
|
|
|
96
96
|
useFileReferenceForRecord,
|
|
97
97
|
useFilesByCategory,
|
|
98
98
|
usePublicPageContext as usePublicPageContext2
|
|
99
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-JIRBF5HR.js";
|
|
100
100
|
import {
|
|
101
101
|
Alert,
|
|
102
102
|
AlertDescription,
|
|
@@ -146,7 +146,7 @@ import {
|
|
|
146
146
|
max,
|
|
147
147
|
min,
|
|
148
148
|
sum
|
|
149
|
-
} from "./chunk-
|
|
149
|
+
} from "./chunk-SVMR7EVX.js";
|
|
150
150
|
import {
|
|
151
151
|
useAccessLevel,
|
|
152
152
|
useCachedPermissions,
|
|
@@ -159,7 +159,7 @@ import {
|
|
|
159
159
|
useResolvedScope,
|
|
160
160
|
useResourcePermissions,
|
|
161
161
|
useRoleManagement
|
|
162
|
-
} from "./chunk-
|
|
162
|
+
} from "./chunk-BPIFVNEO.js";
|
|
163
163
|
import {
|
|
164
164
|
CACHE_PATTERNS,
|
|
165
165
|
RBACCache,
|
package/dist/rbac/index.d.ts
CHANGED
|
@@ -1286,13 +1286,20 @@ declare function useResourcePermissions(resource: string, options?: UseResourceP
|
|
|
1286
1286
|
* Hook to get user's permissions in a scope
|
|
1287
1287
|
*
|
|
1288
1288
|
* @param userId - User ID
|
|
1289
|
-
* @param
|
|
1289
|
+
* @param organisationId - Organisation ID
|
|
1290
|
+
* @param eventId - Event ID (optional)
|
|
1291
|
+
* @param appId - Application ID (optional)
|
|
1290
1292
|
* @returns Permission state and methods
|
|
1291
1293
|
*
|
|
1292
1294
|
* @example
|
|
1293
1295
|
* ```tsx
|
|
1294
1296
|
* function MyComponent() {
|
|
1295
|
-
* const { permissions, isLoading, error } = usePermissions(
|
|
1297
|
+
* const { permissions, isLoading, error } = usePermissions(
|
|
1298
|
+
* userId,
|
|
1299
|
+
* organisationId,
|
|
1300
|
+
* eventId,
|
|
1301
|
+
* appId
|
|
1302
|
+
* );
|
|
1296
1303
|
*
|
|
1297
1304
|
* if (isLoading) return <div>Loading...</div>;
|
|
1298
1305
|
* if (error) return <div>Error: {error.message}</div>;
|
|
@@ -1306,7 +1313,7 @@ declare function useResourcePermissions(resource: string, options?: UseResourceP
|
|
|
1306
1313
|
* }
|
|
1307
1314
|
* ```
|
|
1308
1315
|
*/
|
|
1309
|
-
declare function usePermissions(userId: UUID,
|
|
1316
|
+
declare function usePermissions(userId: UUID, organisationId: string | undefined, eventId: string | undefined, appId: string | undefined): {
|
|
1310
1317
|
permissions: PermissionMap;
|
|
1311
1318
|
isLoading: boolean;
|
|
1312
1319
|
error: Error | null;
|
package/dist/rbac/index.js
CHANGED
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
withAccessLevelGuard,
|
|
31
31
|
withPermissionGuard,
|
|
32
32
|
withRoleGuard
|
|
33
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-5PH366QI.js";
|
|
34
34
|
import {
|
|
35
35
|
useAccessLevel,
|
|
36
36
|
useCachedPermissions,
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
useResolvedScope,
|
|
44
44
|
useResourcePermissions,
|
|
45
45
|
useRoleManagement
|
|
46
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-BPIFVNEO.js";
|
|
47
47
|
import {
|
|
48
48
|
CACHE_PATTERNS,
|
|
49
49
|
RBACCache,
|
package/dist/utils.js
CHANGED
|
@@ -614,7 +614,7 @@ function createLazyComponent(importFn, componentName, options = {}) {
|
|
|
614
614
|
return WrappedComponent;
|
|
615
615
|
}
|
|
616
616
|
var LazyDataTable = createLazyComponent(
|
|
617
|
-
() => import("./DataTable-
|
|
617
|
+
() => import("./DataTable-Z6IYTME3.js").then((module) => ({ default: module.DataTable })),
|
|
618
618
|
"DataTable"
|
|
619
619
|
);
|
|
620
620
|
|
package/docs/api/modules.md
CHANGED
|
@@ -6578,7 +6578,7 @@ ___
|
|
|
6578
6578
|
|
|
6579
6579
|
### usePermissions
|
|
6580
6580
|
|
|
6581
|
-
▸ **usePermissions**(`userId`, `
|
|
6581
|
+
▸ **usePermissions**(`userId`, `organisationId`, `eventId`, `appId`): `Object`
|
|
6582
6582
|
|
|
6583
6583
|
Hook to get user's permissions in a scope
|
|
6584
6584
|
|
|
@@ -6587,7 +6587,9 @@ Hook to get user's permissions in a scope
|
|
|
6587
6587
|
| Name | Type | Description |
|
|
6588
6588
|
| :------ | :------ | :------ |
|
|
6589
6589
|
| `userId` | `string` | User ID |
|
|
6590
|
-
| `
|
|
6590
|
+
| `organisationId` | `undefined` \| `string` | Organisation ID |
|
|
6591
|
+
| `eventId` | `undefined` \| `string` | Event ID (optional) |
|
|
6592
|
+
| `appId` | `undefined` \| `string` | Application ID (optional) |
|
|
6591
6593
|
|
|
6592
6594
|
#### Returns
|
|
6593
6595
|
|
|
@@ -6609,7 +6611,12 @@ Permission state and methods
|
|
|
6609
6611
|
|
|
6610
6612
|
```tsx
|
|
6611
6613
|
function MyComponent() {
|
|
6612
|
-
const { permissions, isLoading, error } = usePermissions(
|
|
6614
|
+
const { permissions, isLoading, error } = usePermissions(
|
|
6615
|
+
userId,
|
|
6616
|
+
organisationId,
|
|
6617
|
+
eventId,
|
|
6618
|
+
appId
|
|
6619
|
+
);
|
|
6613
6620
|
|
|
6614
6621
|
if (isLoading) return <div>Loading...</div>;
|
|
6615
6622
|
if (error) return <div>Error: {error.message}</div>;
|
|
@@ -6625,7 +6632,7 @@ function MyComponent() {
|
|
|
6625
6632
|
|
|
6626
6633
|
#### Defined in
|
|
6627
6634
|
|
|
6628
|
-
[packages/core/src/rbac/hooks/usePermissions.ts:
|
|
6635
|
+
[packages/core/src/rbac/hooks/usePermissions.ts:57](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L57)
|
|
6629
6636
|
|
|
6630
6637
|
___
|
|
6631
6638
|
|
|
@@ -6673,7 +6680,7 @@ function MyComponent() {
|
|
|
6673
6680
|
|
|
6674
6681
|
#### Defined in
|
|
6675
6682
|
|
|
6676
|
-
[packages/core/src/rbac/hooks/usePermissions.ts:
|
|
6683
|
+
[packages/core/src/rbac/hooks/usePermissions.ts:328](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L328)
|
|
6677
6684
|
|
|
6678
6685
|
___
|
|
6679
6686
|
|
|
@@ -6723,7 +6730,7 @@ function MyComponent() {
|
|
|
6723
6730
|
|
|
6724
6731
|
#### Defined in
|
|
6725
6732
|
|
|
6726
|
-
[packages/core/src/rbac/hooks/usePermissions.ts:
|
|
6733
|
+
[packages/core/src/rbac/hooks/usePermissions.ts:524](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L524)
|
|
6727
6734
|
|
|
6728
6735
|
___
|
|
6729
6736
|
|
|
@@ -6780,7 +6787,7 @@ function MyComponent() {
|
|
|
6780
6787
|
|
|
6781
6788
|
#### Defined in
|
|
6782
6789
|
|
|
6783
|
-
[packages/core/src/rbac/hooks/usePermissions.ts:
|
|
6790
|
+
[packages/core/src/rbac/hooks/usePermissions.ts:599](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L599)
|
|
6784
6791
|
|
|
6785
6792
|
___
|
|
6786
6793
|
|
|
@@ -6831,7 +6838,7 @@ function MyComponent() {
|
|
|
6831
6838
|
|
|
6832
6839
|
#### Defined in
|
|
6833
6840
|
|
|
6834
|
-
[packages/core/src/rbac/hooks/usePermissions.ts:
|
|
6841
|
+
[packages/core/src/rbac/hooks/usePermissions.ts:682](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L682)
|
|
6835
6842
|
|
|
6836
6843
|
___
|
|
6837
6844
|
|
|
@@ -6882,7 +6889,7 @@ function MyComponent() {
|
|
|
6882
6889
|
|
|
6883
6890
|
#### Defined in
|
|
6884
6891
|
|
|
6885
|
-
[packages/core/src/rbac/hooks/usePermissions.ts:
|
|
6892
|
+
[packages/core/src/rbac/hooks/usePermissions.ts:768](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L768)
|
|
6886
6893
|
|
|
6887
6894
|
___
|
|
6888
6895
|
|
|
@@ -6933,7 +6940,7 @@ function MyComponent() {
|
|
|
6933
6940
|
|
|
6934
6941
|
#### Defined in
|
|
6935
6942
|
|
|
6936
|
-
[packages/core/src/rbac/hooks/usePermissions.ts:
|
|
6943
|
+
[packages/core/src/rbac/hooks/usePermissions.ts:853](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L853)
|
|
6937
6944
|
|
|
6938
6945
|
___
|
|
6939
6946
|
|
package/package.json
CHANGED
|
@@ -29,10 +29,13 @@ const mockIsPermittedCached = vi.mocked(isPermittedCached);
|
|
|
29
29
|
|
|
30
30
|
describe('usePermissions Hook Stability', () => {
|
|
31
31
|
const mockUserId = 'user-123';
|
|
32
|
+
const mockOrgId = 'org-123';
|
|
33
|
+
const mockEventId = 'event-123';
|
|
34
|
+
const mockAppId = 'app-123';
|
|
32
35
|
const mockScope = {
|
|
33
|
-
organisationId:
|
|
34
|
-
eventId:
|
|
35
|
-
appId:
|
|
36
|
+
organisationId: mockOrgId,
|
|
37
|
+
eventId: mockEventId,
|
|
38
|
+
appId: mockAppId
|
|
36
39
|
};
|
|
37
40
|
|
|
38
41
|
beforeEach(() => {
|
|
@@ -49,7 +52,7 @@ describe('usePermissions Hook Stability', () => {
|
|
|
49
52
|
mockGetPermissionMap.mockResolvedValue(mockPermissions);
|
|
50
53
|
|
|
51
54
|
const { result, rerender } = renderHook(() =>
|
|
52
|
-
usePermissions(mockUserId,
|
|
55
|
+
usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId)
|
|
53
56
|
);
|
|
54
57
|
|
|
55
58
|
// Wait for initial load
|
|
@@ -122,7 +125,7 @@ describe('usePermissions Hook Stability', () => {
|
|
|
122
125
|
|
|
123
126
|
const { result } = renderHook(() => {
|
|
124
127
|
renderCount++;
|
|
125
|
-
return usePermissions(mockUserId,
|
|
128
|
+
return usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId);
|
|
126
129
|
});
|
|
127
130
|
|
|
128
131
|
// Wait for initial load
|
|
@@ -215,7 +218,7 @@ describe('usePermissions Hook Stability', () => {
|
|
|
215
218
|
mockGetPermissionMap.mockResolvedValue({ 'read:users': true });
|
|
216
219
|
|
|
217
220
|
const { result, rerender } = renderHook(
|
|
218
|
-
({ userId }) => usePermissions(userId,
|
|
221
|
+
({ userId }) => usePermissions(userId, mockOrgId, mockEventId, mockAppId),
|
|
219
222
|
{ initialProps: { userId: 'user-1' } }
|
|
220
223
|
);
|
|
221
224
|
|
|
@@ -243,8 +246,8 @@ describe('usePermissions Hook Stability', () => {
|
|
|
243
246
|
mockGetPermissionMap.mockResolvedValue({ 'read:users': true });
|
|
244
247
|
|
|
245
248
|
const { result, rerender } = renderHook(
|
|
246
|
-
({
|
|
247
|
-
{ initialProps: {
|
|
249
|
+
({ orgId }) => usePermissions(mockUserId, orgId, mockEventId, mockAppId),
|
|
250
|
+
{ initialProps: { orgId: 'org-1' } }
|
|
248
251
|
);
|
|
249
252
|
|
|
250
253
|
await act(async () => {
|
|
@@ -252,7 +255,7 @@ describe('usePermissions Hook Stability', () => {
|
|
|
252
255
|
});
|
|
253
256
|
|
|
254
257
|
// Change scope
|
|
255
|
-
rerender({
|
|
258
|
+
rerender({ orgId: 'org-2' });
|
|
256
259
|
|
|
257
260
|
await act(async () => {
|
|
258
261
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
@@ -594,30 +594,12 @@ export const NavigationMenu = React.forwardRef<
|
|
|
594
594
|
}
|
|
595
595
|
}, [filterByPermissions, stableScope.organisationId, stableScope.eventId, stableScope.appId, userId]);
|
|
596
596
|
|
|
597
|
-
//
|
|
598
|
-
// CRITICAL: Use stableScope properties DIRECTLY in dependencies, not extracted values
|
|
599
|
-
// React needs to see the actual property changes to trigger re-memoization
|
|
600
|
-
const stableScopeForPermissions = React.useMemo(() => {
|
|
601
|
-
const scope = {
|
|
602
|
-
organisationId: stableScope.organisationId || '',
|
|
603
|
-
eventId: stableScope.eventId,
|
|
604
|
-
appId: stableScope.appId
|
|
605
|
-
};
|
|
606
|
-
// Log when scope changes to verify React detects the change
|
|
607
|
-
if (filterByPermissions && scope.organisationId) {
|
|
608
|
-
logger.warn('NavigationMenu', 'stableScopeForPermissions created', {
|
|
609
|
-
organisationId: scope.organisationId,
|
|
610
|
-
eventId: scope.eventId,
|
|
611
|
-
appId: scope.appId,
|
|
612
|
-
hasAppId: !!scope.appId
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
|
-
return scope;
|
|
616
|
-
}, [filterByPermissions, stableScope.organisationId, stableScope.eventId, stableScope.appId]);
|
|
617
|
-
|
|
597
|
+
// Call usePermissions with primitive parameters for reliable React dependency tracking
|
|
618
598
|
const { permissions: permissionMap, hasAnyPermission, isLoading: permissionsLoading, error: permissionsError } = usePermissions(
|
|
619
599
|
userId as any,
|
|
620
|
-
|
|
600
|
+
stableScope.organisationId,
|
|
601
|
+
stableScope.eventId,
|
|
602
|
+
stableScope.appId
|
|
621
603
|
);
|
|
622
604
|
|
|
623
605
|
// Debug logging for permission map state
|
|
@@ -332,7 +332,7 @@ describe('Service Hooks', () => {
|
|
|
332
332
|
|
|
333
333
|
mockUseContext.mockReturnValue({ rbacService: mockService });
|
|
334
334
|
|
|
335
|
-
const { result } = renderHook(() => usePermissions('user-1',
|
|
335
|
+
const { result } = renderHook(() => usePermissions('user-1', 'org-1', 'event-1', 'test-app'), { wrapper });
|
|
336
336
|
|
|
337
337
|
expect(result.current.permissions).toEqual({ 'events:read': true });
|
|
338
338
|
expect(result.current.roles).toEqual(['admin']);
|
|
@@ -535,7 +535,7 @@ describe('Service Hooks', () => {
|
|
|
535
535
|
const { result: authResult } = renderHook(() => useAuth(), { wrapper });
|
|
536
536
|
|
|
537
537
|
mockUseContext.mockReturnValue({ rbacService: mockRBACService });
|
|
538
|
-
const { result: permissionsResult } = renderHook(() => usePermissions('user-1',
|
|
538
|
+
const { result: permissionsResult } = renderHook(() => usePermissions('user-1', 'org-1', 'event-1', 'test-app'), { wrapper });
|
|
539
539
|
|
|
540
540
|
mockUseContext.mockReturnValue({ organisationService: mockOrganisationService });
|
|
541
541
|
const { result: organisationResult } = renderHook(() => useCurrentOrganisation(), { wrapper });
|
|
@@ -27,9 +27,13 @@ vi.mock('../../api', () => ({
|
|
|
27
27
|
import { getPermissionMap } from '../../api';
|
|
28
28
|
|
|
29
29
|
const mockUserId = 'user-123';
|
|
30
|
+
const mockOrgId = 'org-123';
|
|
31
|
+
const mockEventId = 'event-123';
|
|
32
|
+
const mockAppId = 'app-123';
|
|
30
33
|
const mockScope = {
|
|
31
|
-
organisationId:
|
|
32
|
-
eventId:
|
|
34
|
+
organisationId: mockOrgId,
|
|
35
|
+
eventId: mockEventId,
|
|
36
|
+
appId: mockAppId
|
|
33
37
|
};
|
|
34
38
|
|
|
35
39
|
const mockPermissionMap = {
|
|
@@ -54,9 +58,9 @@ describe('usePermissions Integration Tests', () => {
|
|
|
54
58
|
describe('Cache Behavior', () => {
|
|
55
59
|
it('fetches permissions only once for same dependencies', async () => {
|
|
56
60
|
const { result, rerender } = renderHook(
|
|
57
|
-
({ userId,
|
|
61
|
+
({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
|
|
58
62
|
{
|
|
59
|
-
initialProps: { userId: mockUserId,
|
|
63
|
+
initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: mockAppId }
|
|
60
64
|
}
|
|
61
65
|
);
|
|
62
66
|
|
|
@@ -75,9 +79,9 @@ describe('usePermissions Integration Tests', () => {
|
|
|
75
79
|
|
|
76
80
|
it('refetches when organisationId changes', async () => {
|
|
77
81
|
const { result, rerender } = renderHook(
|
|
78
|
-
({ userId,
|
|
82
|
+
({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
|
|
79
83
|
{
|
|
80
|
-
initialProps: { userId: mockUserId,
|
|
84
|
+
initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: mockAppId }
|
|
81
85
|
}
|
|
82
86
|
);
|
|
83
87
|
|
|
@@ -95,9 +99,9 @@ describe('usePermissions Integration Tests', () => {
|
|
|
95
99
|
|
|
96
100
|
it('refetches when eventId changes', async () => {
|
|
97
101
|
const { result, rerender } = renderHook(
|
|
98
|
-
({ userId,
|
|
102
|
+
({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
|
|
99
103
|
{
|
|
100
|
-
initialProps: { userId: mockUserId,
|
|
104
|
+
initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: mockAppId }
|
|
101
105
|
}
|
|
102
106
|
);
|
|
103
107
|
|
|
@@ -114,11 +118,10 @@ describe('usePermissions Integration Tests', () => {
|
|
|
114
118
|
});
|
|
115
119
|
|
|
116
120
|
it('refetches when appId changes', async () => {
|
|
117
|
-
const scopeWithApp = { ...mockScope, appId: 'app-1' };
|
|
118
121
|
const { result, rerender } = renderHook(
|
|
119
|
-
({ userId,
|
|
122
|
+
({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
|
|
120
123
|
{
|
|
121
|
-
initialProps: { userId: mockUserId,
|
|
124
|
+
initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: 'app-1' }
|
|
122
125
|
}
|
|
123
126
|
);
|
|
124
127
|
|
|
@@ -137,7 +140,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
137
140
|
|
|
138
141
|
describe('Refetch Scenarios', () => {
|
|
139
142
|
it('refetch updates permissions after external change', async () => {
|
|
140
|
-
const { result } = renderHook(() => usePermissions(mockUserId,
|
|
143
|
+
const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
141
144
|
|
|
142
145
|
await waitFor(() => {
|
|
143
146
|
expect(result.current.isLoading).toBe(false);
|
|
@@ -159,7 +162,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
159
162
|
it('refetch clears error state', async () => {
|
|
160
163
|
// First render with error
|
|
161
164
|
mockGetPermissionMap.mockRejectedValueOnce(new Error('Network error'));
|
|
162
|
-
const { result } = renderHook(() => usePermissions(mockUserId,
|
|
165
|
+
const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
163
166
|
|
|
164
167
|
await waitFor(() => {
|
|
165
168
|
expect(result.current.error).toBeDefined();
|
|
@@ -176,7 +179,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
176
179
|
});
|
|
177
180
|
|
|
178
181
|
it('refetch triggers API call', async () => {
|
|
179
|
-
const { result } = renderHook(() => usePermissions(mockUserId,
|
|
182
|
+
const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
180
183
|
|
|
181
184
|
await waitFor(() => {
|
|
182
185
|
expect(result.current.isLoading).toBe(false);
|
|
@@ -192,7 +195,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
192
195
|
});
|
|
193
196
|
|
|
194
197
|
it('refetch does nothing when userId is empty', async () => {
|
|
195
|
-
const { result } = renderHook(() => usePermissions('',
|
|
198
|
+
const { result } = renderHook(() => usePermissions('', mockOrgId, mockEventId, mockAppId));
|
|
196
199
|
|
|
197
200
|
await waitFor(() => {
|
|
198
201
|
expect(result.current.isLoading).toBe(false);
|
|
@@ -207,8 +210,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
207
210
|
});
|
|
208
211
|
|
|
209
212
|
it('refetch does nothing when organisationId is empty', async () => {
|
|
210
|
-
const
|
|
211
|
-
const { result } = renderHook(() => usePermissions(mockUserId, invalidScope));
|
|
213
|
+
const { result } = renderHook(() => usePermissions(mockUserId, '', mockEventId, mockAppId));
|
|
212
214
|
|
|
213
215
|
await waitFor(() => {
|
|
214
216
|
expect(result.current.isLoading).toBe(true);
|
|
@@ -225,7 +227,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
225
227
|
|
|
226
228
|
describe('Concurrent Permission Checks', () => {
|
|
227
229
|
it('handles rapid permission checks correctly', async () => {
|
|
228
|
-
const { result } = renderHook(() => usePermissions(mockUserId,
|
|
230
|
+
const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
229
231
|
|
|
230
232
|
await waitFor(() => {
|
|
231
233
|
expect(result.current.isLoading).toBe(false);
|
|
@@ -250,8 +252,8 @@ describe('usePermissions Integration Tests', () => {
|
|
|
250
252
|
});
|
|
251
253
|
|
|
252
254
|
it('handles multiple hooks with same scope', async () => {
|
|
253
|
-
const { result: result1 } = renderHook(() => usePermissions(mockUserId,
|
|
254
|
-
const { result: result2 } = renderHook(() => usePermissions(mockUserId,
|
|
255
|
+
const { result: result1 } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
256
|
+
const { result: result2 } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
255
257
|
|
|
256
258
|
await waitFor(() => {
|
|
257
259
|
expect(result1.current.isLoading).toBe(false);
|
|
@@ -266,8 +268,8 @@ describe('usePermissions Integration Tests', () => {
|
|
|
266
268
|
});
|
|
267
269
|
|
|
268
270
|
it('handles refetch from multiple components', async () => {
|
|
269
|
-
const { result: result1 } = renderHook(() => usePermissions(mockUserId,
|
|
270
|
-
const { result: result2 } = renderHook(() => usePermissions(mockUserId,
|
|
271
|
+
const { result: result1 } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
272
|
+
const { result: result2 } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
271
273
|
|
|
272
274
|
await waitFor(() => {
|
|
273
275
|
expect(result1.current.isLoading).toBe(false);
|
|
@@ -286,7 +288,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
286
288
|
|
|
287
289
|
describe('Permission Array Operations', () => {
|
|
288
290
|
it('hasAnyPermission handles complex arrays', async () => {
|
|
289
|
-
const { result } = renderHook(() => usePermissions(mockUserId,
|
|
291
|
+
const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
290
292
|
|
|
291
293
|
await waitFor(() => {
|
|
292
294
|
expect(result.current.isLoading).toBe(false);
|
|
@@ -298,7 +300,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
298
300
|
});
|
|
299
301
|
|
|
300
302
|
it('hasAllPermissions handles complex arrays', async () => {
|
|
301
|
-
const { result } = renderHook(() => usePermissions(mockUserId,
|
|
303
|
+
const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
302
304
|
|
|
303
305
|
await waitFor(() => {
|
|
304
306
|
expect(result.current.isLoading).toBe(false);
|
|
@@ -316,7 +318,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
316
318
|
}
|
|
317
319
|
|
|
318
320
|
mockGetPermissionMap.mockResolvedValue(largePermissionMap);
|
|
319
|
-
const { result } = renderHook(() => usePermissions(mockUserId,
|
|
321
|
+
const { result } = renderHook(() => usePermissions(mockUserId, mockOrgId, mockEventId, mockAppId));
|
|
320
322
|
|
|
321
323
|
await waitFor(() => {
|
|
322
324
|
expect(result.current.isLoading).toBe(false);
|
|
@@ -371,8 +373,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
371
373
|
|
|
372
374
|
describe('Invalid Scope Handling', () => {
|
|
373
375
|
it('handles empty organisationId gracefully', async () => {
|
|
374
|
-
const
|
|
375
|
-
const { result } = renderHook(() => usePermissions(mockUserId, invalidScope));
|
|
376
|
+
const { result } = renderHook(() => usePermissions(mockUserId, '', mockEventId, mockAppId));
|
|
376
377
|
|
|
377
378
|
// Should not fetch with invalid scope
|
|
378
379
|
await waitFor(() => {
|
|
@@ -381,8 +382,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
381
382
|
});
|
|
382
383
|
|
|
383
384
|
it('handles whitespace-only organisationId', async () => {
|
|
384
|
-
const
|
|
385
|
-
const { result } = renderHook(() => usePermissions(mockUserId, invalidScope));
|
|
385
|
+
const { result } = renderHook(() => usePermissions(mockUserId, ' ', mockEventId, mockAppId));
|
|
386
386
|
|
|
387
387
|
// Should not fetch with invalid scope
|
|
388
388
|
await waitFor(() => {
|
|
@@ -391,9 +391,7 @@ describe('usePermissions Integration Tests', () => {
|
|
|
391
391
|
});
|
|
392
392
|
|
|
393
393
|
it('handles missing organisationId', async () => {
|
|
394
|
-
const
|
|
395
|
-
delete (invalidScope as any).organisationId;
|
|
396
|
-
const { result } = renderHook(() => usePermissions(mockUserId, invalidScope));
|
|
394
|
+
const { result } = renderHook(() => usePermissions(mockUserId, undefined, mockEventId, mockAppId));
|
|
397
395
|
|
|
398
396
|
// Should not fetch with invalid scope
|
|
399
397
|
await waitFor(() => {
|
|
@@ -405,9 +403,9 @@ describe('usePermissions Integration Tests', () => {
|
|
|
405
403
|
describe('Memoization', () => {
|
|
406
404
|
it('returns stable references for helpers', async () => {
|
|
407
405
|
const { result, rerender } = renderHook(
|
|
408
|
-
({ userId,
|
|
406
|
+
({ userId, orgId, eventId, appId }) => usePermissions(userId, orgId, eventId, appId),
|
|
409
407
|
{
|
|
410
|
-
initialProps: { userId: mockUserId,
|
|
408
|
+
initialProps: { userId: mockUserId, orgId: mockOrgId, eventId: mockEventId, appId: mockAppId }
|
|
411
409
|
}
|
|
412
410
|
);
|
|
413
411
|
|