aboutsummaryrefslogtreecommitdiff
path: root/Timeline.Tests
diff options
context:
space:
mode:
author杨宇千 <crupest@outlook.com>2019-08-09 21:48:12 +0800
committerGitHub <noreply@github.com>2019-08-09 21:48:12 +0800
commit38ff45fcc0b58a95ad52ba43a8be4ff466694269 (patch)
treef1cf455b758e8bf0265d4db0e42a404e9877b321 /Timeline.Tests
parente283a3e745bad05a55c572646d7b20fbaaeb522d (diff)
parentea8397bafe24b5c9ab814891eb3a293a07ca217e (diff)
downloadtimeline-38ff45fcc0b58a95ad52ba43a8be4ff466694269.tar.gz
timeline-38ff45fcc0b58a95ad52ba43a8be4ff466694269.tar.bz2
timeline-38ff45fcc0b58a95ad52ba43a8be4ff466694269.zip
Merge pull request #38 from crupest/null-request-field
Do 3 things.
Diffstat (limited to 'Timeline.Tests')
-rw-r--r--Timeline.Tests/AuthorizationUnitTest.cs6
-rw-r--r--Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs18
-rw-r--r--Timeline.Tests/Helpers/HttpClientExtensions.cs15
-rw-r--r--Timeline.Tests/Helpers/InvalidModelTestHelpers.cs27
-rw-r--r--Timeline.Tests/Helpers/MyWebApplicationFactory.cs6
-rw-r--r--Timeline.Tests/Helpers/ResponseExtensions.cs47
-rw-r--r--Timeline.Tests/Helpers/TestUsers.cs42
-rw-r--r--Timeline.Tests/Helpers/UserInfoComparers.cs2
-rw-r--r--Timeline.Tests/Mock/Data/TestUsers.cs52
-rw-r--r--Timeline.Tests/Mock/Services/TestClock.cs (renamed from Timeline.Tests/Helpers/TestClock.cs)2
-rw-r--r--Timeline.Tests/Timeline.Tests.csproj2
-rw-r--r--Timeline.Tests/TokenUnitTest.cs89
-rw-r--r--Timeline.Tests/UserUnitTest.cs192
-rw-r--r--Timeline.Tests/coverletArgs.runsettings13
14 files changed, 425 insertions, 88 deletions
diff --git a/Timeline.Tests/AuthorizationUnitTest.cs b/Timeline.Tests/AuthorizationUnitTest.cs
index 8df23c45..d9fb7406 100644
--- a/Timeline.Tests/AuthorizationUnitTest.cs
+++ b/Timeline.Tests/AuthorizationUnitTest.cs
@@ -34,7 +34,7 @@ namespace Timeline.Tests
[Fact]
public async Task AuthenticationTest()
{
- using (var client = await _factory.CreateClientWithUser("user", "user"))
+ using (var client = await _factory.CreateClientAsUser())
{
var response = await client.GetAsync(AuthorizeUrl);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@@ -44,7 +44,7 @@ namespace Timeline.Tests
[Fact]
public async Task UserAuthorizationTest()
{
- using (var client = await _factory.CreateClientWithUser("user", "user"))
+ using (var client = await _factory.CreateClientAsUser())
{
var response1 = await client.GetAsync(UserUrl);
Assert.Equal(HttpStatusCode.OK, response1.StatusCode);
@@ -56,7 +56,7 @@ namespace Timeline.Tests
[Fact]
public async Task AdminAuthorizationTest()
{
- using (var client = await _factory.CreateClientWithUser("admin", "admin"))
+ using (var client = await _factory.CreateClientAsAdmin())
{
var response1 = await client.GetAsync(UserUrl);
Assert.Equal(HttpStatusCode.OK, response1.StatusCode);
diff --git a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
index c8bec266..8a44c852 100644
--- a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
+++ b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
@@ -2,7 +2,8 @@ using Microsoft.AspNetCore.Mvc.Testing;
using Newtonsoft.Json;
using System.Net.Http;
using System.Threading.Tasks;
-using Timeline.Entities.Http;
+using Timeline.Models.Http;
+using Timeline.Tests.Mock.Data;
namespace Timeline.Tests.Helpers.Authentication
{
@@ -10,19 +11,30 @@ namespace Timeline.Tests.Helpers.Authentication
{
private const string CreateTokenUrl = "/token/create";
- public static async Task<CreateTokenResponse> CreateUserTokenAsync(this HttpClient client, string username, string password, double? expireOffset = null)
+ 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;
}
- public static async Task<HttpClient> CreateClientWithUser<T>(this WebApplicationFactory<T> factory, string username, string password) where T : class
+ public static async Task<HttpClient> CreateClientWithCredential<T>(this WebApplicationFactory<T> factory, string username, string password) where T : class
{
var client = factory.CreateDefaultClient();
var token = (await client.CreateUserTokenAsync(username, password)).Token;
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
return client;
}
+
+ public static Task<HttpClient> CreateClientAsUser<T>(this WebApplicationFactory<T> factory) where T : class
+ {
+ return factory.CreateClientWithCredential(MockUsers.UserUsername, MockUsers.UserPassword);
+ }
+
+ public static Task<HttpClient> CreateClientAsAdmin<T>(this WebApplicationFactory<T> factory) where T : class
+ {
+ return factory.CreateClientWithCredential(MockUsers.AdminUsername, MockUsers.AdminPassword);
+ }
}
}
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
new file mode 100644
index 00000000..1c079d0e
--- /dev/null
+++ b/Timeline.Tests/Helpers/InvalidModelTestHelpers.cs
@@ -0,0 +1,27 @@
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Timeline.Models.Http;
+using Xunit;
+
+namespace Timeline.Tests.Helpers
+{
+ public static class InvalidModelTestHelpers
+ {
+ public static async Task TestPostInvalidModel<T>(HttpClient client, string url, T body)
+ {
+ var response = await client.PostAsJsonAsync(url, body);
+ Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
+ 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/MyWebApplicationFactory.cs b/Timeline.Tests/Helpers/MyWebApplicationFactory.cs
index d9503526..b49756e4 100644
--- a/Timeline.Tests/Helpers/MyWebApplicationFactory.cs
+++ b/Timeline.Tests/Helpers/MyWebApplicationFactory.cs
@@ -5,8 +5,10 @@ using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using Timeline.Models;
+using Timeline.Entities;
using Timeline.Services;
+using Timeline.Tests.Mock.Data;
+using Timeline.Tests.Mock.Services;
using Xunit.Abstractions;
namespace Timeline.Tests.Helpers
@@ -34,7 +36,7 @@ namespace Timeline.Tests.Helpers
using (var context = new DatabaseContext(options))
{
context.Database.EnsureCreated();
- context.Users.AddRange(TestMockUsers.MockUsers);
+ context.Users.AddRange(MockUsers.Users);
context.SaveChanges();
}
}
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/Helpers/TestUsers.cs b/Timeline.Tests/Helpers/TestUsers.cs
deleted file mode 100644
index 71de8237..00000000
--- a/Timeline.Tests/Helpers/TestUsers.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using Timeline.Entities;
-using Timeline.Models;
-using Timeline.Services;
-
-namespace Timeline.Tests.Helpers
-{
- public static class TestMockUsers
- {
- static TestMockUsers()
- {
- var mockUsers = new List<User>();
- var passwordService = new PasswordService();
-
- mockUsers.Add(new User
- {
- Name = "user",
- EncryptedPassword = passwordService.HashPassword("user"),
- RoleString = UserUtility.IsAdminToRoleString(false),
- Version = 0,
- });
- mockUsers.Add(new User
- {
- Name = "admin",
- EncryptedPassword = passwordService.HashPassword("admin"),
- RoleString = UserUtility.IsAdminToRoleString(true),
- Version = 0,
- });
-
- MockUsers = mockUsers;
-
- var mockUserInfos = mockUsers.Select(u => UserUtility.CreateUserInfo(u)).ToList();
- mockUserInfos.Sort(UserInfoComparers.Comparer);
- MockUserInfos = mockUserInfos;
- }
-
- public static List<User> MockUsers { get; }
-
- public static IReadOnlyList<UserInfo> MockUserInfos { get; }
- }
-}
diff --git a/Timeline.Tests/Helpers/UserInfoComparers.cs b/Timeline.Tests/Helpers/UserInfoComparers.cs
index c7c584b7..1a1c652d 100644
--- a/Timeline.Tests/Helpers/UserInfoComparers.cs
+++ b/Timeline.Tests/Helpers/UserInfoComparers.cs
@@ -1,5 +1,5 @@
using System.Collections.Generic;
-using Timeline.Entities;
+using Timeline.Models;
namespace Timeline.Tests.Helpers
{
diff --git a/Timeline.Tests/Mock/Data/TestUsers.cs b/Timeline.Tests/Mock/Data/TestUsers.cs
new file mode 100644
index 00000000..d784e48c
--- /dev/null
+++ b/Timeline.Tests/Mock/Data/TestUsers.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Linq;
+using Timeline.Entities;
+using Timeline.Models;
+using Timeline.Services;
+using Timeline.Tests.Helpers;
+
+namespace Timeline.Tests.Mock.Data
+{
+ public static class MockUsers
+ {
+ static MockUsers()
+ {
+ var mockUsers = new List<User>();
+ var passwordService = new PasswordService();
+
+ mockUsers.Add(new User
+ {
+ Name = UserUsername,
+ EncryptedPassword = passwordService.HashPassword(UserPassword),
+ RoleString = UserUtility.IsAdminToRoleString(false),
+ Version = 0,
+ });
+ mockUsers.Add(new User
+ {
+ Name = AdminUsername,
+ EncryptedPassword = passwordService.HashPassword(AdminPassword),
+ RoleString = UserUtility.IsAdminToRoleString(true),
+ Version = 0,
+ });
+
+ Users = mockUsers;
+
+ var mockUserInfos = mockUsers.Select(u => UserUtility.CreateUserInfo(u)).ToList();
+ UserUserInfo = mockUserInfos[0];
+ AdminUserInfo = mockUserInfos[1];
+ mockUserInfos.Sort(UserInfoComparers.Comparer);
+ UserInfos = mockUserInfos;
+ }
+
+ public const string UserUsername = "user";
+ public const string AdminUsername = "admin";
+ public const string UserPassword= "user";
+ public const string AdminPassword = "admin";
+
+ internal static IReadOnlyList<User> Users { get; }
+ public static IReadOnlyList<UserInfo> UserInfos { get; }
+
+ public static UserInfo AdminUserInfo { get; }
+ public static UserInfo UserUserInfo { get; }
+ }
+}
diff --git a/Timeline.Tests/Helpers/TestClock.cs b/Timeline.Tests/Mock/Services/TestClock.cs
index ea90305f..0082171e 100644
--- a/Timeline.Tests/Helpers/TestClock.cs
+++ b/Timeline.Tests/Mock/Services/TestClock.cs
@@ -3,7 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
using System;
using Timeline.Services;
-namespace Timeline.Tests.Helpers
+namespace Timeline.Tests.Mock.Services
{
public class TestClock : IClock
{
diff --git a/Timeline.Tests/Timeline.Tests.csproj b/Timeline.Tests/Timeline.Tests.csproj
index 8cc304f4..854c63ac 100644
--- a/Timeline.Tests/Timeline.Tests.csproj
+++ b/Timeline.Tests/Timeline.Tests.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
+<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
diff --git a/Timeline.Tests/TokenUnitTest.cs b/Timeline.Tests/TokenUnitTest.cs
index f942767d..5f3b8e6d 100644
--- a/Timeline.Tests/TokenUnitTest.cs
+++ b/Timeline.Tests/TokenUnitTest.cs
@@ -2,14 +2,15 @@ using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System;
-using System.Linq;
using System.Net;
using System.Net.Http;
using Timeline.Controllers;
-using Timeline.Entities.Http;
+using Timeline.Models.Http;
using Timeline.Services;
using Timeline.Tests.Helpers;
using Timeline.Tests.Helpers.Authentication;
+using Timeline.Tests.Mock.Data;
+using Timeline.Tests.Mock.Services;
using Xunit;
using Xunit.Abstractions;
@@ -28,56 +29,92 @@ namespace Timeline.Tests
}
[Fact]
- public async void CreateTokenTest_UserNotExist()
+ public async void CreateToken_MissingUsername()
{
using (var client = _factory.CreateDefaultClient())
{
- var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "usernotexist", Password = "???" });
- Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
- var body = await response.ReadBodyAsJson<CommonResponse>();
- Assert.Equal(TokenController.ErrorCodes.Create_UserNotExist, body.Code);
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl,
+ new CreateTokenRequest { Username = null, Password = "user" });
+ }
+ }
+
+ [Fact]
+ public async void CreateToken_InvalidModel_MissingPassword()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl,
+ new CreateTokenRequest { Username = "user", Password = null });
}
}
[Fact]
- public async void CreateTokenTest_BadPassword()
+ public async void CreateToken_InvalidModel_BadExpireOffset()
{
using (var client = _factory.CreateDefaultClient())
{
- var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "???" });
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl,
+ new CreateTokenRequest
+ {
+ Username = MockUsers.UserUsername,
+ Password = MockUsers.UserPassword,
+ ExpireOffset = -1000
+ });
+ }
+ }
+
+ [Fact]
+ public async void CreateToken_UserNotExist()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ var response = await client.PostAsJsonAsync(CreateTokenUrl,
+ new CreateTokenRequest { Username = "usernotexist", Password = "???" });
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var body = await response.ReadBodyAsJson<CommonResponse>();
- Assert.Equal(TokenController.ErrorCodes.Create_BadPassword, body.Code);
+ Assert.Equal(TokenController.ErrorCodes.Create_UserNotExist, body.Code);
}
}
[Fact]
- public async void CreateTokenTest_BadExpireOffset()
+ public async void CreateToken_BadPassword()
{
using (var client = _factory.CreateDefaultClient())
{
- var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "???", Password = "???", ExpireOffset = -1000 });
+ var response = await client.PostAsJsonAsync(CreateTokenUrl,
+ new CreateTokenRequest { Username = MockUsers.UserUsername, Password = "???" });
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var body = await response.ReadBodyAsJson<CommonResponse>();
- Assert.Equal(TokenController.ErrorCodes.Create_BadExpireOffset, body.Code);
+ Assert.Equal(TokenController.ErrorCodes.Create_BadPassword, body.Code);
}
}
[Fact]
- public async void CreateTokenTest_Success()
+ public async void CreateToken_Success()
{
using (var client = _factory.CreateDefaultClient())
{
- var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "user" });
+ var response = await client.PostAsJsonAsync(CreateTokenUrl,
+ new CreateTokenRequest { Username = MockUsers.UserUsername, Password = MockUsers.UserPassword });
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = await response.ReadBodyAsJson<CreateTokenResponse>();
Assert.NotEmpty(body.Token);
- Assert.Equal(TestMockUsers.MockUserInfos.Where(u => u.Username == "user").Single(), body.User, UserInfoComparers.EqualityComparer);
+ Assert.Equal(MockUsers.UserUserInfo, body.User, UserInfoComparers.EqualityComparer);
+ }
+ }
+
+ [Fact]
+ public async void VerifyToken_InvalidModel_MissingToken()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ await InvalidModelTestHelpers.TestPostInvalidModel(client, VerifyTokenUrl,
+ new VerifyTokenRequest { Token = null });
}
}
[Fact]
- public async void VerifyTokenTest_BadToken()
+ public async void VerifyToken_BadToken()
{
using (var client = _factory.CreateDefaultClient())
{
@@ -89,7 +126,7 @@ namespace Timeline.Tests
}
[Fact]
- public async void VerifyTokenTest_BadVersion_AND_UserNotExist()
+ public async void VerifyToken_BadVersion_AND_UserNotExist()
{
using (var client = _factory.CreateDefaultClient())
{
@@ -131,7 +168,7 @@ namespace Timeline.Tests
}
[Fact]
- public async void VerifyTokenTest_Expired()
+ public async void VerifyToken_Expired()
{
using (var client = _factory.CreateDefaultClient())
{
@@ -139,8 +176,9 @@ namespace Timeline.Tests
// because verify logic is encapsuled in other library.
var mockClock = _factory.GetTestClock();
mockClock.MockCurrentTime = DateTime.Now - TimeSpan.FromDays(2);
- var token = (await client.CreateUserTokenAsync("user", "user", 1)).Token;
- var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token });
+ var token = (await client.CreateUserTokenAsync(MockUsers.UserUsername, MockUsers.UserPassword, 1)).Token;
+ var response = await client.PostAsJsonAsync(VerifyTokenUrl,
+ new VerifyTokenRequest { Token = token });
var body = await response.ReadBodyAsJson<CommonResponse>();
Assert.Equal(TokenController.ErrorCodes.Verify_Expired, body.Code);
mockClock.MockCurrentTime = null;
@@ -148,15 +186,16 @@ namespace Timeline.Tests
}
[Fact]
- public async void VerifyTokenTest_Success()
+ public async void VerifyToken_Success()
{
using (var client = _factory.CreateDefaultClient())
{
- var createTokenResult = await client.CreateUserTokenAsync("user", "user");
- var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = createTokenResult.Token });
+ var createTokenResult = await client.CreateUserTokenAsync(MockUsers.UserUsername, MockUsers.UserPassword);
+ var response = await client.PostAsJsonAsync(VerifyTokenUrl,
+ new VerifyTokenRequest { Token = createTokenResult.Token });
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var body = JsonConvert.DeserializeObject<VerifyTokenResponse>(await response.Content.ReadAsStringAsync());
- Assert.Equal(TestMockUsers.MockUserInfos.Where(u => u.Username == "user").Single(), body.User, UserInfoComparers.EqualityComparer);
+ Assert.Equal(MockUsers.UserUserInfo, body.User, UserInfoComparers.EqualityComparer);
}
}
}
diff --git a/Timeline.Tests/UserUnitTest.cs b/Timeline.Tests/UserUnitTest.cs
index de429c7f..c5c91d34 100644
--- a/Timeline.Tests/UserUnitTest.cs
+++ b/Timeline.Tests/UserUnitTest.cs
@@ -1,11 +1,13 @@
using Microsoft.AspNetCore.Mvc.Testing;
-using Newtonsoft.Json;
-using System.Linq;
using System.Net;
+using System.Net.Http;
using System.Threading.Tasks;
-using Timeline.Entities;
+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;
@@ -21,15 +23,185 @@ namespace Timeline.Tests
}
[Fact]
- public async Task UserTest()
+ public async Task Get_Users_List()
{
- using (var client = await _factory.CreateClientWithUser("admin", "admin"))
+ 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(TestMockUsers.MockUserInfos, 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.Tests/coverletArgs.runsettings b/Timeline.Tests/coverletArgs.runsettings
new file mode 100644
index 00000000..24cd1822
--- /dev/null
+++ b/Timeline.Tests/coverletArgs.runsettings
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<RunSettings>
+ <DataCollectionRunSettings>
+ <DataCollectors>
+ <DataCollector friendlyName="XPlat code coverage">
+ <Configuration>
+ <!-- [Assembly-Filter]Type-Filter -->
+ <Exclude>[xunit.*]*,[Timeline]Timeline.Migrations.*</Exclude>
+ </Configuration>
+ </DataCollector>
+ </DataCollectors>
+ </DataCollectionRunSettings>
+</RunSettings>