Skip to content

Commit 081b0a7

Browse files
committed
Added UserArgs class; Updated and cleaned up tests
1 parent 8413f25 commit 081b0a7

File tree

5 files changed

+336
-178
lines changed

5 files changed

+336
-178
lines changed

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseUserManagerTest.cs

Lines changed: 212 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
using System.Threading.Tasks;
2020
using FirebaseAdmin.Tests;
2121
using Google.Apis.Auth.OAuth2;
22+
using Google.Apis.Json;
23+
using Newtonsoft.Json.Linq;
2224
using Xunit;
2325

2426
namespace FirebaseAdmin.Auth.Tests
@@ -31,48 +33,9 @@ public class FirebaseUserManagerTest
3133
GoogleCredential.FromAccessToken("test-token");
3234

3335
[Fact]
34-
public void InvalidUidForUserRecord()
36+
public void UserRecordWithNullResponse()
3537
{
36-
Assert.Throws<ArgumentException>(() => new UserRecord((string)null));
37-
Assert.Throws<ArgumentException>(() => new UserRecord((GetAccountInfoResponse.User)null));
38-
Assert.Throws<ArgumentException>(() => new UserRecord(string.Empty));
39-
Assert.Throws<ArgumentException>(() => new UserRecord(new string('a', 129)));
40-
}
41-
42-
[Fact]
43-
public void ReservedClaims()
44-
{
45-
foreach (var key in FirebaseTokenFactory.ReservedClaims)
46-
{
47-
var customClaims = new Dictionary<string, object>()
48-
{
49-
{ key, "value" },
50-
};
51-
52-
Assert.Throws<ArgumentException>(() => new UserRecord("user1") { CustomClaims = customClaims });
53-
}
54-
}
55-
56-
[Fact]
57-
public void EmptyClaims()
58-
{
59-
var emptyClaims = new Dictionary<string, object>()
60-
{
61-
{ string.Empty, "value" },
62-
};
63-
64-
Assert.Throws<ArgumentException>(() => new UserRecord("user1") { CustomClaims = emptyClaims });
65-
}
66-
67-
[Fact]
68-
public void TooLargeClaimsPayload()
69-
{
70-
var customClaims = new Dictionary<string, object>()
71-
{
72-
{ "testClaim", new string('a', 1001) },
73-
};
74-
75-
Assert.Throws<ArgumentException>(() => new UserRecord("user1") { CustomClaims = customClaims });
38+
Assert.Throws<ArgumentException>(() => new UserRecord(null));
7639
}
7740

7841
[Fact]
@@ -98,11 +61,11 @@ public async Task GetUserById()
9861
Assert.Null(userRecord.PhoneNumber);
9962
Assert.Null(userRecord.PhotoUrl);
10063
Assert.Equal("firebase", userRecord.ProviderId);
101-
Assert.Empty(userRecord.CustomClaims);
102-
Assert.Empty(userRecord.ProviderData);
10364
Assert.False(userRecord.Disabled);
10465
Assert.False(userRecord.EmailVerified);
10566
Assert.Equal(UserRecord.UnixEpoch, userRecord.TokensValidAfterTimestamp);
67+
Assert.Empty(userRecord.CustomClaims);
68+
Assert.Empty(userRecord.ProviderData);
10669
Assert.Equal(DateTime.MinValue, userRecord.UserMetaData.CreationTimestamp);
10770
Assert.Equal(DateTime.MinValue, userRecord.UserMetaData.LastSignInTimestamp);
10871
}
@@ -160,6 +123,9 @@ public async Task GetUserByIdWithProperties()
160123
Assert.Equal("+11234567890", userRecord.PhoneNumber);
161124
Assert.Equal("https://domain.com/user.png", userRecord.PhotoUrl);
162125
Assert.Equal("firebase", userRecord.ProviderId);
126+
Assert.True(userRecord.Disabled);
127+
Assert.True(userRecord.EmailVerified);
128+
Assert.Equal(UserRecord.UnixEpoch.AddSeconds(3600), userRecord.TokensValidAfterTimestamp);
163129

