Files
2026-06-23 11:18:54 -05:00

159 lines
6.5 KiB
C#

using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Moq;
using NUnit.Framework;
using Strata.Analytics.Api.Authorization;
using Strata.Analytics.Biz.DataSources.Services;
using Strata.Analytics.Biz.DataSources.Models;
using Strata.Testing.Categories;
using System.Security.Claims;
using FluentAssertions;
using Microsoft.AspNetCore.Http.Features;
using System.IO;
using System.Text;
using Newtonsoft.Json;
namespace Strata.Analytics.Test.Unit.Api.Authorization
{
[NUnit.Framework.Category(TestCategory.Unit)]
[Parallelizable(ParallelScope.Self)]
public class DataSourceMinimumRoleHandlerTest
{
[Test]
public async Task Handler_Fails_GivenDataSourceIdNotInRouteAndNotInBody()
{
// arrange
var mockDataSourceService = new Mock<IDataSourceService>();
var mockHttpContextAccessor = new Mock<IHttpContextAccessor>();
var httpContext = new DefaultHttpContext();
mockHttpContextAccessor.Setup(_ => _.HttpContext).Returns(httpContext);
var authorizationHandlerContext = GetMockAuthorizationHandlerContext(DataSourceRole.Viewer);
var handler = new DataSourceMinimumRoleHandler(mockDataSourceService.Object, mockHttpContextAccessor.Object);
// act
await handler.HandleAsync(authorizationHandlerContext);
// assert
authorizationHandlerContext.HasSucceeded.Should().BeFalse();
}
[Test]
public async Task Handler_Succeeds_GivenDataSourceIdNotInRouteButInBody()
{
// arrange
var dataSourceService = GetMockDataSourceService(DataSourceRole.Viewer);
var httpContextAccessor = GetMockHttpContextAccessor(false, true);
var authorizationHandlerContext = GetMockAuthorizationHandlerContext(DataSourceRole.Viewer);
var handler = new DataSourceMinimumRoleHandler(dataSourceService, httpContextAccessor);
// act
await handler.HandleAsync(authorizationHandlerContext);
// assert
authorizationHandlerContext.HasSucceeded.Should().BeTrue();
}
[Test]
public async Task Handler_Succeeds_GivenDataSourceIdInRouteAndInBody()
{
// arrange
var dataSourceService = GetMockDataSourceService(DataSourceRole.Viewer);
var httpContextAccessor = GetMockHttpContextAccessor(true, true);
var authorizationHandlerContext = GetMockAuthorizationHandlerContext(DataSourceRole.Viewer);
var handler = new DataSourceMinimumRoleHandler(dataSourceService, httpContextAccessor);
// act
await handler.HandleAsync(authorizationHandlerContext);
// assert
authorizationHandlerContext.HasSucceeded.Should().BeTrue();
}
[TestCase(DataSourceRole.Viewer, DataSourceRole.Viewer)]
[TestCase(DataSourceRole.Viewer, DataSourceRole.Editor)]
[TestCase(DataSourceRole.Editor, DataSourceRole.Editor)]
public async Task Handler_Succeeds_GivenUserHasMinimumAccess(DataSourceRole minimumDataSourceRole, DataSourceRole userDataSourceRole)
{
// arrange
var dataSourceService = GetMockDataSourceService(userDataSourceRole);
var httpContextAccessor = GetMockHttpContextAccessor();
var authorizationHandlerContext = GetMockAuthorizationHandlerContext(minimumDataSourceRole);
var handler = new DataSourceMinimumRoleHandler(dataSourceService, httpContextAccessor);
// act
await handler.HandleAsync(authorizationHandlerContext);
// assert
authorizationHandlerContext.HasSucceeded.Should().BeTrue();
}
[TestCase(DataSourceRole.Editor, DataSourceRole.Viewer)]
public async Task Handler_Fails_GivenUserDoesNotHaveMinimumAccess(DataSourceRole minimumDataSourceRole, DataSourceRole userDataSourceRole)
{
// arrange
var dataSourceService = GetMockDataSourceService(userDataSourceRole);
var httpContextAccessor = GetMockHttpContextAccessor();
var authorizationHandlerContext = GetMockAuthorizationHandlerContext(minimumDataSourceRole);
var handler = new DataSourceMinimumRoleHandler(dataSourceService, httpContextAccessor);
// act
await handler.HandleAsync(authorizationHandlerContext);
// assert
authorizationHandlerContext.HasSucceeded.Should().BeFalse();
}
private IDataSourceService GetMockDataSourceService(DataSourceRole userDataSourceRole)
{
var mockDataSourceService = new Mock<IDataSourceService>();
mockDataSourceService.Setup(service => service.GetCurrentUserRoleAsync(5, System.Threading.CancellationToken.None))
.ReturnsAsync(userDataSourceRole);
return mockDataSourceService.Object;
}
private IHttpContextAccessor GetMockHttpContextAccessor(bool dataSourceIdInRoute = true, bool dataSourceIdInBody = false)
{
var mockHttpContextAccessor = new Mock<IHttpContextAccessor>();
var features = new FeatureCollection();
if (dataSourceIdInRoute)
{
var routeFeature = new RouteValuesFeature();
routeFeature.RouteValues.Add("dataSourceId", 5);
features.Set<IRouteValuesFeature>(routeFeature);
}
if (dataSourceIdInBody)
{
var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { dataSourceId = 5 }));
var ms = new MemoryStream(bytes);
var request = new HttpRequestFeature() { Body = ms };
request.Headers["Content-Type"] = "application/json";
features.Set<IHttpRequestFeature>(request);
}
var httpContext = new DefaultHttpContext(features);
mockHttpContextAccessor.Setup(_ => _.HttpContext).Returns(httpContext);
return mockHttpContextAccessor.Object;
}
private AuthorizationHandlerContext GetMockAuthorizationHandlerContext(DataSourceRole minimumDataSourceRole)
{
var requirement = new DataSourceMinimumRoleRequirement(minimumDataSourceRole);
var user = new ClaimsPrincipal(
new ClaimsIdentity(
new Claim[] { }, "Basic"));
return new AuthorizationHandlerContext(new[] { requirement }, user, null);
}
}
}