@@ -22,6 +22,10 @@ class PermissionsTest extends TestCase
2222{
2323 use RequestHelper;
2424
25+ private const PERMISSIONS_URL = '/permissions ' ;
26+
27+ private const PROCESSES_URL = '/processes ' ;
28+
2529 protected function withUserSetup ()
2630 {
2731 $ this ->user ->is_administrator = false ;
@@ -59,10 +63,10 @@ public function testApiPermissions()
5963 'status ' => 'ACTIVE ' ,
6064 ]);
6165
62- $ response = $ this ->apiCall ('GET ' , ' /processes ' );
66+ $ response = $ this ->apiCall ('GET ' , self :: PROCESSES_URL );
6367 $ response ->assertStatus (200 );
6468
65- $ response = $ this ->apiCall ('GET ' , ' /processes / ' . $ process ->id );
69+ $ response = $ this ->apiCall ('GET ' , self :: PROCESSES_URL . ' / ' . $ process ->id );
6670 $ response ->assertStatus (200 );
6771
6872 $ permission = Permission::byName ('archive-processes ' );
@@ -74,7 +78,7 @@ public function testApiPermissions()
7478 // Invalidate permission cache to ensure changes take effect
7579 $ this ->user ->invalidatePermissionCache ();
7680
77- $ response = $ this ->apiCall ('DELETE ' , ' /processes / ' . $ process ->id );
81+ $ response = $ this ->apiCall ('DELETE ' , self :: PROCESSES_URL . ' / ' . $ process ->id );
7882 $ response ->assertStatus (403 );
7983
8084 $ this ->user ->permissions ()->attach ($ permission ->id );
@@ -84,7 +88,7 @@ public function testApiPermissions()
8488 // Invalidate permission cache to ensure the new permission takes effect
8589 $ this ->user ->invalidatePermissionCache ();
8690
87- $ response = $ this ->apiCall ('DELETE ' , ' /processes / ' . $ process ->id );
91+ $ response = $ this ->apiCall ('DELETE ' , self :: PROCESSES_URL . ' / ' . $ process ->id );
8892 $ response ->assertStatus (204 );
8993 }
9094
@@ -97,7 +101,7 @@ public function testSetPermissionsForUser()
97101
98102 $ testUser = User::factory ()->create ();
99103 $ testPermission = Permission::factory ()->create ();
100- $ response = $ this ->apiCall ('PUT ' , ' /permissions ' , [
104+ $ response = $ this ->apiCall ('PUT ' , self :: PERMISSIONS_URL , [
101105 'user_id ' => $ testUser ->id ,
102106 'permission_names ' => [$ testPermission ->name ],
103107 ]);
@@ -109,6 +113,113 @@ public function testSetPermissionsForUser()
109113 $ this ->assertEquals ($ testUser ->permissions ->first ()->id , $ testPermission ->id );
110114 }
111115
116+ public function testSetPermissionsForGroupWithInheritedEditGroupsPermission ()
117+ {
118+ $ this ->user = User::factory ()->create ([
119+ 'password ' => Hash::make ('password ' ),
120+ 'is_administrator ' => false ,
121+ ]);
122+ $ this ->initializePermissions (false );
123+
124+ $ adminGroup = Group::factory ()->create ();
125+ $ adminGroup ->permissions ()->attach (Permission::whereIn ('name ' , [
126+ 'view-groups ' ,
127+ 'create-groups ' ,
128+ 'edit-groups ' ,
129+ 'delete-groups ' ,
130+ ])->pluck ('id ' ));
131+
132+ GroupMember::factory ()->create ([
133+ 'group_id ' => $ adminGroup ->id ,
134+ 'member_type ' => User::class,
135+ 'member_id ' => $ this ->user ->id ,
136+ ]);
137+
138+ $ this ->user ->invalidatePermissionCache ();
139+
140+ $ targetGroup = Group::factory ()->create ();
141+
142+ $ response = $ this ->apiCall ('PUT ' , self ::PERMISSIONS_URL , [
143+ 'group_id ' => $ targetGroup ->id ,
144+ 'permission_names ' => ['view-groups ' , 'edit-groups ' ],
145+ ]);
146+
147+ $ response ->assertStatus (204 );
148+ $ this ->assertEqualsCanonicalizing (
149+ ['view-groups ' , 'edit-groups ' ],
150+ $ targetGroup ->refresh ()->permissions ()->pluck ('name ' )->toArray ()
151+ );
152+ }
153+
154+ public function testSetPermissionsForUserRequiresEditUsersPermission ()
155+ {
156+ $ this ->user = User::factory ()->create ([
157+ 'password ' => Hash::make ('password ' ),
158+ 'is_administrator ' => false ,
159+ ]);
160+ $ this ->initializePermissions (false );
161+
162+ $ adminGroup = Group::factory ()->create ();
163+ $ adminGroup ->permissions ()->attach (Permission::byName ('edit-groups ' )->id );
164+
165+ GroupMember::factory ()->create ([
166+ 'group_id ' => $ adminGroup ->id ,
167+ 'member_type ' => User::class,
168+ 'member_id ' => $ this ->user ->id ,
169+ ]);
170+
171+ $ this ->user ->invalidatePermissionCache ();
172+
173+ $ targetUser = User::factory ()->create ();
174+
175+ $ response = $ this ->apiCall ('PUT ' , self ::PERMISSIONS_URL , [
176+ 'user_id ' => $ targetUser ->id ,
177+ 'permission_names ' => ['view-groups ' ],
178+ ]);
179+
180+ $ response ->assertStatus (403 );
181+ $ this ->assertFalse ($ targetUser ->refresh ()->permissions ()->where ('name ' , 'view-groups ' )->exists ());
182+ }
183+
184+ public function testSetPermissionsForGroupRequiresEditGroupsPermission ()
185+ {
186+ $ this ->user = User::factory ()->create ([
187+ 'password ' => Hash::make ('password ' ),
188+ 'is_administrator ' => false ,
189+ ]);
190+ $ this ->initializePermissions (false );
191+
192+ $ targetGroup = Group::factory ()->create ();
193+
194+ $ response = $ this ->apiCall ('PUT ' , self ::PERMISSIONS_URL , [
195+ 'group_id ' => $ targetGroup ->id ,
196+ 'permission_names ' => ['view-groups ' ],
197+ ]);
198+
199+ $ response ->assertStatus (403 );
200+ $ this ->assertCount (0 , $ targetGroup ->refresh ()->permissions );
201+ }
202+
203+ public function testSetPermissionsRequiresExactlyOneTarget ()
204+ {
205+ $ targetUser = User::factory ()->create ();
206+ $ targetGroup = Group::factory ()->create ();
207+
208+ $ response = $ this ->apiCall ('PUT ' , self ::PERMISSIONS_URL , [
209+ 'permission_names ' => ['view-groups ' ],
210+ ]);
211+
212+ $ response ->assertStatus (422 );
213+
214+ $ response = $ this ->apiCall ('PUT ' , self ::PERMISSIONS_URL , [
215+ 'user_id ' => $ targetUser ->id ,
216+ 'group_id ' => $ targetGroup ->id ,
217+ 'permission_names ' => ['view-groups ' ],
218+ ]);
219+
220+ $ response ->assertStatus (422 );
221+ }
222+
112223 public function testSetPermissionsViewProcessCatalogForUser ()
113224 {
114225 $ faker = Faker::create ();
@@ -180,7 +291,7 @@ public function testCategoryPermission()
180291 // Invalidate permission cache to ensure the new permission takes effect
181292 $ this ->user ->invalidatePermissionCache ();
182293
183- $ response = $ this ->apiCall ('PUT ' , $ url , $ attrs );
294+ $ this ->apiCall ('PUT ' , $ url , $ attrs );
184295 $ this ->assertEquals ('Test Category Update ' , $ class ::find ($ id )->name );
185296
186297 // test view permission
@@ -250,8 +361,8 @@ public function testSetPermissionsViewMyRequestForUser()
250361 public function testSetPermissionsViewMyRequestForUsersAndGroupCreated ()
251362 {
252363 // Set up the users and groups
253- $ users = User::factory ()->count (5 )->create ();
254- $ groups = Group::factory ()->count (3 )->create ();
364+ User::factory ()->count (5 )->create ();
365+ Group::factory ()->count (3 )->create ();
255366
256367 // Run the seeder
257368 $ this ->seed (PermissionSeeder::class);
@@ -279,7 +390,7 @@ public function testAdministratorRoleAssignment()
279390 $ this ->user = $ regularUser ;
280391 $ this ->user ->save ();
281392
282- $ response = $ this ->apiCall ('PUT ' , ' /permissions ' , [
393+ $ response = $ this ->apiCall ('PUT ' , self :: PERMISSIONS_URL , [
283394 'user_id ' => $ targetUser ->id ,
284395 'is_administrator ' => true ,
285396 'permission_names ' => [],
@@ -292,7 +403,7 @@ public function testAdministratorRoleAssignment()
292403 $ targetUser ->is_administrator = true ;
293404 $ targetUser ->save ();
294405
295- $ response = $ this ->apiCall ('PUT ' , ' /permissions ' , [
406+ $ response = $ this ->apiCall ('PUT ' , self :: PERMISSIONS_URL , [
296407 'user_id ' => $ targetUser ->id ,
297408 'is_administrator ' => false ,
298409 'permission_names ' => [],
@@ -306,7 +417,7 @@ public function testAdministratorRoleAssignment()
306417 $ this ->user = $ adminUser ;
307418 $ this ->user ->save ();
308419
309- $ response = $ this ->apiCall ('PUT ' , ' /permissions ' , [
420+ $ response = $ this ->apiCall ('PUT ' , self :: PERMISSIONS_URL , [
310421 'user_id ' => $ targetUser ->id ,
311422 'is_administrator ' => false ,
312423 'permission_names ' => [],
@@ -317,7 +428,7 @@ public function testAdministratorRoleAssignment()
317428 $ this ->assertFalse ($ targetUser ->is_administrator );
318429
319430 // Test 4: Admin can grant admin role
320- $ response = $ this ->apiCall ('PUT ' , ' /permissions ' , [
431+ $ response = $ this ->apiCall ('PUT ' , self :: PERMISSIONS_URL , [
321432 'user_id ' => $ targetUser ->id ,
322433 'is_administrator ' => true ,
323434 'permission_names ' => [],
0 commit comments