aboutsummaryrefslogtreecommitdiff
path: root/Timeline.Tests
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline.Tests')
-rw-r--r--Timeline.Tests/Controllers/TokenControllerTest.cs6
-rw-r--r--Timeline.Tests/Controllers/UserControllerTest.cs6
-rw-r--r--Timeline.Tests/IntegratedTests/UserDetailTest.cs145
-rw-r--r--Timeline.Tests/UserDetailServiceTest.cs271
-rw-r--r--Timeline.Tests/UserDetailValidatorTest.cs97
-rw-r--r--Timeline.Tests/UsernameValidatorUnitTest.cs7
6 files changed, 10 insertions, 522 deletions
diff --git a/Timeline.Tests/Controllers/TokenControllerTest.cs b/Timeline.Tests/Controllers/TokenControllerTest.cs
index 71520e77..53b6c606 100644
--- a/Timeline.Tests/Controllers/TokenControllerTest.cs
+++ b/Timeline.Tests/Controllers/TokenControllerTest.cs
@@ -101,9 +101,9 @@ namespace Timeline.Tests.Controllers
public static IEnumerable<object[]> Verify_BadRequest_Data()
{
- yield return new object[] { new JwtTokenVerifyException(JwtTokenVerifyException.ErrorCodes.Expired), Verify.Expired };
- yield return new object[] { new JwtTokenVerifyException(JwtTokenVerifyException.ErrorCodes.IdClaimBadFormat), Verify.BadFormat };
- yield return new object[] { new BadTokenVersionException(), Verify.OldVersion };
+ yield return new object[] { new JwtVerifyException(JwtVerifyException.ErrorCodes.Expired), Verify.Expired };
+ yield return new object[] { new JwtVerifyException(JwtVerifyException.ErrorCodes.IdClaimBadFormat), Verify.BadFormat };
+ yield return new object[] { new JwtVerifyException(JwtVerifyException.ErrorCodes.OldVersion), Verify.OldVersion };
yield return new object[] { new UserNotExistException(), Verify.UserNotExist };
}
diff --git a/Timeline.Tests/Controllers/UserControllerTest.cs b/Timeline.Tests/Controllers/UserControllerTest.cs
index ddbc3fbc..471ed851 100644
--- a/Timeline.Tests/Controllers/UserControllerTest.cs
+++ b/Timeline.Tests/Controllers/UserControllerTest.cs
@@ -69,8 +69,8 @@ namespace Timeline.Tests.Controllers
}
[Theory]
- [InlineData(PutResult.Created, true)]
- [InlineData(PutResult.Modified, false)]
+ [InlineData(PutResult.Create, true)]
+ [InlineData(PutResult.Modify, false)]
public async Task Put_Success(PutResult result, bool create)
{
const string username = "aaa";
@@ -176,7 +176,7 @@ namespace Timeline.Tests.Controllers
[Theory]
[InlineData(typeof(UserNotExistException), Op.ChangeUsername.NotExist)]
- [InlineData(typeof(UserAlreadyExistException), Op.ChangeUsername.AlreadyExist)]
+ [InlineData(typeof(UsernameConfictException), Op.ChangeUsername.AlreadyExist)]
public async Task Op_ChangeUsername_Failure(Type exceptionType, int code)
{
const string oldUsername = "aaa";
diff --git a/Timeline.Tests/IntegratedTests/UserDetailTest.cs b/Timeline.Tests/IntegratedTests/UserDetailTest.cs
deleted file mode 100644
index 4d268efa..00000000
--- a/Timeline.Tests/IntegratedTests/UserDetailTest.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-using FluentAssertions;
-using Microsoft.AspNetCore.Mvc.Testing;
-using System;
-using System.Net;
-using System.Threading.Tasks;
-using Timeline.Controllers;
-using Timeline.Models;
-using Timeline.Tests.Helpers;
-using Timeline.Tests.Helpers.Authentication;
-using Timeline.Tests.Mock.Data;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public class UserDetailTest : IClassFixture<WebApplicationFactory<Startup>>, IDisposable
- {
- private readonly TestApplication _testApp;
- private readonly WebApplicationFactory<Startup> _factory;
-
- public UserDetailTest(WebApplicationFactory<Startup> factory)
- {
- _testApp = new TestApplication(factory);
- _factory = _testApp.Factory;
- }
-
- public void Dispose()
- {
- _testApp.Dispose();
- }
-
- [Fact]
- public async Task TestAsUser()
- {
- using (var client = await _factory.CreateClientAsUser())
- {
- {
- var res = await client.GetAsync($"users/usernotexist/nickname");
- res.Should().HaveStatusCode(404)
- .And.Should().HaveCommonBody().Which.Code.Should().Be(UserDetailController.ErrorCodes.GetNickname_UserNotExist);
- }
-
- {
- var res = await client.GetAsync($"users/usernotexist/details");
- res.Should().HaveStatusCode(404)
- .And.Should().HaveCommonBody().Which.Code.Should().Be(UserDetailController.ErrorCodes.Get_UserNotExist);
- }
-
- async Task GetAndTest(UserDetail d)
- {
- var res = await client.GetAsync($"users/{MockUser.User.Username}/details");
- res.Should().HaveStatusCode(200)
- .And.Should().HaveJsonBody<UserDetail>()
- .Which.Should().BeEquivalentTo(d);
- }
-
- await GetAndTest(new UserDetail());
-
- {
- var res = await client.PatchAsJsonAsync($"users/{MockUser.Admin.Username}/details", new UserDetail());
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden)
- .And.Should().HaveCommonBody().Which.Code.Should().Be(UserDetailController.ErrorCodes.Patch_Forbid);
- }
-
- {
- var res = await client.PatchAsJsonAsync($"users/{MockUser.User.Username}/details", new UserDetail
- {
- Nickname = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
- QQ = "aaaaaaa",
- Email = "aaaaaa",
- PhoneNumber = "aaaaaaaa"
- });
- var body = res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.Should().HaveCommonBody().Which;
- body.Code.Should().Be(ErrorCodes.Http.Common.InvalidModel);
- foreach (var key in new string[] { "nickname", "qq", "email", "phonenumber" })
- {
- body.Message.Should().ContainEquivalentOf(key);
- }
- }
-
-
- var detail = new UserDetail
- {
- Nickname = "aaa",
- QQ = "1234567",
- Email = "aaaa@aaa.net",
- Description = "aaaaaaaaa"
- };
-
- {
- var res = await client.PatchAsJsonAsync($"users/{MockUser.User.Username}/details", detail);
- res.Should().HaveStatusCode(200);
- await GetAndTest(detail);
- }
-
- {
- var res = await client.GetAsync($"users/{MockUser.User.Username}/nickname");
- res.Should().HaveStatusCode(200).And.Should().HaveJsonBody<UserDetail>()
- .Which.Should().BeEquivalentTo(new UserDetail
- {
- Nickname = detail.Nickname
- });
- }
-
- var detail2 = new UserDetail
- {
- QQ = "",
- PhoneNumber = "12345678910",
- Description = "bbbbbbbb"
- };
-
- {
- var res = await client.PatchAsJsonAsync($"users/{MockUser.User.Username}/details", detail2);
- res.Should().HaveStatusCode(200);
- await GetAndTest(new UserDetail
- {
- Nickname = detail.Nickname,
- QQ = null,
- Email = detail.Email,
- PhoneNumber = detail2.PhoneNumber,
- Description = detail2.Description
- });
- }
- }
- }
-
- [Fact]
- public async Task TestAsAdmin()
- {
- using (var client = await _factory.CreateClientAsAdmin())
- {
- {
- var res = await client.PatchAsJsonAsync($"users/{MockUser.User.Username}/details", new UserDetail());
- res.Should().HaveStatusCode(200);
- }
-
- {
- var res = await client.PatchAsJsonAsync($"users/usernotexist/details", new UserDetail());
- res.Should().HaveStatusCode(404)
- .And.Should().HaveCommonBody().Which.Code.Should().Be(UserDetailController.ErrorCodes.Patch_UserNotExist);
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/Timeline.Tests/UserDetailServiceTest.cs b/Timeline.Tests/UserDetailServiceTest.cs
deleted file mode 100644
index d16d1a40..00000000
--- a/Timeline.Tests/UserDetailServiceTest.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-using FluentAssertions;
-using Microsoft.Extensions.Logging.Abstractions;
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using Timeline.Entities;
-using Timeline.Models;
-using Timeline.Services;
-using Timeline.Tests.Helpers;
-using Timeline.Tests.Mock.Data;
-using Xunit;
-
-namespace Timeline.Tests
-{
- public class UserDetailServiceTest : IDisposable
- {
- private readonly TestDatabase _database;
-
- private readonly UserDetailService _service;
-
- public UserDetailServiceTest()
- {
- _database = new TestDatabase();
-
- _service = new UserDetailService(NullLogger<UserDetailService>.Instance, _database.DatabaseContext);
- }
-
- public void Dispose()
- {
- _database.Dispose();
- }
-
- [Fact]
- public void GetNickname_ShouldThrow_ArgumentException()
- {
- // no need to await because arguments are checked syncronizedly.
- _service.Invoking(s => s.GetUserNickname(null)).Should().Throw<ArgumentException>()
- .Where(e => e.ParamName == "username" && e.Message.Contains("null", StringComparison.OrdinalIgnoreCase));
- _service.Invoking(s => s.GetUserNickname("")).Should().Throw<ArgumentException>()
- .Where(e => e.ParamName == "username" && e.Message.Contains("empty", StringComparison.OrdinalIgnoreCase));
- }
-
- [Fact]
- public void GetNickname_ShouldThrow_UserNotExistException()
- {
- const string username = "usernotexist";
- _service.Awaiting(s => s.GetUserNickname(username)).Should().Throw<UserNotExistException>()
- .Where(e => e.Username == username);
- }
-
- [Fact]
- public async Task GetNickname_Should_Create_And_ReturnDefault()
- {
- {
- var nickname = await _service.GetUserNickname(MockUser.User.Username);
- nickname.Should().BeNull();
- }
-
- {
- var context = _database.DatabaseContext;
- var userId = await DatabaseExtensions.CheckAndGetUser(context.Users, MockUser.User.Username);
- var detail = context.UserDetails.Where(e => e.UserId == userId).Single();
- detail.Nickname.Should().BeNullOrEmpty();
- detail.QQ.Should().BeNullOrEmpty();
- detail.Email.Should().BeNullOrEmpty();
- detail.PhoneNumber.Should().BeNullOrEmpty();
- detail.Description.Should().BeNullOrEmpty();
- }
- }
-
- [Theory]
- [InlineData(null)]
- [InlineData("")]
- [InlineData("nickname")]
- public async Task GetNickname_Should_ReturnData(string nickname)
- {
- {
- var context = _database.DatabaseContext;
- var userId = await DatabaseExtensions.CheckAndGetUser(context.Users, MockUser.User.Username);
- var entity = new UserDetailEntity
- {
- Nickname = nickname,
- UserId = userId
- };
- context.Add(entity);
- await context.SaveChangesAsync();
- }
-
- {
- var n = await _service.GetUserNickname(MockUser.User.Username);
- n.Should().Equals(string.IsNullOrEmpty(nickname) ? null : nickname);
- }
- }
-
- [Fact]
- public void GetDetail_ShouldThrow_ArgumentException()
- {
- // no need to await because arguments are checked syncronizedly.
- _service.Invoking(s => s.GetUserDetail(null)).Should().Throw<ArgumentException>()
- .Where(e => e.ParamName == "username" && e.Message.Contains("null", StringComparison.OrdinalIgnoreCase));
- _service.Invoking(s => s.GetUserDetail("")).Should().Throw<ArgumentException>()
- .Where(e => e.ParamName == "username" && e.Message.Contains("empty", StringComparison.OrdinalIgnoreCase));
- }
-
- [Fact]
- public void GetDetail_ShouldThrow_UserNotExistException()
- {
- const string username = "usernotexist";
- _service.Awaiting(s => s.GetUserDetail(username)).Should().Throw<UserNotExistException>()
- .Where(e => e.Username == username);
- }
-
- [Fact]
- public async Task GetDetail_Should_Create_And_ReturnDefault()
- {
- {
- var detail = await _service.GetUserDetail(MockUser.User.Username);
- detail.Should().BeEquivalentTo(new UserDetail());
- }
-
- {
- var context = _database.DatabaseContext;
- var userId = await DatabaseExtensions.CheckAndGetUser(context.Users, MockUser.User.Username);
- var detail = context.UserDetails.Where(e => e.UserId == userId).Single();
- detail.Nickname.Should().BeNullOrEmpty();
- detail.QQ.Should().BeNullOrEmpty();
- detail.Email.Should().BeNullOrEmpty();
- detail.PhoneNumber.Should().BeNullOrEmpty();
- detail.Description.Should().BeNullOrEmpty();
- }
- }
-
- [Fact]
- public async Task GetDetail_Should_ReturnData()
- {
- const string email = "ha@aaa.net";
- const string description = "hahaha";
-
-
- {
- var context = _database.DatabaseContext;
- var userId = await DatabaseExtensions.CheckAndGetUser(context.Users, MockUser.User.Username);
- var entity = new UserDetailEntity
- {
- Email = email,
- Description = description,
- UserId = userId
- };
- context.Add(entity);
- await context.SaveChangesAsync();
- }
-
- {
- var detail = await _service.GetUserDetail(MockUser.User.Username);
- detail.Should().BeEquivalentTo(new UserDetail
- {
- Email = email,
- Description = description
- });
- }
- }
-
- [Fact]
- public void UpdateDetail_ShouldThrow_ArgumentException()
- {
- // no need to await because arguments are checked syncronizedly.
- _service.Invoking(s => s.UpdateUserDetail(null, new UserDetail())).Should().Throw<ArgumentException>()
- .Where(e => e.ParamName == "username" && e.Message.Contains("null", StringComparison.OrdinalIgnoreCase));
- _service.Invoking(s => s.UpdateUserDetail("", new UserDetail())).Should().Throw<ArgumentException>()
- .Where(e => e.ParamName == "username" && e.Message.Contains("empty", StringComparison.OrdinalIgnoreCase));
- _service.Invoking(s => s.UpdateUserDetail("aaa", null)).Should().Throw<ArgumentException>()
- .Where(e => e.ParamName == "detail");
- }
-
- [Fact]
- public void UpdateDetail_ShouldThrow_UserNotExistException()
- {
- const string username = "usernotexist";
- _service.Awaiting(s => s.UpdateUserDetail(username, new UserDetail())).Should().Throw<UserNotExistException>()
- .Where(e => e.Username == username);
- }
-
- [Fact]
- public async Task UpdateDetail_Empty_Should_Work()
- {
- await _service.UpdateUserDetail(MockUser.User.Username, new UserDetail());
-
- var context = _database.DatabaseContext;
- var userId = await DatabaseExtensions.CheckAndGetUser(context.Users, MockUser.User.Username);
- var entity = context.UserDetails.Where(e => e.UserId == userId).Single();
- entity.Nickname.Should().BeNullOrEmpty();
- entity.QQ.Should().BeNullOrEmpty();
- entity.Email.Should().BeNullOrEmpty();
- entity.PhoneNumber.Should().BeNullOrEmpty();
- entity.Description.Should().BeNullOrEmpty();
- }
-
- [Theory]
- [InlineData(nameof(UserDetail.Nickname), nameof(UserDetailEntity.Nickname), "aaaa", "bbbb")]
- [InlineData(nameof(UserDetail.QQ), nameof(UserDetailEntity.QQ), "12345678910", "987654321")]
- [InlineData(nameof(UserDetail.Email), nameof(UserDetailEntity.Email), "aaa@aaa.aaa", "bbb@bbb.bbb")]
- [InlineData(nameof(UserDetail.PhoneNumber), nameof(UserDetailEntity.PhoneNumber), "12345678910", "987654321")]
- [InlineData(nameof(UserDetail.Description), nameof(UserDetailEntity.Description), "descriptionA", "descriptionB")]
- public async Task UpdateDetail_Single_Should_Work(string propertyName, string entityPropertyName, string mockData1, string mockData2)
- {
-
- UserDetail CreateWith(string propertyValue)
- {
- var detail = new UserDetail();
- typeof(UserDetail).GetProperty(propertyName).SetValue(detail, propertyValue);
- return detail;
- }
-
- await _service.UpdateUserDetail(MockUser.User.Username, CreateWith(mockData1));
-
- var context = _database.DatabaseContext;
- var userId = await DatabaseExtensions.CheckAndGetUser(context.Users, MockUser.User.Username);
- var entity = context.UserDetails.Where(e => e.UserId == userId).Single();
-
- void TestWith(string propertyValue)
- {
- typeof(UserDetailEntity).GetProperty(entityPropertyName).GetValue(entity).Should().Equals(propertyValue);
- foreach (var p in typeof(UserDetailEntity).GetProperties().Where(p => p.Name != entityPropertyName))
- (p.GetValue(entity) as string).Should().BeNullOrEmpty();
- }
-
- TestWith(mockData1);
-
- await _service.UpdateUserDetail(MockUser.User.Username, CreateWith(mockData2));
- TestWith(mockData2);
- await _service.UpdateUserDetail(MockUser.User.Username, CreateWith(""));
- TestWith("");
- }
-
- [Fact]
- public async Task UpdateDetail_Multiple_Should_Work()
- {
- var detail = new UserDetail
- {
- QQ = "12345678",
- Email = "aaa@aaa.aaa",
- PhoneNumber = "11111111111",
- Description = "aaaaaaaaaa"
- };
-
- await _service.UpdateUserDetail(MockUser.User.Username, detail);
-
- var context = _database.DatabaseContext;
- var userId = await DatabaseExtensions.CheckAndGetUser(context.Users, MockUser.User.Username);
- var entity = context.UserDetails.Where(e => e.UserId == userId).Single();
- entity.QQ.Should().Equals(detail.QQ);
- entity.Email.Should().Equals(detail.Email);
- entity.PhoneNumber.Should().Equals(detail.PhoneNumber);
- entity.Description.Should().Equals(detail.Description);
-
- var detail2 = new UserDetail
- {
- QQ = null,
- Email = "bbb@bbb.bbb",
- PhoneNumber = "",
- Description = "bbbbbbbbb"
- };
-
- await _service.UpdateUserDetail(MockUser.User.Username, detail2);
- entity.QQ.Should().Equals(detail.QQ);
- entity.Email.Should().Equals(detail2.Email);
- entity.PhoneNumber.Should().BeNullOrEmpty();
- entity.Description.Should().Equals(detail2.Description);
- }
- }
-}
diff --git a/Timeline.Tests/UserDetailValidatorTest.cs b/Timeline.Tests/UserDetailValidatorTest.cs
deleted file mode 100644
index 9b112946..00000000
--- a/Timeline.Tests/UserDetailValidatorTest.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using FluentAssertions;
-using System.Collections.Generic;
-using Timeline.Models.Validation;
-using Xunit;
-
-namespace Timeline.Tests
-{
- public static class UserDetailValidatorsTest
- {
- private static void SucceedWith<TValidator>(object value) where TValidator : class, IValidator, new()
- {
- var result = new TValidator().Validate(value, out var message);
- result.Should().BeTrue();
- message.Should().Equals(ValidationConstants.SuccessMessage);
- }
-
- private static void FailWith<TValidator>(object value, params string[] messageContains) where TValidator : class, IValidator, new()
- {
- var result = new TValidator().Validate(value, out var message);
- result.Should().BeFalse();
-
- foreach (var m in messageContains)
- {
- message.Should().ContainEquivalentOf(m);
- }
- }
-
- public class QQ
- {
- [Theory]
- [InlineData(null)]
- [InlineData("")]
- [InlineData("12345678")]
- public void Success(object qq)
- {
- SucceedWith<UserDetailValidators.QQValidator>(qq);
- }
-
- [Theory]
- [InlineData(123, "type")]
- [InlineData("123", "short")]
- [InlineData("111111111111111111111111111111111111", "long")]
- [InlineData("aaaaaaaa", "digit")]
- public void Fail(object qq, string messageContains)
- {
- FailWith<UserDetailValidators.QQValidator>(qq, messageContains);
- }
- }
-
- public class EMail
- {
- [Theory]
- [InlineData(null)]
- [InlineData("")]
- [InlineData("aaa@aaa.net")]
- public void Success(object email)
- {
- SucceedWith<UserDetailValidators.EMailValidator>(email);
- }
-
- public static IEnumerable<object[]> FailTestData()
- {
- yield return new object[] { 123, "type" };
- yield return new object[] { new string('a', 100), "long" };
- yield return new object[] { "aaaaaaaa", "format" };
- }
-
- [Theory]
- [MemberData(nameof(FailTestData))]
- public void Fail(object email, string messageContains)
- {
- FailWith<UserDetailValidators.EMailValidator>(email, messageContains);
- }
- }
-
- public class PhoneNumber
- {
- [Theory]
- [InlineData(null)]
- [InlineData("")]
- [InlineData("12345678910")]
- public void Success(object phoneNumber)
- {
- SucceedWith<UserDetailValidators.PhoneNumberValidator>(phoneNumber);
- }
-
- [Theory]
- [InlineData(123, "type")]
- [InlineData("111111111111111111111111111111111111", "long")]
- [InlineData("aaaaaaaa", "digit")]
- public void Fail(object phoneNumber, string messageContains)
- {
- FailWith<UserDetailValidators.PhoneNumberValidator>(phoneNumber, messageContains);
- }
- }
- }
-}
diff --git a/Timeline.Tests/UsernameValidatorUnitTest.cs b/Timeline.Tests/UsernameValidatorUnitTest.cs
index 6a635ba1..9a80a3a2 100644
--- a/Timeline.Tests/UsernameValidatorUnitTest.cs
+++ b/Timeline.Tests/UsernameValidatorUnitTest.cs
@@ -1,5 +1,6 @@
using FluentAssertions;
using Timeline.Models.Validation;
+using Timeline.Tests.Mock.Services;
using Xunit;
namespace Timeline.Tests
@@ -15,14 +16,14 @@ namespace Timeline.Tests
private string FailAndMessage(string username)
{
- var result = _validator.Validate(username, out var message);
+ var result = _validator.Validate(username, TestStringLocalizerFactory.Create(), out var message);
result.Should().BeFalse();
return message;
}
private void Succeed(string username)
{
- _validator.Validate(username, out var message).Should().BeTrue();
+ _validator.Validate(username, TestStringLocalizerFactory.Create(), out var message).Should().BeTrue();
message.Should().Be(ValidationConstants.SuccessMessage);
}
@@ -35,7 +36,7 @@ namespace Timeline.Tests
[Fact]
public void NotString()
{
- var result = _validator.Validate(123, out var message);
+ var result = _validator.Validate(123, TestStringLocalizerFactory.Create(), out var message);
result.Should().BeFalse();
message.Should().ContainEquivalentOf("type");
}