164130
var claims = new Dictionary<string, object>()
165131
{
@@ -185,10 +151,6 @@ public async Task GetUserByIdWithProperties()
185151
Assert.Equal("+10987654321", provider.PhoneNumber);
186152
Assert.Equal("https://other.com/user.png", provider.PhotoUrl);
187153

188-
Assert.True(userRecord.Disabled);
189-
Assert.True(userRecord.EmailVerified);
190-
191-
Assert.Equal(UserRecord.UnixEpoch.AddSeconds(3600), userRecord.TokensValidAfterTimestamp);
192154
var metadata = userRecord.UserMetaData;
193155
Assert.NotNull(metadata);
194156
Assert.Equal(UserRecord.UnixEpoch.AddMilliseconds(100), metadata.CreationTimestamp);
@@ -200,7 +162,7 @@ public async Task GetUserByIdUserNotFound()
200162
{
201163
var handler = new MockMessageHandler()
202164
{
203-
StatusCode = HttpStatusCode.NotFound,
165+
Response = @"{""users"": []}",
204166
};
205167
var userManager = this.CreateFirebaseUserManager(handler);
206168

@@ -213,22 +175,196 @@ public async Task UpdateUser()
213175
{
214176
var handler = new MockMessageHandler()
215177
{
216-
Response = new GetAccountInfoResponse()
217-
{
218-
Kind = "identitytoolkit#GetAccountInfoResponse",
219-
Users = new List<GetAccountInfoResponse.User>()
220-
{
221-
new GetAccountInfoResponse.User() { UserId = "user1" },
222-
},
223-
},
178+
Response = @"{""localId"": ""user1""}",
224179
};
225180
var userManager = this.CreateFirebaseUserManager(handler);
226181
var customClaims = new Dictionary<string, object>()
227182
{
228183
{ "admin", true },
184+
{ "level", 4 },
185+
{ "package", "gold" },
186+
};
187+
188+
await userManager.UpdateUserAsync(new UserArgs()
189+
{
190+
Uid = "user1",
191+
CustomClaims = customClaims,
192+
});
193+
194+
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Request);
195+
Assert.Equal("user1", request["localId"]);
196+
var claims = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>((string)request["customAttributes"]);
197+
Assert.True((bool)claims["admin"]);
198+
Assert.Equal(4L, claims["level"]);
199+
Assert.Equal("gold", claims["package"]);
200+
}
201+
202+
[Fact]
203+
public async Task LargeClaimsUnderLimit()
204+
{
205+
var handler = new MockMessageHandler()
206+
{
207+
Response = @"{""localId"": ""user1""}",
229208
};
209+
var userManager = this.CreateFirebaseUserManager(handler);
210+
var customClaims = new Dictionary<string, object>()
211+
{
212+
{ "testClaim", new string('a', 950) },
213+
};
214+
215+
await userManager.UpdateUserAsync(new UserArgs()
216+
{
217+
Uid = "user1",
218+
CustomClaims = customClaims,
219+
});
220+
}
221+
222+
[Fact]
223+
public async Task EmptyClaims()
224+
{
225+
var handler = new MockMessageHandler()
226+
{
227+
Response = @"{""localId"": ""user1""}",
228+
};
229+
var userManager = this.CreateFirebaseUserManager(handler);
230+
231+
await userManager.UpdateUserAsync(new UserArgs()
232+
{
233+
Uid = "user1",
234+
CustomClaims = new Dictionary<string, object>(),
235+
});
236+
237+
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Request);
238+
Assert.Equal("user1", request["localId"]);
239+
Assert.Equal("{}", request["customAttributes"]);
240+
}
241+
242+
[Fact]
243+
public async Task NullClaims()
244+
{
245+
var handler = new MockMessageHandler()
246+
{
247+
Response = @"{""localId"": ""user1""}",
248+
};
249+
var userManager = this.CreateFirebaseUserManager(handler);
250+
251+
await userManager.UpdateUserAsync(new UserArgs()
252+
{
253+
Uid = "user1",
254+
CustomClaims = null,
255+
});
230256

231-
await userManager.UpdateUserAsync(new UserRecord("user1") { CustomClaims = customClaims });
257+
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Request);
258+
Assert.Equal("user1", request["localId"]);
259+
Assert.Equal("{}", request["customAttributes"]);
260+
}
261+
262+
[Fact]
263+
public void ReservedClaims()
264+
{
265+
var handler = new MockMessageHandler()
266+
{
267+
Response = @"{""localId"": ""user1""}",
268+
};
269+
var userManager = this.CreateFirebaseUserManager(handler);
270+
271+
foreach (var key in FirebaseTokenFactory.ReservedClaims)
272+
{
273+
var customClaims = new Dictionary<string, object>()
274+
{
275+
{ key, "value" },
276+
};
277+
278+
var args = new UserArgs()
279+
{
280+
Uid = "user1",
281+
CustomClaims = customClaims,
282+
};
283+
Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
284+
}
285+
}
286+
287+
[Fact]
288+
public void UpdateUserNoUid()
289+
{
290+
var handler = new MockMessageHandler()
291+
{
292+
Response = @"{""localId"": ""user1""}",
293+
};
294+
var userManager = this.CreateFirebaseUserManager(handler);
295+
var customClaims = new Dictionary<string, object>()
296+
{
297+
{ "key", "value" },
298+
};
299+
300+
var args = new UserArgs()
301+
{
302+
CustomClaims = customClaims,
303+
};
304+
Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
305+
}
306+
307+
[Fact]
308+
public void UpdateUserInvalidUid()
309+
{
310+
var handler = new MockMessageHandler()
311+
{
312+
Response = @"{""localId"": ""user1""}",
313+
};
314+
var userManager = this.CreateFirebaseUserManager(handler);
315+
var customClaims = new Dictionary<string, object>()
316+
{
317+
{ "key", "value" },
318+
};
319+
320+
var args = new UserArgs()
321+
{
322+
Uid = new string('a', 129),
323+
CustomClaims = customClaims,
324+
};
325+
Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
326+
}
327+
328+
[Fact]
329+
public void EmptyNameClaims()
330+
{
331+
var handler = new MockMessageHandler()
332+
{
333+
Response = @"{""localId"": ""user1""}",
334+
};
335+
var userManager = this.CreateFirebaseUserManager(handler);
336+
var emptyClaims = new Dictionary<string, object>()
337+
{
338+
{ string.Empty, "value" },
339+
};
340+
341+
var args = new UserArgs()
342+
{
343+
Uid = "user1",
344+
CustomClaims = emptyClaims,
345+
};
346+
Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
347+
}
348+
349+
[Fact]
350+
public void LargeClaimsOverLimit()
351+
{
352+
var handler = new MockMessageHandler()
353+
{
354+
Response = @"{""localId"": ""user1""}",
355+
};
356+
var userManager = this.CreateFirebaseUserManager(handler);
357+
var largeClaims = new Dictionary<string, object>()
358+
{
359+
{ "testClaim", new string('a', 1001) },
360+
};
361+
362+
var args = new UserArgs()
363+
{
364+
Uid = "user1",
365+
CustomClaims = largeClaims,
366+
};
367+
Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
232368
}
233369

