From def8e8dd78812c019a0d6e8e5a3e2de4e82ae3e4 Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Thu, 17 Oct 2019 20:46:57 +0800 Subject: ... --- .../IntegratedTests/AuthorizationUnitTest.cs | 68 +++++ Timeline.Tests/IntegratedTests/TokenUnitTest.cs | 185 ++++++++++++ Timeline.Tests/IntegratedTests/UserAvatarTests.cs | 23 +- Timeline.Tests/IntegratedTests/UserDetailTest.cs | 29 +- Timeline.Tests/IntegratedTests/UserUnitTest.cs | 320 +++++++++++++++++++++ 5 files changed, 598 insertions(+), 27 deletions(-) create mode 100644 Timeline.Tests/IntegratedTests/AuthorizationUnitTest.cs create mode 100644 Timeline.Tests/IntegratedTests/TokenUnitTest.cs create mode 100644 Timeline.Tests/IntegratedTests/UserUnitTest.cs (limited to 'Timeline.Tests/IntegratedTests') diff --git a/Timeline.Tests/IntegratedTests/AuthorizationUnitTest.cs b/Timeline.Tests/IntegratedTests/AuthorizationUnitTest.cs new file mode 100644 index 00000000..a67bffcf --- /dev/null +++ b/Timeline.Tests/IntegratedTests/AuthorizationUnitTest.cs @@ -0,0 +1,68 @@ +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using System; +using System.Net; +using System.Threading.Tasks; +using Timeline.Tests.Helpers; +using Timeline.Tests.Helpers.Authentication; +using Xunit; + +namespace Timeline.Tests.IntegratedTests +{ + public class AuthorizationUnitTest : IClassFixture>, IDisposable + { + private const string AuthorizeUrl = "Test/User/Authorize"; + private const string UserUrl = "Test/User/User"; + private const string AdminUrl = "Test/User/Admin"; + + private readonly TestApplication _testApp; + private readonly WebApplicationFactory _factory; + + public AuthorizationUnitTest(WebApplicationFactory factory) + { + _testApp = new TestApplication(factory); + _factory = _testApp.Factory; + } + + public void Dispose() + { + _testApp.Dispose(); + } + + [Fact] + public async Task UnauthenticationTest() + { + using var client = _factory.CreateDefaultClient(); + var response = await client.GetAsync(AuthorizeUrl); + response.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + } + + [Fact] + public async Task AuthenticationTest() + { + using var client = await _factory.CreateClientAsUser(); + var response = await client.GetAsync(AuthorizeUrl); + response.Should().HaveStatusCode(HttpStatusCode.OK); + } + + [Fact] + public async Task UserAuthorizationTest() + { + using var client = await _factory.CreateClientAsUser(); + var response1 = await client.GetAsync(UserUrl); + response1.Should().HaveStatusCode(HttpStatusCode.OK); + var response2 = await client.GetAsync(AdminUrl); + response2.Should().HaveStatusCode(HttpStatusCode.Forbidden); + } + + [Fact] + public async Task AdminAuthorizationTest() + { + using var client = await _factory.CreateClientAsAdmin(); + var response1 = await client.GetAsync(UserUrl); + response1.Should().HaveStatusCode(HttpStatusCode.OK); + var response2 = await client.GetAsync(AdminUrl); + response2.Should().HaveStatusCode(HttpStatusCode.OK); + } + } +} diff --git a/Timeline.Tests/IntegratedTests/TokenUnitTest.cs b/Timeline.Tests/IntegratedTests/TokenUnitTest.cs new file mode 100644 index 00000000..05e2b3e5 --- /dev/null +++ b/Timeline.Tests/IntegratedTests/TokenUnitTest.cs @@ -0,0 +1,185 @@ +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Timeline.Models.Http; +using Timeline.Services; +using Timeline.Tests.Helpers; +using Timeline.Tests.Helpers.Authentication; +using Timeline.Tests.Mock.Data; +using Xunit; +using static Timeline.ErrorCodes.Http.Token; + +namespace Timeline.Tests +{ + public class TokenUnitTest : IClassFixture>, IDisposable + { + private const string CreateTokenUrl = "token/create"; + private const string VerifyTokenUrl = "token/verify"; + + private readonly TestApplication _testApp; + private readonly WebApplicationFactory _factory; + + public TokenUnitTest(WebApplicationFactory factory) + { + _testApp = new TestApplication(factory); + _factory = _testApp.Factory; + } + + public void Dispose() + { + _testApp.Dispose(); + } + [Fact] + public async Task CreateToken_InvalidModel() + { + using var client = _factory.CreateDefaultClient(); + // missing username + await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl, + new CreateTokenRequest { Username = null, Password = "user" }); + // missing password + await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl, + new CreateTokenRequest { Username = "user", Password = null }); + // bad expire offset + await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl, + new CreateTokenRequest + { + Username = "user", + Password = "password", + Expire = 1000 + }); + } + + [Fact] + public async void CreateToken_UserNotExist() + { + using var client = _factory.CreateDefaultClient(); + var response = await client.PostAsJsonAsync(CreateTokenUrl, + new CreateTokenRequest { Username = "usernotexist", Password = "???" }); + response.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(Create.BadCredential); + } + + [Fact] + public async void CreateToken_BadPassword() + { + using (var client = _factory.CreateDefaultClient()) + { + var response = await client.PostAsJsonAsync(CreateTokenUrl, + new CreateTokenRequest { Username = MockUser.User.Username, Password = "???" }); + response.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(Create.BadCredential); + } + } + + [Fact] + public async void CreateToken_Success() + { + using (var client = _factory.CreateDefaultClient()) + { + var response = await client.PostAsJsonAsync(CreateTokenUrl, + new CreateTokenRequest { Username = MockUser.User.Username, Password = MockUser.User.Password }); + var body = response.Should().HaveStatusCodeOk() + .And.Should().HaveBodyAsJson().Which; + body.Token.Should().NotBeNullOrWhiteSpace(); + body.User.Should().BeEquivalentTo(MockUser.User.Info); + } + } + + [Fact] + public async void VerifyToken_InvalidModel() + { + using (var client = _factory.CreateDefaultClient()) + { + // missing token + await InvalidModelTestHelpers.TestPostInvalidModel(client, VerifyTokenUrl, + new VerifyTokenRequest { Token = null }); + } + } + + [Fact] + public async void VerifyToken_BadToken() + { + using (var client = _factory.CreateDefaultClient()) + { + var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = "bad token hahaha" }); + response.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(Verify.BadFormat); + } + } + + [Fact] + public async void VerifyToken_BadVersion() + { + using (var client = _factory.CreateDefaultClient()) + { + var token = (await client.CreateUserTokenAsync(MockUser.User.Username, MockUser.User.Password)).Token; + + using (var scope = _factory.Server.Host.Services.CreateScope()) // UserService is scoped. + { + // create a user for test + var userService = scope.ServiceProvider.GetRequiredService(); + await userService.PatchUser(MockUser.User.Username, null, null); + } + + var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token }); + response.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(Verify.OldVersion); + } + } + + [Fact] + public async void VerifyToken_UserNotExist() + { + using (var client = _factory.CreateDefaultClient()) + { + var token = (await client.CreateUserTokenAsync(MockUser.User.Username, MockUser.User.Password)).Token; + + using (var scope = _factory.Server.Host.Services.CreateScope()) // UserService is scoped. + { + // create a user for test + var userService = scope.ServiceProvider.GetRequiredService(); + await userService.DeleteUser(MockUser.User.Username); + } + + var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token }); + response.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(Verify.UserNotExist); + } + } + + //[Fact] + //public async void VerifyToken_Expired() + //{ + // using (var client = _factory.CreateDefaultClient()) + // { + // // I can only control the token expired time but not current time + // // because verify logic is encapsuled in other library. + // var mockClock = _factory.GetTestClock(); + // mockClock.MockCurrentTime = DateTime.Now - TimeSpan.FromDays(2); + // var token = (await client.CreateUserTokenAsync(MockUsers.UserUsername, MockUsers.UserPassword, 1)).Token; + // var response = await client.PostAsJsonAsync(VerifyTokenUrl, + // new VerifyTokenRequest { Token = token }); + // response.Should().HaveStatusCodeBadRequest() + // .And.Should().HaveBodyAsCommonResponseWithCode(TokenController.ErrorCodes.Verify_Expired); + // mockClock.MockCurrentTime = null; + // } + //} + + [Fact] + public async void VerifyToken_Success() + { + using (var client = _factory.CreateDefaultClient()) + { + var createTokenResult = await client.CreateUserTokenAsync(MockUser.User.Username, MockUser.User.Password); + var response = await client.PostAsJsonAsync(VerifyTokenUrl, + new VerifyTokenRequest { Token = createTokenResult.Token }); + response.Should().HaveStatusCodeOk() + .And.Should().HaveBodyAsJson() + .Which.User.Should().BeEquivalentTo(MockUser.User.Info); + } + } + } +} diff --git a/Timeline.Tests/IntegratedTests/UserAvatarTests.cs b/Timeline.Tests/IntegratedTests/UserAvatarTests.cs index 2a3442d1..439e8d9b 100644 --- a/Timeline.Tests/IntegratedTests/UserAvatarTests.cs +++ b/Timeline.Tests/IntegratedTests/UserAvatarTests.cs @@ -3,9 +3,9 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.DependencyInjection; using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.Formats.Gif; using System; using System.Collections.Generic; using System.IO; @@ -14,28 +14,27 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using Timeline.Controllers; -using Timeline.Models.Http; using Timeline.Services; using Timeline.Tests.Helpers; using Timeline.Tests.Helpers.Authentication; using Xunit; -using Xunit.Abstractions; namespace Timeline.Tests.IntegratedTests { - public class UserAvatarUnitTest : IClassFixture>, IDisposable + public class UserAvatarUnitTest : IClassFixture>, IDisposable { + private readonly TestApplication _testApp; private readonly WebApplicationFactory _factory; - private readonly Action _disposeAction; - public UserAvatarUnitTest(MyWebApplicationFactory factory, ITestOutputHelper outputHelper) + public UserAvatarUnitTest(WebApplicationFactory factory) { - _factory = factory.WithTestConfig(outputHelper, out _disposeAction); + _testApp = new TestApplication(factory); + _factory = _testApp.Factory; } public void Dispose() { - _disposeAction(); + _testApp.Dispose(); } [Fact] @@ -92,7 +91,7 @@ namespace Timeline.Tests.IntegratedTests request.Headers.TryAddWithoutValidation("If-None-Match", "\"dsdfd"); var res = await client.SendAsync(request); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveBodyAsCommonResponseWithCode(CommonResponse.ErrorCodes.Header_BadFormat_IfNonMatch); + .And.Should().HaveBodyAsCommonResponseWithCode(ErrorCodes.Http.Common.Header.BadFormat_IfNonMatch); } { @@ -122,7 +121,7 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveBodyAsCommonResponseWithCode(CommonResponse.ErrorCodes.Header_Missing_ContentLength); + .And.Should().HaveBodyAsCommonResponseWithCode(ErrorCodes.Http.Common.Header.Missing_ContentLength); } { @@ -130,7 +129,7 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentLength = 1; var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveBodyAsCommonResponseWithCode(CommonResponse.ErrorCodes.Header_Missing_ContentType); + .And.Should().HaveBodyAsCommonResponseWithCode(ErrorCodes.Http.Common.Header.Missing_ContentType); } { @@ -139,7 +138,7 @@ namespace Timeline.Tests.IntegratedTests content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); var res = await client.PutAsync("users/user/avatar", content); res.Should().HaveStatusCode(HttpStatusCode.BadRequest) - .And.Should().HaveBodyAsCommonResponseWithCode(CommonResponse.ErrorCodes.Header_Zero_ContentLength); + .And.Should().HaveBodyAsCommonResponseWithCode(ErrorCodes.Http.Common.Header.Zero_ContentLength); } { diff --git a/Timeline.Tests/IntegratedTests/UserDetailTest.cs b/Timeline.Tests/IntegratedTests/UserDetailTest.cs index ba15b7ca..d1a67d9d 100644 --- a/Timeline.Tests/IntegratedTests/UserDetailTest.cs +++ b/Timeline.Tests/IntegratedTests/UserDetailTest.cs @@ -5,28 +5,27 @@ using System.Net; using System.Threading.Tasks; using Timeline.Controllers; using Timeline.Models; -using Timeline.Models.Http; using Timeline.Tests.Helpers; using Timeline.Tests.Helpers.Authentication; using Timeline.Tests.Mock.Data; using Xunit; -using Xunit.Abstractions; namespace Timeline.Tests.IntegratedTests { - public class UserDetailTest : IClassFixture>, IDisposable + public class UserDetailTest : IClassFixture>, IDisposable { + private readonly TestApplication _testApp; private readonly WebApplicationFactory _factory; - private readonly Action _disposeAction; - public UserDetailTest(MyWebApplicationFactory factory, ITestOutputHelper outputHelper) + public UserDetailTest(WebApplicationFactory factory) { - _factory = factory.WithTestConfig(outputHelper, out _disposeAction); + _testApp = new TestApplication(factory); + _factory = _testApp.Factory; } public void Dispose() { - _disposeAction(); + _testApp.Dispose(); } [Fact] @@ -48,7 +47,7 @@ namespace Timeline.Tests.IntegratedTests async Task GetAndTest(UserDetail d) { - var res = await client.GetAsync($"users/{MockUsers.UserUsername}/details"); + var res = await client.GetAsync($"users/{MockUser.User.Username}/details"); res.Should().HaveStatusCodeOk() .And.Should().HaveBodyAsJson() .Which.Should().BeEquivalentTo(d); @@ -57,13 +56,13 @@ namespace Timeline.Tests.IntegratedTests await GetAndTest(new UserDetail()); { - var res = await client.PatchAsJsonAsync($"users/{MockUsers.AdminUsername}/details", new UserDetail()); + var res = await client.PatchAsJsonAsync($"users/{MockUser.Admin.Username}/details", new UserDetail()); res.Should().HaveStatusCode(HttpStatusCode.Forbidden) .And.Should().HaveBodyAsCommonResponseWithCode(UserDetailController.ErrorCodes.Patch_Forbid); } { - var res = await client.PatchAsJsonAsync($"users/{MockUsers.UserUsername}/details", new UserDetail + var res = await client.PatchAsJsonAsync($"users/{MockUser.User.Username}/details", new UserDetail { Nickname = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", QQ = "aaaaaaa", @@ -72,7 +71,7 @@ namespace Timeline.Tests.IntegratedTests }); var body = res.Should().HaveStatusCode(HttpStatusCode.BadRequest) .And.Should().HaveBodyAsCommonResponse().Which; - body.Code.Should().Be(CommonResponse.ErrorCodes.InvalidModel); + body.Code.Should().Be(ErrorCodes.Http.Common.InvalidModel); foreach (var key in new string[] { "nickname", "qq", "email", "phonenumber" }) { body.Message.Should().ContainEquivalentOf(key); @@ -89,13 +88,13 @@ namespace Timeline.Tests.IntegratedTests }; { - var res = await client.PatchAsJsonAsync($"users/{MockUsers.UserUsername}/details", detail); + var res = await client.PatchAsJsonAsync($"users/{MockUser.User.Username}/details", detail); res.Should().HaveStatusCodeOk(); await GetAndTest(detail); } { - var res = await client.GetAsync($"users/{MockUsers.UserUsername}/nickname"); + var res = await client.GetAsync($"users/{MockUser.User.Username}/nickname"); res.Should().HaveStatusCodeOk().And.Should().HaveBodyAsJson() .Which.Should().BeEquivalentTo(new UserDetail { @@ -111,7 +110,7 @@ namespace Timeline.Tests.IntegratedTests }; { - var res = await client.PatchAsJsonAsync($"users/{MockUsers.UserUsername}/details", detail2); + var res = await client.PatchAsJsonAsync($"users/{MockUser.User.Username}/details", detail2); res.Should().HaveStatusCodeOk(); await GetAndTest(new UserDetail { @@ -131,7 +130,7 @@ namespace Timeline.Tests.IntegratedTests using (var client = await _factory.CreateClientAsAdmin()) { { - var res = await client.PatchAsJsonAsync($"users/{MockUsers.UserUsername}/details", new UserDetail()); + var res = await client.PatchAsJsonAsync($"users/{MockUser.User.Username}/details", new UserDetail()); res.Should().HaveStatusCodeOk(); } diff --git a/Timeline.Tests/IntegratedTests/UserUnitTest.cs b/Timeline.Tests/IntegratedTests/UserUnitTest.cs new file mode 100644 index 00000000..d228c563 --- /dev/null +++ b/Timeline.Tests/IntegratedTests/UserUnitTest.cs @@ -0,0 +1,320 @@ +using FluentAssertions; +using Microsoft.AspNetCore.Mvc.Testing; +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Timeline.Controllers; +using Timeline.Models; +using Timeline.Models.Http; +using Timeline.Tests.Helpers; +using Timeline.Tests.Helpers.Authentication; +using Timeline.Tests.Mock.Data; +using Xunit; + +namespace Timeline.Tests +{ + public class UserUnitTest : IClassFixture>, IDisposable + { + private readonly TestApplication _testApp; + private readonly WebApplicationFactory _factory; + + public UserUnitTest(WebApplicationFactory factory) + { + _testApp = new TestApplication(factory); + _factory = _testApp.Factory; + } + + public void Dispose() + { + _testApp.Dispose(); + } + + [Fact] + public async Task Get_Users_List() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + var res = await client.GetAsync("users"); + res.Should().HaveStatusCodeOk().And.Should().HaveBodyAsJson() + .Which.Should().BeEquivalentTo(MockUser.UserInfoList); + } + } + + [Fact] + public async Task Get_Users_User() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + var res = await client.GetAsync("users/" + MockUser.User.Username); + res.Should().HaveStatusCodeOk() + .And.Should().HaveBodyAsJson() + .Which.Should().BeEquivalentTo(MockUser.User.Info); + } + } + + [Fact] + public async Task Get_Users_404() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + var res = await client.GetAsync("users/usernotexist"); + res.Should().HaveStatusCodeNotFound() + .And.Should().HaveBodyAsCommonResponseWithCode(UserController.ErrorCodes.Get_NotExist); + } + } + + [Fact] + public async Task Put_InvalidModel() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + const string url = "users/aaaaaaaa"; + // missing password + await InvalidModelTestHelpers.TestPutInvalidModel(client, url, new UserPutRequest { Password = null, Administrator = false }); + // missing administrator + await InvalidModelTestHelpers.TestPutInvalidModel(client, url, new UserPutRequest { Password = "???", Administrator = null }); + } + } + + [Fact] + public async Task Put_BadUsername() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + var res = await client.PutAsJsonAsync("users/dsf fddf", new UserPutRequest + { + Password = "???", + Administrator = false + }); + res.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(UserController.ErrorCodes.Put_BadUsername); + } + } + + private async Task CheckAdministrator(HttpClient client, string username, bool administrator) + { + var res = await client.GetAsync("users/" + username); + res.Should().HaveStatusCodeOk() + .And.Should().HaveBodyAsJson() + .Which.Administrator.Should().Be(administrator); + } + + [Fact] + public async Task Put_Modiefied() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + var res = await client.PutAsJsonAsync("users/" + MockUser.User.Username, new UserPutRequest + { + Password = "password", + Administrator = false + }); + res.Should().BePutModify(); + await CheckAdministrator(client, MockUser.User.Username, false); + } + } + + [Fact] + public async Task Put_Created() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + const string username = "puttest"; + const string url = "users/" + username; + + var res = await client.PutAsJsonAsync(url, new UserPutRequest + { + Password = "password", + Administrator = false + }); + res.Should().BePutCreate(); + await CheckAdministrator(client, username, false); + } + } + + [Fact] + public async Task Patch_NotExist() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + var res = await client.PatchAsJsonAsync("users/usernotexist", new UserPatchRequest { }); + res.Should().HaveStatusCodeNotFound() + .And.Should().HaveBodyAsCommonResponseWithCode(UserController.ErrorCodes.Patch_NotExist); + } + } + + [Fact] + public async Task Patch_Success() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + { + var res = await client.PatchAsJsonAsync("users/" + MockUser.User.Username, + new UserPatchRequest { Administrator = false }); + res.Should().HaveStatusCodeOk(); + await CheckAdministrator(client, MockUser.User.Username, false); + } + } + } + + [Fact] + public async Task Delete_Deleted() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + { + var url = "users/" + MockUser.User.Username; + var res = await client.DeleteAsync(url); + res.Should().BeDeleteDelete(); + + var res2 = await client.GetAsync(url); + res2.Should().HaveStatusCodeNotFound(); + } + } + } + + [Fact] + public async Task Delete_NotExist() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + { + var res = await client.DeleteAsync("users/usernotexist"); + res.Should().BeDeleteNotExist(); + } + } + } + + + public class ChangeUsernameUnitTest : IClassFixture>, IDisposable + { + private const string url = "userop/changeusername"; + + private readonly TestApplication _testApp; + private readonly WebApplicationFactory _factory; + + public ChangeUsernameUnitTest(WebApplicationFactory factory) + { + _testApp = new TestApplication(factory); + _factory = _testApp.Factory; + } + + public void Dispose() + { + _testApp.Dispose(); + } + + [Fact] + public async Task InvalidModel() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + // missing old username + await InvalidModelTestHelpers.TestPostInvalidModel(client, url, + new ChangeUsernameRequest { OldUsername = null, NewUsername = "hhh" }); + // missing new username + await InvalidModelTestHelpers.TestPostInvalidModel(client, url, + new ChangeUsernameRequest { OldUsername = "hhh", NewUsername = null }); + // bad username + await InvalidModelTestHelpers.TestPostInvalidModel(client, url, + new ChangeUsernameRequest { OldUsername = "hhh", NewUsername = "???" }); + } + } + + [Fact] + public async Task UserNotExist() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + var res = await client.PostAsJsonAsync(url, + new ChangeUsernameRequest { OldUsername = "usernotexist", NewUsername = "newUsername" }); + res.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(UserController.ErrorCodes.ChangeUsername_NotExist); + } + } + + [Fact] + public async Task UserAlreadyExist() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + var res = await client.PostAsJsonAsync(url, + new ChangeUsernameRequest { OldUsername = MockUser.User.Username, NewUsername = MockUser.Admin.Username }); + res.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(UserController.ErrorCodes.ChangeUsername_AlreadyExist); + } + } + + [Fact] + public async Task Success() + { + using (var client = await _factory.CreateClientAsAdmin()) + { + const string newUsername = "hahaha"; + var res = await client.PostAsJsonAsync(url, + new ChangeUsernameRequest { OldUsername = MockUser.User.Username, NewUsername = newUsername }); + res.Should().HaveStatusCodeOk(); + await client.CreateUserTokenAsync(newUsername, MockUser.User.Password); + } + } + } + + + public class ChangePasswordUnitTest : IClassFixture>, IDisposable + { + private const string url = "userop/changepassword"; + + private readonly TestApplication _testApp; + private readonly WebApplicationFactory _factory; + + public ChangePasswordUnitTest(WebApplicationFactory factory) + { + _testApp = new TestApplication(factory); + _factory = _testApp.Factory; + } + + public void Dispose() + { + _testApp.Dispose(); + } + + [Fact] + public async Task InvalidModel() + { + using (var client = await _factory.CreateClientAsUser()) + { + // missing old password + await InvalidModelTestHelpers.TestPostInvalidModel(client, url, + new ChangePasswordRequest { OldPassword = null, NewPassword = "???" }); + // missing new password + await InvalidModelTestHelpers.TestPostInvalidModel(client, url, + new ChangePasswordRequest { OldPassword = "???", NewPassword = null }); + } + } + + [Fact] + public async Task BadOldPassword() + { + using (var client = await _factory.CreateClientAsUser()) + { + var res = await client.PostAsJsonAsync(url, new ChangePasswordRequest { OldPassword = "???", NewPassword = "???" }); + res.Should().HaveStatusCodeBadRequest() + .And.Should().HaveBodyAsCommonResponseWithCode(UserController.ErrorCodes.ChangePassword_BadOldPassword); + } + } + + [Fact] + public async Task Success() + { + using (var client = await _factory.CreateClientAsUser()) + { + const string newPassword = "new"; + var res = await client.PostAsJsonAsync(url, + new ChangePasswordRequest { OldPassword = MockUser.User.Password, NewPassword = newPassword }); + res.Should().HaveStatusCodeOk(); + await client.CreateUserTokenAsync(MockUser.User.Username, newPassword); + } + } + } + } +} -- cgit v1.2.3