diff options
author | 杨宇千 <crupest@outlook.com> | 2019-08-09 15:39:58 +0800 |
---|---|---|
committer | 杨宇千 <crupest@outlook.com> | 2019-08-09 15:39:58 +0800 |
commit | 58986da4a5bfe519af44e5834edfbe8d4651b51c (patch) | |
tree | 26432b04bb7b2b2f59b3e8170f2e37cd5ce08c57 | |
parent | 6c50630c4d6576446fc2338714feaefbf28c4ed1 (diff) | |
download | timeline-58986da4a5bfe519af44e5834edfbe8d4651b51c.tar.gz timeline-58986da4a5bfe519af44e5834edfbe8d4651b51c.tar.bz2 timeline-58986da4a5bfe519af44e5834edfbe8d4651b51c.zip |
Add UserController unit tests.
-rw-r--r-- | Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs | 1 | ||||
-rw-r--r-- | Timeline.Tests/Helpers/HttpClientExtensions.cs | 15 | ||||
-rw-r--r-- | Timeline.Tests/Helpers/InvalidModelTestHelpers.cs | 8 | ||||
-rw-r--r-- | Timeline.Tests/Helpers/ResponseExtensions.cs | 47 | ||||
-rw-r--r-- | Timeline.Tests/UserUnitTest.cs | 187 | ||||
-rw-r--r-- | Timeline/Controllers/UserController.cs | 4 |
6 files changed, 252 insertions, 10 deletions
diff --git a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs index e31bd51c..8a44c852 100644 --- a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs +++ b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs @@ -14,6 +14,7 @@ namespace Timeline.Tests.Helpers.Authentication public static async Task<CreateTokenResponse> CreateUserTokenAsync(this HttpClient client, string username, string password, int? expireOffset = null)
{
var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = username, Password = password, ExpireOffset = expireOffset });
+ response.AssertOk();
var result = JsonConvert.DeserializeObject<CreateTokenResponse>(await response.Content.ReadAsStringAsync());
return result;
}
diff --git a/Timeline.Tests/Helpers/HttpClientExtensions.cs b/Timeline.Tests/Helpers/HttpClientExtensions.cs new file mode 100644 index 00000000..cd40d91e --- /dev/null +++ b/Timeline.Tests/Helpers/HttpClientExtensions.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Timeline.Tests.Helpers
+{
+ public static class HttpClientExtensions
+ {
+ public static Task<HttpResponseMessage> PatchAsJsonAsync<T>(this HttpClient client, string url, T body)
+ {
+ return client.PatchAsync(url, new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"));
+ }
+ }
+}
diff --git a/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs b/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs index 51919021..1c079d0e 100644 --- a/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs +++ b/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs @@ -15,5 +15,13 @@ namespace Timeline.Tests.Helpers var responseBody = await response.ReadBodyAsJson<CommonResponse>();
Assert.Equal(CommonResponse.ErrorCodes.InvalidModel, responseBody.Code);
}
+
+ public static async Task TestPutInvalidModel<T>(HttpClient client, string url, T body)
+ {
+ var response = await client.PutAsJsonAsync(url, body);
+ Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
+ var responseBody = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(CommonResponse.ErrorCodes.InvalidModel, responseBody.Code);
+ }
}
}
diff --git a/Timeline.Tests/Helpers/ResponseExtensions.cs b/Timeline.Tests/Helpers/ResponseExtensions.cs index 155836fb..46c9e81d 100644 --- a/Timeline.Tests/Helpers/ResponseExtensions.cs +++ b/Timeline.Tests/Helpers/ResponseExtensions.cs @@ -1,11 +1,58 @@ using Newtonsoft.Json;
+using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
+using Timeline.Models.Http;
+using Xunit;
namespace Timeline.Tests.Helpers
{
public static class ResponseExtensions
{
+ public static void AssertOk(this HttpResponseMessage response)
+ {
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ }
+
+ public static void AssertNotFound(this HttpResponseMessage response)
+ {
+ Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
+ }
+
+ public static void AssertBadRequest(this HttpResponseMessage response)
+ {
+ Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
+ }
+
+ public static async Task AssertIsPutCreated(this HttpResponseMessage response)
+ {
+ Assert.Equal(HttpStatusCode.Created, response.StatusCode);
+ var body = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(CommonPutResponse.CreatedCode, body.Code);
+ }
+
+ public static async Task AssertIsPutModified(this HttpResponseMessage response)
+ {
+ response.AssertOk();
+ var body = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(CommonPutResponse.ModifiedCode, body.Code);
+ }
+
+
+ public static async Task AssertIsDeleteDeleted(this HttpResponseMessage response)
+ {
+ response.AssertOk();
+ var body = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(CommonDeleteResponse.DeletedCode, body.Code);
+ }
+
+ public static async Task AssertIsDeleteNotExist(this HttpResponseMessage response)
+ {
+ response.AssertOk();
+ var body = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(CommonDeleteResponse.NotExistsCode, body.Code);
+ }
+
public static async Task<T> ReadBodyAsJson<T>(this HttpResponseMessage response)
{
return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
diff --git a/Timeline.Tests/UserUnitTest.cs b/Timeline.Tests/UserUnitTest.cs index 7935dd9a..c5c91d34 100644 --- a/Timeline.Tests/UserUnitTest.cs +++ b/Timeline.Tests/UserUnitTest.cs @@ -1,9 +1,10 @@ using Microsoft.AspNetCore.Mvc.Testing;
-using Newtonsoft.Json;
-using System.Linq;
using System.Net;
+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;
@@ -22,15 +23,185 @@ namespace Timeline.Tests }
[Fact]
- public async Task UserTest()
+ public async Task Get_Users_List()
{
using (var client = await _factory.CreateClientAsAdmin())
{
- var res1 = await client.GetAsync("users");
- Assert.Equal(HttpStatusCode.OK, res1.StatusCode);
- var users = JsonConvert.DeserializeObject<UserInfo[]>(await res1.Content.ReadAsStringAsync()).ToList();
- users.Sort(UserInfoComparers.Comparer);
- Assert.Equal(MockUsers.UserInfos, users, UserInfoComparers.EqualityComparer);
+ var res = await client.GetAsync("users");
+ Assert.Equal(HttpStatusCode.OK, res.StatusCode);
+
+ // Because tests are running asyncronized. So database may be modified and
+ // we can't check the exact user lists at this point. So only check the format.
+
+ // var users = (await res.ReadBodyAsJson<UserInfo[]>()).ToList();
+ // users.Sort(UserInfoComparers.Comparer);
+ // Assert.Equal(MockUsers.UserInfos, users, UserInfoComparers.EqualityComparer);
+ await res.ReadBodyAsJson<UserInfo[]>();
+ }
+ }
+
+ [Fact]
+ public async Task Get_Users_User()
+ {
+ using (var client = await _factory.CreateClientAsAdmin())
+ {
+ var res = await client.GetAsync("users/" + MockUsers.UserUsername);
+ res.AssertOk();
+ var user = await res.ReadBodyAsJson<UserInfo>();
+ Assert.Equal(MockUsers.UserUserInfo, user, UserInfoComparers.EqualityComparer);
+ }
+ }
+
+ [Fact]
+ public async Task Get_Users_404()
+ {
+ using (var client = await _factory.CreateClientAsAdmin())
+ {
+ var res = await client.GetAsync("users/usernotexist");
+ res.AssertNotFound();
+ var body = await res.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(UserController.ErrorCodes.Get_NotExist, body.Code);
+ }
+ }
+
+ [Fact]
+ public async Task Put_Patch_Delete_User()
+ {
+ using (var client = await _factory.CreateClientAsAdmin())
+ {
+ const string username = "putpatchdeleteuser";
+ const string password = "password";
+ const string url = "users/" + username;
+
+ // Put Invalid Model
+ await InvalidModelTestHelpers.TestPutInvalidModel(client, url, new UserPutRequest { Password = null, Administrator = false });
+ await InvalidModelTestHelpers.TestPutInvalidModel(client, url, new UserPutRequest { Password = password, Administrator = null });
+
+ async Task CheckAdministrator(bool administrator)
+ {
+ var res = await client.GetAsync(url);
+ res.AssertOk();
+ var body = await res.ReadBodyAsJson<UserInfo>();
+ Assert.Equal(administrator, body.Administrator);
+ }
+
+ {
+ // Put Created.
+ var res = await client.PutAsJsonAsync(url, new UserPutRequest
+ {
+ Password = password,
+ Administrator = false
+ });
+ await res.AssertIsPutCreated();
+ await CheckAdministrator(false);
+ }
+
+ {
+ // Put Modified.
+ var res = await client.PutAsJsonAsync(url, new UserPutRequest
+ {
+ Password = password,
+ Administrator = true
+ });
+ await res.AssertIsPutModified();
+ await CheckAdministrator(true);
+ }
+
+ // Patch Not Exist
+ {
+ var res = await client.PatchAsJsonAsync("users/usernotexist", new UserPatchRequest { });
+ res.AssertNotFound();
+ var body = await res.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(UserController.ErrorCodes.Patch_NotExist, body.Code);
+ }
+
+ // Patch Success
+ {
+ var res = await client.PatchAsJsonAsync(url, new UserPatchRequest { Administrator = false });
+ res.AssertOk();
+ await CheckAdministrator(false);
+ }
+
+ // Delete Deleted
+ {
+ var res = await client.DeleteAsync(url);
+ await res.AssertIsDeleteDeleted();
+
+ var res2 = await client.GetAsync(url);
+ res2.AssertNotFound();
+ }
+
+ // Delete Not Exist
+ {
+ var res = await client.DeleteAsync(url);
+ await res.AssertIsDeleteNotExist();
+ }
+ }
+ }
+
+
+ public class ChangePasswordUnitTest : IClassFixture<MyWebApplicationFactory<Startup>>
+ {
+ private const string url = "userop/changepassword";
+
+ private readonly WebApplicationFactory<Startup> _factory;
+
+ public ChangePasswordUnitTest(MyWebApplicationFactory<Startup> factory, ITestOutputHelper outputHelper)
+ {
+ _factory = factory.WithTestLogging(outputHelper);
+ }
+
+
+ [Fact]
+ public async Task InvalidModel_OldPassword()
+ {
+ using (var client = await _factory.CreateClientAsUser())
+ {
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, url, new ChangePasswordRequest { OldPassword = null, NewPassword = "???" });
+ }
+ }
+
+ [Fact]
+ public async Task InvalidModel_NewPassword()
+ {
+ using (var client = await _factory.CreateClientAsUser())
+ {
+ 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.AssertBadRequest();
+ var body = await res.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(UserController.ErrorCodes.ChangePassword_BadOldPassword, body.Code);
+ }
+ }
+
+ [Fact]
+ public async Task Success()
+ {
+ const string username = "changepasswordtest";
+ const string password = "password";
+
+ // create a new user to avoid interference
+ using (var client = await _factory.CreateClientAsAdmin())
+ {
+ var res = await client.PutAsJsonAsync("users/" + username, new UserPutRequest { Password = password, Administrator = false });
+ Assert.Equal(HttpStatusCode.Created, res.StatusCode);
+ }
+
+ using (var client = await _factory.CreateClientWithCredential(username, password))
+ {
+ const string newPassword = "new";
+ var res = await client.PostAsJsonAsync(url, new ChangePasswordRequest { OldPassword = password, NewPassword = newPassword });
+ res.AssertOk();
+ await client.CreateUserTokenAsync(username, newPassword);
+ }
}
}
}
diff --git a/Timeline/Controllers/UserController.cs b/Timeline/Controllers/UserController.cs index af4cfb53..6f2fe77f 100644 --- a/Timeline/Controllers/UserController.cs +++ b/Timeline/Controllers/UserController.cs @@ -14,7 +14,7 @@ namespace Timeline.Controllers [ApiController]
public class UserController : Controller
{
- private static class ErrorCodes
+ public static class ErrorCodes
{
public const int Get_NotExist = -1001;
@@ -78,7 +78,7 @@ namespace Timeline.Controllers catch (UserNotExistException e)
{
_logger.LogInformation(e, FormatLogMessage("Attempt to patch a non-existent user.", Pair("Username", username)));
- return BadRequest(new CommonResponse(ErrorCodes.Patch_NotExist , "The user does not exist."));
+ return NotFound(new CommonResponse(ErrorCodes.Patch_NotExist, "The user does not exist."));
}
}
|