mirror of
https://github.com/dotnetcore/AgileConfig.git
synced 2026-10-22 07:05:56 +08:00
295 lines
12 KiB
C#
295 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using AgileConfig.Server.Application;
|
|
using AgileConfig.Server.Application.Roles;
|
|
using AgileConfig.Server.Common;
|
|
using AgileConfig.Server.Data.Entity;
|
|
using AgileConfig.Server.IService;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using Moq;
|
|
|
|
namespace AgileConfig.Server.ApplicationTests;
|
|
|
|
[TestClass]
|
|
public sealed class RoleManagementServiceTests
|
|
{
|
|
[TestMethod]
|
|
public async Task GetAllAsync_FiltersSuperAdminSortsAndLoadsFunctions()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
var superAdmin = new Role
|
|
{
|
|
Id = SystemRoleConstants.SuperAdminId,
|
|
Name = "Super Administrator",
|
|
IsSystem = true
|
|
};
|
|
var operatorRole = new Role
|
|
{
|
|
Id = SystemRoleConstants.OperatorId,
|
|
Name = "Operator",
|
|
IsSystem = true
|
|
};
|
|
var adminRole = new Role
|
|
{
|
|
Id = SystemRoleConstants.AdminId,
|
|
Name = "Administrator",
|
|
IsSystem = true
|
|
};
|
|
var zetaRole = new Role { Id = "zeta", Name = "Zeta", IsSystem = false };
|
|
var alphaRole = new Role { Id = "alpha", Name = "Alpha", IsSystem = false };
|
|
|
|
roleService.Setup(x => x.GetAllAsync())
|
|
.ReturnsAsync(new List<Role> { zetaRole, superAdmin, operatorRole, alphaRole, adminRole });
|
|
roleService.Setup(x => x.GetFunctionsAsync(adminRole.Id))
|
|
.ReturnsAsync(new List<string> { Functions.Role_Read });
|
|
roleService.Setup(x => x.GetFunctionsAsync(operatorRole.Id))
|
|
.ReturnsAsync(new List<string> { Functions.App_Read, Functions.Config_Read });
|
|
roleService.Setup(x => x.GetFunctionsAsync(alphaRole.Id))
|
|
.ReturnsAsync(new List<string>());
|
|
roleService.Setup(x => x.GetFunctionsAsync(zetaRole.Id))
|
|
.ReturnsAsync(new List<string> { Functions.Log_Read });
|
|
|
|
var result = await CreateService(roleService).GetAllAsync();
|
|
|
|
Assert.AreEqual(4, result.Count);
|
|
Assert.AreSame(adminRole, result[0].Role);
|
|
Assert.AreSame(operatorRole, result[1].Role);
|
|
Assert.AreSame(alphaRole, result[2].Role);
|
|
Assert.AreSame(zetaRole, result[3].Role);
|
|
CollectionAssert.AreEqual(new[] { Functions.Role_Read }, result[0].Functions.ToArray());
|
|
CollectionAssert.AreEqual(
|
|
new[] { Functions.App_Read, Functions.Config_Read },
|
|
result[1].Functions.ToArray());
|
|
Assert.IsFalse(result.Any(x => x.Role.Id == SystemRoleConstants.SuperAdminId));
|
|
roleService.Verify(x => x.GetFunctionsAsync(SystemRoleConstants.SuperAdminId), Times.Never);
|
|
roleService.Verify(x => x.GetFunctionsAsync(It.IsAny<string>()), Times.Exactly(4));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task CreateAsync_MapsRoleAndNormalizesFunctions()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
Role createdRole = null;
|
|
List<string> createdFunctions = null;
|
|
roleService.Setup(x => x.GetAsync("custom-role"))
|
|
.ReturnsAsync((Role)null);
|
|
roleService.Setup(x => x.CreateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()))
|
|
.Callback<Role, IEnumerable<string>>((role, functions) =>
|
|
{
|
|
createdRole = role;
|
|
createdFunctions = functions.ToList();
|
|
})
|
|
.ReturnsAsync((Role role, IEnumerable<string> _) => role);
|
|
|
|
var result = await CreateService(roleService).CreateAsync(new CreateRoleCommand(
|
|
"custom-role",
|
|
"Custom role",
|
|
null,
|
|
new[] { Functions.Role_Read, " ", Functions.Role_Read, null, Functions.App_Read }));
|
|
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.AreSame(createdRole, result.Value);
|
|
Assert.AreEqual("custom-role", createdRole.Id);
|
|
Assert.AreEqual("Custom role", createdRole.Name);
|
|
Assert.AreEqual(string.Empty, createdRole.Description);
|
|
Assert.IsFalse(createdRole.IsSystem);
|
|
CollectionAssert.AreEqual(
|
|
new[] { Functions.Role_Read, Functions.App_Read },
|
|
createdFunctions);
|
|
roleService.Verify(x => x.CreateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task CreateAsync_WhenIdentifierExistsReturnsConflictWithoutWriting()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
roleService.Setup(x => x.GetAsync("existing"))
|
|
.ReturnsAsync(new Role { Id = "existing" });
|
|
|
|
var result = await CreateService(roleService).CreateAsync(new CreateRoleCommand(
|
|
"existing", "Duplicate", "description", Array.Empty<string>()));
|
|
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual(ApplicationError.Conflict, result.Error);
|
|
roleService.Verify(x => x.CreateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()), Times.Never);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateAsync_WhenRoleDoesNotExistReturnsNotFoundWithoutWriting()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
roleService.Setup(x => x.GetAsync("missing"))
|
|
.ReturnsAsync((Role)null);
|
|
|
|
var result = await CreateService(roleService).UpdateAsync(new UpdateRoleCommand(
|
|
"missing", "Updated", null, Array.Empty<string>()));
|
|
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual(ApplicationError.NotFound, result.Error);
|
|
roleService.Verify(x => x.UpdateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()), Times.Never);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateAsync_WhenRoleIsSuperAdminReturnsForbiddenWithoutWriting()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
roleService.Setup(x => x.GetAsync(SystemRoleConstants.SuperAdminId))
|
|
.ReturnsAsync(new Role
|
|
{
|
|
Id = SystemRoleConstants.SuperAdminId,
|
|
Name = "Super Administrator",
|
|
IsSystem = true
|
|
});
|
|
|
|
var result = await CreateService(roleService).UpdateAsync(new UpdateRoleCommand(
|
|
SystemRoleConstants.SuperAdminId,
|
|
"Changed",
|
|
"Changed description",
|
|
new[] { Functions.Role_Edit }));
|
|
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual(ApplicationError.Forbidden, result.Error);
|
|
roleService.Verify(x => x.UpdateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()), Times.Never);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateAsync_PreservesSystemFlagAndMapsNormalizedFunctions()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
var existingRole = new Role
|
|
{
|
|
Id = "system-role",
|
|
Name = "Old name",
|
|
Description = "Old description",
|
|
IsSystem = true
|
|
};
|
|
Role updatedRole = null;
|
|
List<string> updatedFunctions = null;
|
|
roleService.Setup(x => x.GetAsync(existingRole.Id)).ReturnsAsync(existingRole);
|
|
roleService.Setup(x => x.UpdateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()))
|
|
.Callback<Role, IEnumerable<string>>((role, functions) =>
|
|
{
|
|
updatedRole = role;
|
|
updatedFunctions = functions.ToList();
|
|
})
|
|
.ReturnsAsync(true);
|
|
|
|
var result = await CreateService(roleService).UpdateAsync(new UpdateRoleCommand(
|
|
existingRole.Id,
|
|
"New name",
|
|
null,
|
|
new[] { Functions.Config_Read, "", Functions.Config_Read }));
|
|
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.AreSame(updatedRole, result.Value);
|
|
Assert.AreEqual(existingRole.Id, updatedRole.Id);
|
|
Assert.AreEqual("New name", updatedRole.Name);
|
|
Assert.AreEqual(string.Empty, updatedRole.Description);
|
|
Assert.IsTrue(updatedRole.IsSystem);
|
|
CollectionAssert.AreEqual(new[] { Functions.Config_Read }, updatedFunctions);
|
|
roleService.Verify(x => x.UpdateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task UpdateAsync_WhenPersistenceFailsReturnsOperationFailed()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
roleService.Setup(x => x.GetAsync("role-1"))
|
|
.ReturnsAsync(new Role { Id = "role-1", IsSystem = false });
|
|
roleService.Setup(x => x.UpdateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()))
|
|
.ReturnsAsync(false);
|
|
|
|
var result = await CreateService(roleService).UpdateAsync(new UpdateRoleCommand(
|
|
"role-1", "Updated", "description", new[] { Functions.Role_Read }));
|
|
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual(ApplicationError.OperationFailed, result.Error);
|
|
roleService.Verify(x => x.UpdateAsync(It.IsAny<Role>(), It.IsAny<IEnumerable<string>>()), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task DeleteAsync_WhenRoleDoesNotExistReturnsNotFoundWithoutDeleting()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
roleService.Setup(x => x.GetAsync("missing"))
|
|
.ReturnsAsync((Role)null);
|
|
|
|
var result = await CreateService(roleService).DeleteAsync("missing");
|
|
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual(ApplicationError.NotFound, result.Error);
|
|
roleService.Verify(x => x.DeleteAsync(It.IsAny<string>()), Times.Never);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task DeleteAsync_WhenRoleIsSystemReturnsForbiddenWithoutDeleting()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
roleService.Setup(x => x.GetAsync(SystemRoleConstants.AdminId))
|
|
.ReturnsAsync(new Role
|
|
{
|
|
Id = SystemRoleConstants.AdminId,
|
|
Name = "Administrator",
|
|
IsSystem = true
|
|
});
|
|
|
|
var result = await CreateService(roleService).DeleteAsync(SystemRoleConstants.AdminId);
|
|
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual(ApplicationError.Forbidden, result.Error);
|
|
roleService.Verify(x => x.DeleteAsync(It.IsAny<string>()), Times.Never);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task DeleteAsync_WhenRoleIsDeletedReturnsSuccess()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
roleService.Setup(x => x.GetAsync("role-1"))
|
|
.ReturnsAsync(new Role { Id = "role-1", IsSystem = false });
|
|
roleService.Setup(x => x.DeleteAsync("role-1"))
|
|
.ReturnsAsync(true);
|
|
|
|
var result = await CreateService(roleService).DeleteAsync("role-1");
|
|
|
|
Assert.IsTrue(result.Succeeded);
|
|
Assert.AreEqual(ApplicationError.None, result.Error);
|
|
roleService.Verify(x => x.DeleteAsync("role-1"), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task DeleteAsync_WhenPersistenceFailsReturnsOperationFailed()
|
|
{
|
|
var roleService = new Mock<IRoleService>();
|
|
roleService.Setup(x => x.GetAsync("role-1"))
|
|
.ReturnsAsync(new Role { Id = "role-1", IsSystem = false });
|
|
roleService.Setup(x => x.DeleteAsync("role-1"))
|
|
.ReturnsAsync(false);
|
|
|
|
var result = await CreateService(roleService).DeleteAsync("role-1");
|
|
|
|
Assert.IsFalse(result.Succeeded);
|
|
Assert.AreEqual(ApplicationError.OperationFailed, result.Error);
|
|
roleService.Verify(x => x.DeleteAsync("role-1"), Times.Once);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void GetSupportedPermissions_ReturnsCorePermissionKeys()
|
|
{
|
|
var permissions = CreateService(new Mock<IRoleService>()).GetSupportedPermissions();
|
|
|
|
Assert.IsTrue(permissions.Count > 0);
|
|
CollectionAssert.Contains(permissions.ToList(), Functions.App_Read);
|
|
CollectionAssert.Contains(permissions.ToList(), Functions.Config_Publish);
|
|
CollectionAssert.Contains(permissions.ToList(), Functions.Role_Read);
|
|
CollectionAssert.Contains(permissions.ToList(), Functions.Log_Read);
|
|
Assert.AreEqual(permissions.Count, permissions.Distinct().Count());
|
|
}
|
|
|
|
private static RoleManagementService CreateService(Mock<IRoleService> roleService)
|
|
{
|
|
return new RoleManagementService(roleService.Object);
|
|
}
|
|
}
|