using Bit.Core.Context; using Bit.Core.Exceptions; using Bit.Core.Services; using Bit.Core.Utilities; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using NSubstitute; using Xunit; namespace Bit.Core.Test.Utilities; public class RequireFeatureAttributeTests { private const string _testFeature = "test-feature"; [Fact] public void Throws_When_Feature_Disabled() { // Arrange var rfa = new RequireFeatureAttribute(_testFeature); // Act & Assert Assert.Throws(() => rfa.OnActionExecuting(GetContext(enabled: false))); } [Fact] public void Throws_When_Feature_Not_Found() { // Arrange var rfa = new RequireFeatureAttribute("missing-feature"); // Act & Assert Assert.Throws(() => rfa.OnActionExecuting(GetContext(enabled: false))); } [Fact] public void Success_When_Feature_Enabled() { // Arrange var rfa = new RequireFeatureAttribute(_testFeature); // Act rfa.OnActionExecuting(GetContext(enabled: true)); // Assert // The Assert here is NOT throwing an exception } /// /// Generates a ActionExecutingContext with the necessary services registered to test /// the /// /// Mock value for the flag /// private static ActionExecutingContext GetContext(bool enabled) { IServiceCollection services = new ServiceCollection(); var featureService = Substitute.For(); var currentContext = Substitute.For(); featureService.IsEnabled(_testFeature).Returns(enabled); services.AddSingleton(featureService); services.AddSingleton(currentContext); var httpContext = new DefaultHttpContext(); httpContext.RequestServices = services.BuildServiceProvider(); var context = Substitute.For( Substitute.For(httpContext, new RouteData(), Substitute.For()), new List(), new Dictionary(), Substitute.For()); return context; } }