@jmruthers/pace-core 0.5.4 → 0.5.5
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-ZQDRE46Q.js → DataTable-3SSI644S.js} +2 -2
- package/dist/{chunk-M4RW7PIP.js → chunk-2BJFM2JC.js} +105 -81
- package/dist/chunk-2BJFM2JC.js.map +1 -0
- package/dist/{chunk-5H3C2SWM.js → chunk-RTCA5ZNK.js} +2 -2
- package/dist/components.js +2 -2
- package/dist/index.js +2 -2
- package/dist/utils.js +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/interfaces/AggregateConfig.md +1 -1
- 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/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 +34 -34
- 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/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/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 +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- 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/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 +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/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +1 -1
- 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/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/docs/implementation-guides/data-tables.md +20 -0
- package/docs/quick-reference.md +9 -0
- package/docs/rbac/examples.md +4 -0
- package/package.json +1 -1
- package/src/__tests__/helpers/test-utils.tsx +147 -1
- package/src/components/DataTable/DataTable.tsx +20 -0
- package/src/components/DataTable/__tests__/DataTable.hooks.test 2.tsx +191 -0
- package/src/components/DataTable/__tests__/DataTable.hooks.test.tsx +191 -0
- package/src/components/DataTable/components/DataTableCore.tsx +167 -138
- package/src/hooks/__tests__/hooks.integration.test.tsx +575 -0
- package/src/hooks/__tests__/useApiFetch.unit.test.ts +115 -0
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +133 -0
- package/src/hooks/__tests__/useDebounce.unit.test.ts +82 -0
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +293 -0
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +385 -0
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +286 -0
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +838 -0
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +104 -0
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +633 -0
- package/src/hooks/__tests__/useRBAC.unit.test.ts +856 -0
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +537 -0
- package/src/hooks/__tests__/useToast.unit.test.tsx +62 -0
- package/src/hooks/__tests__/useZodForm.unit.test.tsx +37 -0
- package/src/rbac/utils/__tests__/eventContext.test.ts +428 -0
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +428 -0
- package/src/utils/__tests__/appConfig.unit.test.ts +55 -0
- package/src/utils/__tests__/audit.unit.test.ts +69 -0
- package/src/utils/__tests__/auth-utils.unit.test.ts +70 -0
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +317 -0
- package/src/utils/__tests__/cn.unit.test.ts +34 -0
- package/src/utils/__tests__/deviceFingerprint.unit.test.ts +503 -0
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +322 -0
- package/src/utils/__tests__/formatDate.unit.test.ts +109 -0
- package/src/utils/__tests__/formatting.unit.test.ts +66 -0
- package/src/utils/__tests__/index.unit.test.ts +251 -0
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +309 -0
- package/src/utils/__tests__/organisationContext.unit.test.ts +192 -0
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +259 -0
- package/src/utils/__tests__/permissionTypes.unit.test.ts +250 -0
- package/src/utils/__tests__/permissionUtils.unit.test.ts +362 -0
- package/src/utils/__tests__/sanitization.unit.test.ts +346 -0
- package/src/utils/__tests__/schemaUtils.unit.test.ts +441 -0
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +334 -0
- package/src/utils/__tests__/secureErrors.unit.test.ts +377 -0
- package/src/utils/__tests__/secureStorage.unit.test.ts +293 -0
- package/src/utils/__tests__/security.unit.test.ts +127 -0
- package/src/utils/__tests__/securityMonitor.unit.test.ts +280 -0
- package/src/utils/__tests__/sessionTracking.unit.test.ts +356 -0
- package/src/utils/__tests__/validation.unit.test.ts +84 -0
- package/src/utils/__tests__/validationUtils.unit.test.ts +571 -0
- package/src/validation/__tests__/common.unit.test.ts +101 -0
- package/src/validation/__tests__/csrf.unit.test.ts +302 -0
- package/src/validation/__tests__/passwordSchema.unit.test 2.ts +98 -0
- package/src/validation/__tests__/passwordSchema.unit.test.ts +98 -0
- package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +466 -0
- package/dist/chunk-M4RW7PIP.js.map +0 -1
- /package/dist/{DataTable-ZQDRE46Q.js.map → DataTable-3SSI644S.js.map} +0 -0
- /package/dist/{chunk-5H3C2SWM.js.map → chunk-RTCA5ZNK.js.map} +0 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
transformPermissionMapToBoolean,
|
|
4
|
+
hasPermission,
|
|
5
|
+
hasAnyPermission,
|
|
6
|
+
hasAllPermissions
|
|
7
|
+
} from '../permissionUtils';
|
|
8
|
+
|
|
9
|
+
describe('permissionUtils', () => {
|
|
10
|
+
describe('transformPermissionMapToBoolean', () => {
|
|
11
|
+
it('should transform permission map to boolean values', () => {
|
|
12
|
+
const permissions = {
|
|
13
|
+
'read:users': true,
|
|
14
|
+
'write:users': false,
|
|
15
|
+
'delete:users': 1,
|
|
16
|
+
'admin:users': 0,
|
|
17
|
+
'view:reports': 'true',
|
|
18
|
+
'edit:reports': false
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const result = transformPermissionMapToBoolean(permissions);
|
|
22
|
+
|
|
23
|
+
expect(result).toEqual({
|
|
24
|
+
'read:users': true,
|
|
25
|
+
'write:users': false,
|
|
26
|
+
'delete:users': true,
|
|
27
|
+
'admin:users': false,
|
|
28
|
+
'view:reports': true,
|
|
29
|
+
'edit:reports': false
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should handle empty permission map', () => {
|
|
34
|
+
const permissions = {};
|
|
35
|
+
|
|
36
|
+
const result = transformPermissionMapToBoolean(permissions);
|
|
37
|
+
|
|
38
|
+
expect(result).toEqual({});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should handle various truthy and falsy values', () => {
|
|
42
|
+
const permissions = {
|
|
43
|
+
'permission1': true,
|
|
44
|
+
'permission2': false,
|
|
45
|
+
'permission3': 1,
|
|
46
|
+
'permission4': 0,
|
|
47
|
+
'permission5': 'true',
|
|
48
|
+
'permission6': 'false',
|
|
49
|
+
'permission7': '',
|
|
50
|
+
'permission8': null,
|
|
51
|
+
'permission9': undefined
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const result = transformPermissionMapToBoolean(permissions);
|
|
55
|
+
|
|
56
|
+
expect(result).toEqual({
|
|
57
|
+
'permission1': true,
|
|
58
|
+
'permission2': false,
|
|
59
|
+
'permission3': true,
|
|
60
|
+
'permission4': false,
|
|
61
|
+
'permission5': true,
|
|
62
|
+
'permission6': false,
|
|
63
|
+
'permission7': false,
|
|
64
|
+
'permission8': false,
|
|
65
|
+
'permission9': false
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should handle mixed data types', () => {
|
|
70
|
+
const permissions = {
|
|
71
|
+
'read': true,
|
|
72
|
+
'write': 'yes',
|
|
73
|
+
'delete': 1,
|
|
74
|
+
'admin': 'no',
|
|
75
|
+
'view': 0,
|
|
76
|
+
'edit': false
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const result = transformPermissionMapToBoolean(permissions);
|
|
80
|
+
|
|
81
|
+
expect(result).toEqual({
|
|
82
|
+
'read': true,
|
|
83
|
+
'write': true,
|
|
84
|
+
'delete': true,
|
|
85
|
+
'admin': true,
|
|
86
|
+
'view': false,
|
|
87
|
+
'edit': false
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('hasPermission', () => {
|
|
93
|
+
it('should return true when permission exists and is true', () => {
|
|
94
|
+
const permissions = {
|
|
95
|
+
'read:users': true,
|
|
96
|
+
'write:users': false,
|
|
97
|
+
'delete:users': true
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
expect(hasPermission(permissions, 'read:users')).toBe(true);
|
|
101
|
+
expect(hasPermission(permissions, 'delete:users')).toBe(true);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should return false when permission exists but is false', () => {
|
|
105
|
+
const permissions = {
|
|
106
|
+
'read:users': true,
|
|
107
|
+
'write:users': false,
|
|
108
|
+
'delete:users': true
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
expect(hasPermission(permissions, 'write:users')).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should return false when permission does not exist', () => {
|
|
115
|
+
const permissions = {
|
|
116
|
+
'read:users': true,
|
|
117
|
+
'write:users': false
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
expect(hasPermission(permissions, 'admin:users')).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should handle empty permissions object', () => {
|
|
124
|
+
const permissions = {};
|
|
125
|
+
|
|
126
|
+
expect(hasPermission(permissions, 'any:permission')).toBe(false);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should handle various truthy and falsy values', () => {
|
|
130
|
+
const permissions = {
|
|
131
|
+
'truthy1': true,
|
|
132
|
+
'truthy2': 1,
|
|
133
|
+
'truthy3': 'true',
|
|
134
|
+
'falsy1': false,
|
|
135
|
+
'falsy2': 0,
|
|
136
|
+
'falsy3': 'false',
|
|
137
|
+
'falsy4': '',
|
|
138
|
+
'falsy5': null,
|
|
139
|
+
'falsy6': undefined
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
expect(hasPermission(permissions, 'truthy1')).toBe(true);
|
|
143
|
+
expect(hasPermission(permissions, 'truthy2')).toBe(true);
|
|
144
|
+
expect(hasPermission(permissions, 'truthy3')).toBe(true);
|
|
145
|
+
expect(hasPermission(permissions, 'falsy1')).toBe(false);
|
|
146
|
+
expect(hasPermission(permissions, 'falsy2')).toBe(false);
|
|
147
|
+
expect(hasPermission(permissions, 'falsy3')).toBe(true);
|
|
148
|
+
expect(hasPermission(permissions, 'falsy4')).toBe(false);
|
|
149
|
+
expect(hasPermission(permissions, 'falsy5')).toBe(false);
|
|
150
|
+
expect(hasPermission(permissions, 'falsy6')).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('hasAnyPermission', () => {
|
|
155
|
+
it('should return true when any permission in list is granted', () => {
|
|
156
|
+
const permissions = {
|
|
157
|
+
'read:users': true,
|
|
158
|
+
'write:users': false,
|
|
159
|
+
'delete:users': false,
|
|
160
|
+
'admin:users': true
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
expect(hasAnyPermission(permissions, ['read:users', 'write:users'])).toBe(true);
|
|
164
|
+
expect(hasAnyPermission(permissions, ['write:users', 'delete:users', 'admin:users'])).toBe(true);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('should return false when no permissions in list are granted', () => {
|
|
168
|
+
const permissions = {
|
|
169
|
+
'read:users': false,
|
|
170
|
+
'write:users': false,
|
|
171
|
+
'delete:users': false
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
expect(hasAnyPermission(permissions, ['read:users', 'write:users', 'delete:users'])).toBe(false);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should return false when permission list is empty', () => {
|
|
178
|
+
const permissions = {
|
|
179
|
+
'read:users': true,
|
|
180
|
+
'write:users': true
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
expect(hasAnyPermission(permissions, [])).toBe(false);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('should return false when permissions object is empty', () => {
|
|
187
|
+
const permissions = {};
|
|
188
|
+
|
|
189
|
+
expect(hasAnyPermission(permissions, ['read:users', 'write:users'])).toBe(false);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('should handle permissions that do not exist', () => {
|
|
193
|
+
const permissions = {
|
|
194
|
+
'read:users': true,
|
|
195
|
+
'write:users': false
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
expect(hasAnyPermission(permissions, ['read:users', 'nonexistent:permission'])).toBe(true);
|
|
199
|
+
expect(hasAnyPermission(permissions, ['nonexistent1:permission', 'nonexistent2:permission'])).toBe(false);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should handle single permission in list', () => {
|
|
203
|
+
const permissions = {
|
|
204
|
+
'read:users': true,
|
|
205
|
+
'write:users': false
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
expect(hasAnyPermission(permissions, ['read:users'])).toBe(true);
|
|
209
|
+
expect(hasAnyPermission(permissions, ['write:users'])).toBe(false);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe('hasAllPermissions', () => {
|
|
214
|
+
it('should return true when all permissions in list are granted', () => {
|
|
215
|
+
const permissions = {
|
|
216
|
+
'read:users': true,
|
|
217
|
+
'write:users': true,
|
|
218
|
+
'delete:users': true
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
expect(hasAllPermissions(permissions, ['read:users', 'write:users', 'delete:users'])).toBe(true);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('should return false when any permission in list is not granted', () => {
|
|
225
|
+
const permissions = {
|
|
226
|
+
'read:users': true,
|
|
227
|
+
'write:users': false,
|
|
228
|
+
'delete:users': true
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
expect(hasAllPermissions(permissions, ['read:users', 'write:users', 'delete:users'])).toBe(false);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('should return true when permission list is empty', () => {
|
|
235
|
+
const permissions = {
|
|
236
|
+
'read:users': true,
|
|
237
|
+
'write:users': true
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
expect(hasAllPermissions(permissions, [])).toBe(true);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should return false when permissions object is empty but list is not', () => {
|
|
244
|
+
const permissions = {};
|
|
245
|
+
|
|
246
|
+
expect(hasAllPermissions(permissions, ['read:users', 'write:users'])).toBe(false);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should handle permissions that do not exist', () => {
|
|
250
|
+
const permissions = {
|
|
251
|
+
'read:users': true,
|
|
252
|
+
'write:users': true
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
expect(hasAllPermissions(permissions, ['read:users', 'nonexistent:permission'])).toBe(false);
|
|
256
|
+
expect(hasAllPermissions(permissions, ['nonexistent1:permission', 'nonexistent2:permission'])).toBe(false);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('should handle single permission in list', () => {
|
|
260
|
+
const permissions = {
|
|
261
|
+
'read:users': true,
|
|
262
|
+
'write:users': false
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
expect(hasAllPermissions(permissions, ['read:users'])).toBe(true);
|
|
266
|
+
expect(hasAllPermissions(permissions, ['write:users'])).toBe(false);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('should handle mixed existing and non-existing permissions', () => {
|
|
270
|
+
const permissions = {
|
|
271
|
+
'read:users': true,
|
|
272
|
+
'write:users': true
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
expect(hasAllPermissions(permissions, ['read:users', 'write:users', 'nonexistent:permission'])).toBe(false);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
describe('Integration tests', () => {
|
|
280
|
+
it('should work together in a realistic permission scenario', () => {
|
|
281
|
+
const userPermissions = {
|
|
282
|
+
'read:users': true,
|
|
283
|
+
'write:users': false,
|
|
284
|
+
'delete:users': false,
|
|
285
|
+
'read:reports': true,
|
|
286
|
+
'write:reports': true,
|
|
287
|
+
'admin:system': false
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
// Transform permissions to ensure boolean values
|
|
291
|
+
const booleanPermissions = transformPermissionMapToBoolean(userPermissions);
|
|
292
|
+
|
|
293
|
+
// Check individual permissions
|
|
294
|
+
expect(hasPermission(booleanPermissions, 'read:users')).toBe(true);
|
|
295
|
+
expect(hasPermission(booleanPermissions, 'write:users')).toBe(false);
|
|
296
|
+
expect(hasPermission(booleanPermissions, 'admin:system')).toBe(false);
|
|
297
|
+
|
|
298
|
+
// Check if user has any user management permissions
|
|
299
|
+
expect(hasAnyPermission(booleanPermissions, ['read:users', 'write:users', 'delete:users'])).toBe(true);
|
|
300
|
+
|
|
301
|
+
// Check if user has all user management permissions
|
|
302
|
+
expect(hasAllPermissions(booleanPermissions, ['read:users', 'write:users', 'delete:users'])).toBe(false);
|
|
303
|
+
|
|
304
|
+
// Check if user has all report permissions
|
|
305
|
+
expect(hasAllPermissions(booleanPermissions, ['read:reports', 'write:reports'])).toBe(true);
|
|
306
|
+
|
|
307
|
+
// Check if user has any admin permissions
|
|
308
|
+
expect(hasAnyPermission(booleanPermissions, ['admin:system', 'admin:users'])).toBe(false);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it('should handle complex permission hierarchies', () => {
|
|
312
|
+
const adminPermissions = {
|
|
313
|
+
'read:users': true,
|
|
314
|
+
'write:users': true,
|
|
315
|
+
'delete:users': true,
|
|
316
|
+
'read:reports': true,
|
|
317
|
+
'write:reports': true,
|
|
318
|
+
'delete:reports': true,
|
|
319
|
+
'admin:system': true
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const managerPermissions = {
|
|
323
|
+
'read:users': true,
|
|
324
|
+
'write:users': true,
|
|
325
|
+
'delete:users': false,
|
|
326
|
+
'read:reports': true,
|
|
327
|
+
'write:reports': true,
|
|
328
|
+
'delete:reports': false,
|
|
329
|
+
'admin:system': false
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const userPermissions = {
|
|
333
|
+
'read:users': true,
|
|
334
|
+
'write:users': false,
|
|
335
|
+
'delete:users': false,
|
|
336
|
+
'read:reports': true,
|
|
337
|
+
'write:reports': false,
|
|
338
|
+
'delete:reports': false,
|
|
339
|
+
'admin:system': false
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const booleanAdminPermissions = transformPermissionMapToBoolean(adminPermissions);
|
|
343
|
+
const booleanManagerPermissions = transformPermissionMapToBoolean(managerPermissions);
|
|
344
|
+
const booleanUserPermissions = transformPermissionMapToBoolean(userPermissions);
|
|
345
|
+
|
|
346
|
+
// Admin should have all permissions
|
|
347
|
+
expect(hasAllPermissions(booleanAdminPermissions, ['read:users', 'write:users', 'delete:users'])).toBe(true);
|
|
348
|
+
expect(hasAllPermissions(booleanAdminPermissions, ['read:reports', 'write:reports', 'delete:reports'])).toBe(true);
|
|
349
|
+
expect(hasPermission(booleanAdminPermissions, 'admin:system')).toBe(true);
|
|
350
|
+
|
|
351
|
+
// Manager should have some but not all permissions
|
|
352
|
+
expect(hasAllPermissions(booleanManagerPermissions, ['read:users', 'write:users'])).toBe(true);
|
|
353
|
+
expect(hasAllPermissions(booleanManagerPermissions, ['read:users', 'write:users', 'delete:users'])).toBe(false);
|
|
354
|
+
expect(hasAnyPermission(booleanManagerPermissions, ['delete:users', 'delete:reports'])).toBe(false);
|
|
355
|
+
|
|
356
|
+
// User should have limited permissions
|
|
357
|
+
expect(hasAllPermissions(booleanUserPermissions, ['read:users', 'read:reports'])).toBe(true);
|
|
358
|
+
expect(hasAnyPermission(booleanUserPermissions, ['write:users', 'write:reports'])).toBe(false);
|
|
359
|
+
expect(hasPermission(booleanUserPermissions, 'admin:system')).toBe(false);
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
});
|