diff options
author | crupest <crupest@outlook.com> | 2020-11-13 16:10:12 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-11-13 16:10:12 +0800 |
commit | f34d9ccfa729c5367c5169d8461f74df11a5b2fb (patch) | |
tree | 56169c24d7cb81351f50b2d809ed86af82f9ad29 | |
parent | 609804f4e7d5d27496c9c31ed1ec84d6e86313c3 (diff) | |
download | timeline-f34d9ccfa729c5367c5169d8461f74df11a5b2fb.tar.gz timeline-f34d9ccfa729c5367c5169d8461f74df11a5b2fb.tar.bz2 timeline-f34d9ccfa729c5367c5169d8461f74df11a5b2fb.zip |
test: Add integrated tests for permission api.
6 files changed, 316 insertions, 10 deletions
diff --git a/BackEnd/Timeline.Tests/IntegratedTests/UserPermissionTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/UserPermissionTest.cs new file mode 100644 index 00000000..cf27a6c6 --- /dev/null +++ b/BackEnd/Timeline.Tests/IntegratedTests/UserPermissionTest.cs @@ -0,0 +1,308 @@ +using FluentAssertions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http.Json;
+using System.Threading.Tasks;
+using Timeline.Models.Http;
+using Timeline.Services;
+using Xunit;
+
+namespace Timeline.Tests.IntegratedTests
+{
+ public class UserPermissionTest : IntegratedTestBase
+ {
+ public UserPermissionTest() : base(3) { }
+
+ [Fact]
+ public async Task RootUserShouldReturnAllPermissions()
+ {
+ using var client = await CreateDefaultClient();
+ var res = await client.GetAsync("users/admin");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(Enum.GetNames<UserPermission>());
+ }
+
+ [Fact]
+ public async Task NonRootUserShouldReturnNonPermissions()
+ {
+ using var client = await CreateDefaultClient();
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEmpty();
+ }
+
+ public static IEnumerable<object[]> EveryPermissionTestData()
+ {
+ return Enum.GetValues<UserPermission>().Select(p => new object[] { p });
+ }
+
+ [Theory]
+ [MemberData(nameof(EveryPermissionTestData))]
+ public async Task ModifyRootUserPermissionShouldHaveNoEffect(UserPermission permission)
+ {
+ using var client = await CreateClientAsAdministrator();
+
+ {
+ var res = await client.DeleteAsync($"users/admin/permissions/{permission}");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/admin");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(Enum.GetNames<UserPermission>());
+ }
+
+ {
+ var res = await client.PutAsync($"users/admin/permissions/{permission}", null);
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/admin");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(Enum.GetNames<UserPermission>());
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(EveryPermissionTestData))]
+ public async Task ModifyUserPermissionShouldWork(UserPermission permission)
+ {
+ using var client = await CreateClientAsAdministrator();
+
+ {
+ var res = await client.PutAsync($"users/user1/permissions/{permission}", null);
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(permission.ToString());
+ }
+
+ {
+ var res = await client.DeleteAsync($"users/user1/permissions/{permission}");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEmpty();
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(EveryPermissionTestData))]
+ public async Task PutExistPermissionShouldHaveNoEffect(UserPermission permission)
+ {
+ using var client = await CreateClientAsAdministrator();
+
+ {
+ var res = await client.PutAsync($"users/user1/permissions/{permission}", null);
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(permission.ToString());
+ }
+
+ {
+ var res = await client.PutAsync($"users/user1/permissions/{permission}", null);
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(permission.ToString());
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(EveryPermissionTestData))]
+ public async Task DeleteNonExistPermissionShouldHaveNoEffect(UserPermission permission)
+ {
+ using var client = await CreateClientAsAdministrator();
+
+ {
+ var res = await client.DeleteAsync($"users/user1/permissions/{permission}");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEmpty();
+ }
+ }
+
+ [Fact]
+ public async Task AGeneralTest()
+ {
+ using var client = await CreateClientAsAdministrator();
+
+ {
+ var res = await client.PutAsync($"users/user1/permissions/{UserPermission.AllTimelineManagement}", null);
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(UserPermission.AllTimelineManagement.ToString());
+ }
+
+ {
+ var res = await client.PutAsync($"users/user1/permissions/{UserPermission.HighlightTimelineManangement}", null);
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(UserPermission.AllTimelineManagement.ToString(),
+ UserPermission.HighlightTimelineManangement.ToString());
+ }
+
+ {
+ var res = await client.PutAsync($"users/user1/permissions/{UserPermission.UserManagement}", null);
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(
+ UserPermission.AllTimelineManagement.ToString(),
+ UserPermission.HighlightTimelineManangement.ToString(),
+ UserPermission.UserManagement.ToString());
+ }
+
+ {
+ var res = await client.DeleteAsync($"users/user1/permissions/{UserPermission.HighlightTimelineManangement}");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(
+ UserPermission.AllTimelineManagement.ToString(),
+ UserPermission.UserManagement.ToString());
+ }
+
+ {
+ var res = await client.DeleteAsync($"users/user1/permissions/{UserPermission.AllTimelineManagement}");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(UserPermission.UserManagement.ToString());
+ }
+
+ {
+ var res = await client.PutAsync($"users/user1/permissions/{UserPermission.HighlightTimelineManangement}", null);
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(
+ UserPermission.HighlightTimelineManangement.ToString(), UserPermission.UserManagement.ToString());
+ }
+
+ {
+ var res = await client.DeleteAsync($"users/user1/permissions/{UserPermission.HighlightTimelineManangement}");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEquivalentTo(UserPermission.UserManagement.ToString());
+ }
+
+ {
+ var res = await client.DeleteAsync($"users/user1/permissions/{UserPermission.UserManagement}");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ }
+
+ {
+ var res = await client.GetAsync("users/user1");
+ res.StatusCode.Should().Be(HttpStatusCode.OK);
+ var body = await res.Content.ReadFromJsonAsync<UserInfo>();
+ body.Permissions.Should().BeEmpty();
+ }
+ }
+
+ [Theory]
+ [InlineData("users/user1/permissions/aaa")]
+ [InlineData("users/!!!/permissions/UserManagement")]
+ public async Task InvalidModel(string url)
+ {
+ using var client = await CreateClientAsAdministrator();
+
+ {
+ var res = await client.PutAsync(url, null);
+ res.StatusCode.Should().Be(HttpStatusCode.BadRequest);
+ var body = await res.Content.ReadFromJsonAsync<CommonResponse>();
+ body.Code.Should().Be(ErrorCodes.Common.InvalidModel);
+ }
+
+ {
+ var res = await client.DeleteAsync(url);
+ res.StatusCode.Should().Be(HttpStatusCode.BadRequest);
+ var body = await res.Content.ReadFromJsonAsync<CommonResponse>();
+ body.Code.Should().Be(ErrorCodes.Common.InvalidModel);
+ }
+ }
+
+ [Fact]
+ public async Task UserNotExist()
+ {
+ using var client = await CreateClientAsAdministrator();
+
+ const string url = "users/user123/permissions/UserManagement";
+
+ {
+ var res = await client.PutAsync(url, null);
+ res.StatusCode.Should().Be(HttpStatusCode.NotFound);
+ var body = await res.Content.ReadFromJsonAsync<CommonResponse>();
+ body.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
+ }
+
+ {
+ var res = await client.DeleteAsync(url);
+ res.StatusCode.Should().Be(HttpStatusCode.NotFound);
+ var body = await res.Content.ReadFromJsonAsync<CommonResponse>();
+ body.Code.Should().Be(ErrorCodes.UserCommon.NotExist);
+ }
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Controllers/UserController.cs b/BackEnd/Timeline/Controllers/UserController.cs index c5d1d4de..bbdb5d57 100644 --- a/BackEnd/Timeline/Controllers/UserController.cs +++ b/BackEnd/Timeline/Controllers/UserController.cs @@ -200,7 +200,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task<ActionResult> PutUserPermission([FromRoute] string username, [FromRoute] UserPermission permission)
+ public async Task<ActionResult> PutUserPermission([FromRoute][Username] string username, [FromRoute] UserPermission permission)
{
try
{
@@ -220,7 +220,7 @@ namespace Timeline.Controllers [ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task<ActionResult> DeleteUserPermission([FromRoute] string username, [FromRoute] UserPermission permission)
+ public async Task<ActionResult> DeleteUserPermission([FromRoute][Username] string username, [FromRoute] UserPermission permission)
{
try
{
diff --git a/BackEnd/Timeline/GlobalSuppressions.cs b/BackEnd/Timeline/GlobalSuppressions.cs index 2b0da576..155ed9ff 100644 --- a/BackEnd/Timeline/GlobalSuppressions.cs +++ b/BackEnd/Timeline/GlobalSuppressions.cs @@ -5,10 +5,8 @@ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "This is not a UI application.")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "This is not bad.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "No need to check the null because it's ASP.Net's duty.", Scope = "namespaceanddescendants", Target = "Timeline.Controllers")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Migrations code are auto generated.", Scope = "namespaceanddescendants", Target = "Timeline.Migrations")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Generated error response identifiers.", Scope = "type", Target = "Timeline.Models.Http.ErrorResponse")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1724:Type names should not match namespaces", Justification = "Generated error response identifiers.", Scope = "type", Target = "Timeline.Models.Http.ErrorResponse")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "Generated error response.", Scope = "type", Target = "Timeline.Models.Http.ErrorResponse")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1056:Uri properties should not be strings", Justification = "That's unnecessary.")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Adundant")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Redundant")]
diff --git a/BackEnd/Timeline/Resources/Services/UserService.Designer.cs b/BackEnd/Timeline/Resources/Services/UserService.Designer.cs index cdf7f390..564dd26c 100644 --- a/BackEnd/Timeline/Resources/Services/UserService.Designer.cs +++ b/BackEnd/Timeline/Resources/Services/UserService.Designer.cs @@ -70,7 +70,7 @@ namespace Timeline.Resources.Services { }
/// <summary>
- /// Looks up a localized string similar to Nickname is of bad format, because {}..
+ /// Looks up a localized string similar to Nickname is of bad format, because {0}..
/// </summary>
internal static string ExceptionNicknameBadFormat {
get {
@@ -106,7 +106,7 @@ namespace Timeline.Resources.Services { }
/// <summary>
- /// Looks up a localized string similar to Username is of bad format, because {}..
+ /// Looks up a localized string similar to Username is of bad format, because {0}..
/// </summary>
internal static string ExceptionUsernameBadFormat {
get {
diff --git a/BackEnd/Timeline/Resources/Services/UserService.resx b/BackEnd/Timeline/Resources/Services/UserService.resx index 09bd4abb..1f3c0011 100644 --- a/BackEnd/Timeline/Resources/Services/UserService.resx +++ b/BackEnd/Timeline/Resources/Services/UserService.resx @@ -121,7 +121,7 @@ <value>New username is of bad format.</value>
</data>
<data name="ExceptionNicknameBadFormat" xml:space="preserve">
- <value>Nickname is of bad format, because {}.</value>
+ <value>Nickname is of bad format, because {0}.</value>
</data>
<data name="ExceptionOldUsernameBadFormat" xml:space="preserve">
<value>Old username is of bad format.</value>
@@ -133,7 +133,7 @@ <value>Password can't be null.</value>
</data>
<data name="ExceptionUsernameBadFormat" xml:space="preserve">
- <value>Username is of bad format, because {}.</value>
+ <value>Username is of bad format, because {0}.</value>
</data>
<data name="ExceptionUsernameConflict" xml:space="preserve">
<value>A user with given username already exists.</value>
diff --git a/BackEnd/Timeline/Services/UserPermissionService.cs b/BackEnd/Timeline/Services/UserPermissionService.cs index deedf0a6..ff09b4ee 100644 --- a/BackEnd/Timeline/Services/UserPermissionService.cs +++ b/BackEnd/Timeline/Services/UserPermissionService.cs @@ -70,7 +70,7 @@ namespace Timeline.Services /// <returns>A string list.</returns>
public List<string> ToStringList()
{
- return _permissions.Select(p => p.ToString().ToUpperInvariant()).ToList();
+ return _permissions.Select(p => p.ToString()).ToList();
}
/// <summary>
|