diff options
Diffstat (limited to 'Timeline.Tests')
-rw-r--r-- | Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs | 4 | ||||
-rw-r--r-- | Timeline.Tests/Helpers/TestClock.cs | 50 | ||||
-rw-r--r-- | Timeline.Tests/Helpers/WebApplicationFactoryExtensions.cs | 12 | ||||
-rw-r--r-- | Timeline.Tests/Timeline.Tests.csproj | 45 | ||||
-rw-r--r-- | Timeline.Tests/TokenUnitTest.cs | 312 |
5 files changed, 221 insertions, 202 deletions
diff --git a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs index 03fb9714..27362ac3 100644 --- a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs +++ b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs @@ -10,9 +10,9 @@ namespace Timeline.Tests.Helpers.Authentication { private const string CreateTokenUrl = "/token/create"; - public static async Task<CreateTokenResponse> CreateUserTokenAsync(this HttpClient client, string username, string password) + public static async Task<CreateTokenResponse> CreateUserTokenAsync(this HttpClient client, string username, string password, double? expireOffset = null) { - var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = username, Password = password }); + var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = username, Password = password, ExpireOffset = expireOffset }); var result = JsonConvert.DeserializeObject<CreateTokenResponse>(await response.Content.ReadAsStringAsync()); return result; } diff --git a/Timeline.Tests/Helpers/TestClock.cs b/Timeline.Tests/Helpers/TestClock.cs index fc200be9..91523f2b 100644 --- a/Timeline.Tests/Helpers/TestClock.cs +++ b/Timeline.Tests/Helpers/TestClock.cs @@ -1,25 +1,25 @@ -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.Extensions.DependencyInjection; -using System; -using Timeline.Services; - -namespace Timeline.Tests.Helpers -{ - public class TestClock : IClock - { - DateTime? MockCurrentTime { get; set; } = null; - - public DateTime GetCurrentTime() - { - return MockCurrentTime.GetValueOrDefault(DateTime.Now); - } - } - - public static class TestClockWebApplicationFactoryExtensions - { - public static TestClock GetTestClock<T>(this WebApplicationFactory<T> factory) where T : class - { - return factory.Server.Host.Services.GetRequiredService<IClock>() as TestClock; - } - } -} +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<T>(this WebApplicationFactory<T> factory) where T : class
+ {
+ return factory.Server.Host.Services.GetRequiredService<IClock>() as TestClock;
+ }
+ }
+}
diff --git a/Timeline.Tests/Helpers/WebApplicationFactoryExtensions.cs b/Timeline.Tests/Helpers/WebApplicationFactoryExtensions.cs index aa005ba3..5a1f97d5 100644 --- a/Timeline.Tests/Helpers/WebApplicationFactoryExtensions.cs +++ b/Timeline.Tests/Helpers/WebApplicationFactoryExtensions.cs @@ -1,11 +1,11 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.AspNetCore.TestHost; +using Microsoft.AspNetCore.TestHost;
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Timeline.Models; -using Timeline.Services; +using Timeline.Services;
using Xunit.Abstractions; namespace Timeline.Tests.Helpers @@ -24,12 +24,12 @@ namespace Timeline.Tests.Helpers .ConfigureServices(services => { var serviceProvider = new ServiceCollection() - .AddEntityFrameworkInMemoryDatabase() + .AddEntityFrameworkSqlite() .BuildServiceProvider(); services.AddDbContext<DatabaseContext>(options => { - options.UseInMemoryDatabase("timeline"); + options.UseSqlite("Data Source=:memory:;"); //TODO! This not work! options.UseInternalServiceProvider(serviceProvider); }); @@ -50,8 +50,8 @@ namespace Timeline.Tests.Helpers } }) .ConfigureTestServices(services => - { - services.AddSingleton<IClock, TestClock>(); + {
+ services.AddSingleton<IClock, TestClock>();
}); }); } diff --git a/Timeline.Tests/Timeline.Tests.csproj b/Timeline.Tests/Timeline.Tests.csproj index 820737cc..1a5f2850 100644 --- a/Timeline.Tests/Timeline.Tests.csproj +++ b/Timeline.Tests/Timeline.Tests.csproj @@ -1,22 +1,23 @@ -<Project Sdk="Microsoft.NET.Sdk.Web"> - - <PropertyGroup> - <TargetFramework>netcoreapp2.2</TargetFramework> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.AspNetCore.App" /> - <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" /> - <PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="2.2.0-rtm-35646" /> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" /> - <PackageReference Include="xunit" Version="2.4.1" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1"> - <PrivateAssets>all</PrivateAssets> - <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> - </PackageReference> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\Timeline\Timeline.csproj" /> - </ItemGroup> -</Project> +<Project Sdk="Microsoft.NET.Sdk.Web">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.2</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.AspNetCore.App" />
+ <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Testing" Version="2.2.0-rtm-35646" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
+ <PackageReference Include="xunit" Version="2.4.1" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Timeline\Timeline.csproj" />
+ </ItemGroup>
+</Project>
diff --git a/Timeline.Tests/TokenUnitTest.cs b/Timeline.Tests/TokenUnitTest.cs index d7df8797..1fe3cff6 100644 --- a/Timeline.Tests/TokenUnitTest.cs +++ b/Timeline.Tests/TokenUnitTest.cs @@ -1,147 +1,165 @@ -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json; -using System.Linq; -using System.Net; -using System.Net.Http; -using Timeline.Controllers; -using Timeline.Entities; -using Timeline.Entities.Http; -using Timeline.Models; -using Timeline.Services; -using Timeline.Tests.Helpers; -using Timeline.Tests.Helpers.Authentication; -using Xunit; -using Xunit.Abstractions; - -namespace Timeline.Tests -{ - public class TokenUnitTest : IClassFixture<WebApplicationFactory<Startup>> - { - private const string CreateTokenUrl = "token/create"; - private const string VerifyTokenUrl = "token/verify"; - - private readonly WebApplicationFactory<Startup> _factory; - - public TokenUnitTest(WebApplicationFactory<Startup> factory, ITestOutputHelper outputHelper) - { - _factory = factory.WithTestConfig(outputHelper); - } - - [Fact] - public async void CreateTokenTest_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_UserNotExist, body.Code); - } - } - - [Fact] - public async void CreateTokenTest_BadPassword() - { - using (var client = _factory.CreateDefaultClient()) - { - var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "???" }); - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - var body = await response.ReadBodyAsJson<CommonResponse>(); - Assert.Equal(TokenController.ErrorCodes.Create_BadPassword, body.Code); - } - } - - [Fact] - public async void CreateTokenTest_BadExpireOffset() - { - using (var client = _factory.CreateDefaultClient()) - { - var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "???", Password = "???", ExpireOffset = -1000 }); - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - var body = await response.ReadBodyAsJson<CommonResponse>(); - Assert.Equal(TokenController.ErrorCodes.Create_BadExpireOffset, body.Code); - } - } - - [Fact] - public async void CreateTokenTest_Success() - { - using (var client = _factory.CreateDefaultClient()) - { - var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "user" }); - 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); - } - } - - [Fact] - public async void VerifyTokenTest_BadToken() - { - using (var client = _factory.CreateDefaultClient()) - { - var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = "bad token hahaha" }); - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - var body = await response.ReadBodyAsJson<CommonResponse>(); - Assert.Equal(TokenController.ErrorCodes.Verify_BadToken, body.Code); - } - } - - [Fact] - public async void VerifyTokenTest_BadVersion_AND_UserNotExist() - { - using (var client = _factory.CreateDefaultClient()) - { - using (var scope = _factory.Server.Host.Services.CreateScope()) // UserService is scoped. - { - // create a user for test - var userService = scope.ServiceProvider.GetRequiredService<IUserService>(); - - const string username = "verifytokentest0"; - const string password = "12345678"; - - await userService.PutUser(username, password, false); - - // create a token - var token = (await client.CreateUserTokenAsync(username, password)).Token; - - // increase version - await userService.PatchUser(username, null, null); - - // test against bad version - var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token }); - Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - var body = await response.ReadBodyAsJson<CommonResponse>(); - Assert.Equal(TokenController.ErrorCodes.Verify_BadVersion, body.Code); - - // create another token - var token2 = (await client.CreateUserTokenAsync(username, password)).Token; - - // delete user - await userService.DeleteUser(username); - - // test against user not exist - var response2 = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token }); - Assert.Equal(HttpStatusCode.BadRequest, response2.StatusCode); - var body2 = await response2.ReadBodyAsJson<CommonResponse>(); - Assert.Equal(TokenController.ErrorCodes.Verify_UserNotExist, body2.Code); - } - } - } - - [Fact] - public async void VerifyTokenTest_Success() - { - using (var client = _factory.CreateDefaultClient()) - { - var createTokenResult = await client.CreateUserTokenAsync("admin", "admin"); - 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); - } - } - } -} +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;
+using Timeline.Entities.Http;
+using Timeline.Models;
+using Timeline.Services;
+using Timeline.Tests.Helpers;
+using Timeline.Tests.Helpers.Authentication;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Timeline.Tests
+{
+ public class TokenUnitTest : IClassFixture<WebApplicationFactory<Startup>>
+ {
+ private const string CreateTokenUrl = "token/create";
+ private const string VerifyTokenUrl = "token/verify";
+
+ private readonly WebApplicationFactory<Startup> _factory;
+
+ public TokenUnitTest(WebApplicationFactory<Startup> factory, ITestOutputHelper outputHelper)
+ {
+ _factory = factory.WithTestConfig(outputHelper);
+ }
+
+ [Fact]
+ public async void CreateTokenTest_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_UserNotExist, body.Code);
+ }
+ }
+
+ [Fact]
+ public async void CreateTokenTest_BadPassword()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "???" });
+ Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
+ var body = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(TokenController.ErrorCodes.Create_BadPassword, body.Code);
+ }
+ }
+
+ [Fact]
+ public async void CreateTokenTest_BadExpireOffset()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "???", Password = "???", ExpireOffset = -1000 });
+ Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
+ var body = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(TokenController.ErrorCodes.Create_BadExpireOffset, body.Code);
+ }
+ }
+
+ [Fact]
+ public async void CreateTokenTest_Success()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ var response = await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest { Username = "user", Password = "user" });
+ 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);
+ }
+ }
+
+ [Fact]
+ public async void VerifyTokenTest_BadToken()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = "bad token hahaha" });
+ Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
+ var body = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(TokenController.ErrorCodes.Verify_BadToken, body.Code);
+ }
+ }
+
+ [Fact]
+ public async void VerifyTokenTest_BadVersion_AND_UserNotExist()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ using (var scope = _factory.Server.Host.Services.CreateScope()) // UserService is scoped.
+ {
+ // create a user for test
+ var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
+
+ const string username = "verifytokentest0";
+ const string password = "12345678";
+
+ await userService.PutUser(username, password, false);
+
+ // create a token
+ var token = (await client.CreateUserTokenAsync(username, password)).Token;
+
+ // increase version
+ await userService.PatchUser(username, null, null);
+
+ // test against bad version
+ var response = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token });
+ Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
+ var body = await response.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(TokenController.ErrorCodes.Verify_BadVersion, body.Code);
+
+ // create another token
+ var token2 = (await client.CreateUserTokenAsync(username, password)).Token;
+
+ // delete user
+ await userService.DeleteUser(username);
+
+ // test against user not exist
+ var response2 = await client.PostAsJsonAsync(VerifyTokenUrl, new VerifyTokenRequest { Token = token });
+ Assert.Equal(HttpStatusCode.BadRequest, response2.StatusCode);
+ var body2 = await response2.ReadBodyAsJson<CommonResponse>();
+ Assert.Equal(TokenController.ErrorCodes.Verify_UserNotExist, body2.Code);
+ }
+ }
+ }
+
+ [Fact]
+ public async void VerifyTokenTest_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("user", "user", 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;
+ }
+ }
+
+ [Fact]
+ public async void VerifyTokenTest_Success()
+ {
+ using (var client = _factory.CreateDefaultClient())
+ {
+ var createTokenResult = await client.CreateUserTokenAsync("user", "user");
+ 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);
+ }
+ }
+ }
+}
|