From dc1ab11cea249f4ca967f86b115147a63f7c93a5 Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Mon, 5 Aug 2019 18:58:56 +0800 Subject: 3 things. 1. Exchange Models and Entities namespace. 2. Fix the bug that input with missing field leads to 500. 3. Write unit tests. --- Timeline.Tests/TokenUnitTest.cs | 62 ++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 17 deletions(-) (limited to 'Timeline.Tests/TokenUnitTest.cs') diff --git a/Timeline.Tests/TokenUnitTest.cs b/Timeline.Tests/TokenUnitTest.cs index 7b83cd13..5c7496b5 100644 --- a/Timeline.Tests/TokenUnitTest.cs +++ b/Timeline.Tests/TokenUnitTest.cs @@ -6,7 +6,7 @@ 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; @@ -28,43 +28,61 @@ 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(); - Assert.Equal(TokenController.ErrorCodes.Create_UserNotExist, body.Code); + await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl, + new CreateTokenRequest { Username = null, Password = "user" }); } } [Fact] - public async void CreateTokenTest_BadPassword() + public async void CreateToken_InvalidModel_MissingPassword() { using (var client = _factory.CreateDefaultClient()) { - var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "???" }); + await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl, + new CreateTokenRequest { Username = "user", Password = null }); + } + } + + [Fact] + public async void CreateToken_InvalidModel_BadExpireOffset() + { + using (var client = _factory.CreateDefaultClient()) + { + await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl, + new CreateTokenRequest { Username = "user", Password = "user", 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(); - 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 = "user", Password = "???" }); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); var body = await response.ReadBodyAsJson(); - 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()) { @@ -77,7 +95,17 @@ namespace Timeline.Tests } [Fact] - public async void VerifyTokenTest_BadToken() + public async void VerifyToken_InvalidModel_MissingToken() + { + using (var client = _factory.CreateDefaultClient()) + { + await InvalidModelTestHelpers.TestPostInvalidModel(client, VerifyTokenUrl, + new VerifyTokenRequest { Token = null }); + } + } + + [Fact] + public async void VerifyToken_BadToken() { using (var client = _factory.CreateDefaultClient()) { @@ -89,7 +117,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 +159,7 @@ namespace Timeline.Tests } [Fact] - public async void VerifyTokenTest_Expired() + public async void VerifyToken_Expired() { using (var client = _factory.CreateDefaultClient()) { @@ -148,7 +176,7 @@ namespace Timeline.Tests } [Fact] - public async void VerifyTokenTest_Success() + public async void VerifyToken_Success() { using (var client = _factory.CreateDefaultClient()) { -- cgit v1.2.3 From d3e8485bcd1070108299995d6335318dea6a1c22 Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Thu, 8 Aug 2019 17:41:59 +0800 Subject: Reorganize unit tests. --- Timeline.Tests/AuthorizationUnitTest.cs | 6 +-- .../Authentication/AuthenticationExtensions.cs | 13 +++++- Timeline.Tests/Helpers/MyWebApplicationFactory.cs | 4 +- Timeline.Tests/Helpers/TestClock.cs | 25 ----------- Timeline.Tests/Helpers/TestUsers.cs | 42 ----------------- Timeline.Tests/Mock/Data/TestUsers.cs | 52 ++++++++++++++++++++++ Timeline.Tests/Mock/Services/TestClock.cs | 25 +++++++++++ Timeline.Tests/Timeline.Tests.csproj | 2 +- Timeline.Tests/TokenUnitTest.cs | 33 +++++++++----- Timeline.Tests/UserUnitTest.cs | 5 ++- 10 files changed, 121 insertions(+), 86 deletions(-) delete mode 100644 Timeline.Tests/Helpers/TestClock.cs delete mode 100644 Timeline.Tests/Helpers/TestUsers.cs create mode 100644 Timeline.Tests/Mock/Data/TestUsers.cs create mode 100644 Timeline.Tests/Mock/Services/TestClock.cs (limited to 'Timeline.Tests/TokenUnitTest.cs') 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 de88fd35..e31bd51c 100644 --- a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs +++ b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs @@ -3,6 +3,7 @@ using Newtonsoft.Json; using System.Net.Http; using System.Threading.Tasks; using Timeline.Models.Http; +using Timeline.Tests.Mock.Data; namespace Timeline.Tests.Helpers.Authentication { @@ -17,12 +18,22 @@ namespace Timeline.Tests.Helpers.Authentication return result; } - public static async Task CreateClientWithUser(this WebApplicationFactory factory, string username, string password) where T : class + public static async Task CreateClientWithCredential(this WebApplicationFactory 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 CreateClientAsUser(this WebApplicationFactory factory) where T : class + { + return factory.CreateClientWithCredential(MockUsers.UserUsername, MockUsers.UserPassword); + } + + public static Task CreateClientAsAdmin(this WebApplicationFactory factory) where T : class + { + return factory.CreateClientWithCredential(MockUsers.AdminUsername, MockUsers.AdminPassword); + } } } diff --git a/Timeline.Tests/Helpers/MyWebApplicationFactory.cs b/Timeline.Tests/Helpers/MyWebApplicationFactory.cs index d8da7168..b49756e4 100644 --- a/Timeline.Tests/Helpers/MyWebApplicationFactory.cs +++ b/Timeline.Tests/Helpers/MyWebApplicationFactory.cs @@ -7,6 +7,8 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; 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/TestClock.cs b/Timeline.Tests/Helpers/TestClock.cs deleted file mode 100644 index ea90305f..00000000 --- a/Timeline.Tests/Helpers/TestClock.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.Extensions.DependencyInjection; -using System; -using Timeline.Services; - -namespace Timeline.Tests.Helpers -{ - public class TestClock : IClock - { - public DateTime? MockCurrentTime { get; set; } = null; - - public DateTime GetCurrentTime() - { - return MockCurrentTime.GetValueOrDefault(DateTime.Now); - } - } - - public static class TestClockWebApplicationFactoryExtensions - { - public static TestClock GetTestClock(this WebApplicationFactory factory) where T : class - { - return factory.Server.Host.Services.GetRequiredService() as TestClock; - } - } -} 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(); - 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 MockUsers { get; } - - public static IReadOnlyList MockUserInfos { get; } - } -} 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(); + 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 Users { get; } + public static IReadOnlyList UserInfos { get; } + + public static UserInfo AdminUserInfo { get; } + public static UserInfo UserUserInfo { get; } + } +} diff --git a/Timeline.Tests/Mock/Services/TestClock.cs b/Timeline.Tests/Mock/Services/TestClock.cs new file mode 100644 index 00000000..0082171e --- /dev/null +++ b/Timeline.Tests/Mock/Services/TestClock.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; +using System; +using Timeline.Services; + +namespace Timeline.Tests.Mock.Services +{ + public class TestClock : IClock + { + public DateTime? MockCurrentTime { get; set; } = null; + + public DateTime GetCurrentTime() + { + return MockCurrentTime.GetValueOrDefault(DateTime.Now); + } + } + + public static class TestClockWebApplicationFactoryExtensions + { + public static TestClock GetTestClock(this WebApplicationFactory factory) where T : class + { + return factory.Server.Host.Services.GetRequiredService() as TestClock; + } + } +} 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 @@ - + netcoreapp2.2 diff --git a/Timeline.Tests/TokenUnitTest.cs b/Timeline.Tests/TokenUnitTest.cs index d2a68553..5f3b8e6d 100644 --- a/Timeline.Tests/TokenUnitTest.cs +++ b/Timeline.Tests/TokenUnitTest.cs @@ -2,7 +2,6 @@ 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; @@ -10,6 +9,8 @@ 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; @@ -53,7 +54,12 @@ namespace Timeline.Tests using (var client = _factory.CreateDefaultClient()) { await InvalidModelTestHelpers.TestPostInvalidModel(client, CreateTokenUrl, - new CreateTokenRequest { Username = "user", Password = "user", ExpireOffset = -1000 }); + new CreateTokenRequest + { + Username = MockUsers.UserUsername, + Password = MockUsers.UserPassword, + ExpireOffset = -1000 + }); } } @@ -62,7 +68,8 @@ namespace Timeline.Tests { using (var client = _factory.CreateDefaultClient()) { - var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "usernotexist", Password = "???" }); + var response = await client.PostAsJsonAsync(CreateTokenUrl, + new CreateTokenRequest { Username = "usernotexist", Password = "???" }); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); var body = await response.ReadBodyAsJson(); Assert.Equal(TokenController.ErrorCodes.Create_UserNotExist, body.Code); @@ -74,7 +81,8 @@ namespace Timeline.Tests { using (var client = _factory.CreateDefaultClient()) { - var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "???" }); + var response = await client.PostAsJsonAsync(CreateTokenUrl, + new CreateTokenRequest { Username = MockUsers.UserUsername, Password = "???" }); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); var body = await response.ReadBodyAsJson(); Assert.Equal(TokenController.ErrorCodes.Create_BadPassword, body.Code); @@ -86,11 +94,12 @@ namespace Timeline.Tests { 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(); 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); } } @@ -167,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(); Assert.Equal(TokenController.ErrorCodes.Verify_Expired, body.Code); mockClock.MockCurrentTime = null; @@ -180,11 +190,12 @@ namespace Timeline.Tests { 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(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 82284a82..7935dd9a 100644 --- a/Timeline.Tests/UserUnitTest.cs +++ b/Timeline.Tests/UserUnitTest.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Timeline.Models; using Timeline.Tests.Helpers; using Timeline.Tests.Helpers.Authentication; +using Timeline.Tests.Mock.Data; using Xunit; using Xunit.Abstractions; @@ -23,13 +24,13 @@ namespace Timeline.Tests [Fact] public async Task UserTest() { - 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(await res1.Content.ReadAsStringAsync()).ToList(); users.Sort(UserInfoComparers.Comparer); - Assert.Equal(TestMockUsers.MockUserInfos, users, UserInfoComparers.EqualityComparer); + Assert.Equal(MockUsers.UserInfos, users, UserInfoComparers.EqualityComparer); } } } -- cgit v1.2.3