Skip to content

Commit 60c3589

Browse files
committed
Added more tests for list users API
1 parent a08df9e commit 60c3589

File tree

6 files changed

+172
-108
lines changed

6 files changed

+172
-108
lines changed

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseUserManagerTest.cs

Lines changed: 128 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,24 @@ public class FirebaseUserManagerTest
3636
GoogleCredential.FromAccessToken("test-token");
3737

3838
private static readonly string CreateUserResponse = @"{""localId"": ""user1""}";
39+
private static readonly IList<string> ListUsersResponse = new List<string>()
40+
{
41+
@"{
42+
""nextPageToken"": ""token"",
43+
""users"": [
44+
{""localId"": ""user1""},
45+
{""localId"": ""user2""},
46+
{""localId"": ""user3""}
47+
]
48+
}",
49+
@"{
50+
""users"": [
51+
{""localId"": ""user4""},
52+
{""localId"": ""user5""},
53+
{""localId"": ""user6""}
54+
]
55+
}",
56+
};
3957

4058
[Fact]
4159
public async Task GetUserById()
@@ -304,24 +322,7 @@ public async Task ListUsersPaged()
304322
{
305323
var handler = new MockMessageHandler()
306324
{
307-
Response = new List<string>()
308-
{
309-
@"{
310-
""nextPageToken"": ""token"",
311-
""users"": [
312-
{""localId"": ""user1""},
313-
{""localId"": ""user2""},
314-
{""localId"": ""user3""}
315-
]
316-
}",
317-
@"{
318-
""users"": [
319-
{""localId"": ""user4""},
320-
{""localId"": ""user5""},
321-
{""localId"": ""user6""}
322-
]
323-
}",
324-
},
325+
Response = ListUsersResponse,
325326
};
326327
var userManager = this.CreateFirebaseUserManager(handler);
327328
var users = new List<ExportedUserRecord>();
@@ -334,7 +335,7 @@ public async Task ListUsersPaged()
334335
pageCounter++;
335336
tokens.Add(userPage.NextPageToken);
336337
users.AddRange(userPage);
337-
if (string.IsNullOrEmpty(userPage.NextPageToken))
338+
if (userPage.NextPageToken == null)
338339
{
339340
break;
340341
}
@@ -352,15 +353,12 @@ public async Task ListUsersPaged()
352353
Assert.Equal("user6", users[5].Uid);
353354

