Skip to content

Commit 2823871

Browse files
committed
Tests for UpdateUser API
1 parent 47992b5 commit 2823871

File tree

3 files changed

+285
-10
lines changed

3 files changed

+285
-10
lines changed

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseUserManagerTest.cs

Lines changed: 244 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,19 @@ public async Task CreateUserShortPassword()
501501
Assert.Null(handler.Request);
502502
}
503503

504+
[Fact]
505+
public async Task CreateUserIncorrectResponse()
506+
{
507+
var handler = new MockMessageHandler()
508+
{
509+
Response = "{}",
510+
};
511+
var userManager = this.CreateFirebaseUserManager(handler);
512+
513+
var args = new UserRecordArgs();
514+
await Assert.ThrowsAsync<FirebaseException>(async () => await userManager.CreateUserAsync(args));
515+
}
516+
504517
[Fact]
505518
public async Task UpdateUser()
506519
{
@@ -513,13 +526,114 @@ public async Task UpdateUser()
513526
{ "package", "gold" },
514527
};
515528

529+
await userManager.UpdateUserAsync(new UserRecordArgs()
530+
{
531+
CustomClaims = customClaims,
532+
Disabled = true,
533+
DisplayName = "Test User",
534+
Email = "[email protected]",
535+
EmailVerified = true,
536+
Password = "secret",
537+
PhoneNumber = "+1234567890",
538+
PhotoUrl = "https://example.com/user.png",
539+
Uid = "user1",
540+
});
541+
542+
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Request);
543+
Assert.Equal("user1", request["localId"]);
544+
Assert.True((bool)request["disableUser"]);
545+
Assert.Equal("Test User", request["displayName"]);
546+
Assert.Equal("[email protected]", request["email"]);
547+
Assert.True((bool)request["emailVerified"]);
548+
Assert.Equal("secret", request["password"]);
549+
Assert.Equal("+1234567890", request["phoneNumber"]);
550+
Assert.Equal("https://example.com/user.png", request["photoUrl"]);
551+
552+
var claims = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>((string)request["customAttributes"]);
553+
Assert.True((bool)claims["admin"]);
554+
Assert.Equal(4L, claims["level"]);
555+
Assert.Equal("gold", claims["package"]);
556+
}
557+
558+
[Fact]
559+
public async Task UpdateUserPartial()
560+
{
561+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
562+
var userManager = this.CreateFirebaseUserManager(handler);
563+
564+
await userManager.UpdateUserAsync(new UserRecordArgs()
565+
{
566+
EmailVerified = true,
567+
Uid = "user1",
568+
});
569+
570+
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Request);
571+
Assert.Equal(2, request.Count);
572+
Assert.Equal("user1", request["localId"]);
573+
Assert.True((bool)request["emailVerified"]);
574+
}
575+
576+
[Fact]
577+
public async Task UpdateUserRemoveAttributes()
578+
{
579+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
580+
var userManager = this.CreateFirebaseUserManager(handler);
581+
582+
await userManager.UpdateUserAsync(new UserRecordArgs()
583+
{
584+
DisplayName = null,
585+
PhotoUrl = null,
586+
Uid = "user1",
587+
});
588+
589+
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Request);
590+
Assert.Equal(2, request.Count);
591+
Assert.Equal("user1", request["localId"]);
592+
Assert.Equal(
593+
new JArray() { "DISPLAY_NAME", "PHOTO_URL" },
594+
request["deleteAttribute"]);
595+
}
596+
597+
[Fact]
598+
public async Task UpdateUserRemoveProviders()
599+
{
600+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
601+
var userManager = this.CreateFirebaseUserManager(handler);
602+
603+
await userManager.UpdateUserAsync(new UserRecordArgs()
604+
{
605+
PhoneNumber = null,
606+
Uid = "user1",
607+
});
608+
609+
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Request);
610+
Assert.Equal(2, request.Count);
611+
Assert.Equal("user1", request["localId"]);
612+
Assert.Equal(
613+
new JArray() { "phone" },
614+
request["deleteProvider"]);
615+
}
616+
617+
[Fact]
618+
public async Task UpdateUserSetCustomClaims()
619+
{
620+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
621+
var userManager = this.CreateFirebaseUserManager(handler);
622+
var customClaims = new Dictionary<string, object>()
623+
{
624+
{ "admin", true },
625+
{ "level", 4 },
626+
{ "package", "gold" },
627+
};
628+
516629
await userManager.UpdateUserAsync(new UserRecordArgs()
517630
{
518631
Uid = "user1",
519632
CustomClaims = customClaims,
520633
});
521634

522635
var request = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>(handler.Request);
636+
Assert.Equal(2, request.Count);
523637
Assert.Equal("user1", request["localId"]);
524638
var claims = NewtonsoftJsonSerializer.Instance.Deserialize<JObject>((string)request["customAttributes"]);
525639
Assert.True((bool)claims["admin"]);
@@ -605,34 +719,155 @@ public void UpdateUserNoUid()
605719
{
606720
var handler = new MockMessageHandler() { Response = CreateUserResponse };
607721
var userManager = this.CreateFirebaseUserManager(handler);
608-
var customClaims = new Dictionary<string, object>()
722+
723+
var args = new UserRecordArgs()
609724
{
610-
{ "key", "value" },
725+
EmailVerified = true,
611726
};
727+
Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
728+
}
729+
730+
[Fact]
731+
public void UpdateUserInvalidUid()
732+
{
733+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
734+
var userManager = this.CreateFirebaseUserManager(handler);
612735

613736
var args = new UserRecordArgs()
614737
{
615-
CustomClaims = customClaims,
738+
EmailVerified = true,
739+
Uid = new string('a', 129),
616740
};
617741
Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
618742
}
619743

620744
[Fact]
621-
public void UpdateUserInvalidUid()
745+
public async Task UpdateUserEmptyUid()
622746
{
623747
var handler = new MockMessageHandler() { Response = CreateUserResponse };
624748
var userManager = this.CreateFirebaseUserManager(handler);
625-
var customClaims = new Dictionary<string, object>()
749+
var args = new UserRecordArgs()
626750
{
627-
{ "key", "value" },
751+
Uid = string.Empty,
628752
};
629753

754+
await Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
755+
Assert.Null(handler.Request);
756+
}
757+
758+
[Fact]
759+
public async Task UpdateUserEmptyEmail()
760+
{
761+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
762+
var userManager = this.CreateFirebaseUserManager(handler);
630763
var args = new UserRecordArgs()
631764
{
632-
Uid = new string('a', 129),
633-
CustomClaims = customClaims,
765+
Email = string.Empty,
766+
Uid = "user1",
634767
};
635-
Assert.ThrowsAsync<ArgumentException>(async () => await userManager.UpdateUserAsync(args));
768+
769+
await Assert.ThrowsAsync<ArgumentException>(
770+
async () => await userManager.UpdateUserAsync(args));
771+
Assert.Null(handler.Request);
772+
}
773+
774+
[Fact]
775+
public async Task UpdateUserInvalidEmail()
776+
{
777+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
778+
var userManager = this.CreateFirebaseUserManager(handler);
779+
var args = new UserRecordArgs()
780+
{
781+
Email = "not-an-email",
782+
Uid = "user1",
783+
};
784+
785+
await Assert.ThrowsAsync<ArgumentException>(
786+
async () => await userManager.UpdateUserAsync(args));
787+
Assert.Null(handler.Request);
788+
}
789+
790+
[Fact]
791+
public async Task UpdateUserEmptyPhoneNumber()
792+
{
793+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
794+
var userManager = this.CreateFirebaseUserManager(handler);
795+
var args = new UserRecordArgs()
796+
{
797+
PhoneNumber = string.Empty,
798+
Uid = "user1",
799+
};
800+
801+
await Assert.ThrowsAsync<ArgumentException>(
802+
async () => await userManager.UpdateUserAsync(args));
803+
Assert.Null(handler.Request);
804+
}
805+
806+
[Fact]
807+
public async Task UpdateUserInvalidPhoneNumber()
808+
{
809+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
810+
var userManager = this.CreateFirebaseUserManager(handler);
811+
var args = new UserRecordArgs()
812+
{
813+
PhoneNumber = "1234567890",
814+
Uid = "user1",
815+
};
816+
817+
var exception = await Assert.ThrowsAsync<ArgumentException>(
818+
async () => await userManager.UpdateUserAsync(args));
819+
Assert.Equal(
820+
"Phone number must be a valid, E.164 compliant identifier starting with a '+' sign.",
821+
exception.Message);
822+
Assert.Null(handler.Request);
823+
}
824+
825+
[Fact]
826+
public async Task UpdateUserEmptyPhotoUrl()
827+
{
828+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
829+
var userManager = this.CreateFirebaseUserManager(handler);
830+
var args = new UserRecordArgs()
831+
{
832+
PhotoUrl = string.Empty,
833+
Uid = "user1",
834+
};
835+
836+
await Assert.ThrowsAsync<ArgumentException>(
837+
async () => await userManager.UpdateUserAsync(args));
838+
Assert.Null(handler.Request);
839+
}
840+
841+
[Fact]
842+
public async Task UpdateUserInvalidPhotoUrl()
843+
{
844+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
845+
var userManager = this.CreateFirebaseUserManager(handler);
846+
var args = new UserRecordArgs()
847+
{
848+
PhotoUrl = "not a url",
849+
Uid = "user1",
850+
};
851+
852+
var exception = await Assert.ThrowsAsync<ArgumentException>(
853+
async () => await userManager.UpdateUserAsync(args));
854+
Assert.Null(handler.Request);
855+
}
856+
857+
[Fact]
858+
public async Task UpdateUserShortPassword()
859+
{
860+
var handler = new MockMessageHandler() { Response = CreateUserResponse };
861+
var userManager = this.CreateFirebaseUserManager(handler);
862+
var args = new UserRecordArgs()
863+
{
864+
Password = "only5",
865+
Uid = "user1",
866+
};
867+
868+
var exception = await Assert.ThrowsAsync<ArgumentException>(
869+
async () => await userManager.UpdateUserAsync(args));
870+
Assert.Null(handler.Request);
636871
}
637872

638873
[Fact]

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseAuth.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,44 @@ public async Task<UserRecord> GetUserByPhoneNumberAsync(
403403
.ConfigureAwait(false);
404404
}
405405

406+
/// <summary>
407+
/// Updates an existing user account with the attributes contained in the specified <see cref="UserRecordArgs"/>.
408+
/// The <see cref="UserRecordArgs.Uid"/> property must be specified.
409+
/// </summary>
410+
/// <param name="args">Attributes that will be updated.</param>
411+
/// <returns>A task that completes with a <see cref="UserRecord"/> representing
412+
/// the updated user account.</returns>
413+
/// <exception cref="ArgumentNullException">If <paramref name="args"/> is null.</exception>
414+
/// <exception cref="ArgumentException">If any of the values in <paramref name="args"/> are invalid.</exception>
415+
/// <exception cref="FirebaseException">If an error occurs while updating the user account.</exception>
416+
public async Task<UserRecord> UpdateUserAsync(UserRecordArgs args)
417+
{
418+
return await this.UpdateUserAsync(args, default(CancellationToken))
419+
.ConfigureAwait(false);
420+
}
421+
422+
/// <summary>
423+
/// Updates an existing user account with the attributes contained in the specified <see cref="UserRecordArgs"/>.
424+
/// The <see cref="UserRecordArgs.Uid"/> property must be specified.
425+
/// </summary>
426+
/// <param name="args">Attributes that will be updated.</param>
427+
/// <param name="cancellationToken">A cancellation token to monitor the asynchronous
428+
/// operation.</param>
429+
/// <returns>A task that completes with a <see cref="UserRecord"/> representing
430+
/// the updated user account.</returns>
431+
/// <exception cref="ArgumentNullException">If <paramref name="args"/> is null.</exception>
432+
/// <exception cref="ArgumentException">If any of the values in <paramref name="args"/> are invalid.</exception>
433+
/// <exception cref="FirebaseException">If an error occurs while updating the user account.</exception>
434+
public async Task<UserRecord> UpdateUserAsync(
435+
UserRecordArgs args, CancellationToken cancellationToken)
436+
{
437+
var userManager = this.IfNotDeleted(() => this.userManager.Value);
438+
var uid = await userManager.UpdateUserAsync(args, cancellationToken)
439+
.ConfigureAwait(false);
440+
return await userManager.GetUserByIdAsync(uid, cancellationToken)
441+
.ConfigureAwait(false);
442+
}
443+
406444
/// <summary>
407445
/// Deletes the user identified by the specified <paramref name="uid"/>.
408446
/// </summary>

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseUserManager.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ internal async Task<string> CreateUserAsync(
168168
/// <param name="args">The user account data to be updated.</param>
169169
/// <param name="cancellationToken">A cancellation token to monitor the asynchronous
170170
/// operation.</param>
171-
internal async Task UpdateUserAsync(
171+
internal async Task<string> UpdateUserAsync(
172172
UserRecordArgs args, CancellationToken cancellationToken = default(CancellationToken))
173173
{
174174
var payload = args.ToUpdateUserRequest();
@@ -178,6 +178,8 @@ internal async Task UpdateUserAsync(
178178
{
179179
throw new FirebaseException($"Failed to update user: {payload.Uid}");
180180
}
181+
182+
return payload.Uid;
181183
}
182184

183185
/// <summary>

0 commit comments

Comments
 (0)