201 lines
5.7 KiB
C#
201 lines
5.7 KiB
C#
using FluentAssertions;
|
|
using Xunit;
|
|
|
|
namespace StellaOps.FeatureFlags.Tests;
|
|
|
|
[Trait("Category", "Unit")]
|
|
public class FeatureFlagModelsTests
|
|
{
|
|
[Fact]
|
|
public void FeatureFlagResult_CanBeCreated()
|
|
{
|
|
// Act
|
|
var result = new FeatureFlagResult(
|
|
Key: "test-flag",
|
|
Enabled: true,
|
|
Variant: "blue",
|
|
Reason: "Test reason",
|
|
Source: "TestProvider");
|
|
|
|
// Assert
|
|
result.Key.Should().Be("test-flag");
|
|
result.Enabled.Should().BeTrue();
|
|
result.Variant.Should().Be("blue");
|
|
result.Reason.Should().Be("Test reason");
|
|
result.Source.Should().Be("TestProvider");
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagResult_WithNullOptionalValues()
|
|
{
|
|
// Act
|
|
var result = new FeatureFlagResult(
|
|
Key: "simple-flag",
|
|
Enabled: false,
|
|
Variant: null,
|
|
Reason: null,
|
|
Source: "TestProvider");
|
|
|
|
// Assert
|
|
result.Variant.Should().BeNull();
|
|
result.Reason.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagEvaluationContext_Empty_HasNullValues()
|
|
{
|
|
// Act
|
|
var context = FeatureFlagEvaluationContext.Empty;
|
|
|
|
// Assert
|
|
context.UserId.Should().BeNull();
|
|
context.TenantId.Should().BeNull();
|
|
context.Environment.Should().BeNull();
|
|
context.Attributes.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagEvaluationContext_CanBeCreatedWithAllValues()
|
|
{
|
|
// Arrange
|
|
var attributes = new Dictionary<string, object>
|
|
{
|
|
{ "role", "admin" },
|
|
{ "subscription", "premium" }
|
|
};
|
|
|
|
// Act
|
|
var context = new FeatureFlagEvaluationContext(
|
|
UserId: "user-123",
|
|
TenantId: "tenant-456",
|
|
Environment: "production",
|
|
Attributes: attributes);
|
|
|
|
// Assert
|
|
context.UserId.Should().Be("user-123");
|
|
context.TenantId.Should().Be("tenant-456");
|
|
context.Environment.Should().Be("production");
|
|
context.Attributes.Should().HaveCount(2);
|
|
context.Attributes!["role"].Should().Be("admin");
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagDefinition_CanBeCreatedWithRequiredValues()
|
|
{
|
|
// Act
|
|
var definition = new FeatureFlagDefinition(
|
|
Key: "my-feature",
|
|
Description: "My feature description",
|
|
DefaultValue: true,
|
|
Enabled: false);
|
|
|
|
// Assert
|
|
definition.Key.Should().Be("my-feature");
|
|
definition.Description.Should().Be("My feature description");
|
|
definition.DefaultValue.Should().BeTrue();
|
|
definition.Enabled.Should().BeFalse();
|
|
definition.Tags.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagDefinition_CanBeCreatedWithTags()
|
|
{
|
|
// Arrange
|
|
var tags = new List<string> { "team-a", "critical" };
|
|
|
|
// Act
|
|
var definition = new FeatureFlagDefinition(
|
|
Key: "feature",
|
|
Description: null,
|
|
DefaultValue: false,
|
|
Enabled: true,
|
|
Tags: tags);
|
|
|
|
// Assert
|
|
definition.Tags.Should().NotBeNull();
|
|
definition.Tags.Should().Contain("team-a");
|
|
definition.Tags.Should().Contain("critical");
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagChangedEvent_CanBeCreated()
|
|
{
|
|
// Arrange
|
|
var timestamp = DateTimeOffset.UtcNow;
|
|
|
|
// Act
|
|
var evt = new FeatureFlagChangedEvent(
|
|
Key: "toggle-flag",
|
|
OldValue: false,
|
|
NewValue: true,
|
|
Source: "ConfigProvider",
|
|
Timestamp: timestamp);
|
|
|
|
// Assert
|
|
evt.Key.Should().Be("toggle-flag");
|
|
evt.OldValue.Should().BeFalse();
|
|
evt.NewValue.Should().BeTrue();
|
|
evt.Source.Should().Be("ConfigProvider");
|
|
evt.Timestamp.Should().Be(timestamp);
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagOptions_HasCorrectDefaults()
|
|
{
|
|
// Act
|
|
var options = new FeatureFlagOptions();
|
|
|
|
// Assert
|
|
options.DefaultValue.Should().BeFalse();
|
|
options.EnableCaching.Should().BeTrue();
|
|
options.CacheDuration.Should().Be(TimeSpan.FromSeconds(30));
|
|
options.EnableLogging.Should().BeTrue();
|
|
options.EnableMetrics.Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagOptions_CanBeModified()
|
|
{
|
|
// Act
|
|
var options = new FeatureFlagOptions
|
|
{
|
|
DefaultValue = true,
|
|
EnableCaching = false,
|
|
CacheDuration = TimeSpan.FromHours(1),
|
|
EnableLogging = false
|
|
};
|
|
|
|
// Assert
|
|
options.DefaultValue.Should().BeTrue();
|
|
options.EnableCaching.Should().BeFalse();
|
|
options.CacheDuration.Should().Be(TimeSpan.FromHours(1));
|
|
options.EnableLogging.Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagEvaluationContext_RecordEquality()
|
|
{
|
|
// Arrange
|
|
var context1 = new FeatureFlagEvaluationContext("user", "tenant", "env", null);
|
|
var context2 = new FeatureFlagEvaluationContext("user", "tenant", "env", null);
|
|
var context3 = new FeatureFlagEvaluationContext("other", "tenant", "env", null);
|
|
|
|
// Assert - Records have value equality
|
|
context1.Should().Be(context2);
|
|
context1.Should().NotBe(context3);
|
|
}
|
|
|
|
[Fact]
|
|
public void FeatureFlagResult_RecordEquality()
|
|
{
|
|
// Arrange
|
|
var result1 = new FeatureFlagResult("key", true, null, "reason", "source");
|
|
var result2 = new FeatureFlagResult("key", true, null, "reason", "source");
|
|
var result3 = new FeatureFlagResult("key", false, null, "reason", "source");
|
|
|
|
// Assert
|
|
result1.Should().Be(result2);
|
|
result1.Should().NotBe(result3);
|
|
}
|
|
}
|