Files
git.stella-ops.org/src/Router/__Tests/StellaOps.Gateway.WebService.Tests/Routing/StellaOpsRouteResolverTests.cs

151 lines
4.6 KiB
C#

using Microsoft.AspNetCore.Http;
using StellaOps.Gateway.WebService.Routing;
using StellaOps.Router.Gateway.Configuration;
namespace StellaOps.Gateway.WebService.Tests.Routing;
public sealed class StellaOpsRouteResolverTests
{
private static StellaOpsRoute MakeRoute(
string path,
StellaOpsRouteType type = StellaOpsRouteType.Microservice,
bool isRegex = false,
string? translatesTo = null)
{
return new StellaOpsRoute
{
Path = path,
Type = type,
IsRegex = isRegex,
TranslatesTo = translatesTo ?? "http://backend:5000"
};
}
[Fact]
public void Resolve_ExactPathMatch_ReturnsRoute()
{
var route = MakeRoute("/dashboard");
var resolver = new StellaOpsRouteResolver(new[] { route });
var result = resolver.Resolve(new PathString("/dashboard"));
Assert.NotNull(result.Route);
Assert.Equal("/dashboard", result.Route.Path);
Assert.Null(result.RegexMatch);
}
[Fact]
public void Resolve_PrefixMatch_ReturnsRoute()
{
var route = MakeRoute("/app");
var resolver = new StellaOpsRouteResolver(new[] { route });
var result = resolver.Resolve(new PathString("/app/index.html"));
Assert.NotNull(result.Route);
Assert.Equal("/app", result.Route.Path);
Assert.Null(result.RegexMatch);
}
[Fact]
public void Resolve_RegexRoute_Matches()
{
var route = MakeRoute(@"^/api/v[0-9]+/.*", isRegex: true);
var resolver = new StellaOpsRouteResolver(new[] { route });
var result = resolver.Resolve(new PathString("/api/v2/data"));
Assert.NotNull(result.Route);
Assert.True(result.Route.IsRegex);
Assert.Equal(@"^/api/v[0-9]+/.*", result.Route.Path);
Assert.NotNull(result.RegexMatch);
Assert.True(result.RegexMatch.Success);
}
[Fact]
public void Resolve_RegexRoute_ReturnsCaptureGroups()
{
var route = MakeRoute(
@"^/api/v1/([^/]+)(.*)",
isRegex: true,
translatesTo: "http://$1.stella-ops.local/api/v1/$1$2");
var resolver = new StellaOpsRouteResolver(new[] { route });
var result = resolver.Resolve(new PathString("/api/v1/scanner/health"));
Assert.NotNull(result.Route);
Assert.NotNull(result.RegexMatch);
Assert.Equal("scanner", result.RegexMatch.Groups[1].Value);
Assert.Equal("/health", result.RegexMatch.Groups[2].Value);
}
[Fact]
public void Resolve_NoMatch_ReturnsNull()
{
var route = MakeRoute("/dashboard");
var resolver = new StellaOpsRouteResolver(new[] { route });
var result = resolver.Resolve(new PathString("/unknown"));
Assert.Null(result.Route);
Assert.Null(result.RegexMatch);
}
[Fact]
public void Resolve_FirstMatchWins()
{
var firstRoute = MakeRoute("/api", translatesTo: "http://first:5000");
var secondRoute = MakeRoute("/api", translatesTo: "http://second:5000");
var resolver = new StellaOpsRouteResolver(new[] { firstRoute, secondRoute });
var result = resolver.Resolve(new PathString("/api/resource"));
Assert.NotNull(result.Route);
Assert.Equal("http://first:5000", result.Route.TranslatesTo);
}
[Fact]
public void Resolve_NotFoundPageRoute_IsExcluded()
{
var notFoundRoute = MakeRoute("/not-found", type: StellaOpsRouteType.NotFoundPage);
var resolver = new StellaOpsRouteResolver(new[] { notFoundRoute });
var result = resolver.Resolve(new PathString("/not-found"));
Assert.Null(result.Route);
}
[Fact]
public void Resolve_ServerErrorPageRoute_IsExcluded()
{
var errorRoute = MakeRoute("/error", type: StellaOpsRouteType.ServerErrorPage);
var resolver = new StellaOpsRouteResolver(new[] { errorRoute });
var result = resolver.Resolve(new PathString("/error"));
Assert.Null(result.Route);
}
[Fact]
public void Resolve_CaseInsensitive_Matches()
{
var route = MakeRoute("/app");
var resolver = new StellaOpsRouteResolver(new[] { route });
var result = resolver.Resolve(new PathString("/APP"));
Assert.NotNull(result.Route);
Assert.Equal("/app", result.Route.Path);
}
[Fact]
public void Resolve_EmptyRoutes_ReturnsNull()
{
var resolver = new StellaOpsRouteResolver(Array.Empty<StellaOpsRoute>());
var result = resolver.Resolve(new PathString("/anything"));
Assert.Null(result.Route);
}
}