audit, advisories and doctors/setup work
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using StellaOps.FeatureFlags.Providers;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.FeatureFlags.Tests;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public class ConfigurationFeatureFlagProviderTests : IDisposable
|
||||
{
|
||||
private readonly ConfigurationFeatureFlagProvider _sut;
|
||||
private readonly IConfigurationRoot _configuration;
|
||||
|
||||
public ConfigurationFeatureFlagProviderTests()
|
||||
{
|
||||
var configData = new Dictionary<string, string?>
|
||||
{
|
||||
{ "FeatureFlags:SimpleFlag", "true" },
|
||||
{ "FeatureFlags:DisabledFlag", "false" },
|
||||
{ "FeatureFlags:ComplexFlag:Enabled", "true" },
|
||||
{ "FeatureFlags:ComplexFlag:Variant", "blue" },
|
||||
{ "FeatureFlags:ComplexFlag:Description", "A complex feature flag" },
|
||||
{ "FeatureFlags:VariantOnlyFlag:Enabled", "false" },
|
||||
{ "FeatureFlags:VariantOnlyFlag:Variant", "control" },
|
||||
{ "CustomSection:MyFlag", "true" }
|
||||
};
|
||||
|
||||
_configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(configData)
|
||||
.Build();
|
||||
|
||||
_sut = new ConfigurationFeatureFlagProvider(_configuration);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_sut.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Name_ReturnsConfiguration()
|
||||
{
|
||||
_sut.Name.Should().Be("Configuration");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Priority_ReturnsDefaultValue()
|
||||
{
|
||||
_sut.Priority.Should().Be(50);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SupportsWatch_ReturnsTrue()
|
||||
{
|
||||
_sut.SupportsWatch.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_ReturnsTrueForEnabledSimpleFlag()
|
||||
{
|
||||
// Act
|
||||
var result = await _sut.TryGetFlagAsync("SimpleFlag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeTrue();
|
||||
result.Key.Should().Be("SimpleFlag");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_ReturnsFalseForDisabledSimpleFlag()
|
||||
{
|
||||
// Act
|
||||
var result = await _sut.TryGetFlagAsync("DisabledFlag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_ReturnsNullForUnknownFlag()
|
||||
{
|
||||
// Act
|
||||
var result = await _sut.TryGetFlagAsync("UnknownFlag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_ParsesComplexFlagWithVariant()
|
||||
{
|
||||
// Act
|
||||
var result = await _sut.TryGetFlagAsync("ComplexFlag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeTrue();
|
||||
result.Variant.Should().Be("blue");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_ParsesComplexFlagWithEnabledFalse()
|
||||
{
|
||||
// Act
|
||||
var result = await _sut.TryGetFlagAsync("VariantOnlyFlag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeFalse();
|
||||
result.Variant.Should().Be("control");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListFlagsAsync_ReturnsAllDefinedFlags()
|
||||
{
|
||||
// Act
|
||||
var result = await _sut.ListFlagsAsync();
|
||||
|
||||
// Assert
|
||||
result.Should().HaveCount(4);
|
||||
result.Select(f => f.Key).Should().Contain([
|
||||
"SimpleFlag", "DisabledFlag", "ComplexFlag", "VariantOnlyFlag"
|
||||
]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListFlagsAsync_ParsesDefaultValuesCorrectly()
|
||||
{
|
||||
// Act
|
||||
var result = await _sut.ListFlagsAsync();
|
||||
|
||||
// Assert
|
||||
var simpleFlag = result.Single(f => f.Key == "SimpleFlag");
|
||||
simpleFlag.DefaultValue.Should().BeTrue();
|
||||
|
||||
var disabledFlag = result.Single(f => f.Key == "DisabledFlag");
|
||||
disabledFlag.DefaultValue.Should().BeFalse();
|
||||
|
||||
var complexFlag = result.Single(f => f.Key == "ComplexFlag");
|
||||
complexFlag.DefaultValue.Should().BeTrue();
|
||||
complexFlag.Description.Should().Be("A complex feature flag");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithCustomSection_ReadsFromThatSection()
|
||||
{
|
||||
// Arrange
|
||||
using var provider = new ConfigurationFeatureFlagProvider(_configuration, "CustomSection");
|
||||
|
||||
// Act & Assert
|
||||
var result = provider.TryGetFlagAsync("MyFlag", FeatureFlagEvaluationContext.Empty).Result;
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithCustomPriority_SetsCorrectPriority()
|
||||
{
|
||||
// Arrange
|
||||
using var provider = new ConfigurationFeatureFlagProvider(_configuration, priority: 25);
|
||||
|
||||
// Assert
|
||||
provider.Priority.Should().Be(25);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("TRUE", true)]
|
||||
[InlineData("True", true)]
|
||||
[InlineData("true", true)]
|
||||
[InlineData("FALSE", false)]
|
||||
[InlineData("False", false)]
|
||||
[InlineData("false", false)]
|
||||
public async Task TryGetFlagAsync_HandlesCaseInsensitiveBooleanValues(string configValue, bool expected)
|
||||
{
|
||||
// Arrange
|
||||
var configData = new Dictionary<string, string?>
|
||||
{
|
||||
{ "FeatureFlags:CaseFlag", configValue }
|
||||
};
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(configData)
|
||||
.Build();
|
||||
|
||||
using var provider = new ConfigurationFeatureFlagProvider(configuration);
|
||||
|
||||
// Act
|
||||
var result = await provider.TryGetFlagAsync("CaseFlag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().Be(expected);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user