234370
[Fact]
@@ -244,25 +380,33 @@ public async Task UpdateUserIncorrectResponseObject()
244380
{ "admin", true },
245381
};
246382

247-
await Assert.ThrowsAsync<FirebaseException>(
248-
async () => await userManager.UpdateUserAsync(new UserRecord("user1") { CustomClaims = customClaims }));
383+
var args = new UserArgs()
384+
{
385+
Uid = "user1",
386+
CustomClaims = customClaims,
387+
};
388+
await Assert.ThrowsAsync<FirebaseException>(async () => await userManager.UpdateUserAsync(args));
249389
}
250390

251391
[Fact]
252392
public async Task UpdateUserIncorrectResponseUid()
253393
{
254394
var handler = new MockMessageHandler()
255395
{
256-
Response = new UserRecord("testuser"),
396+
Response = @"{""localId"": ""notuser1""}",
257397
};
258398
var userManager = this.CreateFirebaseUserManager(handler);
259399
var customClaims = new Dictionary<string, object>()
260400
{
261401
{ "admin", true },
262402
};
263403

264-
await Assert.ThrowsAsync<FirebaseException>(
265-
async () => await userManager.UpdateUserAsync(new UserRecord("user1") { CustomClaims = customClaims }));
404+
var args = new UserArgs()
405+
{
406+
Uid = "user1",
407+
CustomClaims = customClaims,
408+
};
409+
await Assert.ThrowsAsync<FirebaseException>(async () => await userManager.UpdateUserAsync(args));
266410
}
267411

268412
[Fact]
@@ -277,9 +421,13 @@ public async Task UpdateUserHttpError()
277421
{
278422
{ "admin", true },
279423
};
424+
var args = new UserArgs()
425+
{
426+
Uid = "user1",
427+
CustomClaims = customClaims,
428+
};
280429

281-
await Assert.ThrowsAsync<FirebaseException>(
282-
async () => await userManager.UpdateUserAsync(new UserRecord("user1") { CustomClaims = customClaims }));
430+
await Assert.ThrowsAsync<FirebaseException>(async () => await userManager.UpdateUserAsync(args));
283431
}
284432

285433
[Fact]

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseAuth.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,9 @@ public async Task SetCustomUserClaimsAsync(
366366
string uid, IReadOnlyDictionary<string, object> claims, CancellationToken cancellationToken)
367367
{
368368
var userManager = this.IfNotDeleted(() => this.userManager.Value);
369-
var user = new UserRecord(uid)
369+
var user = new UserArgs()
370370
{
371+
Uid = uid,
371372
CustomClaims = claims,
372373
};
373374

0 commit comments

Comments
 (0)