354355
Assert.Equal(2, handler.Requests.Count);
355-
var req = handler.Requests[0];
356-
var query = req.Url.Query.Substring(1).Split('&').ToDictionary(
357-
entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
356+
var query = this.ExtractQueryParams(handler.Requests[0]);
357+
Assert.Single(query);
358358
Assert.Equal("3", query["maxResults"]);
359-
Assert.Equal(string.Empty, query["nextPageToken"]);
360359

361-
req = handler.Requests[1];
362-
query = req.Url.Query.Substring(1).Split('&').ToDictionary(
363-
entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
360+
query = this.ExtractQueryParams(handler.Requests[1]);
361+
Assert.Equal(2, query.Count);
364362
Assert.Equal("3", query["maxResults"]);
365363
Assert.Equal("token", query["nextPageToken"]);
366364
}
@@ -370,29 +368,12 @@ public void ListUsersByEntries()
370368
{
371369
var handler = new MockMessageHandler()
372370
{
373-
Response = new List<string>()
374-
{
375-
@"{
376-
""nextPageToken"": ""token"",
377-
""users"": [
378-
{""localId"": ""user1""},
379-
{""localId"": ""user2""},
380-
{""localId"": ""user3""}
381-
]
382-
}",
383-
@"{
384-
""users"": [
385-
{""localId"": ""user4""},
386-
{""localId"": ""user5""},
387-
{""localId"": ""user6""}
388-
]
389-
}",
390-
},
371+
Response = ListUsersResponse,
391372
};
392373
var userManager = this.CreateFirebaseUserManager(handler);
393-
394-
var pagedEnumerable = userManager.ListUsers(new ListUsersOptions());
395374
var users = new List<ExportedUserRecord>();
375+
376+
var pagedEnumerable = userManager.ListUsers(null);
396377
foreach (var user in pagedEnumerable.ToEnumerable())
397378
{
398379
users.Add(user);
@@ -407,15 +388,99 @@ public void ListUsersByEntries()
407388
Assert.Equal("user6", users[5].Uid);
408389

409390
Assert.Equal(2, handler.Requests.Count);
410-
var req = handler.Requests[0];
411-
var query = req.Url.Query.Substring(1).Split('&').ToDictionary(
412-
entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
391+
var query = this.ExtractQueryParams(handler.Requests[0]);
392+
Assert.Single(query);
413393
Assert.Equal("1000", query["maxResults"]);
414-
Assert.Equal(string.Empty, query["nextPageToken"]);
415394

416-
req = handler.Requests[1];
417-
query = req.Url.Query.Substring(1).Split('&').ToDictionary(
418-
entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
395+
query = this.ExtractQueryParams(handler.Requests[1]);
396+
Assert.Equal(2, query.Count);
397+
Assert.Equal("1000", query["maxResults"]);
398+
Assert.Equal("token", query["nextPageToken"]);
399+
}
400+
401+
[Fact]
402+
public void ListUsersPageSizeTooLarge()
403+
{
404+
var handler = new MockMessageHandler()
405+
{
406+
Response = ListUsersResponse,
407+
};
408+
var userManager = this.CreateFirebaseUserManager(handler);
409+
var options = new ListUsersOptions()
410+
{
411+
PageSize = 1001,
412+
};
413+
414+
Assert.Throws<ArgumentException>(() => userManager.ListUsers(options));
415+
Assert.Empty(handler.Requests);
416+
}
417+
418+
[Fact]
419+
public void ListUsersPageSizeZero()
420+
{
421+
var handler = new MockMessageHandler()
422+
{
423+
Response = ListUsersResponse,
424+
};
425+
var userManager = this.CreateFirebaseUserManager(handler);
426+
var options = new ListUsersOptions()
427+
{
428+
PageSize = 0,
429+
};
430+
431+
Assert.Throws<ArgumentException>(() => userManager.ListUsers(options));
432+
Assert.Empty(handler.Requests);
433+
}
434+
435+
[Fact]
436+
public void ListUsersPageSizeNegative()
437+
{
438+
var handler = new MockMessageHandler()
439+
{
440+
Response = ListUsersResponse,
441+
};
442+
var userManager = this.CreateFirebaseUserManager(handler);
443+
var options = new ListUsersOptions()
444+
{
445+
PageSize = -1,
446+
};
447+
448+
Assert.Throws<ArgumentException>(() => userManager.ListUsers(options));
449+
Assert.Empty(handler.Requests);
450+
}
451+
452+
[Fact]
453+
public void ListUsersAsRawResponses()
454+
{
455+
var handler = new MockMessageHandler()
456+
{
457+
Response = ListUsersResponse,
458+
};
459+
var userManager = this.CreateFirebaseUserManager(handler);
460+
var users = new List<ExportedUserRecord>();
461+
462+
var pagedEnumerable = userManager.ListUsers(null);
463+
var responses = pagedEnumerable.AsRawResponses();
464+
foreach (var records in responses.ToEnumerable())
465+
{
466+
users.AddRange(records.Users);
467+
}
468+
469+
Assert.Equal(6, users.Count);
470+
Assert.Equal("user1", users[0].Uid);
471+
Assert.Equal("user2", users[1].Uid);
472+
Assert.Equal("user3", users[2].Uid);
473+
Assert.Equal("user4", users[3].Uid);
474+
Assert.Equal("user5", users[4].Uid);
475+
Assert.Equal("user6", users[5].Uid);
476+
477+
Assert.Equal(2, handler.Requests.Count);
478+
var query = this.ExtractQueryParams(handler.Requests[0]);
479+
Assert.Single(query);
480+
Assert.Equal("1000", query["maxResults"]);
481+
482+
query = this.ExtractQueryParams(handler.Requests[1]);
483+
Assert.Equal(2, query.Count);
419484
Assert.Equal("1000", query["maxResults"]);
420485
Assert.Equal("token", query["nextPageToken"]);
421486
}
@@ -450,11 +515,9 @@ public async Task ListUsers()
450515
Assert.Equal("user3", userRecords[2].Uid);
451516

452517
Assert.Single(handler.Requests);
453-
var req = handler.Requests[0];
454-
var query = req.Url.Query.Substring(1).Split('&').ToDictionary(
455-
entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
518+
var query = this.ExtractQueryParams(handler.Requests[0]);
519+
Assert.Single(query);
456520
Assert.Equal("3", query["maxResults"]);
457-
Assert.Equal(string.Empty, query["nextPageToken"]);
458521
}
459522

460523
[Fact]
@@ -484,33 +547,11 @@ public void ListUsersMaxDefault()
484547
Assert.Equal("user3", userRecords[2].Uid);
485548
Assert.Single(handler.Requests);
486549

487-
var req = handler.Requests[0];
488-
var query = req.Url.Query.Substring(1).Split('&').ToDictionary(
489-
entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
550+
var query = this.ExtractQueryParams(handler.Requests[0]);
551+
Assert.Single(query);
490552
Assert.Equal("1000", query["maxResults"]);
491-
Assert.Equal(string.Empty, query["nextPageToken"]);
492553
}
493554

494-
/* [Fact]
495-
public void ListUsersRequestOptionsAreSet()
496-
{
497-
var userManager = this.CreateFirebaseUserManager(new MockMessageHandler());
498-
499-
var listUsersRequest = userManager.CreateListUserRequest(new ListUsersOptions());
500-
501-
// by default they are set
502-
Assert.True(listUsersRequest.RequestParameters.ContainsKey("maxResults"));
503-
Assert.True(listUsersRequest.RequestParameters.ContainsKey("nextPageToken"));
504-
Assert.Equal(FirebaseUserManager.MaxListUsersResults, int.Parse(listUsersRequest.RequestParameters["maxResults"].DefaultValue));
505-
Assert.Null(listUsersRequest.RequestParameters["nextPageToken"].DefaultValue);
506-
507-
// change the values and check again
508-
listUsersRequest.SetPageSize(10);
509-
listUsersRequest.SetPageToken("theNewNextPageToken");
510-
Assert.Equal(10, int.Parse(listUsersRequest.RequestParameters["maxResults"].DefaultValue));
511-
Assert.Equal("theNewNextPageToken", listUsersRequest.RequestParameters["nextPageToken"].DefaultValue);
512-
} */
513-
514555
[Fact]
515556
public async Task CreateUser()
516557
{
@@ -1219,5 +1260,11 @@ private FirebaseUserManager CreateFirebaseUserManager(HttpMessageHandler handler
12191260
};
12201261
return new FirebaseUserManager(args);
12211262
}
1263+
1264+
private IDictionary<string, string> ExtractQueryParams(MockMessageHandler.IncomingRequest req)
1265+
{
1266+
return req.Url.Query.Substring(1).Split('&').ToDictionary(
1267+
entry => entry.Split('=')[0], entry => entry.Split('=')[1]);
1268+
}
12221269
}
12231270
}

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseAuth.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -526,15 +526,18 @@ public async Task SetCustomUserClaimsAsync(
526526
}
527527

