aboutsummaryrefslogtreecommitdiff
path: root/Timeline.Tests/IntegratedTests
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline.Tests/IntegratedTests')
-rw-r--r--Timeline.Tests/IntegratedTests/AuthorizationTest.cs4
-rw-r--r--Timeline.Tests/IntegratedTests/I18nTest.cs59
-rw-r--r--Timeline.Tests/IntegratedTests/IntegratedTestBase.cs118
-rw-r--r--Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs375
-rw-r--r--Timeline.Tests/IntegratedTests/TokenTest.cs45
-rw-r--r--Timeline.Tests/IntegratedTests/UserAvatarTest.cs98
-rw-r--r--Timeline.Tests/IntegratedTests/UserDetailTest.cs153
-rw-r--r--Timeline.Tests/IntegratedTests/UserTest.cs438
8 files changed, 655 insertions, 635 deletions
diff --git a/Timeline.Tests/IntegratedTests/AuthorizationTest.cs b/Timeline.Tests/IntegratedTests/AuthorizationTest.cs
index 0bc094af..4aa6b3ae 100644
--- a/Timeline.Tests/IntegratedTests/AuthorizationTest.cs
+++ b/Timeline.Tests/IntegratedTests/AuthorizationTest.cs
@@ -22,7 +22,7 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task UnauthenticationTest()
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
var response = await client.GetAsync(AuthorizeUrl);
response.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
}
@@ -48,7 +48,7 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task AdminAuthorizationTest()
{
- using var client = await CreateClientAsAdmin();
+ using var client = await CreateClientAsAdministrator();
var response1 = await client.GetAsync(UserUrl);
response1.Should().HaveStatusCode(HttpStatusCode.OK);
var response2 = await client.GetAsync(AdminUrl);
diff --git a/Timeline.Tests/IntegratedTests/I18nTest.cs b/Timeline.Tests/IntegratedTests/I18nTest.cs
deleted file mode 100644
index 855179af..00000000
--- a/Timeline.Tests/IntegratedTests/I18nTest.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using FluentAssertions;
-using Microsoft.AspNetCore.Mvc.Testing;
-using System;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Threading.Tasks;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1054:Uri parameters should not be strings")]
- public class I18nTest : IntegratedTestBase
- {
- private readonly HttpClient _client;
-
- public I18nTest(WebApplicationFactory<Startup> factory)
- : base(factory)
- {
- _client = Factory.CreateDefaultClient();
- }
-
- protected override void OnDispose()
- {
- _client.Dispose();
- }
-
- private const string DirectUrl = "testing/i18n/direct";
- private const string LocalizerUrl = "testing/i18n/localizer";
-
- [Theory]
- [InlineData(DirectUrl)]
- [InlineData(LocalizerUrl)]
- public async Task DefaultShouldReturnEnglish(string url)
- {
- (await _client.GetStringAsync(url)).Should().ContainEquivalentOf("English");
- }
-
- [Theory]
- [InlineData(DirectUrl, "en", true)]
- [InlineData(LocalizerUrl, "en", true)]
- [InlineData(DirectUrl, "en-US", true)]
- [InlineData(LocalizerUrl, "en-US", true)]
- [InlineData(DirectUrl, "zh", false)]
- [InlineData(LocalizerUrl, "zh", false)]
- public async Task ShouldWork(string url, string acceptLanguage, bool english)
- {
- var request = new HttpRequestMessage
- {
- Method = HttpMethod.Get,
- RequestUri = new Uri(url, UriKind.RelativeOrAbsolute)
- };
- request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(acceptLanguage));
- var body = await (await _client.SendAsync(request)).Content.ReadAsStringAsync();
- body.Should().ContainEquivalentOf(english ? "English" : "中文");
- request.Dispose();
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs b/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs
index 242a452d..dfde2ea5 100644
--- a/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs
+++ b/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs
@@ -1,51 +1,82 @@
-using Microsoft.AspNetCore.Mvc.Testing;
+using AutoMapper;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Microsoft.Extensions.DependencyInjection;
using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Timeline.Models.Http;
+using Timeline.Services;
using Timeline.Tests.Helpers;
using Xunit;
namespace Timeline.Tests.IntegratedTests
{
- public enum AuthType
- {
- None,
- User,
- Admin
- }
-
- public static class AuthTypeExtensions
+ public abstract class IntegratedTestBase : IClassFixture<WebApplicationFactory<Startup>>, IDisposable
{
- public static MockUser GetMockUser(this AuthType authType)
- {
- return authType switch
- {
- AuthType.None => null,
- AuthType.User => MockUser.User,
- AuthType.Admin => MockUser.Admin,
- _ => throw new InvalidOperationException("Unknown auth type.")
- };
+ static IntegratedTestBase()
+ {
+ FluentAssertions.AssertionOptions.AssertEquivalencyUsing(options =>
+ options.Excluding(m => m.RuntimeType == typeof(UserInfoLinks)));
}
- public static string GetUsername(this AuthType authType) => authType.GetMockUser().Username;
- }
-
- public abstract class IntegratedTestBase : IClassFixture<WebApplicationFactory<Startup>>, IDisposable
- {
protected TestApplication TestApp { get; }
protected WebApplicationFactory<Startup> Factory => TestApp.Factory;
- public IntegratedTestBase(WebApplicationFactory<Startup> factory)
+ public IntegratedTestBase(WebApplicationFactory<Startup> factory) : this(factory, 1)
+ {
+
+ }
+
+ public IntegratedTestBase(WebApplicationFactory<Startup> factory, int userCount)
{
+ if (userCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(userCount), userCount, "User count can't be negative.");
+
TestApp = new TestApplication(factory);
+
+ using (var scope = Factory.Services.CreateScope())
+ {
+ var users = new List<User>()
+ {
+ new User
+ {
+ Username = "admin",
+ Password = "adminpw",
+ Administrator = true,
+ Nickname = "administrator"
+ }
+ };
+
+ for (int i = 1; i <= userCount; i++)
+ {
+ users.Add(new User
+ {
+ Username = $"user{i}",
+ Password = $"user{i}pw",
+ Administrator = false,
+ Nickname = $"imuser{i}"
+ });
+ }
+
+ var userInfoList = new List<UserInfo>();
+
+ var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
+ var mapper = scope.ServiceProvider.GetRequiredService<IMapper>();
+
+ foreach (var user in users)
+ {
+ userService.CreateUser(user).Wait();
+ userInfoList.Add(mapper.Map<UserInfo>(user));
+ }
+
+ UserInfos = userInfoList;
+ }
}
protected virtual void OnDispose()
{
-
}
public void Dispose()
@@ -54,14 +85,9 @@ namespace Timeline.Tests.IntegratedTests
TestApp.Dispose();
}
- protected void CreateExtraMockUsers(int count)
- {
- TestApp.Database.CreateExtraMockUsers(count);
- }
-
- protected IReadOnlyList<MockUser> ExtraMockUsers => TestApp.Database.ExtraMockUsers;
+ public IReadOnlyList<UserInfo> UserInfos { get; }
- public Task<HttpClient> CreateClientWithNoAuth()
+ public Task<HttpClient> CreateDefaultClient()
{
return Task.FromResult(Factory.CreateDefaultClient());
}
@@ -77,18 +103,24 @@ namespace Timeline.Tests.IntegratedTests
return client;
}
- public Task<HttpClient> CreateClientAs(MockUser user)
+ public Task<HttpClient> CreateClientAs(int userNumber)
{
- if (user == null)
- return CreateClientWithNoAuth();
- return CreateClientWithCredential(user.Username, user.Password);
+ if (userNumber < 0)
+ return CreateDefaultClient();
+ if (userNumber == 0)
+ return CreateClientWithCredential("admin", "adminpw");
+ else
+ return CreateClientWithCredential($"user{userNumber}", $"user{userNumber}pw");
}
- public Task<HttpClient> CreateClientAs(AuthType authType) => CreateClientAs(authType.GetMockUser());
-
-
- public Task<HttpClient> CreateClientAsUser() => CreateClientAs(MockUser.User);
- public Task<HttpClient> CreateClientAsAdmin() => CreateClientAs(MockUser.Admin);
-
+ public Task<HttpClient> CreateClientAsAdministrator()
+ {
+ return CreateClientAs(0);
+ }
+
+ public Task<HttpClient> CreateClientAsUser()
+ {
+ return CreateClientAs(1);
+ }
}
}
diff --git a/Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs b/Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs
index c5d0addd..81446fd8 100644
--- a/Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs
+++ b/Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs
@@ -5,7 +5,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
-using Timeline.Models;
using Timeline.Models.Http;
using Timeline.Tests.Helpers;
using Xunit;
@@ -15,7 +14,7 @@ namespace Timeline.Tests.IntegratedTests
public class PersonalTimelineTest : IntegratedTestBase
{
public PersonalTimelineTest(WebApplicationFactory<Startup> factory)
- : base(factory)
+ : base(factory, 3)
{
}
@@ -23,14 +22,82 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task TimelineGet_Should_Work()
{
- using var client = await CreateClientWithNoAuth();
- var res = await client.GetAsync("users/user/timeline");
+ using var client = await CreateDefaultClient();
+ var res = await client.GetAsync("users/user1/timeline");
var body = res.Should().HaveStatusCode(200)
.And.HaveJsonBody<BaseTimelineInfo>().Which;
- body.Owner.Should().Be("user");
+ body.Owner.Should().BeEquivalentTo(UserInfos[1]);
body.Visibility.Should().Be(TimelineVisibility.Register);
body.Description.Should().Be("");
body.Members.Should().NotBeNull().And.BeEmpty();
+ }
+
+ [Fact]
+ public async Task InvalidModel_BadUsername()
+ {
+ using var client = await CreateClientAsAdministrator();
+ {
+ var res = await client.GetAsync("users/user!!!/timeline");
+ res.Should().BeInvalidModel();
+ }
+ {
+ var res = await client.PatchAsJsonAsync("users/user!!!/timeline", new TimelinePatchRequest { });
+ res.Should().BeInvalidModel();
+ }
+ {
+ var res = await client.PutAsync("users/user!!!/timeline/members/user1", null);
+ res.Should().BeInvalidModel();
+ }
+ {
+ var res = await client.DeleteAsync("users/user!!!/timeline/members/user1");
+ res.Should().BeInvalidModel();
+ }
+ {
+ var res = await client.GetAsync("users/user!!!/timeline/posts");
+ res.Should().BeInvalidModel();
+ }
+ {
+ var res = await client.PostAsJsonAsync("users/user!!!/timeline/posts", new TimelinePostCreateRequest { Content = "aaa" });
+ res.Should().BeInvalidModel();
+ }
+ {
+ var res = await client.DeleteAsync("users/user!!!/timeline/posts/123");
+ res.Should().BeInvalidModel();
+ }
+ }
+
+ [Fact]
+ public async Task NotFound()
+ {
+ using var client = await CreateClientAsAdministrator();
+ {
+ var res = await client.GetAsync("users/usernotexist/timeline");
+ res.Should().HaveStatusCode(404).And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
+ }
+ {
+ var res = await client.PatchAsJsonAsync("users/usernotexist/timeline", new TimelinePatchRequest { });
+ res.Should().HaveStatusCode(404).And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
+ }
+ {
+ var res = await client.PutAsync("users/usernotexist/timeline/members/user1", null);
+ res.Should().HaveStatusCode(404).And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
+ }
+ {
+ var res = await client.DeleteAsync("users/usernotexist/timeline/members/user1");
+ res.Should().HaveStatusCode(404).And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
+ }
+ {
+ var res = await client.GetAsync("users/usernotexist/timeline/posts");
+ res.Should().HaveStatusCode(404).And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
+ }
+ {
+ var res = await client.PostAsJsonAsync("users/usernotexist/timeline/posts", new TimelinePostCreateRequest { Content = "aaa" });
+ res.Should().HaveStatusCode(404).And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
+ }
+ {
+ var res = await client.DeleteAsync("users/usernotexist/timeline/posts/123");
+ res.Should().HaveStatusCode(404).And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
+ }
}
[Fact]
@@ -40,7 +107,7 @@ namespace Timeline.Tests.IntegratedTests
async Task AssertDescription(string description)
{
- var res = await client.GetAsync("users/user/timeline");
+ var res = await client.GetAsync("users/user1/timeline");
var body = res.Should().HaveStatusCode(200)
.And.HaveJsonBody<BaseTimelineInfo>()
.Which.Description.Should().Be(description);
@@ -50,21 +117,24 @@ namespace Timeline.Tests.IntegratedTests
await AssertDescription("");
{
- var res = await client.PostAsJsonAsync("users/user/timeline/op/property",
- new TimelinePropertyChangeRequest { Description = mockDescription });
- res.Should().HaveStatusCode(200);
+ var res = await client.PatchAsJsonAsync("users/user1/timeline",
+ new TimelinePatchRequest { Description = mockDescription });
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<BaseTimelineInfo>().Which.Description.Should().Be(mockDescription);
await AssertDescription(mockDescription);
}
{
- var res = await client.PostAsJsonAsync("users/user/timeline/op/property",
- new TimelinePropertyChangeRequest { Description = null });
- res.Should().HaveStatusCode(200);
+ var res = await client.PatchAsJsonAsync("users/user1/timeline",
+ new TimelinePatchRequest { Description = null });
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<BaseTimelineInfo>().Which.Description.Should().Be(mockDescription);
await AssertDescription(mockDescription);
}
{
- var res = await client.PostAsJsonAsync("users/user/timeline/op/property",
- new TimelinePropertyChangeRequest { Description = "" });
- res.Should().HaveStatusCode(200);
+ var res = await client.PatchAsJsonAsync("users/user1/timeline",
+ new TimelinePatchRequest { Description = "" });
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<BaseTimelineInfo>().Which.Description.Should().Be("");
await AssertDescription("");
}
}
@@ -72,11 +142,10 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task Member_Should_Work()
{
- const string getUrl = "users/user/timeline";
- const string changeUrl = "users/user/timeline/op/member";
+ const string getUrl = "users/user1/timeline";
using var client = await CreateClientAsUser();
- async Task AssertMembers(IList<string> members)
+ async Task AssertMembers(IList<UserInfo> members)
{
var res = await client.GetAsync(getUrl);
res.Should().HaveStatusCode(200)
@@ -94,90 +163,86 @@ namespace Timeline.Tests.IntegratedTests
await AssertEmptyMembers();
{
- var res = await client.PostAsJsonAsync(changeUrl,
- new TimelineMemberChangeRequest { Add = new List<string> { "admin", "usernotexist" } });
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.Http.Timeline.ChangeMemberUserNotExist);
- }
- {
- var res = await client.PostAsJsonAsync(changeUrl,
- new TimelineMemberChangeRequest { Remove = new List<string> { "admin", "usernotexist" } });
+ var res = await client.PutAsync("/users/user1/timeline/members/usernotexist", null);
res.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.Http.Timeline.ChangeMemberUserNotExist);
+ .And.HaveCommonBody(ErrorCodes.TimelineController.MemberPut_NotExist);
}
+ await AssertEmptyMembers();
{
- var res = await client.PostAsJsonAsync(changeUrl,
- new TimelineMemberChangeRequest { Add = new List<string> { "admin" }, Remove = new List<string> { "admin" } });
+ var res = await client.PutAsync("/users/user1/timeline/members/user2", null);
res.Should().HaveStatusCode(200);
- await AssertEmptyMembers();
}
+ await AssertMembers(new List<UserInfo> { UserInfos[2] });
{
- var res = await client.PostAsJsonAsync(changeUrl,
- new TimelineMemberChangeRequest { Add = new List<string> { "admin" } });
- res.Should().HaveStatusCode(200);
- await AssertMembers(new List<string> { "admin" });
- }
+ var res = await client.DeleteAsync("/users/user1/timeline/members/user2");
+ res.Should().BeDelete(true);
+ }
+ await AssertEmptyMembers();
{
- var res = await client.PostAsJsonAsync(changeUrl,
- new TimelineMemberChangeRequest { Remove = new List<string> { "admin" } });
- res.Should().HaveStatusCode(200);
- await AssertEmptyMembers();
+ var res = await client.DeleteAsync("/users/user1/timeline/members/users2");
+ res.Should().BeDelete(false);
}
+ await AssertEmptyMembers();
}
[Theory]
- [InlineData(AuthType.None, 200, 401, 401, 401, 401)]
- [InlineData(AuthType.User, 200, 200, 403, 200, 403)]
- [InlineData(AuthType.Admin, 200, 200, 200, 200, 200)]
- public async Task Permission_Timeline(AuthType authType, int get, int opPropertyUser, int opPropertyAdmin, int opMemberUser, int opMemberAdmin)
+ [InlineData(-1, 200, 401, 401, 401, 401)]
+ [InlineData(1, 200, 200, 403, 200, 403)]
+ [InlineData(0, 200, 200, 200, 200, 200)]
+ public async Task Permission_Timeline(int userNumber, int get, int opPatchUser, int opPatchAdmin, int opMemberUser, int opMemberAdmin)
{
- using var client = await CreateClientAs(authType);
+ using var client = await CreateClientAs(userNumber);
{
- var res = await client.GetAsync("users/user/timeline");
+ var res = await client.GetAsync("users/user1/timeline");
res.Should().HaveStatusCode(get);
}
{
- var res = await client.PostAsJsonAsync("users/user/timeline/op/property",
- new TimelinePropertyChangeRequest { Description = "hahaha" });
- res.Should().HaveStatusCode(opPropertyUser);
+ var res = await client.PatchAsJsonAsync("users/user1/timeline", new TimelinePatchRequest { Description = "hahaha" });
+ res.Should().HaveStatusCode(opPatchUser);
}
{
- var res = await client.PostAsJsonAsync("users/admin/timeline/op/property",
- new TimelinePropertyChangeRequest { Description = "hahaha" });
- res.Should().HaveStatusCode(opPropertyAdmin);
+ var res = await client.PatchAsJsonAsync("users/admin/timeline", new TimelinePatchRequest { Description = "hahaha" });
+ res.Should().HaveStatusCode(opPatchAdmin);
}
{
- var res = await client.PostAsJsonAsync("users/user/timeline/op/member",
- new TimelineMemberChangeRequest { Add = new List<string> { "admin" } });
+ var res = await client.PutAsync("users/user1/timeline/members/user2", null);
+ res.Should().HaveStatusCode(opMemberUser);
+ }
+
+ {
+ var res = await client.DeleteAsync("users/user1/timeline/members/user2");
res.Should().HaveStatusCode(opMemberUser);
}
{
- var res = await client.PostAsJsonAsync("users/admin/timeline/op/member",
- new TimelineMemberChangeRequest { Add = new List<string> { "user" } });
+ var res = await client.PutAsync("users/admin/timeline/members/user2", null);
+ res.Should().HaveStatusCode(opMemberAdmin);
+ }
+
+ {
+ var res = await client.DeleteAsync("users/admin/timeline/members/user2");
res.Should().HaveStatusCode(opMemberAdmin);
}
}
[Fact]
- public async Task Permission_GetPost()
+ public async Task Visibility_Test()
{
- const string userUrl = "users/user/timeline/posts";
+ const string userUrl = "users/user1/timeline/posts";
const string adminUrl = "users/admin/timeline/posts";
- {
+ {
+
using var client = await CreateClientAsUser();
- var res = await client.PostAsync("users/user/timeline/op/property",
- new StringContent(@"{""visibility"":""abcdefg""}", System.Text.Encoding.UTF8, System.Net.Mime.MediaTypeNames.Application.Json));
+ using var content = new StringContent(@"{""visibility"":""abcdefg""}", System.Text.Encoding.UTF8, System.Net.Mime.MediaTypeNames.Application.Json);
+ var res = await client.PatchAsync("users/user1/timeline", content);
res.Should().BeInvalidModel();
}
{ // default visibility is registered
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
var res = await client.GetAsync(userUrl);
res.Should().HaveStatusCode(403);
}
@@ -192,12 +257,12 @@ namespace Timeline.Tests.IntegratedTests
{ // change visibility to public
{
using var client = await CreateClientAsUser();
- var res = await client.PostAsJsonAsync("users/user/timeline/op/property",
- new TimelinePropertyChangeRequest { Visibility = TimelineVisibility.Public });
+ var res = await client.PatchAsJsonAsync("users/user1/timeline",
+ new TimelinePatchRequest { Visibility = TimelineVisibility.Public });
res.Should().HaveStatusCode(200);
}
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
var res = await client.GetAsync(userUrl);
res.Should().HaveStatusCode(200);
}
@@ -205,20 +270,20 @@ namespace Timeline.Tests.IntegratedTests
{ // change visibility to private
{
- using var client = await CreateClientAsAdmin();
+ using var client = await CreateClientAsAdministrator();
{
- var res = await client.PostAsJsonAsync("users/user/timeline/op/property",
- new TimelinePropertyChangeRequest { Visibility = TimelineVisibility.Private });
+ var res = await client.PatchAsJsonAsync("users/user1/timeline",
+ new TimelinePatchRequest { Visibility = TimelineVisibility.Private });
res.Should().HaveStatusCode(200);
}
{
- var res = await client.PostAsJsonAsync("users/admin/timeline/op/property",
- new TimelinePropertyChangeRequest { Visibility = TimelineVisibility.Private });
+ var res = await client.PatchAsJsonAsync("users/admin/timeline",
+ new TimelinePatchRequest { Visibility = TimelineVisibility.Private });
res.Should().HaveStatusCode(200);
}
}
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
var res = await client.GetAsync(userUrl);
res.Should().HaveStatusCode(403);
}
@@ -228,14 +293,13 @@ namespace Timeline.Tests.IntegratedTests
res.Should().HaveStatusCode(403);
}
{ // admin can read user's
- using var client = await CreateClientAsAdmin();
+ using var client = await CreateClientAsAdministrator();
var res = await client.GetAsync(userUrl);
res.Should().HaveStatusCode(200);
}
{ // add member
- using var client = await CreateClientAsAdmin();
- var res = await client.PostAsJsonAsync("users/admin/timeline/op/member",
- new TimelineMemberChangeRequest { Add = new List<string> { "user" } });
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.PutAsync("/users/admin/timeline/members/user1", null);
res.Should().HaveStatusCode(200);
}
{ // now user can read admin's
@@ -250,19 +314,16 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task Permission_Post_Create()
{
- CreateExtraMockUsers(1);
-
using (var client = await CreateClientAsUser())
{
- var res = await client.PostAsJsonAsync("users/user/timeline/op/member",
- new TimelineMemberChangeRequest { Add = new List<string> { "user0" } });
+ var res = await client.PutAsync("users/user1/timeline/members/user2", null);
res.Should().HaveStatusCode(200);
}
- using (var client = await CreateClientWithNoAuth())
+ using (var client = await CreateDefaultClient())
{
{ // no auth should get 401
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = "aaa" });
res.Should().HaveStatusCode(401);
}
@@ -271,30 +332,30 @@ namespace Timeline.Tests.IntegratedTests
using (var client = await CreateClientAsUser())
{
{ // post self's
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = "aaa" });
res.Should().HaveStatusCode(200);
}
{ // post other not as a member should get 403
- var res = await client.PostAsJsonAsync("users/admin/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/admin/timeline/posts",
new TimelinePostCreateRequest { Content = "aaa" });
res.Should().HaveStatusCode(403);
}
}
- using (var client = await CreateClientAsAdmin())
+ using (var client = await CreateClientAsAdministrator())
{
{ // post as admin
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = "aaa" });
res.Should().HaveStatusCode(200);
}
}
- using (var client = await CreateClientAs(ExtraMockUsers[0]))
+ using (var client = await CreateClientAs(2))
{
{ // post as member
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = "aaa" });
res.Should().HaveStatusCode(200);
}
@@ -304,69 +365,66 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task Permission_Post_Delete()
{
- CreateExtraMockUsers(2);
-
- async Task<long> CreatePost(MockUser auth, string timeline)
+ async Task<long> CreatePost(int userNumber)
{
- using var client = await CreateClientAs(auth);
- var res = await client.PostAsJsonAsync($"users/{timeline}/timeline/postop/create",
+ using var client = await CreateClientAs(userNumber);
+ var res = await client.PostAsJsonAsync($"users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = "aaa" });
return res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostCreateResponse>()
+ .And.HaveJsonBody<TimelinePostInfo>()
.Which.Id;
}
using (var client = await CreateClientAsUser())
{
- var res = await client.PostAsJsonAsync("users/user/timeline/op/member",
- new TimelineMemberChangeRequest { Add = new List<string> { "user0", "user1" } });
- res.Should().HaveStatusCode(200);
+ {
+ var res = await client.PutAsync("users/user1/timeline/members/user2", null);
+ res.Should().HaveStatusCode(200);
+ }
+ {
+ var res = await client.PutAsync("users/user1/timeline/members/user3", null);
+ res.Should().HaveStatusCode(200);
+ }
}
{ // no auth should get 401
- using var client = await CreateClientWithNoAuth();
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/delete",
- new TimelinePostDeleteRequest { Id = 12 });
+ using var client = await CreateDefaultClient();
+ var res = await client.DeleteAsync("users/user1/timeline/posts/12");
res.Should().HaveStatusCode(401);
}
{ // self can delete self
- var postId = await CreatePost(MockUser.User, "user");
+ var postId = await CreatePost(1);
using var client = await CreateClientAsUser();
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/delete",
- new TimelinePostDeleteRequest { Id = postId });
+ var res = await client.DeleteAsync($"users/user1/timeline/posts/{postId}");
res.Should().HaveStatusCode(200);
}
{ // admin can delete any
- var postId = await CreatePost(MockUser.User, "user");
- using var client = await CreateClientAsAdmin();
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/delete",
- new TimelinePostDeleteRequest { Id = postId });
+ var postId = await CreatePost(1);
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.DeleteAsync($"users/user1/timeline/posts/{postId}");
res.Should().HaveStatusCode(200);
}
{ // owner can delete other
- var postId = await CreatePost(ExtraMockUsers[0], "user");
+ var postId = await CreatePost(2);
using var client = await CreateClientAsUser();
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/delete",
- new TimelinePostDeleteRequest { Id = postId });
+ var res = await client.DeleteAsync($"users/user1/timeline/posts/{postId}");
res.Should().HaveStatusCode(200);
}
{ // author can delete self
- var postId = await CreatePost(ExtraMockUsers[0], "user");
- using var client = await CreateClientAs(ExtraMockUsers[0]);
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/delete",
- new TimelinePostDeleteRequest { Id = postId });
+ var postId = await CreatePost(2);
+ using var client = await CreateClientAs(2);
+ var res = await client.DeleteAsync($"users/user1/timeline/posts/{postId}");
res.Should().HaveStatusCode(200);
}
{ // otherwise is forbidden
- var postId = await CreatePost(ExtraMockUsers[0], "user");
- using var client = await CreateClientAs(ExtraMockUsers[1]);
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/delete",
- new TimelinePostDeleteRequest { Id = postId });
+ var postId = await CreatePost(2);
+ using var client = await CreateClientAs(3);
+ var res = await client.DeleteAsync($"users/user1/timeline/posts/{postId}");
res.Should().HaveStatusCode(403);
}
}
@@ -377,96 +435,69 @@ namespace Timeline.Tests.IntegratedTests
{
using var client = await CreateClientAsUser();
{
- var res = await client.GetAsync("users/user/timeline/posts");
+ var res = await client.GetAsync("users/user1/timeline/posts");
res.Should().HaveStatusCode(200)
.And.HaveJsonBody<TimelinePostInfo[]>()
.Which.Should().NotBeNull().And.BeEmpty();
}
{
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = null });
res.Should().BeInvalidModel();
}
const string mockContent = "aaa";
- TimelinePostCreateResponse createRes;
+ TimelinePostInfo createRes;
{
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = mockContent });
var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostCreateResponse>()
+ .And.HaveJsonBody<TimelinePostInfo>()
.Which;
body.Should().NotBeNull();
+ body.Content.Should().Be(mockContent);
+ body.Author.Should().BeEquivalentTo(UserInfos[1]);
createRes = body;
}
{
- var res = await client.GetAsync("users/user/timeline/posts");
+ var res = await client.GetAsync("users/user1/timeline/posts");
res.Should().HaveStatusCode(200)
.And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.Should().NotBeNull().And.BeEquivalentTo(
- new TimelinePostInfo
- {
- Id = createRes.Id,
- Author = "user",
- Content = mockContent,
- Time = createRes.Time
- });
+ .Which.Should().NotBeNull().And.BeEquivalentTo(createRes);
}
const string mockContent2 = "bbb";
var mockTime2 = DateTime.Now.AddDays(-1);
- TimelinePostCreateResponse createRes2;
+ TimelinePostInfo createRes2;
{
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = mockContent2, Time = mockTime2 });
var body = res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostCreateResponse>()
+ .And.HaveJsonBody<TimelinePostInfo>()
.Which;
- body.Should().NotBeNull();
+ body.Should().NotBeNull();
+ body.Content.Should().Be(mockContent2);
+ body.Author.Should().BeEquivalentTo(UserInfos[1]);
+ body.Time.Should().BeCloseTo(mockTime2, 1000);
createRes2 = body;
}
{
- var res = await client.GetAsync("users/user/timeline/posts");
+ var res = await client.GetAsync("users/user1/timeline/posts");
res.Should().HaveStatusCode(200)
.And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.Should().NotBeNull().And.BeEquivalentTo(
- new TimelinePostInfo
- {
- Id = createRes.Id,
- Author = "user",
- Content = mockContent,
- Time = createRes.Time
- },
- new TimelinePostInfo
- {
- Id = createRes2.Id,
- Author = "user",
- Content = mockContent2,
- Time = createRes2.Time
- });
+ .Which.Should().NotBeNull().And.BeEquivalentTo(createRes, createRes2);
}
{
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/delete",
- new TimelinePostDeleteRequest { Id = createRes.Id });
- res.Should().HaveStatusCode(200);
+ var res = await client.DeleteAsync($"users/user1/timeline/posts/{createRes.Id}");
+ res.Should().BeDelete(true);
}
{
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/delete",
- new TimelinePostDeleteRequest { Id = 30000 });
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.Http.Timeline.PostOperationDeleteNotExist);
+ var res = await client.DeleteAsync("users/user1/timeline/posts/30000");
+ res.Should().BeDelete(false);
}
{
- var res = await client.GetAsync("users/user/timeline/posts");
+ var res = await client.GetAsync("users/user1/timeline/posts");
res.Should().HaveStatusCode(200)
.And.HaveJsonBody<TimelinePostInfo[]>()
- .Which.Should().NotBeNull().And.BeEquivalentTo(
- new TimelinePostInfo
- {
- Id = createRes2.Id,
- Author = "user",
- Content = mockContent2,
- Time = createRes2.Time
- });
+ .Which.Should().NotBeNull().And.BeEquivalentTo(createRes2);
}
}
}
@@ -478,10 +509,10 @@ namespace Timeline.Tests.IntegratedTests
async Task<long> CreatePost(DateTime time)
{
- var res = await client.PostAsJsonAsync("users/user/timeline/postop/create",
+ var res = await client.PostAsJsonAsync("users/user1/timeline/posts",
new TimelinePostCreateRequest { Content = "aaa", Time = time });
return res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<TimelinePostCreateResponse>()
+ .And.HaveJsonBody<TimelinePostInfo>()
.Which.Id;
}
@@ -491,7 +522,7 @@ namespace Timeline.Tests.IntegratedTests
var id2 = await CreatePost(now);
{
- var res = await client.GetAsync("users/user/timeline/posts");
+ var res = await client.GetAsync("users/user1/timeline/posts");
res.Should().HaveStatusCode(200)
.And.HaveJsonBody<TimelinePostInfo[]>()
.Which.Select(p => p.Id).Should().Equal(id1, id2, id0);
diff --git a/Timeline.Tests/IntegratedTests/TokenTest.cs b/Timeline.Tests/IntegratedTests/TokenTest.cs
index e62228fc..928d546c 100644
--- a/Timeline.Tests/IntegratedTests/TokenTest.cs
+++ b/Timeline.Tests/IntegratedTests/TokenTest.cs
@@ -8,7 +8,6 @@ using Timeline.Models.Http;
using Timeline.Services;
using Timeline.Tests.Helpers;
using Xunit;
-using static Timeline.ErrorCodes.Http.Token;
namespace Timeline.Tests.IntegratedTests
{
@@ -42,7 +41,7 @@ namespace Timeline.Tests.IntegratedTests
[MemberData(nameof(CreateToken_InvalidModel_Data))]
public async Task CreateToken_InvalidModel(string username, string password, int expire)
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
(await client.PostAsJsonAsync(CreateTokenUrl, new CreateTokenRequest
{
Username = username,
@@ -54,37 +53,37 @@ namespace Timeline.Tests.IntegratedTests
public static IEnumerable<object[]> CreateToken_UserCredential_Data()
{
yield return new[] { "usernotexist", "p" };
- yield return new[] { MockUser.User.Username, "???" };
+ yield return new[] { "user1", "???" };
}
[Theory]
[MemberData(nameof(CreateToken_UserCredential_Data))]
public async void CreateToken_UserCredential(string username, string password)
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
var response = await client.PostAsJsonAsync(CreateTokenUrl,
new CreateTokenRequest { Username = username, Password = password });
response.Should().HaveStatusCode(400)
.And.HaveCommonBody()
- .Which.Code.Should().Be(Create.BadCredential);
+ .Which.Code.Should().Be(ErrorCodes.TokenController.Create_BadCredential);
}
[Fact]
public async Task CreateToken_Success()
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
var response = await client.PostAsJsonAsync(CreateTokenUrl,
- new CreateTokenRequest { Username = MockUser.User.Username, Password = MockUser.User.Password });
+ new CreateTokenRequest { Username = "user1", Password = "user1pw" });
var body = response.Should().HaveStatusCode(200)
.And.HaveJsonBody<CreateTokenResponse>().Which;
body.Token.Should().NotBeNullOrWhiteSpace();
- body.User.Should().BeEquivalentTo(MockUser.User.Info);
+ body.User.Should().BeEquivalentTo(UserInfos[1]);
}
[Fact]
public async Task VerifyToken_InvalidModel()
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
(await client.PostAsJsonAsync(VerifyTokenUrl,
new VerifyTokenRequest { Token = null })).Should().BeInvalidModel();
}
@@ -92,51 +91,51 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task VerifyToken_BadFormat()
{
- using var client = await CreateClientWithNoAuth();
+ using var client = await CreateDefaultClient();
var response = await client.PostAsJsonAsync(VerifyTokenUrl,
new VerifyTokenRequest { Token = "bad token hahaha" });
response.Should().HaveStatusCode(400)
.And.HaveCommonBody()
- .Which.Code.Should().Be(Verify.BadFormat);
+ .Which.Code.Should().Be(ErrorCodes.TokenController.Verify_BadFormat);
}
[Fact]
public async Task VerifyToken_OldVersion()
{
- using var client = await CreateClientWithNoAuth();
- var token = (await CreateUserTokenAsync(client, MockUser.User.Username, MockUser.User.Password)).Token;
+ using var client = await CreateDefaultClient();
+ var token = (await CreateUserTokenAsync(client, "user1", "user1pw")).Token;
- using (var scope = Factory.Server.Host.Services.CreateScope()) // UserService is scoped.
+ using (var scope = Factory.Services.CreateScope()) // UserService is scoped.
{
// create a user for test
var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
- await userService.PatchUser(MockUser.User.Username, null, null);
+ await userService.ModifyUser("user1", new User { Password = "user1pw" });
}
(await client.PostAsJsonAsync(VerifyTokenUrl,
new VerifyTokenRequest { Token = token }))
.Should().HaveStatusCode(400)
.And.HaveCommonBody()
- .Which.Code.Should().Be(Verify.OldVersion);
+ .Which.Code.Should().Be(ErrorCodes.TokenController.Verify_OldVersion);
}
[Fact]
public async Task VerifyToken_UserNotExist()
{
- using var client = await CreateClientWithNoAuth();
- var token = (await CreateUserTokenAsync(client, MockUser.User.Username, MockUser.User.Password)).Token;
+ using var client = await CreateDefaultClient();
+ var token = (await CreateUserTokenAsync(client, "user1", "user1pw")).Token;
using (var scope = Factory.Server.Host.Services.CreateScope()) // UserService is scoped.
{
var userService = scope.ServiceProvider.GetRequiredService<IUserService>();
- await userService.DeleteUser(MockUser.User.Username);
+ await userService.DeleteUser("user1");
}
(await client.PostAsJsonAsync(VerifyTokenUrl,
new VerifyTokenRequest { Token = token }))
.Should().HaveStatusCode(400)
.And.HaveCommonBody()
- .Which.Code.Should().Be(Verify.UserNotExist);
+ .Which.Code.Should().Be(ErrorCodes.TokenController.Verify_UserNotExist);
}
//[Fact]
@@ -160,13 +159,13 @@ namespace Timeline.Tests.IntegratedTests
[Fact]
public async Task VerifyToken_Success()
{
- using var client = await CreateClientWithNoAuth();
- var createTokenResult = await CreateUserTokenAsync(client, MockUser.User.Username, MockUser.User.Password);
+ using var client = await CreateDefaultClient();
+ var createTokenResult = await CreateUserTokenAsync(client, "user1", "user1pw");
var response = await client.PostAsJsonAsync(VerifyTokenUrl,
new VerifyTokenRequest { Token = createTokenResult.Token });
response.Should().HaveStatusCode(200)
.And.HaveJsonBody<VerifyTokenResponse>()
- .Which.User.Should().BeEquivalentTo(MockUser.User.Info);
+ .Which.User.Should().BeEquivalentTo(UserInfos[1]);
}
}
}
diff --git a/Timeline.Tests/IntegratedTests/UserAvatarTest.cs b/Timeline.Tests/IntegratedTests/UserAvatarTest.cs
index 25a7b675..fa0120f1 100644
--- a/Timeline.Tests/IntegratedTests/UserAvatarTest.cs
+++ b/Timeline.Tests/IntegratedTests/UserAvatarTest.cs
@@ -13,11 +13,10 @@ using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
+using Timeline.Models.Http;
using Timeline.Services;
using Timeline.Tests.Helpers;
using Xunit;
-using static Timeline.ErrorCodes.Http.Common;
-using static Timeline.ErrorCodes.Http.UserAvatar;
namespace Timeline.Tests.IntegratedTests
{
@@ -30,7 +29,6 @@ namespace Timeline.Tests.IntegratedTests
}
[Fact]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "HttpMessageRequest should be disposed ???")]
public async Task Test()
{
Avatar mockAvatar = new Avatar
@@ -45,13 +43,13 @@ namespace Timeline.Tests.IntegratedTests
var res = await client.GetAsync("users/usernotexist/avatar");
res.Should().HaveStatusCode(404)
.And.HaveCommonBody()
- .Which.Code.Should().Be(Get.UserNotExist);
+ .Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
}
var env = Factory.Server.Host.Services.GetRequiredService<IWebHostEnvironment>();
var defaultAvatarData = await File.ReadAllBytesAsync(Path.Combine(env.ContentRootPath, "default-avatar.png"));
- async Task GetReturnDefault(string username = "user")
+ async Task GetReturnDefault(string username = "user1")
{
var res = await client.GetAsync($"users/{username}/avatar");
res.Should().HaveStatusCode(200);
@@ -62,7 +60,7 @@ namespace Timeline.Tests.IntegratedTests
EntityTagHeaderValue eTag;
{
- var res = await client.GetAsync($"users/user/avatar");
+ var res = await client.GetAsync($"users/user1/avatar");
res.Should().HaveStatusCode(200);
res.Content.Headers.ContentType.MediaType.Should().Be("image/png");
var body = await res.Content.ReadAsByteArrayAsync();
@@ -77,21 +75,21 @@ namespace Timeline.Tests.IntegratedTests
await GetReturnDefault("admin");
{
- var request = new HttpRequestMessage()
+ using var request = new HttpRequestMessage()
{
- RequestUri = new Uri(client.BaseAddress, "users/user/avatar"),
+ RequestUri = new Uri(client.BaseAddress, "users/user1/avatar"),
Method = HttpMethod.Get,
};
request.Headers.TryAddWithoutValidation("If-None-Match", "\"dsdfd");
var res = await client.SendAsync(request);
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(Header.IfNonMatch.BadFormat);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Header.IfNonMatch_BadFormat);
}
{
- var request = new HttpRequestMessage()
+ using var request = new HttpRequestMessage()
{
- RequestUri = new Uri(client.BaseAddress, "users/user/avatar"),
+ RequestUri = new Uri(client.BaseAddress, "users/user1/avatar"),
Method = HttpMethod.Get,
};
request.Headers.TryAddWithoutValidation("If-None-Match", "\"aaa\"");
@@ -100,9 +98,9 @@ namespace Timeline.Tests.IntegratedTests
}
{
- var request = new HttpRequestMessage()
+ using var request = new HttpRequestMessage()
{
- RequestUri = new Uri(client.BaseAddress, "users/user/avatar"),
+ RequestUri = new Uri(client.BaseAddress, "users/user1/avatar"),
Method = HttpMethod.Get,
};
request.Headers.Add("If-None-Match", eTag.ToString());
@@ -111,85 +109,85 @@ namespace Timeline.Tests.IntegratedTests
}
{
- var content = new ByteArrayContent(new[] { (byte)0x00 });
+ using var content = new ByteArrayContent(new[] { (byte)0x00 });
content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user/avatar", content);
+ var res = await client.PutAsync("users/user1/avatar", content);
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentLength.Missing); ;
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Header.ContentLength_Missing); ;
}
{
- var content = new ByteArrayContent(new[] { (byte)0x00 });
+ using var content = new ByteArrayContent(new[] { (byte)0x00 });
content.Headers.ContentLength = 1;
- var res = await client.PutAsync("users/user/avatar", content);
+ var res = await client.PutAsync("users/user1/avatar", content);
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentType.Missing);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Header.ContentType_Missing);
}
{
- var content = new ByteArrayContent(new[] { (byte)0x00 });
+ using var content = new ByteArrayContent(new[] { (byte)0x00 });
content.Headers.ContentLength = 0;
content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user/avatar", content);
+ var res = await client.PutAsync("users/user1/avatar", content);
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Http.Filter.Header.ContentLength.Zero);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Header.ContentLength_Zero);
}
{
- var res = await client.PutByteArrayAsync("users/user/avatar", new[] { (byte)0x00 }, "image/notaccept");
+ var res = await client.PutByteArrayAsync("users/user1/avatar", new[] { (byte)0x00 }, "image/notaccept");
res.Should().HaveStatusCode(HttpStatusCode.UnsupportedMediaType);
}
{
- var content = new ByteArrayContent(new[] { (byte)0x00 });
+ using var content = new ByteArrayContent(new[] { (byte)0x00 });
content.Headers.ContentLength = 1000 * 1000 * 11;
content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user/avatar", content);
+ var res = await client.PutAsync("users/user1/avatar", content);
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(Content.TooBig);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Content.TooBig);
}
{
- var content = new ByteArrayContent(new[] { (byte)0x00 });
+ using var content = new ByteArrayContent(new[] { (byte)0x00 });
content.Headers.ContentLength = 2;
content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user/avatar", content);
+ var res = await client.PutAsync("users/user1/avatar", content);
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(Content.UnmatchedLength_Smaller);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Content.UnmatchedLength_Smaller);
}
{
- var content = new ByteArrayContent(new[] { (byte)0x00, (byte)0x01 });
+ using var content = new ByteArrayContent(new[] { (byte)0x00, (byte)0x01 });
content.Headers.ContentLength = 1;
content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
- var res = await client.PutAsync("users/user/avatar", content);
+ var res = await client.PutAsync("users/user1/avatar", content);
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(Content.UnmatchedLength_Bigger);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Content.UnmatchedLength_Bigger);
}
{
- var res = await client.PutByteArrayAsync("users/user/avatar", new[] { (byte)0x00 }, "image/png");
+ var res = await client.PutByteArrayAsync("users/user1/avatar", new[] { (byte)0x00 }, "image/png");
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_CantDecode);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.UserAvatar.BadFormat_CantDecode);
}
{
- var res = await client.PutByteArrayAsync("users/user/avatar", mockAvatar.Data, "image/jpeg");
+ var res = await client.PutByteArrayAsync("users/user1/avatar", mockAvatar.Data, "image/jpeg");
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_UnmatchedFormat);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.UserAvatar.BadFormat_UnmatchedFormat);
}
{
- var res = await client.PutByteArrayAsync("users/user/avatar", ImageHelper.CreatePngWithSize(100, 200), "image/png");
+ var res = await client.PutByteArrayAsync("users/user1/avatar", ImageHelper.CreatePngWithSize(100, 200), "image/png");
res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody().Which.Code.Should().Be(Put.BadFormat_BadSize);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.UserAvatar.BadFormat_BadSize);
}
{
- var res = await client.PutByteArrayAsync("users/user/avatar", mockAvatar.Data, mockAvatar.Type);
+ var res = await client.PutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.Type);
res.Should().HaveStatusCode(HttpStatusCode.OK);
- var res2 = await client.GetAsync("users/user/avatar");
+ var res2 = await client.GetAsync("users/user1/avatar");
res2.Should().HaveStatusCode(200);
res2.Content.Headers.ContentType.MediaType.Should().Be(mockAvatar.Type);
var body = await res2.Content.ReadAsByteArrayAsync();
@@ -205,40 +203,40 @@ namespace Timeline.Tests.IntegratedTests
foreach ((var mimeType, var format) in formats)
{
- var res = await client.PutByteArrayAsync("users/user/avatar", ImageHelper.CreateImageWithSize(100, 100, format), mimeType);
+ var res = await client.PutByteArrayAsync("users/user1/avatar", ImageHelper.CreateImageWithSize(100, 100, format), mimeType);
res.Should().HaveStatusCode(HttpStatusCode.OK);
}
{
var res = await client.PutByteArrayAsync("users/admin/avatar", new[] { (byte)0x00 }, "image/png");
res.Should().HaveStatusCode(HttpStatusCode.Forbidden)
- .And.HaveCommonBody().Which.Code.Should().Be(Put.Forbid);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Forbid);
}
{
var res = await client.DeleteAsync("users/admin/avatar");
res.Should().HaveStatusCode(HttpStatusCode.Forbidden)
- .And.HaveCommonBody().Which.Code.Should().Be(Delete.Forbid);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.Common.Forbid);
}
for (int i = 0; i < 2; i++) // double delete should work.
{
- var res = await client.DeleteAsync("users/user/avatar");
+ var res = await client.DeleteAsync("users/user1/avatar");
res.Should().HaveStatusCode(200);
await GetReturnDefault();
}
}
// Authorization check.
- using (var client = await CreateClientAsAdmin())
+ using (var client = await CreateClientAsAdministrator())
{
{
- var res = await client.PutByteArrayAsync("users/user/avatar", mockAvatar.Data, mockAvatar.Type);
+ var res = await client.PutByteArrayAsync("users/user1/avatar", mockAvatar.Data, mockAvatar.Type);
res.Should().HaveStatusCode(HttpStatusCode.OK);
}
{
- var res = await client.DeleteAsync("users/user/avatar");
+ var res = await client.DeleteAsync("users/user1/avatar");
res.Should().HaveStatusCode(HttpStatusCode.OK);
}
@@ -246,18 +244,18 @@ namespace Timeline.Tests.IntegratedTests
var res = await client.PutByteArrayAsync("users/usernotexist/avatar", new[] { (byte)0x00 }, "image/png");
res.Should().HaveStatusCode(400)
.And.HaveCommonBody()
- .Which.Code.Should().Be(Put.UserNotExist);
+ .Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
}
{
var res = await client.DeleteAsync("users/usernotexist/avatar");
res.Should().HaveStatusCode(400)
- .And.HaveCommonBody().Which.Code.Should().Be(Delete.UserNotExist);
+ .And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
}
}
// bad username check
- using (var client = await CreateClientAsAdmin())
+ using (var client = await CreateClientAsAdministrator())
{
{
var res = await client.GetAsync("users/u!ser/avatar");
diff --git a/Timeline.Tests/IntegratedTests/UserDetailTest.cs b/Timeline.Tests/IntegratedTests/UserDetailTest.cs
deleted file mode 100644
index 932c287e..00000000
--- a/Timeline.Tests/IntegratedTests/UserDetailTest.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-using FluentAssertions;
-using Microsoft.AspNetCore.Mvc.Testing;
-using System.Net;
-using System.Net.Http.Headers;
-using System.Net.Mime;
-using System.Threading.Tasks;
-using Timeline.Tests.Helpers;
-using Xunit;
-
-namespace Timeline.Tests.IntegratedTests
-{
- public class UserDetailTest : IntegratedTestBase
- {
- public UserDetailTest(WebApplicationFactory<Startup> factory)
- : base(factory)
- {
-
- }
-
- [Fact]
- public async Task PermissionTest()
- {
- { // unauthorize
- using var client = await CreateClientWithNoAuth();
- { // GET
- var res = await client.GetAsync($"users/{MockUser.User.Username}/nickname");
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
- { // PUT
- var res = await client.PutStringAsync($"users/{MockUser.User.Username}/nickname", "aaa");
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
- { // DELETE
- var res = await client.DeleteAsync($"users/{MockUser.User.Username}/nickname");
- res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
- }
- }
- { // user
- using var client = await CreateClientAsUser();
- { // GET
- var res = await client.GetAsync($"users/{MockUser.User.Username}/nickname");
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
- { // PUT self
- var res = await client.PutStringAsync($"users/{MockUser.User.Username}/nickname", "aaa");
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
- { // PUT other
- var res = await client.PutStringAsync($"users/{MockUser.Admin.Username}/nickname", "aaa");
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
- { // DELETE self
- var res = await client.DeleteAsync($"users/{MockUser.User.Username}/nickname");
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
- { // DELETE other
- var res = await client.DeleteAsync($"users/{MockUser.Admin.Username}/nickname");
- res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
- }
- }
- { // user
- using var client = await CreateClientAsAdmin();
- { // PUT other
- var res = await client.PutStringAsync($"users/{MockUser.User.Username}/nickname", "aaa");
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
- { // DELETE other
- var res = await client.DeleteAsync($"users/{MockUser.User.Username}/nickname");
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
- }
- }
-
- [Fact]
- public async Task FunctionTest()
- {
- var url = $"users/{MockUser.User.Username}/nickname";
- var userNotExistUrl = "users/usernotexist/nickname";
- {
- using var client = await CreateClientAsUser();
- {
- var res = await client.GetAsync(userNotExistUrl);
- res.Should().HaveStatusCode(HttpStatusCode.NotFound)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.Http.Filter.User.NotExist);
-
- }
- {
- var res = await client.GetAsync(url);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- res.Content.Headers.ContentType.Should().Be(new MediaTypeHeaderValue(MediaTypeNames.Text.Plain) { CharSet = "utf-8" });
- var body = await res.Content.ReadAsStringAsync();
- body.Should().Be(MockUser.User.Username);
- }
- {
- var res = await client.PutStringAsync(url, "");
- res.Should().BeInvalidModel();
- }
- {
- var res = await client.PutStringAsync(url, new string('a', 11));
- res.Should().BeInvalidModel();
- }
- var nickname1 = "nnn";
- var nickname2 = "nn2";
- {
- var res = await client.PutStringAsync(url, nickname1);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- (await client.GetStringAsync(url)).Should().Be(nickname1);
- }
- {
- var res = await client.PutStringAsync(url, nickname2);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- (await client.GetStringAsync(url)).Should().Be(nickname2);
- }
- {
- var res = await client.DeleteAsync(url);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- (await client.GetStringAsync(url)).Should().Be(MockUser.User.Username);
- }
- {
- var res = await client.DeleteAsync(url);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- }
- }
- {
- using var client = await CreateClientAsAdmin();
- {
- var res = await client.PutStringAsync(userNotExistUrl, "aaa");
- res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.Http.Filter.User.NotExist);
- }
- {
- var res = await client.DeleteAsync(userNotExistUrl);
- res.Should().HaveStatusCode(HttpStatusCode.BadRequest)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(ErrorCodes.Http.Filter.User.NotExist);
- }
- var nickname = "nnn";
- {
- var res = await client.PutStringAsync(url, nickname);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- (await client.GetStringAsync(url)).Should().Be(nickname);
- }
- {
- var res = await client.DeleteAsync(url);
- res.Should().HaveStatusCode(HttpStatusCode.OK);
- (await client.GetStringAsync(url)).Should().Be(MockUser.User.Username);
- }
- }
- }
- }
-}
diff --git a/Timeline.Tests/IntegratedTests/UserTest.cs b/Timeline.Tests/IntegratedTests/UserTest.cs
index abfea18e..8ce76299 100644
--- a/Timeline.Tests/IntegratedTests/UserTest.cs
+++ b/Timeline.Tests/IntegratedTests/UserTest.cs
@@ -1,13 +1,12 @@
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using System.Collections.Generic;
+using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
-using Timeline.Models;
using Timeline.Models.Http;
using Timeline.Tests.Helpers;
using Xunit;
-using static Timeline.ErrorCodes.Http.User;
namespace Timeline.Tests.IntegratedTests
{
@@ -20,218 +19,395 @@ namespace Timeline.Tests.IntegratedTests
}
[Fact]
- public async Task Get_List_Success()
+ public async Task GetList_NoAuth()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.GetAsync("users");
+ using var client = await CreateDefaultClient();
+ var res = await client.GetAsync("/users");
res.Should().HaveStatusCode(200)
.And.HaveJsonBody<UserInfo[]>()
- .Which.Should().BeEquivalentTo(MockUser.UserInfoList);
+ .Which.Should().BeEquivalentTo(UserInfos);
}
[Fact]
- public async Task Get_Single_Success()
+ public async Task GetList_User()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.GetAsync("users/" + MockUser.User.Username);
+ using var client = await CreateClientAsUser();
+ var res = await client.GetAsync("/users");
res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which.Should().BeEquivalentTo(MockUser.User.Info);
+ .And.HaveJsonBody<UserInfo[]>()
+ .Which.Should().BeEquivalentTo(UserInfos);
}
[Fact]
- public async Task Get_InvalidModel()
+ public async Task GetList_Admin()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.GetAsync("users/aaa!a");
- res.Should().BeInvalidModel();
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.GetAsync("/users");
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo[]>()
+ .Which.Should().BeEquivalentTo(UserInfos);
}
[Fact]
- public async Task Get_Users_404()
+ public async Task Get_NoAuth()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.GetAsync("users/usernotexist");
- res.Should().HaveStatusCode(404)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(Get.NotExist);
+ using var client = await CreateDefaultClient();
+ var res = await client.GetAsync($"/users/admin");
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>()
+ .Which.Should().BeEquivalentTo(UserInfos[0]);
}
- public static IEnumerable<object[]> Put_InvalidModel_Data()
+ [Fact]
+ public async Task Get_User()
{
- yield return new object[] { "aaa", null, false };
- yield return new object[] { "aaa", "p", null };
- yield return new object[] { "aa!a", "p", false };
+ using var client = await CreateClientAsUser();
+ var res = await client.GetAsync($"/users/admin");
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>()
+ .Which.Should().BeEquivalentTo(UserInfos[0]);
}
- [Theory]
- [MemberData(nameof(Put_InvalidModel_Data))]
- public async Task Put_InvalidModel(string username, string password, bool? administrator)
+ [Fact]
+ public async Task Get_Admin()
{
- using var client = await CreateClientAsAdmin();
- (await client.PutAsJsonAsync("users/" + username,
- new UserPutRequest { Password = password, Administrator = administrator }))
- .Should().BeInvalidModel();
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.GetAsync($"/users/user1");
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>()
+ .Which.Should().BeEquivalentTo(UserInfos[1]);
}
- private async Task CheckAdministrator(HttpClient client, string username, bool administrator)
+ [Fact]
+ public async Task Get_InvalidModel()
{
- var res = await client.GetAsync("users/" + username);
- res.Should().HaveStatusCode(200)
- .And.HaveJsonBody<UserInfo>()
- .Which.Administrator.Should().Be(administrator);
+ using var client = await CreateClientAsUser();
+ var res = await client.GetAsync("/users/aaa!a");
+ res.Should().BeInvalidModel();
}
[Fact]
- public async Task Put_Modiefied()
+ public async Task Get_404()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.PutAsJsonAsync("users/" + MockUser.User.Username, new UserPutRequest
+ using var client = await CreateClientAsUser();
+ var res = await client.GetAsync("/users/usernotexist");
+ res.Should().HaveStatusCode(404)
+ .And.HaveCommonBody(ErrorCodes.UserCommon.NotExist);
+ }
+
+ [Fact]
+ public async Task Patch_User()
+ {
+ using var client = await CreateClientAsUser();
+ {
+ var res = await client.PatchAsJsonAsync("/users/user1",
+ new UserPatchRequest { Nickname = "aaa" });
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>()
+ .Which.Nickname.Should().Be("aaa");
+ }
+
{
- Password = "password",
- Administrator = false
- });
- res.Should().BePut(false);
- await CheckAdministrator(client, MockUser.User.Username, false);
+ var res = await client.GetAsync("/users/user1");
+ res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>()
+ .Which.Nickname.Should().Be("aaa");
+ }
}
[Fact]
- public async Task Put_Created()
+ public async Task Patch_Admin()
{
- using var client = await CreateClientAsAdmin();
- const string username = "puttest";
- const string url = "users/" + username;
+ using var client = await CreateClientAsAdministrator();
+ using var userClient = await CreateClientAsUser();
+
+ {
+ var res = await client.PatchAsJsonAsync("/users/user1",
+ new UserPatchRequest
+ {
+ Username = "newuser",
+ Password = "newpw",
+ Administrator = true,
+ Nickname = "aaa"
+ });
+ var body = res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>()
+ .Which;
+ body.Administrator.Should().Be(true);
+ body.Nickname.Should().Be("aaa");
+ }
+
+ {
+ var res = await client.GetAsync("/users/newuser");
+ var body = res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>()
+ .Which;
+ body.Administrator.Should().Be(true);
+ body.Nickname.Should().Be("aaa");
+ }
+
+ {
+ // Token should expire.
+ var res = await userClient.GetAsync("/testing/auth/Authorize");
+ res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
+ }
- var res = await client.PutAsJsonAsync(url, new UserPutRequest
{
- Password = "password",
- Administrator = false
- });
- res.Should().BePut(true);
- await CheckAdministrator(client, username, false);
+ // Check password.
+ (await CreateClientWithCredential("newuser", "newpw")).Dispose();
+ }
}
[Fact]
public async Task Patch_NotExist()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.PatchAsJsonAsync("users/usernotexist", new UserPatchRequest { });
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.PatchAsJsonAsync("/users/usernotexist", new UserPatchRequest { });
res.Should().HaveStatusCode(404)
.And.HaveCommonBody()
- .Which.Code.Should().Be(Patch.NotExist);
+ .Which.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
}
[Fact]
public async Task Patch_InvalidModel()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.PatchAsJsonAsync("users/aaa!a", new UserPatchRequest { });
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.PatchAsJsonAsync("/users/aaa!a", new UserPatchRequest { });
+ res.Should().BeInvalidModel();
+ }
+
+ public static IEnumerable<object[]> Patch_InvalidModel_Body_Data()
+ {
+ yield return new[] { new UserPatchRequest { Username = "aaa!a" } };
+ yield return new[] { new UserPatchRequest { Password = "" } };
+ yield return new[] { new UserPatchRequest { Nickname = new string('a', 50) } };
+ }
+
+ [Theory]
+ [MemberData(nameof(Patch_InvalidModel_Body_Data))]
+ public async Task Patch_InvalidModel_Body(UserPatchRequest body)
+ {
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.PatchAsJsonAsync("/users/user1", body);
res.Should().BeInvalidModel();
}
[Fact]
- public async Task Patch_Success()
+ public async Task Patch_UsernameConflict()
{
- using var client = await CreateClientAsAdmin();
- {
- var res = await client.PatchAsJsonAsync("users/" + MockUser.User.Username,
- new UserPatchRequest { Administrator = false });
- res.Should().HaveStatusCode(200);
- await CheckAdministrator(client, MockUser.User.Username, false);
- }
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.PatchAsJsonAsync("/users/user1", new UserPatchRequest { Username = "admin" });
+ res.Should().HaveStatusCode(400)
+ .And.HaveCommonBody(ErrorCodes.UserController.UsernameConflict);
}
[Fact]
- public async Task Delete_InvalidModel()
+ public async Task Patch_NoAuth_Unauthorized()
{
- using var client = await CreateClientAsAdmin();
- var url = "users/aaa!a";
- var res = await client.DeleteAsync(url);
- res.Should().BeInvalidModel();
+ using var client = await CreateDefaultClient();
+ var res = await client.PatchAsJsonAsync("/users/user1", new UserPatchRequest { Nickname = "aaa" });
+ res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
+ }
+
+ [Fact]
+ public async Task Patch_User_Forbid()
+ {
+ using var client = await CreateClientAsUser();
+ var res = await client.PatchAsJsonAsync("/users/admin", new UserPatchRequest { Nickname = "aaa" });
+ res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
+ }
+
+ [Fact]
+ public async Task Patch_Username_Forbid()
+ {
+ using var client = await CreateClientAsUser();
+ var res = await client.PatchAsJsonAsync("/users/user1", new UserPatchRequest { Username = "aaa" });
+ res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
+ }
+
+ [Fact]
+ public async Task Patch_Password_Forbid()
+ {
+ using var client = await CreateClientAsUser();
+ var res = await client.PatchAsJsonAsync("/users/user1", new UserPatchRequest { Password = "aaa" });
+ res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
+ }
+
+ [Fact]
+ public async Task Patch_Administrator_Forbid()
+ {
+ using var client = await CreateClientAsUser();
+ var res = await client.PatchAsJsonAsync("/users/user1", new UserPatchRequest { Administrator = true });
+ res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
}
[Fact]
public async Task Delete_Deleted()
{
- using var client = await CreateClientAsAdmin();
- var url = "users/" + MockUser.User.Username;
- var res = await client.DeleteAsync(url);
- res.Should().BeDelete(true);
+ using var client = await CreateClientAsAdministrator();
+ {
+ var res = await client.DeleteAsync("/users/user1");
+ res.Should().BeDelete(true);
+ }
- var res2 = await client.GetAsync(url);
- res2.Should().HaveStatusCode(404);
+ {
+ var res = await client.GetAsync("/users/user1");
+ res.Should().HaveStatusCode(404);
+ }
}
[Fact]
public async Task Delete_NotExist()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.DeleteAsync("users/usernotexist");
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.DeleteAsync("/users/usernotexist");
res.Should().BeDelete(false);
}
- private const string changeUsernameUrl = "userop/changeusername";
+ [Fact]
+ public async Task Delete_InvalidModel()
+ {
+ using var client = await CreateClientAsAdministrator();
+ var res = await client.DeleteAsync("/users/aaa!a");
+ res.Should().BeInvalidModel();
+ }
- public static IEnumerable<object[]> Op_ChangeUsername_InvalidModel_Data()
+ [Fact]
+ public async Task Delete_NoAuth_Unauthorized()
{
- yield return new[] { null, "uuu" };
- yield return new[] { "uuu", null };
- yield return new[] { "a!a", "uuu" };
- yield return new[] { "uuu", "a!a" };
+ using var client = await CreateDefaultClient();
+ var res = await client.DeleteAsync("/users/aaa!a");
+ res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
}
- [Theory]
- [MemberData(nameof(Op_ChangeUsername_InvalidModel_Data))]
- public async Task Op_ChangeUsername_InvalidModel(string oldUsername, string newUsername)
+ [Fact]
+ public async Task Delete_User_Forbid()
{
- using var client = await CreateClientAsAdmin();
- (await client.PostAsJsonAsync(changeUsernameUrl,
- new ChangeUsernameRequest { OldUsername = oldUsername, NewUsername = newUsername }))
- .Should().BeInvalidModel();
+ using var client = await CreateClientAsUser();
+ var res = await client.DeleteAsync("/users/aaa!a");
+ res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
}
+ private const string createUserUrl = "/userop/createuser";
+
[Fact]
- public async Task Op_ChangeUsername_UserNotExist()
+ public async Task Op_CreateUser()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.PostAsJsonAsync(changeUsernameUrl,
- new ChangeUsernameRequest { OldUsername = "usernotexist", NewUsername = "newUsername" });
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(Op.ChangeUsername.NotExist);
+ using var client = await CreateClientAsAdministrator();
+ {
+ var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest
+ {
+ Username = "aaa",
+ Password = "bbb",
+ Administrator = true,
+ Nickname = "ccc"
+ });
+ var body = res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>().Which;
+ body.Username.Should().Be("aaa");
+ body.Nickname.Should().Be("ccc");
+ body.Administrator.Should().BeTrue();
+ }
+ {
+ var res = await client.GetAsync("users/aaa");
+ var body = res.Should().HaveStatusCode(200)
+ .And.HaveJsonBody<UserInfo>().Which;
+ body.Username.Should().Be("aaa");
+ body.Nickname.Should().Be("ccc");
+ body.Administrator.Should().BeTrue();
+ }
+ {
+ // Test password.
+ (await CreateClientWithCredential("aaa", "bbb")).Dispose();
+ }
+ }
+
+ public static IEnumerable<object[]> Op_CreateUser_InvalidModel_Data()
+ {
+ yield return new[] { new CreateUserRequest { Username = "aaa", Password = "bbb" } };
+ yield return new[] { new CreateUserRequest { Username = "aaa", Administrator = true } };
+ yield return new[] { new CreateUserRequest { Password = "bbb", Administrator = true } };
+ yield return new[] { new CreateUserRequest { Username = "a!a", Password = "bbb", Administrator = true } };
+ yield return new[] { new CreateUserRequest { Username = "aaa", Password = "", Administrator = true } };
+ yield return new[] { new CreateUserRequest { Username = "aaa", Password = "bbb", Administrator = true, Nickname = new string('a', 40) } };
+ }
+
+ [Theory]
+ [MemberData(nameof(Op_CreateUser_InvalidModel_Data))]
+ public async Task Op_CreateUser_InvalidModel(CreateUserRequest body)
+ {
+ using var client = await CreateClientAsAdministrator();
+ {
+ var res = await client.PostAsJsonAsync(createUserUrl, body);
+ res.Should().BeInvalidModel();
+ }
}
[Fact]
- public async Task Op_ChangeUsername_UserAlreadyExist()
+ public async Task Op_CreateUser_UsernameConflict()
{
- using var client = await CreateClientAsAdmin();
- var res = await client.PostAsJsonAsync(changeUsernameUrl,
- new ChangeUsernameRequest { OldUsername = MockUser.User.Username, NewUsername = MockUser.Admin.Username });
- res.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(Op.ChangeUsername.AlreadyExist);
+ using var client = await CreateClientAsAdministrator();
+ {
+ var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest
+ {
+ Username = "user1",
+ Password = "bbb",
+ Administrator = false
+ });
+ res.Should().HaveStatusCode(400)
+ .And.HaveCommonBody(ErrorCodes.UserController.UsernameConflict);
+ }
}
- private async Task TestLogin(string username, string password)
+ [Fact]
+ public async Task Op_CreateUser_NoAuth_Unauthorized()
{
- using var client = await CreateClientWithNoAuth();
- var response = await client.PostAsJsonAsync("token/create", new CreateTokenRequest { Username = username, Password = password });
- response.Should().HaveStatusCode(200)
- .And.HaveJsonBody<CreateTokenResponse>();
+ using var client = await CreateDefaultClient();
+ {
+ var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest
+ {
+ Username = "aaa",
+ Password = "bbb",
+ Administrator = false
+ });
+ res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
+ }
}
[Fact]
- public async Task Op_ChangeUsername_Success()
+ public async Task Op_CreateUser_User_Forbid()
{
- using var client = await CreateClientAsAdmin();
- const string newUsername = "hahaha";
- var res = await client.PostAsJsonAsync(changeUsernameUrl,
- new ChangeUsernameRequest { OldUsername = MockUser.User.Username, NewUsername = newUsername });
- res.Should().HaveStatusCode(200);
- await TestLogin(newUsername, MockUser.User.Password);
+ using var client = await CreateClientAsUser();
+ {
+ var res = await client.PostAsJsonAsync(createUserUrl, new CreateUserRequest
+ {
+ Username = "aaa",
+ Password = "bbb",
+ Administrator = false
+ });
+ res.Should().HaveStatusCode(HttpStatusCode.Forbidden);
+ }
}
- private const string changePasswordUrl = "userop/changepassword";
+ private const string changePasswordUrl = "/userop/changepassword";
+
+ [Fact]
+ public async Task Op_ChangePassword()
+ {
+ using var client = await CreateClientAsUser();
+ {
+ var res = await client.PostAsJsonAsync(changePasswordUrl,
+ new ChangePasswordRequest { OldPassword = "user1pw", NewPassword = "newpw" });
+ res.Should().HaveStatusCode(200);
+ }
+ {
+ var res = await client.PatchAsJsonAsync("/users/user1", new UserPatchRequest { });
+ res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
+ }
+ {
+ (await CreateClientWithCredential("user1", "newpw")).Dispose();
+ }
+ }
public static IEnumerable<object[]> Op_ChangePassword_InvalidModel_Data()
{
@@ -244,9 +420,9 @@ namespace Timeline.Tests.IntegratedTests
public async Task Op_ChangePassword_InvalidModel(string oldPassword, string newPassword)
{
using var client = await CreateClientAsUser();
- (await client.PostAsJsonAsync(changePasswordUrl,
- new ChangePasswordRequest { OldPassword = oldPassword, NewPassword = newPassword }))
- .Should().BeInvalidModel();
+ var res = await client.PostAsJsonAsync(changePasswordUrl,
+ new ChangePasswordRequest { OldPassword = oldPassword, NewPassword = newPassword });
+ res.Should().BeInvalidModel();
}
[Fact]
@@ -255,19 +431,15 @@ namespace Timeline.Tests.IntegratedTests
using var client = await CreateClientAsUser();
var res = await client.PostAsJsonAsync(changePasswordUrl, new ChangePasswordRequest { OldPassword = "???", NewPassword = "???" });
res.Should().HaveStatusCode(400)
- .And.HaveCommonBody()
- .Which.Code.Should().Be(Op.ChangePassword.BadOldPassword);
+ .And.HaveCommonBody(ErrorCodes.UserController.ChangePassword_BadOldPassword);
}
[Fact]
- public async Task Op_ChangePassword_Success()
+ public async Task Op_ChangePassword_NoAuth_Unauthorized()
{
- using var client = await CreateClientAsUser();
- const string newPassword = "new";
- var res = await client.PostAsJsonAsync(changePasswordUrl,
- new ChangePasswordRequest { OldPassword = MockUser.User.Password, NewPassword = newPassword });
- res.Should().HaveStatusCode(200);
- await TestLogin(MockUser.User.Username, newPassword);
+ using var client = await CreateDefaultClient();
+ var res = await client.PostAsJsonAsync(changePasswordUrl, new ChangePasswordRequest { OldPassword = "???", NewPassword = "???" });
+ res.Should().HaveStatusCode(HttpStatusCode.Unauthorized);
}
}
}