@@ -176,6 +176,36 @@ public async Task GetUsers_WithSearch_ShouldReturnMatchingUsers()
176176 response . StatusCode . Should ( ) . Be ( HttpStatusCode . Forbidden ) ;
177177 }
178178
179+ [ Fact ]
180+ public async Task GetUsers_WhenProjectManagerAndRoleUser_ShouldReturnMatchingUsers ( )
181+ {
182+ await EnsureUserHasRoleAsync ( TestData . User . Email , Roles . ProjectManager ) ;
183+ var userRoleEmail = $ "assignable-{ Guid . NewGuid ( ) : N} @example.com";
184+ await EnsureUserWithRoleAsync ( userRoleEmail , Roles . User ) ;
185+
186+ var token = await GetAccessTokenAsync ( ) ;
187+ _client . DefaultRequestHeaders . Authorization = new AuthenticationHeaderValue ( "Bearer" , token ) ;
188+
189+ var response = await _client . GetAsync ( $ "/api/users?role={ Roles . User } &page=1&pageSize=25") ;
190+ response . StatusCode . Should ( ) . Be ( HttpStatusCode . OK ) ;
191+
192+ var list = await response . Content . ReadFromJsonAsync < UserListResponse > ( ) ;
193+ list . Should ( ) . NotBeNull ( ) ;
194+ list ! . Items . Should ( ) . NotBeEmpty ( ) ;
195+ list . Items . Should ( ) . OnlyContain ( u => u . Roles . Contains ( Roles . User ) ) ;
196+ }
197+
198+ [ Fact ]
199+ public async Task GetUsers_WhenProjectManagerWithoutRoleFilter_ShouldReturnForbidden ( )
200+ {
201+ await EnsureUserHasRoleAsync ( TestData . User . Email , Roles . ProjectManager ) ;
202+ var token = await GetAccessTokenAsync ( ) ;
203+ _client . DefaultRequestHeaders . Authorization = new AuthenticationHeaderValue ( "Bearer" , token ) ;
204+
205+ var response = await _client . GetAsync ( "/api/users?page=1&pageSize=25" ) ;
206+ response . StatusCode . Should ( ) . Be ( HttpStatusCode . Forbidden ) ;
207+ }
208+
179209 [ Fact ]
180210 public async Task GetUsers_WithSearch_WhenAdmin_ShouldReturnMatchingUsers ( )
181211 {
@@ -531,6 +561,40 @@ private async Task<string> GetAdminAccessTokenAsync(string adminEmail, string ad
531561 return await GetAccessTokenAsync ( adminEmail , adminPassword ) ;
532562 }
533563
564+ private async Task EnsureUserWithRoleAsync ( string email , string role , string password = "StrongPassword@123" )
565+ {
566+ using var scope = _factory . Services . CreateScope ( ) ;
567+ var userManager = scope . ServiceProvider . GetRequiredService < UserManager < ApplicationUser > > ( ) ;
568+ var roleManager = scope . ServiceProvider . GetRequiredService < RoleManager < IdentityRole > > ( ) ;
569+
570+ if ( ! await roleManager . RoleExistsAsync ( role ) )
571+ {
572+ await roleManager . CreateAsync ( new IdentityRole ( role ) ) ;
573+ }
574+
575+ var user = await userManager . FindByEmailAsync ( email ) ;
576+ if ( user == null )
577+ {
578+ user = new ApplicationUser
579+ {
580+ UserName = email ,
581+ Email = email ,
582+ EmailConfirmed = true
583+ } ;
584+ var createResult = await userManager . CreateAsync ( user , password ) ;
585+ createResult . Succeeded . Should ( ) . BeTrue ( ) ;
586+ }
587+
588+ if ( ! await userManager . IsInRoleAsync ( user , role ) )
589+ {
590+ var addRoleResult = await userManager . AddToRoleAsync ( user , role ) ;
591+ addRoleResult . Succeeded . Should ( ) . BeTrue ( ) ;
592+ }
593+ }
594+
595+ private Task EnsureUserHasRoleAsync ( string email , string role )
596+ => EnsureUserWithRoleAsync ( email , role ) ;
597+
534598 private static async Task < HttpResponseMessage > InitiateAuthorizationRequest (
535599 HttpClient client ,
536600 AuthorizationParameters parameters )
0 commit comments