1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-08 14:38:15 -05:00

Add missing test coverage

This commit is contained in:
Thomas Rittson 2025-04-07 11:38:24 +10:00
parent 2e8a6ddb90
commit cfdffc4746
No known key found for this signature in database
GPG Key ID: CDDDA03861C35E27
2 changed files with 70 additions and 23 deletions

View File

@ -0,0 +1,28 @@
using Bit.Api.AdminConsole.Authorization;
using Microsoft.AspNetCore.Http;
using NSubstitute;
using Xunit;
namespace Bit.Api.Test.AdminConsole.Authorization;
public class HttpContextExtensionsTests
{
[Fact]
public async Task WithFeaturesCacheAsync_OnlyExecutesCallbackOnce()
{
var httpContext = new DefaultHttpContext();
var callback = Substitute.For<Func<Task<string>>>();
callback().Returns(Task.FromResult("hello world"));
// Call once
var result1 = await httpContext.WithFeaturesCacheAsync(callback);
Assert.Equal("hello world", result1);
await callback.ReceivedWithAnyArgs(1).Invoke();
// Call again - callback not executed again
var result2 = await httpContext.WithFeaturesCacheAsync(callback);
Assert.Equal("hello world", result2);
await callback.ReceivedWithAnyArgs(1).Invoke();
}
}

View File

@ -13,25 +13,13 @@ namespace Bit.Api.Test.AdminConsole.Authorization;
[SutProviderCustomize]
public class OrganizationRequirementHandlerTests
{
[Theory, BitAutoData]
public async Task IfNoOrganizationId_Throws(SutProvider<OrganizationRequirementHandler> sutProvider)
[Theory]
[BitAutoData((string)null)]
[BitAutoData("malformed guid")]
public async Task IfInvalidOrganizationId_Throws(string orgId, Guid userId, SutProvider<OrganizationRequirementHandler> sutProvider)
{
// Arrange
ArrangeRouteAndUser(sutProvider, null!); // no orgId in route
var testRequirement = Substitute.For<IOrganizationRequirement>();
var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null);
// Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => sutProvider.Sut.HandleAsync(authContext));
Assert.Equal(HttpContextExtensions.NoOrgIdError, exception.Message);
Assert.False(authContext.HasSucceeded);
}
[Theory, BitAutoData]
public async Task IfInvalidOrganizationId_Throws(SutProvider<OrganizationRequirementHandler> sutProvider)
{
// Arrange
ArrangeRouteAndUser(sutProvider, "malformed guid");
ArrangeRouteAndUser(sutProvider, orgId, userId);
var testRequirement = Substitute.For<IOrganizationRequirement>();
var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null);
@ -42,10 +30,39 @@ public class OrganizationRequirementHandlerTests
}
[Theory, BitAutoData]
public async Task DoesNotAuthorize_IfAuthorizeAsync_ReturnsFalse(SutProvider<OrganizationRequirementHandler> sutProvider, Guid organizationId)
public async Task IfHttpContextIsNull_Throws(SutProvider<OrganizationRequirementHandler> sutProvider)
{
// Arrange
sutProvider.GetDependency<IHttpContextAccessor>().HttpContext = null;
var testRequirement = Substitute.For<IOrganizationRequirement>();
var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null);
// Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => sutProvider.Sut.HandleAsync(authContext));
Assert.Contains(OrganizationRequirementHandler.NoHttpContextError, exception.Message);
Assert.False(authContext.HasSucceeded);
}
[Theory, BitAutoData]
public async Task IfUserIdIsNull_Throws(Guid orgId, SutProvider<OrganizationRequirementHandler> sutProvider)
{
// Arrange
ArrangeRouteAndUser(sutProvider, orgId.ToString(), null);
var testRequirement = Substitute.For<IOrganizationRequirement>();
var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null);
// Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => sutProvider.Sut.HandleAsync(authContext));
Assert.Contains(OrganizationRequirementHandler.NoUserIdError, exception.Message);
Assert.False(authContext.HasSucceeded);
}
[Theory, BitAutoData]
public async Task DoesNotAuthorize_IfAuthorizeAsync_ReturnsFalse(
SutProvider<OrganizationRequirementHandler> sutProvider, Guid organizationId, Guid userId)
{
// Arrange route values
ArrangeRouteAndUser(sutProvider, organizationId.ToString());
ArrangeRouteAndUser(sutProvider, organizationId.ToString(), userId);
// Arrange requirement
var testRequirement = Substitute.For<IOrganizationRequirement>();
@ -63,10 +80,11 @@ public class OrganizationRequirementHandlerTests
}
[Theory, BitAutoData]
public async Task Authorizes_IfAuthorizeAsync_ReturnsTrue(SutProvider<OrganizationRequirementHandler> sutProvider, Guid organizationId)
public async Task Authorizes_IfAuthorizeAsync_ReturnsTrue(
SutProvider<OrganizationRequirementHandler> sutProvider, Guid organizationId, Guid userId)
{
// Arrange route values
ArrangeRouteAndUser(sutProvider, organizationId.ToString());
ArrangeRouteAndUser(sutProvider, organizationId.ToString(), userId);
// Arrange requirement
var testRequirement = Substitute.For<IOrganizationRequirement>();
@ -83,11 +101,12 @@ public class OrganizationRequirementHandlerTests
Assert.True(authContext.HasSucceeded);
}
private static void ArrangeRouteAndUser(SutProvider<OrganizationRequirementHandler> sutProvider, string orgIdRouteValue)
private static void ArrangeRouteAndUser(SutProvider<OrganizationRequirementHandler> sutProvider, string orgIdRouteValue,
Guid? userId)
{
var httpContext = new DefaultHttpContext();
httpContext.Request.RouteValues["orgId"] = orgIdRouteValue;
sutProvider.GetDependency<IHttpContextAccessor>().HttpContext = httpContext;
sutProvider.GetDependency<IUserService>().GetProperUserId(Arg.Any<ClaimsPrincipal>()).Returns(Guid.NewGuid());
sutProvider.GetDependency<IUserService>().GetProperUserId(Arg.Any<ClaimsPrincipal>()).Returns(userId);
}
}