audit, advisories and doctors/setup work

This commit is contained in:
master
2026-01-13 18:53:39 +02:00
parent 9ca7cb183e
commit d7be6ba34b
811 changed files with 54242 additions and 4056 deletions

View File

@@ -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);
}
}