audit, advisories and doctors/setup work
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.FeatureFlags.Tests;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public class InMemoryFeatureFlagProviderTests
|
||||
{
|
||||
[Fact]
|
||||
public void Name_ReturnsInMemory()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new InMemoryFeatureFlagProvider(new Dictionary<string, bool>());
|
||||
|
||||
// Assert
|
||||
provider.Name.Should().Be("InMemory");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Priority_ReturnsConfiguredValue()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new InMemoryFeatureFlagProvider(new Dictionary<string, bool>(), priority: 5);
|
||||
|
||||
// Assert
|
||||
provider.Priority.Should().Be(5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_ReturnsTrueForEnabledFlag()
|
||||
{
|
||||
// Arrange
|
||||
var flags = new Dictionary<string, bool>
|
||||
{
|
||||
{ "enabled-flag", true }
|
||||
};
|
||||
var provider = new InMemoryFeatureFlagProvider(flags);
|
||||
|
||||
// Act
|
||||
var result = await provider.TryGetFlagAsync("enabled-flag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeTrue();
|
||||
result.Key.Should().Be("enabled-flag");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_ReturnsFalseForDisabledFlag()
|
||||
{
|
||||
// Arrange
|
||||
var flags = new Dictionary<string, bool>
|
||||
{
|
||||
{ "disabled-flag", false }
|
||||
};
|
||||
var provider = new InMemoryFeatureFlagProvider(flags);
|
||||
|
||||
// Act
|
||||
var result = await provider.TryGetFlagAsync("disabled-flag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_ReturnsNullForUnknownFlag()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new InMemoryFeatureFlagProvider(new Dictionary<string, bool>());
|
||||
|
||||
// Act
|
||||
var result = await provider.TryGetFlagAsync("unknown", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryGetFlagAsync_IsCaseInsensitive()
|
||||
{
|
||||
// Arrange
|
||||
var flags = new Dictionary<string, bool>
|
||||
{
|
||||
{ "MyFlag", true }
|
||||
};
|
||||
var provider = new InMemoryFeatureFlagProvider(flags);
|
||||
|
||||
// Act
|
||||
var result = await provider.TryGetFlagAsync("myflag", FeatureFlagEvaluationContext.Empty);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetFlag_AddsNewFlag()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new InMemoryFeatureFlagProvider(new Dictionary<string, bool>());
|
||||
|
||||
// Act
|
||||
provider.SetFlag("new-flag", true);
|
||||
var result = provider.TryGetFlagAsync("new-flag", FeatureFlagEvaluationContext.Empty).Result;
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetFlag_UpdatesExistingFlag()
|
||||
{
|
||||
// Arrange
|
||||
var flags = new Dictionary<string, bool>
|
||||
{
|
||||
{ "toggle-flag", false }
|
||||
};
|
||||
var provider = new InMemoryFeatureFlagProvider(flags);
|
||||
|
||||
// Act
|
||||
provider.SetFlag("toggle-flag", true);
|
||||
var result = provider.TryGetFlagAsync("toggle-flag", FeatureFlagEvaluationContext.Empty).Result;
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Enabled.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetFlag_WithVariant_SetsVariantValue()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new InMemoryFeatureFlagProvider(new Dictionary<string, bool>());
|
||||
|
||||
// Act
|
||||
provider.SetFlag("variant-flag", true, "blue");
|
||||
var result = provider.TryGetFlagAsync("variant-flag", FeatureFlagEvaluationContext.Empty).Result;
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result!.Variant.Should().Be("blue");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveFlag_RemovesExistingFlag()
|
||||
{
|
||||
// Arrange
|
||||
var flags = new Dictionary<string, bool>
|
||||
{
|
||||
{ "to-remove", true }
|
||||
};
|
||||
var provider = new InMemoryFeatureFlagProvider(flags);
|
||||
|
||||
// Act
|
||||
provider.RemoveFlag("to-remove");
|
||||
var result = provider.TryGetFlagAsync("to-remove", FeatureFlagEvaluationContext.Empty).Result;
|
||||
|
||||
// Assert
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveFlag_DoesNotThrowForNonexistentFlag()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new InMemoryFeatureFlagProvider(new Dictionary<string, bool>());
|
||||
|
||||
// Act & Assert
|
||||
provider.Invoking(p => p.RemoveFlag("nonexistent"))
|
||||
.Should().NotThrow();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clear_RemovesAllFlags()
|
||||
{
|
||||
// Arrange
|
||||
var flags = new Dictionary<string, bool>
|
||||
{
|
||||
{ "flag-1", true },
|
||||
{ "flag-2", false }
|
||||
};
|
||||
var provider = new InMemoryFeatureFlagProvider(flags);
|
||||
|
||||
// Act
|
||||
provider.Clear();
|
||||
var result1 = provider.TryGetFlagAsync("flag-1", FeatureFlagEvaluationContext.Empty).Result;
|
||||
var result2 = provider.TryGetFlagAsync("flag-2", FeatureFlagEvaluationContext.Empty).Result;
|
||||
|
||||
// Assert
|
||||
result1.Should().BeNull();
|
||||
result2.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListFlagsAsync_ReturnsAllFlags()
|
||||
{
|
||||
// Arrange
|
||||
var flags = new Dictionary<string, bool>
|
||||
{
|
||||
{ "flag-a", true },
|
||||
{ "flag-b", false },
|
||||
{ "flag-c", true }
|
||||
};
|
||||
var provider = new InMemoryFeatureFlagProvider(flags);
|
||||
|
||||
// Act
|
||||
var result = await provider.ListFlagsAsync();
|
||||
|
||||
// Assert
|
||||
result.Should().HaveCount(3);
|
||||
result.Select(f => f.Key).Should().Contain(["flag-a", "flag-b", "flag-c"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListFlagsAsync_ReturnsEmptyWhenNoFlags()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new InMemoryFeatureFlagProvider(new Dictionary<string, bool>());
|
||||
|
||||
// Act
|
||||
var result = await provider.ListFlagsAsync();
|
||||
|
||||
// Assert
|
||||
result.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListFlagsAsync_ReflectsCurrentStateAfterModifications()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new InMemoryFeatureFlagProvider(new Dictionary<string, bool>());
|
||||
provider.SetFlag("dynamic-flag", true);
|
||||
|
||||
// Act
|
||||
var result = await provider.ListFlagsAsync();
|
||||
|
||||
// Assert
|
||||
result.Should().HaveCount(1);
|
||||
result.Single().Key.Should().Be("dynamic-flag");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user