528528
/// <summary>
529-
/// Gets an async enumerable to page users starting from the specified pageToken. If the pageToken is empty, it starts from the first page.
529+
/// Gets an async enumerable to iterate or page through users starting from the specified
530+
/// page token. If the page token is null or unspecified, iteration starts from the first
531+
/// page.
530532
/// </summary>
531-
/// <param name="requestOptions">The options for the next remote call.</param>
532-
/// <returns>A <see cref="PagedAsyncEnumerable{DownloadAccountResponse, UserRecord}"/> instance.</returns>
533-
public PagedAsyncEnumerable<ExportedUserRecords, ExportedUserRecord> ListUsersAsync(ListUsersOptions requestOptions)
533+
/// <param name="options">The options to control the starting point and page size.</param>
534+
/// <returns>A <see cref="PagedAsyncEnumerable{ExportedUserRecords, ExportedUserRecord}"/> instance.</returns>
535+
public PagedAsyncEnumerable<ExportedUserRecords, ExportedUserRecord> ListUsersAsync(
536+
ListUsersOptions options)
534537
{
535538
var userManager = this.IfNotDeleted(() => this.userManager.Value);
536539

537-
return userManager.ListUsers(requestOptions);
540+
return userManager.ListUsers(options);
538541
}
539542

540543
/// <summary>

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseUserManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2019, Google Inc. All rights reserved.
1+
// Copyright 2019, Google Inc. All rights reserved.
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -140,9 +140,9 @@ internal async Task<UserRecord> GetUserByPhoneNumberAsync(
140140
}
141141

