From 05ccb4d8f1bbe3fb64e117136b4a89bcfb0b0b33 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 27 Oct 2020 19:21:35 +0800 Subject: Split front and back end. --- BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs | 447 +++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs (limited to 'BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs') diff --git a/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs new file mode 100644 index 00000000..9dfcc6a5 --- /dev/null +++ b/BackEnd/Timeline.Tests/IntegratedTests/UserTest.cs @@ -0,0 +1,447 @@ +using FluentAssertions; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Timeline.Models.Http; +using Timeline.Tests.Helpers; +using Xunit; + +namespace Timeline.Tests.IntegratedTests +{ + public class UserTest : IntegratedTestBase + { + [Fact] + public void UserListShouldHaveUniqueId() + { + foreach (var user in UserInfos) + { + user.UniqueId.Should().NotBeNullOrWhiteSpace(); + } + } + + [Fact] + public async Task GetList_NoAuth() + { + using var client = await CreateDefaultClient(); + var res = await client.GetAsync("users"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which.Should().BeEquivalentTo(UserInfos); + } + + [Fact] + public async Task GetList_User() + { + using var client = await CreateClientAsUser(); + var res = await client.GetAsync("users"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which.Should().BeEquivalentTo(UserInfos); + } + + [Fact] + public async Task GetList_Admin() + { + using var client = await CreateClientAsAdministrator(); + var res = await client.GetAsync("users"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which.Should().BeEquivalentTo(UserInfos); + } + + [Fact] + public async Task Get_NoAuth() + { + using var client = await CreateDefaultClient(); + var res = await client.GetAsync($"users/admin"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which.Should().BeEquivalentTo(UserInfos[0]); + } + + [Fact] + public async Task Get_User() + { + using var client = await CreateClientAsUser(); + var res = await client.GetAsync($"users/admin"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which.Should().BeEquivalentTo(UserInfos[0]); + } + + [Fact] + public async Task Get_Admin() + { + using var client = await CreateClientAsAdministrator(); + var res = await client.GetAsync($"users/user1"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which.Should().BeEquivalentTo(UserInfos[1]); + } + + [Fact] + public async Task Get_InvalidModel() + { + using var client = await CreateClientAsUser(); + var res = await client.GetAsync("users/aaa!a"); + res.Should().BeInvalidModel(); + } + + [Fact] + public async Task Get_404() + { + using var client = await CreateClientAsUser(); + var res = await client.GetAsync("users/usernotexist"); + res.Should().HaveStatusCode(404) + .And.HaveCommonBody(ErrorCodes.UserCommon.NotExist); + } + + [Fact] + public async Task Patch_User() + { + using var client = await CreateClientAsUser(); + { + var res = await client.PatchAsJsonAsync("users/user1", + new UserPatchRequest { Nickname = "aaa" }); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which.Nickname.Should().Be("aaa"); + } + + { + var res = await client.GetAsync("users/user1"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which.Nickname.Should().Be("aaa"); + } + } + + [Fact] + public async Task Patch_Admin() + { + using var client = await CreateClientAsAdministrator(); + using var userClient = await CreateClientAsUser(); + + { + var res = await client.PatchAsJsonAsync("users/user1", + new UserPatchRequest + { + Username = "newuser", + Password = "newpw", + Administrator = true, + Nickname = "aaa" + }); + var body = res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which; + body.Administrator.Should().Be(true); + body.Nickname.Should().Be("aaa"); + } + + { + var res = await client.GetAsync("users/newuser"); + var body = res.Should().HaveStatusCode(200) + .And.HaveJsonBody() + .Which; + body.Administrator.Should().Be(true); + body.Nickname.Should().Be("aaa"); + } + + { + // Token should expire. + var res = await userClient.GetAsync("testing/auth/Authorize"); + res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + } + + { + // Check password. + (await CreateClientWithCredential("newuser", "newpw")).Dispose(); + } + } + + [Fact] + public async Task Patch_NotExist() + { + using var client = await CreateClientAsAdministrator(); + var res = await client.PatchAsJsonAsync("users/usernotexist", new UserPatchRequest { }); + res.Should().HaveStatusCode(404) + .And.HaveCommonBody() + .Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist); + } + + [Fact] + public async Task Patch_InvalidModel() + { + using var client = await CreateClientAsAdministrator(); + var res = await client.PatchAsJsonAsync("users/aaa!a", new UserPatchRequest { }); + res.Should().BeInvalidModel(); + } + + public static IEnumerable Patch_InvalidModel_Body_Data() + { + yield return new[] { new UserPatchRequest { Username = "aaa!a" } }; + yield return new[] { new UserPatchRequest { Password = "" } }; + yield return new[] { new UserPatchRequest { Nickname = new string('a', 50) } }; + } + + [Theory] + [MemberData(nameof(Patch_InvalidModel_Body_Data))] + public async Task Patch_InvalidModel_Body(UserPatchRequest body) + { + using var client = await CreateClientAsAdministrator(); + var res = await client.PatchAsJsonAsync("users/user1", body); + res.Should().BeInvalidModel(); + } + + [Fact] + public async Task Patch_UsernameConflict() + { + using var client = await CreateClientAsAdministrator(); + var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Username = "admin" }); + res.Should().HaveStatusCode(400) + .And.HaveCommonBody(ErrorCodes.UserController.UsernameConflict); + } + + [Fact] + public async Task Patch_NoAuth_Unauthorized() + { + using var client = await CreateDefaultClient(); + var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Nickname = "aaa" }); + res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + } + + [Fact] + public async Task Patch_User_Forbid() + { + using var client = await CreateClientAsUser(); + var res = await client.PatchAsJsonAsync("users/admin", new UserPatchRequest { Nickname = "aaa" }); + res.Should().HaveStatusCode(HttpStatusCode.Forbidden); + } + + [Fact] + public async Task Patch_Username_Forbid() + { + using var client = await CreateClientAsUser(); + var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Username = "aaa" }); + res.Should().HaveStatusCode(HttpStatusCode.Forbidden); + } + + [Fact] + public async Task Patch_Password_Forbid() + { + using var client = await CreateClientAsUser(); + var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Password = "aaa" }); + res.Should().HaveStatusCode(HttpStatusCode.Forbidden); + } + + [Fact] + public async Task Patch_Administrator_Forbid() + { + using var client = await CreateClientAsUser(); + var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { Administrator = true }); + res.Should().HaveStatusCode(HttpStatusCode.Forbidden); + } + + [Fact] + public async Task Delete_Deleted() + { + using var client = await CreateClientAsAdministrator(); + { + var res = await client.DeleteAsync("users/user1"); + res.Should().BeDelete(true); + } + + { + var res = await client.GetAsync("users/user1"); + res.Should().HaveStatusCode(404); + } + } + + [Fact] + public async Task Delete_NotExist() + { + using var client = await CreateClientAsAdministrator(); + var res = await client.DeleteAsync("users/usernotexist"); + res.Should().BeDelete(false); + } + + [Fact] + public async Task Delete_InvalidModel() + { + using var client = await CreateClientAsAdministrator(); + var res = await client.DeleteAsync("users/aaa!a"); + res.Should().BeInvalidModel(); + } + + [Fact] + public async Task Delete_NoAuth_Unauthorized() + { + using var client = await CreateDefaultClient(); + var res = await client.DeleteAsync("users/aaa!a"); + res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + } + + [Fact] + public async Task Delete_User_Forbid() + { + using var client = await CreateClientAsUser(); + var res = await client.DeleteAsync("users/aaa!a"); + res.Should().HaveStatusCode(HttpStatusCode.Forbidden); + } + + private const string createUserUrl = "userop/createuser"; + + [Fact] + public async Task Op_CreateUser() + { + using var client = await CreateClientAsAdministrator(); + { + var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest + { + Username = "aaa", + Password = "bbb", + Administrator = true, + Nickname = "ccc" + }); + var body = res.Should().HaveStatusCode(200) + .And.HaveJsonBody().Which; + body.Username.Should().Be("aaa"); + body.Nickname.Should().Be("ccc"); + body.Administrator.Should().BeTrue(); + } + { + var res = await client.GetAsync("users/aaa"); + var body = res.Should().HaveStatusCode(200) + .And.HaveJsonBody().Which; + body.Username.Should().Be("aaa"); + body.Nickname.Should().Be("ccc"); + body.Administrator.Should().BeTrue(); + } + { + // Test password. + (await CreateClientWithCredential("aaa", "bbb")).Dispose(); + } + } + + public static IEnumerable Op_CreateUser_InvalidModel_Data() + { + yield return new[] { new CreateUserRequest { Username = "aaa", Password = "bbb" } }; + yield return new[] { new CreateUserRequest { Username = "aaa", Administrator = true } }; + yield return new[] { new CreateUserRequest { Password = "bbb", Administrator = true } }; + yield return new[] { new CreateUserRequest { Username = "a!a", Password = "bbb", Administrator = true } }; + yield return new[] { new CreateUserRequest { Username = "aaa", Password = "", Administrator = true } }; + yield return new[] { new CreateUserRequest { Username = "aaa", Password = "bbb", Administrator = true, Nickname = new string('a', 40) } }; + } + + [Theory] + [MemberData(nameof(Op_CreateUser_InvalidModel_Data))] + public async Task Op_CreateUser_InvalidModel(CreateUserRequest body) + { + using var client = await CreateClientAsAdministrator(); + { + var res = await client.PostAsJsonAsync(createUserUrl, body); + res.Should().BeInvalidModel(); + } + } + + [Fact] + public async Task Op_CreateUser_UsernameConflict() + { + using var client = await CreateClientAsAdministrator(); + { + var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest + { + Username = "user1", + Password = "bbb", + Administrator = false + }); + res.Should().HaveStatusCode(400) + .And.HaveCommonBody(ErrorCodes.UserController.UsernameConflict); + } + } + + [Fact] + public async Task Op_CreateUser_NoAuth_Unauthorized() + { + using var client = await CreateDefaultClient(); + { + var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest + { + Username = "aaa", + Password = "bbb", + Administrator = false + }); + res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + } + } + + [Fact] + public async Task Op_CreateUser_User_Forbid() + { + using var client = await CreateClientAsUser(); + { + var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest + { + Username = "aaa", + Password = "bbb", + Administrator = false + }); + res.Should().HaveStatusCode(HttpStatusCode.Forbidden); + } + } + + private const string changePasswordUrl = "userop/changepassword"; + + [Fact] + public async Task Op_ChangePassword() + { + using var client = await CreateClientAsUser(); + { + var res = await client.PostAsJsonAsync(changePasswordUrl, + new ChangePasswordRequest { OldPassword = "user1pw", NewPassword = "newpw" }); + res.Should().HaveStatusCode(200); + } + { + var res = await client.PatchAsJsonAsync("users/user1", new UserPatchRequest { }); + res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + } + { + (await CreateClientWithCredential("user1", "newpw")).Dispose(); + } + } + + public static IEnumerable Op_ChangePassword_InvalidModel_Data() + { + yield return new[] { null, "ppp" }; + yield return new[] { "ppp", null }; + } + + [Theory] + [MemberData(nameof(Op_ChangePassword_InvalidModel_Data))] + public async Task Op_ChangePassword_InvalidModel(string oldPassword, string newPassword) + { + using var client = await CreateClientAsUser(); + var res = await client.PostAsJsonAsync(changePasswordUrl, + new ChangePasswordRequest { OldPassword = oldPassword, NewPassword = newPassword }); + res.Should().BeInvalidModel(); + } + + [Fact] + public async Task Op_ChangePassword_BadOldPassword() + { + using var client = await CreateClientAsUser(); + var res = await client.PostAsJsonAsync(changePasswordUrl, new ChangePasswordRequest { OldPassword = "???", NewPassword = "???" }); + res.Should().HaveStatusCode(400) + .And.HaveCommonBody(ErrorCodes.UserController.ChangePassword_BadOldPassword); + } + + [Fact] + public async Task Op_ChangePassword_NoAuth_Unauthorized() + { + using var client = await CreateDefaultClient(); + var res = await client.PostAsJsonAsync(changePasswordUrl, new ChangePasswordRequest { OldPassword = "???", NewPassword = "???" }); + res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + } + } +} -- cgit v1.2.3