diff options
Diffstat (limited to 'Timeline.Tests/IntegratedTests')
-rw-r--r-- | Timeline.Tests/IntegratedTests/AuthorizationUnitTest.cs | 68 | ||||
-rw-r--r-- | Timeline.Tests/IntegratedTests/TokenUnitTest.cs | 185 | ||||
-rw-r--r-- | Timeline.Tests/IntegratedTests/UserAvatarTests.cs | 23 | ||||
-rw-r--r-- | Timeline.Tests/IntegratedTests/UserDetailTest.cs | 29 | ||||
-rw-r--r-- | Timeline.Tests/IntegratedTests/UserUnitTest.cs | 320 |
5 files changed, 598 insertions, 27 deletions
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<WebApplicationFactory<Startup>>, 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<Startup> _factory;
+
+ public AuthorizationUnitTest(WebApplicationFactory<Startup> 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<WebApplicationFactory<Startup>>, IDisposable
+ {
+ private const string CreateTokenUrl = "token/create";
+ private const string VerifyTokenUrl = "token/verify";
+
+ private readonly TestApplication _testApp;
+ private readonly WebApplicationFactory<Startup> _factory;
+
+ public TokenUnitTest(WebApplicationFactory<Startup> 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<CreateTokenResponse>().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<IUserService>();
+ 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<IUserService>();
+ 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<VerifyTokenResponse>()
+ .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<MyWebApplicationFactory<Startup>>, IDisposable
+ public class UserAvatarUnitTest : IClassFixture<WebApplicationFactory<Startup>>, IDisposable
{
+ private readonly TestApplication _testApp;
private readonly WebApplicationFactory<Startup> _factory;
- private readonly Action _disposeAction;
- public UserAvatarUnitTest(MyWebApplicationFactory<Startup> factory, ITestOutputHelper outputHelper)
+ public UserAvatarUnitTest(WebApplicationFactory<Startup> 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<MyWebApplicationFactory<Startup>>, IDisposable
+ public class UserDetailTest : IClassFixture<WebApplicationFactory<Startup>>, IDisposable
{
+ private readonly TestApplication _testApp;
private readonly WebApplicationFactory<Startup> _factory;
- private readonly Action _disposeAction;
- public UserDetailTest(MyWebApplicationFactory<Startup> factory, ITestOutputHelper outputHelper)
+ public UserDetailTest(WebApplicationFactory<Startup> 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<UserDetail>()
.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<UserDetail>()
.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<WebApplicationFactory<Startup>>, IDisposable
+ {
+ private readonly TestApplication _testApp;
+ private readonly WebApplicationFactory<Startup> _factory;
+
+ public UserUnitTest(WebApplicationFactory<Startup> 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<UserInfo[]>()
+ .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<UserInfo>()
+ .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<UserInfo>()
+ .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<WebApplicationFactory<Startup>>, IDisposable
+ {
+ private const string url = "userop/changeusername";
+
+ private readonly TestApplication _testApp;
+ private readonly WebApplicationFactory<Startup> _factory;
+
+ public ChangeUsernameUnitTest(WebApplicationFactory<Startup> 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<WebApplicationFactory<Startup>>, IDisposable
+ {
+ private const string url = "userop/changepassword";
+
+ private readonly TestApplication _testApp;
+ private readonly WebApplicationFactory<Startup> _factory;
+
+ public ChangePasswordUnitTest(WebApplicationFactory<Startup> 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);
+ }
+ }
+ }
+ }
+}
|