142142
internal PagedAsyncEnumerable<ExportedUserRecords, ExportedUserRecord> ListUsers(
143-
ListUsersOptions requestOptions)
143+
ListUsersOptions options)
144144
{
145-
var request = new ListUsersRequest(this.baseUrl, this.httpClient, requestOptions);
145+
var request = new ListUsersRequest(this.baseUrl, this.httpClient, options);
146146
return new RestPagedAsyncEnumerable<ListUsersRequest, ExportedUserRecords, ExportedUserRecord>(
147147
() => request, new ListUsersPageManager());
148148
}

FirebaseAdmin/FirebaseAdmin/Auth/ListUsersOptions.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,25 @@ namespace FirebaseAdmin.Auth
2121
/// </summary>
2222
public sealed class ListUsersOptions
2323
{
24+
/// <summary>
25+
/// Initializes a new instance of the <see cref="ListUsersOptions"/> class.
26+
/// </summary>
27+
public ListUsersOptions() { }
28+
29+
internal ListUsersOptions(ListUsersOptions source)
30+
{
31+
this.PageSize = source?.PageSize;
32+
this.PageToken = source?.PageToken;
33+
}
34+
2435
/// <summary>
2536
/// Gets or sets the number of results to return per page. This modifies the per-request page size.
26-
/// It does not affect the total number of results returned.
37+
/// It does not affect the total number of results returned. Must not exceed 1000.
2738
/// </summary>
2839
public int? PageSize { get; set; }
2940

3041
/// <summary>
31-
/// Gets or sets the page-token. If set, this token is used to indicate a continued list operation.
32-
/// The value should be taken from the <c>NextPageToken</c> property of either a
33-
/// <see cref="Page{TResource}"/> or a raw response from
34-
/// <see cref="PagedEnumerable{TResponse, TResource}.AsRawResponses"/>.
42+
/// Gets or sets the page token. If set, this token is used to indicate a continued list operation.
3543
/// </summary>
3644
public string PageToken { get; set; }
3745
}

FirebaseAdmin/FirebaseAdmin/Auth/ListUsersPageManager.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,7 @@ public void SetPageToken(ListUsersRequest request, string pageToken)
3434

3535
public IEnumerable<ExportedUserRecord> GetResources(ExportedUserRecords response)
3636
{
37-
if (response?.Users == null)
38-
{
39-
return new ExportedUserRecord[0];
40-
}
41-
42-
return response.Users;
37+
return response?.Users;
4338
}
4439

4540
public string GetNextPageToken(ExportedUserRecords response)

0 commit comments

Comments
 (0)