using FluentAssertions; using Microsoft.Extensions.Configuration; using StellaOps.Router.Gateway.RateLimit; using Xunit; namespace StellaOps.Router.Gateway.Tests; public sealed class RateLimitConfigTests { [Fact] public void Load_BindsRoutesAndRules() { var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["rate_limiting:process_back_pressure_when_more_than_per_5min"] = "0", ["rate_limiting:for_environment:valkey_connection"] = "localhost:6379", ["rate_limiting:for_environment:valkey_bucket"] = "stella-router-rate-limit", ["rate_limiting:for_environment:microservices:scanner:routes:scan_submit:pattern"] = "/api/scans", ["rate_limiting:for_environment:microservices:scanner:routes:scan_submit:match_type"] = "Exact", ["rate_limiting:for_environment:microservices:scanner:routes:scan_submit:rules:0:per_seconds"] = "10", ["rate_limiting:for_environment:microservices:scanner:routes:scan_submit:rules:0:max_requests"] = "50", }) .Build(); var config = RateLimitConfig.Load(configuration); config.ActivationThresholdPer5Min.Should().Be(0); config.ForEnvironment.Should().NotBeNull(); config.ForEnvironment!.Microservices.Should().NotBeNull(); var scanner = config.ForEnvironment.Microservices!["scanner"]; scanner.Routes.Should().ContainKey("scan_submit"); var route = scanner.Routes["scan_submit"]; route.MatchType.Should().Be(RouteMatchType.Exact); route.Pattern.Should().Be("/api/scans"); route.Rules.Should().HaveCount(1); route.Rules[0].PerSeconds.Should().Be(10); route.Rules[0].MaxRequests.Should().Be(50); } [Fact] public void Load_ThrowsForInvalidRegexRoute() { var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["rate_limiting:process_back_pressure_when_more_than_per_5min"] = "0", ["rate_limiting:for_environment:valkey_connection"] = "localhost:6379", ["rate_limiting:for_environment:valkey_bucket"] = "stella-router-rate-limit", ["rate_limiting:for_environment:microservices:scanner:routes:bad:pattern"] = "[", ["rate_limiting:for_environment:microservices:scanner:routes:bad:match_type"] = "Regex", ["rate_limiting:for_environment:microservices:scanner:routes:bad:rules:0:per_seconds"] = "10", ["rate_limiting:for_environment:microservices:scanner:routes:bad:rules:0:max_requests"] = "1", }) .Build(); var act = () => RateLimitConfig.Load(configuration); act.Should().Throw() .WithMessage("*Invalid regex pattern*"); } }