@@ -479,23 +479,26 @@ public function test_get_my_cases_counters_ok(): void
479479
480480 public function test_get_all_cases_forbidden_without_view_all_cases_permission (): void
481481 {
482- // Seed permissions and register gates so the `can:view-all_cases`
483- // middleware on api.1.1.cases.all_cases is enforceable in tests.
484- $ this ->initializePermissions ();
482+ // Ensure the permission row exists and register it as a Laravel Gate
483+ // so $user->can('view-all_cases') is enforceable in tests.
484+ Permission::firstOrCreate (
485+ ['name ' => 'view-all_cases ' ],
486+ ['title ' => 'View All Cases ' ],
487+ );
488+ Gate::define ('view-all_cases ' , fn ($ user ) => $ user ->hasPermission ('view-all_cases ' ));
485489
486490 $ nonAdmin = User::factory ()->create ([
487491 'is_administrator ' => false ,
488492 ]);
489493
490- // Create some cases so a permitted user would get a non-empty payload.
491494 self ::createCasesStartedForUser ($ nonAdmin ->id , 3 );
492495
493- // Without the permission, access is denied.
496+ // Unscoped request ( the "All cases" tab) — denied without the permission .
494497 $ response = $ this ->actingAs ($ nonAdmin , 'api ' )
495498 ->json ('GET ' , route ('api.1.1.cases.all_cases ' ));
496499 $ response ->assertStatus (403 );
497500
498- // Granting the permission restores access.
501+ // Granting the permission restores access to the unscoped query .
499502 $ nonAdmin ->giveDirectPermission ('view-all_cases ' );
500503
501504 $ response = $ this ->actingAs ($ nonAdmin , 'api ' )
@@ -504,6 +507,57 @@ public function test_get_all_cases_forbidden_without_view_all_cases_permission()
504507 $ response ->assertJsonCount (3 , 'data ' );
505508 }
506509
510+ public function test_get_all_cases_allows_user_to_view_their_own_cases_without_permission (): void
511+ {
512+ // The endpoint is shared by the "My cases" tab, which scopes the
513+ // query to the authenticated user. That self-scoped path must work
514+ // even when the user lacks `view-all_cases`.
515+ $ nonAdmin = User::factory ()->create ([
516+ 'is_administrator ' => false ,
517+ ]);
518+
519+ $ ownCases = self ::createCasesStartedForUser ($ nonAdmin ->id , 4 );
520+ $ otherUser = self ::createUser ('other_user ' );
521+ self ::createCasesStartedForUser ($ otherUser ->id , 6 );
522+
523+ $ response = $ this ->actingAs ($ nonAdmin , 'api ' )
524+ ->json ('GET ' , route ('api.1.1.cases.all_cases ' , ['userId ' => $ nonAdmin ->id ]));
525+
526+ $ response ->assertStatus (200 );
527+ $ response ->assertJsonCount ($ ownCases ->count (), 'data ' );
528+ $ response ->assertJsonMissing (['user_id ' => $ otherUser ->id ]);
529+ }
530+
531+ public function test_get_all_cases_forbids_user_from_viewing_another_users_cases_without_permission (): void
532+ {
533+ Permission::firstOrCreate (
534+ ['name ' => 'view-all_cases ' ],
535+ ['title ' => 'View All Cases ' ],
536+ );
537+ Gate::define ('view-all_cases ' , fn ($ user ) => $ user ->hasPermission ('view-all_cases ' ));
538+
539+ $ nonAdmin = User::factory ()->create ([
540+ 'is_administrator ' => false ,
541+ ]);
542+ $ otherUser = self ::createUser ('other_user ' );
543+ self ::createCasesStartedForUser ($ otherUser ->id , 2 );
544+
545+ // Passing another user's id must require `view-all_cases`; otherwise
546+ // any authenticated user could iterate userIds to enumerate the
547+ // entire platform.
548+ $ response = $ this ->actingAs ($ nonAdmin , 'api ' )
549+ ->json ('GET ' , route ('api.1.1.cases.all_cases ' , ['userId ' => $ otherUser ->id ]));
550+ $ response ->assertStatus (403 );
551+
552+ // With the permission, the same request succeeds.
553+ $ nonAdmin ->giveDirectPermission ('view-all_cases ' );
554+
555+ $ response = $ this ->actingAs ($ nonAdmin , 'api ' )
556+ ->json ('GET ' , route ('api.1.1.cases.all_cases ' , ['userId ' => $ otherUser ->id ]));
557+ $ response ->assertStatus (200 );
558+ $ response ->assertJsonCount (2 , 'data ' );
559+ }
560+
507561 public function test_get_all_cases_participants (): void
508562 {
509563 $ userA = $ this ->createUser ('user_a ' );
0 commit comments