Skip to content

Commit b53ea31

Browse files
authored
chore: Moving GetUsersTest to a top-level class (#219)
* chore: Moving GetUsersTest to a top-level class * fix: Updated preconditio check and comments
1 parent 227a988 commit b53ea31

File tree

5 files changed

+256
-117
lines changed

5 files changed

+256
-117
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// Copyright 2020, Google Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using System.Threading.Tasks;
19+
using FirebaseAdmin.Auth;
20+
using Xunit;
21+
22+
namespace FirebaseAdmin.IntegrationTests.Auth
23+
{
24+
public class GetUsersTest : IClassFixture<GetUsersFixture>
25+
{
26+
private readonly GetUsersFixture fixture;
27+
28+
public GetUsersTest(GetUsersFixture fixture)
29+
{
30+
this.fixture = fixture;
31+
}
32+
33+
[Fact]
34+
public async void VariousIdentifiers()
35+
{
36+
var getUsersResult = await FirebaseAuth.DefaultInstance.GetUsersAsync(
37+
new List<UserIdentifier>()
38+
{
39+
new UidIdentifier(this.fixture.TestUser1.Uid),
40+
new EmailIdentifier(this.fixture.TestUser2.Email),
41+
new PhoneIdentifier(this.fixture.TestUser3.PhoneNumber),
42+
new ProviderIdentifier("google.com", $"google_{this.fixture.ImportUserUid}"),
43+
});
44+
45+
var uids = getUsersResult.Users.Select(userRecord => userRecord.Uid);
46+
var expectedUids = new List<string>()
47+
{
48+
this.fixture.TestUser1.Uid,
49+
this.fixture.TestUser2.Uid,
50+
this.fixture.TestUser3.Uid,
51+
this.fixture.ImportUserUid,
52+
};
53+
Assert.Equal(expectedUids.Count(), uids.Count());
54+
Assert.All(expectedUids, expectedUid => uids.Contains(expectedUid));
55+
Assert.Empty(getUsersResult.NotFound);
56+
}
57+
58+
[Fact]
59+
public async void IgnoresNonExistingUsers()
60+
{
61+
var doesntExistId = new UidIdentifier("uid_that_doesnt_exist");
62+
var getUsersResult = await FirebaseAuth.DefaultInstance.GetUsersAsync(
63+
new List<UserIdentifier>()
64+
{
65+
new UidIdentifier(this.fixture.TestUser1.Uid),
66+
doesntExistId,
67+
new UidIdentifier(this.fixture.TestUser3.Uid),
68+
});
69+
70+
var uids = getUsersResult.Users.Select(userRecord => userRecord.Uid);
71+
var expectedUids = new List<string>()
72+
{
73+
this.fixture.TestUser1.Uid,
74+
this.fixture.TestUser3.Uid,
75+
};
76+
Assert.Equal(expectedUids.Count(), uids.Count());
77+
Assert.All(expectedUids, expectedUid => uids.Contains(expectedUid));
78+
Assert.Single(getUsersResult.NotFound, doesntExistId);
79+
}
80+
81+
[Fact]
82+
public async void OnlyNonExistingUsers()
83+
{
84+
var doesntExistId = new UidIdentifier("uid_that_doesnt_exist");
85+
var getUsersResult = await FirebaseAuth.DefaultInstance.GetUsersAsync(
86+
new List<UserIdentifier>()
87+
{
88+
doesntExistId,
89+
});
90+
91+
Assert.Empty(getUsersResult.Users);
92+
Assert.Single(getUsersResult.NotFound, doesntExistId);
93+
}
94+
95+
[Fact]
96+
public async void DedupsDuplicateUsers()
97+
{
98+
var getUsersResult = await FirebaseAuth.DefaultInstance.GetUsersAsync(
99+
new List<UserIdentifier>()
100+
{
101+
new UidIdentifier(this.fixture.TestUser1.Uid),
102+
new UidIdentifier(this.fixture.TestUser1.Uid),
103+
});
104+
105+
var uids = getUsersResult.Users.Select(userRecord => userRecord.Uid);
106+
Assert.Single(uids, this.fixture.TestUser1.Uid);
107+
Assert.Empty(getUsersResult.NotFound);
108+
}
109+
}
110+
111+
public class GetUsersFixture : IDisposable
112+
{
113+
private readonly TemporaryUserBuilder userBuilder = new TemporaryUserBuilder();
114+
115+
public GetUsersFixture()
116+
{
117+
this.TestUser1 = this.userBuilder.CreateRandomUserAsync().Result;
118+
this.TestUser2 = this.userBuilder.CreateRandomUserAsync().Result;
119+
this.TestUser3 = this.userBuilder.CreateRandomUserAsync().Result;
120+
this.ImportUserUid = this.ImportUserWithProviderAsync().Result;
121+
}
122+
123+
public UserRecord TestUser1 { get; }
124+
125+
public UserRecord TestUser2 { get; }
126+
127+
public UserRecord TestUser3 { get; }
128+
129+
public string ImportUserUid { get; }
130+
131+
public void Dispose()
132+
{
133+
this.userBuilder.Dispose();
134+
}
135+
136+
private async Task<string> ImportUserWithProviderAsync()
137+
{
138+
var randomArgs = TemporaryUserBuilder.RandomUserRecordArgs();
139+
var importUser = new ImportUserRecordArgs()
140+
{
141+
Uid = randomArgs.Uid,
142+
Email = randomArgs.Email,
143+
PhoneNumber = randomArgs.PhoneNumber,
144+
UserProviders = new List<UserProvider>()
145+
{
146+
new UserProvider()
147+
{
148+
Uid = $"google_{randomArgs.Uid}",
149+
ProviderId = "google.com",
150+
},
151+
},
152+
};
153+
154+
var result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(
155+
new List<ImportUserRecordArgs>()
156+
{
157+
importUser,
158+
});
159+
Assert.Equal(1, result.SuccessCount);
160+
this.userBuilder.AddUid(randomArgs.Uid);
161+
return randomArgs.Uid;
162+
}
163+
}
164+
}

FirebaseAdmin/FirebaseAdmin.IntegrationTests/OidcProviderConfigTest.cs renamed to FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
using FirebaseAdmin.Auth.Providers;
2121
using Xunit;
2222

23-
namespace FirebaseAdmin.IntegrationTests
23+
namespace FirebaseAdmin.IntegrationTests.Auth
2424
{
2525
[TestCaseOrderer(
2626
"FirebaseAdmin.IntegrationTests.TestRankOrderer", "FirebaseAdmin.IntegrationTests")]

FirebaseAdmin/FirebaseAdmin.IntegrationTests/SamlProviderConfigTest.cs renamed to FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/SamlProviderConfigTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
using FirebaseAdmin.Auth.Providers;
1919
using Xunit;
2020

21-
namespace FirebaseAdmin.IntegrationTests
21+
namespace FirebaseAdmin.IntegrationTests.Auth
2222
{
2323
[TestCaseOrderer(
2424
"FirebaseAdmin.IntegrationTests.TestRankOrderer", "FirebaseAdmin.IntegrationTests")]
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright 2020, Google Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using System.Threading;
19+
using System.Threading.Tasks;
20+
using FirebaseAdmin.Auth;
21+
22+
namespace FirebaseAdmin.IntegrationTests.Auth
23+
{
24+
/// <summary>
25+
/// A utility for creating temporary user accounts during tests. Keeps track of the user
26+
/// accounts created, and deletes them on dispose. Other user accounts created outside this
27+
/// class can be marked for deletion using the <see cref="AddUid(string)"/> method. This class
28+
/// deletes user accounts in an idempotent manner. Therefore it's safe to delete any of the
29+
/// user accounts created by this class before this instance is disposed. This class is not
30+
/// thread safe. Any concurrent usage should be synchronized accordingly.
31+
/// <summary>
32+
public sealed class TemporaryUserBuilder : IDisposable
33+
{
34+
private readonly ISet<string> userIds = new HashSet<string>();
35+
36+
public TemporaryUserBuilder()
37+
{
38+
IntegrationTestUtils.EnsureDefaultApp();
39+
}
40+
41+
public static UserRecordArgs RandomUserRecordArgs()
42+
{
43+
var uid = Guid.NewGuid().ToString().Replace("-", string.Empty);
44+
var rand = new Random();
45+
var phoneDigits = Enumerable.Range(0, 10).Select(_ => rand.Next(10));
46+
47+
return new UserRecordArgs()
48+
{
49+
Uid = uid,
50+
Email = $"test{uid.Substring(0, 12)}@example.{uid.Substring(12)}.com",
51+
PhoneNumber = $"+1{string.Join(string.Empty, phoneDigits)}",
52+
DisplayName = "Random User",
53+
PhotoUrl = "https://example.com/photo.png",
54+
Password = "password",
55+
};
56+
}
57+
58+
public async Task<UserRecord> CreateRandomUserAsync()
59+
{
60+
return await this.CreateUserAsync(RandomUserRecordArgs());
61+
}
62+
63+
public async Task<UserRecord> CreateUserAsync(UserRecordArgs args)
64+
{
65+
// Make sure we never create more than 1000 users in a single instance.
66+
// This allows us to delete all user accounts with a single call to DeleteUsers().
67+
// Should not ever occur in practice.
68+
if (this.userIds.Count() >= 1000)
69+
{
70+
throw new InvalidOperationException("Maximum number of users reached.");
71+
}
72+
73+
var user = await FirebaseAuth.DefaultInstance.CreateUserAsync(args);
74+
this.AddUid(user.Uid);
75+
return user;
76+
}
77+
78+
public bool AddUid(string uid)
79+
{
80+
return this.userIds.Add(uid);
81+
}
82+
83+
public void Dispose()
84+
{
85+
Thread.Sleep(1000); // DeleteUsers is rate limited at 1qps.
86+
FirebaseAuth.DefaultInstance.DeleteUsersAsync(this.userIds.ToList()).Wait();
87+
this.userIds.Clear();
88+
}
89+
}
90+
}

FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseAuthTest.cs

Lines changed: 0 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -888,121 +888,6 @@ private async Task<DeleteUsersResult> SlowDeleteUsersAsync(IReadOnlyList<string>
888888
await Task.Delay(millisecondsDelay: 1000);
889889
return await FirebaseAuth.DefaultInstance.DeleteUsersAsync(uids);
890890
}
891-
892-
public class GetUsersFixture : IDisposable
893-
{
894-
public GetUsersFixture()
895-
{
896-
IntegrationTestUtils.EnsureDefaultApp();
897-
898-
this.TestUser1 = NewUserWithParamsAsync().Result;
899-
this.TestUser2 = NewUserWithParamsAsync().Result;
900-
this.TestUser3 = NewUserWithParamsAsync().Result;
901-
902-
// The C# port doesn't support importing users, so unlike the other ports, there's
903-
// no way to create a user with a linked federated provider.
904-
// TODO(rsgowman): Once either FirebaseAuth.ImportUser() exists (or the UpdateUser()
905-
// method supports ProviderToLink (#143)), then use it here and
906-
// adjust the VariousIdentifiers() test below.
907-
}
908-
909-
public UserRecord TestUser1 { get; }
910-
911-
public UserRecord TestUser2 { get; }
912-
913-
public UserRecord TestUser3 { get; }
914-
915-
public void Dispose()
916-
{
917-
// TODO(rsgowman): deleteUsers (plural) would make more sense here, but it's
918-
// currently rate limited to 1qps. When/if that's relaxed, change this to just
919-
// delete them all at once.
920-
var auth = FirebaseAuth.DefaultInstance;
921-
auth.DeleteUserAsync(this.TestUser1.Uid).Wait();
922-
auth.DeleteUserAsync(this.TestUser2.Uid).Wait();
923-
auth.DeleteUserAsync(this.TestUser3.Uid).Wait();
924-
}
925-
}
926-
927-
public class GetUsers : IClassFixture<GetUsersFixture>
928-
{
929-
private FirebaseAuth auth;
930-
private UserRecord testUser1;
931-
private UserRecord testUser2;
932-
private UserRecord testUser3;
933-
934-
public GetUsers(GetUsersFixture fixture)
935-
{
936-
this.auth = FirebaseAuth.DefaultInstance;
937-
this.testUser1 = fixture.TestUser1;
938-
this.testUser2 = fixture.TestUser2;
939-
this.testUser3 = fixture.TestUser3;
940-
}
941-
942-
[Fact]
943-
public async void VariousIdentifiers()
944-
{
945-
var getUsersResult = await this.auth.GetUsersAsync(new List<UserIdentifier>()
946-
{
947-
new UidIdentifier(this.testUser1.Uid),
948-
new EmailIdentifier(this.testUser2.Email),
949-
new PhoneIdentifier(this.testUser3.PhoneNumber),
950-
// TODO(rsgowman): Once we're able to create a user with a
951-
// provider, do so above and fetch the user like this:
952-
// new ProviderIdentifier("google.com", "google_" + importUserUid),
953-
});
954-
955-
var uids = getUsersResult.Users.Select(userRecord => userRecord.Uid);
956-
var expectedUids = new List<string>() { this.testUser1.Uid, this.testUser2.Uid, this.testUser3.Uid };
957-
Assert.True(expectedUids.All(expectedUid => uids.Contains(expectedUid)));
958-
Assert.Empty(getUsersResult.NotFound);
959-
}
960-
961-
[Fact]
962-
public async void IgnoresNonExistingUsers()
963-
{
964-
var doesntExistId = new UidIdentifier("uid_that_doesnt_exist");
965-
var getUsersResult = await this.auth.GetUsersAsync(new List<UserIdentifier>()
966-
{
967-
new UidIdentifier(this.testUser1.Uid),
968-
doesntExistId,
969-
new UidIdentifier(this.testUser3.Uid),
970-
});
971-
972-
var uids = getUsersResult.Users.Select(userRecord => userRecord.Uid);
973-
var expectedUids = new List<string>() { this.testUser1.Uid, this.testUser3.Uid };
974-
Assert.True(expectedUids.All(expectedUid => uids.Contains(expectedUid)));
975-
Assert.Equal(doesntExistId, getUsersResult.NotFound.Single());
976-
}
977-
978-
[Fact]
979-
public async void OnlyNonExistingUsers()
980-
{
981-
var doesntExistId = new UidIdentifier("uid_that_doesnt_exist");
982-
var getUsersResult = await this.auth.GetUsersAsync(new List<UserIdentifier>()
983-
{
984-
doesntExistId,
985-
});
986-
987-
Assert.Empty(getUsersResult.Users);
988-
Assert.Equal(doesntExistId, getUsersResult.NotFound.Single());
989-
}
990-
991-
[Fact]
992-
public async void DedupsDuplicateUsers()
993-
{
994-
var getUsersResult = await this.auth.GetUsersAsync(new List<UserIdentifier>()
995-
{
996-
new UidIdentifier(this.testUser1.Uid),
997-
new UidIdentifier(this.testUser1.Uid),
998-
});
999-
1000-
var uids = getUsersResult.Users.Select(userRecord => userRecord.Uid);
1001-
var expectedUids = new List<string>() { this.testUser3.Uid };
1002-
Assert.Equal(this.testUser1.Uid, getUsersResult.Users.Single().Uid);
1003-
Assert.Empty(getUsersResult.NotFound);
1004-
}
1005-
}
1006891
}
1007892

1008893
/**

0 commit comments

Comments
 (0)