aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2019-11-17 23:04:21 +0800
committercrupest <crupest@outlook.com>2019-11-17 23:04:21 +0800
commit59c10650fc36e8c79c1def088240fd90a5151250 (patch)
tree46282455cd6bdf43bf2215d3918f5803b2a31674
parentc2b107eda8a14f836d663638641a3e3f17373b5d (diff)
downloadtimeline-59c10650fc36e8c79c1def088240fd90a5151250.tar.gz
timeline-59c10650fc36e8c79c1def088240fd90a5151250.tar.bz2
timeline-59c10650fc36e8c79c1def088240fd90a5151250.zip
Fix typo in path of personal timeline controller actions. Add timeline permission test.
-rw-r--r--Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs19
-rw-r--r--Timeline.Tests/IntegratedTests/IntegratedTestBase.cs27
-rw-r--r--Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs62
-rw-r--r--Timeline/Controllers/PersonalTimelineController.cs8
-rw-r--r--Timeline/Startup.cs2
-rw-r--r--Timeline/Timeline.csproj10
6 files changed, 120 insertions, 8 deletions
diff --git a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
index 34d7e460..6a78be7a 100644
--- a/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
+++ b/Timeline.Tests/Helpers/Authentication/AuthenticationExtensions.cs
@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc.Testing;
using Newtonsoft.Json;
+using System;
using System.Net.Http;
using System.Threading.Tasks;
using Timeline.Models.Http;
@@ -7,6 +8,13 @@ using Timeline.Tests.Mock.Data;
namespace Timeline.Tests.Helpers.Authentication
{
+ public enum AuthType
+ {
+ None,
+ User,
+ Admin
+ }
+
public static class AuthenticationExtensions
{
private const string CreateTokenUrl = "/token/create";
@@ -36,5 +44,16 @@ namespace Timeline.Tests.Helpers.Authentication
{
return factory.CreateClientWithCredential(MockUser.Admin.Username, MockUser.Admin.Password);
}
+
+ public static Task<HttpClient> CreateClientAs<T>(this WebApplicationFactory<T> factory, AuthType authType) where T : class
+ {
+ return authType switch
+ {
+ AuthType.None => Task.FromResult(factory.CreateDefaultClient()),
+ AuthType.User => factory.CreateClientAsUser(),
+ AuthType.Admin => factory.CreateClientAsAdmin(),
+ _ => throw new InvalidOperationException("Unknown auth type.")
+ };
+ }
}
}
diff --git a/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs b/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs
new file mode 100644
index 00000000..c4d72faf
--- /dev/null
+++ b/Timeline.Tests/IntegratedTests/IntegratedTestBase.cs
@@ -0,0 +1,27 @@
+using Microsoft.AspNetCore.Mvc.Testing;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Timeline.Tests.Helpers;
+using Xunit;
+
+namespace Timeline.Tests.IntegratedTests
+{
+ public abstract class IntegratedTestBase : IClassFixture<WebApplicationFactory<Startup>>, IDisposable
+ {
+ protected TestApplication TestApp { get; }
+
+ protected WebApplicationFactory<Startup> Factory => TestApp.Factory;
+
+ public IntegratedTestBase(WebApplicationFactory<Startup> factory)
+ {
+ TestApp = new TestApplication(factory);
+ }
+
+ public virtual void Dispose()
+ {
+ TestApp.Dispose();
+ }
+ }
+}
diff --git a/Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs b/Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs
new file mode 100644
index 00000000..9629fc0a
--- /dev/null
+++ b/Timeline.Tests/IntegratedTests/PersonalTimelineTest.cs
@@ -0,0 +1,62 @@
+using FluentAssertions;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.Testing;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text.Json;
+using System.Threading.Tasks;
+using Timeline.Models.Http;
+using Timeline.Tests.Helpers;
+using Timeline.Tests.Helpers.Authentication;
+using Xunit;
+
+namespace Timeline.Tests.IntegratedTests
+{
+ public class PersonalTimelineTest : IntegratedTestBase
+ {
+ public PersonalTimelineTest(WebApplicationFactory<Startup> factory)
+ : base(factory)
+ {
+
+ }
+
+ [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)
+ {
+ using var client = await Factory.CreateClientAs(authType);
+ {
+ var res = await client.GetAsync("users/user/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.PostAsJsonAsync("users/admin/timeline/op/property",
+ new TimelinePropertyChangeRequest { Description = "hahaha" });
+ res.Should().HaveStatusCode(opPropertyAdmin);
+ }
+
+ {
+ var res = await client.PostAsJsonAsync("users/user/timeline/op/member",
+ new TimelineMemberChangeRequest { Add = new List<string> { "admin" } });
+ res.Should().HaveStatusCode(opMemberUser);
+ }
+
+ {
+ var res = await client.PostAsJsonAsync("users/admin/timeline/op/member",
+ new TimelineMemberChangeRequest { Add = new List<string> { "user" } });
+ res.Should().HaveStatusCode(opMemberAdmin);
+ }
+ }
+ }
+}
diff --git a/Timeline/Controllers/PersonalTimelineController.cs b/Timeline/Controllers/PersonalTimelineController.cs
index af6a70f8..88f5ba00 100644
--- a/Timeline/Controllers/PersonalTimelineController.cs
+++ b/Timeline/Controllers/PersonalTimelineController.cs
@@ -87,7 +87,7 @@ namespace Timeline.Controllers
return await _service.GetPosts(username);
}
- [HttpPost("user/{username}/timeline/postop/create")]
+ [HttpPost("users/{username}/timeline/postop/create")]
[Authorize]
[CatchTimelineNotExistException]
public async Task<ActionResult<TimelinePostCreateResponse>> PostOperationCreate([FromRoute][Username] string username, [FromBody] TimelinePostCreateRequest body)
@@ -102,7 +102,7 @@ namespace Timeline.Controllers
return res;
}
- [HttpPost("user/{username}/timeline/postop/delete")]
+ [HttpPost("users/{username}/timeline/postop/delete")]
[Authorize]
[CatchTimelineNotExistException]
public async Task<ActionResult> PostOperationDelete([FromRoute][Username] string username, [FromBody] TimelinePostDeleteRequest body)
@@ -126,7 +126,7 @@ namespace Timeline.Controllers
return Ok();
}
- [HttpPost("user/{username}/timeline/op/property")]
+ [HttpPost("users/{username}/timeline/op/property")]
[Authorize]
[SelfOrAdmin]
[CatchTimelineNotExistException]
@@ -136,7 +136,7 @@ namespace Timeline.Controllers
return Ok();
}
- [HttpPost("user/{username}/timeline/op/member")]
+ [HttpPost("users/{username}/timeline/op/member")]
[Authorize]
[SelfOrAdmin]
[CatchTimelineNotExistException]
diff --git a/Timeline/Startup.cs b/Timeline/Startup.cs
index f6abf36d..b2e958f9 100644
--- a/Timeline/Startup.cs
+++ b/Timeline/Startup.cs
@@ -71,6 +71,8 @@ namespace Timeline
services.AddUserAvatarService();
services.AddScoped<IUserDetailService, UserDetailService>();
+ services.AddScoped<IPersonalTimelineService, PersonalTimelineService>();
+
var databaseConfig = Configuration.GetSection(nameof(DatabaseConfig)).Get<DatabaseConfig>();
services.AddDbContext<DatabaseContext>(options =>
diff --git a/Timeline/Timeline.csproj b/Timeline/Timeline.csproj
index 7e1dd4ef..6b4a2d6e 100644
--- a/Timeline/Timeline.csproj
+++ b/Timeline/Timeline.csproj
@@ -8,6 +8,12 @@
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
+ <ItemGroup>
+ <Compile Remove="Resources\Filters\**" />
+ <Content Remove="Resources\Filters\**" />
+ <EmbeddedResource Remove="Resources\Filters\**" />
+ <None Remove="Resources\Filters\**" />
+ </ItemGroup>
<ItemGroup>
<Content Include="default-avatar.png">
@@ -174,8 +180,4 @@
<LastGenOutput>UserService.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
-
- <ItemGroup>
- <Folder Include="Resources\Filters\" />
- </ItemGroup>
</Project>