diff --git a/test/Ocelot.UnitTests/Configuration/UpstreamHeaderTemplatePatternCreatorTests.cs b/test/Ocelot.UnitTests/Configuration/UpstreamHeaderTemplatePatternCreatorTests.cs index a9478e22d1..52499a6bab 100644 --- a/test/Ocelot.UnitTests/Configuration/UpstreamHeaderTemplatePatternCreatorTests.cs +++ b/test/Ocelot.UnitTests/Configuration/UpstreamHeaderTemplatePatternCreatorTests.cs @@ -1,10 +1,6 @@ using Ocelot.Configuration.Creator; using Ocelot.Configuration.File; using Ocelot.Values; -using Shouldly; -using System.Collections.Generic; -using TestStack.BDDfy; -using Xunit; namespace Ocelot.UnitTests.Configuration; @@ -22,6 +18,7 @@ public UpstreamHeaderTemplatePatternCreatorTests() [Fact] public void Should_create_pattern_without_placeholders() { + // Arrange var fileRoute = new FileRoute { UpstreamHeaderTemplates = new Dictionary @@ -29,16 +26,19 @@ public void Should_create_pattern_without_placeholders() ["country"] = "a text without placeholders", }, }; + GivenTheFollowingFileRoute(fileRoute); - this.Given(x => x.GivenTheFollowingFileRoute(fileRoute)) - .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("country", "^(?i)a text without placeholders$")) - .BDDfy(); + // Act + WhenICreateTheTemplatePattern(); + + // Assert + ThenTheFollowingIsReturned("country", "^(?i)a text without placeholders$"); } [Fact] public void Should_create_pattern_case_sensitive() { + // Arrange var fileRoute = new FileRoute { RouteIsCaseSensitive = true, @@ -47,16 +47,19 @@ public void Should_create_pattern_case_sensitive() ["country"] = "a text without placeholders", }, }; + GivenTheFollowingFileRoute(fileRoute); + + // Act + WhenICreateTheTemplatePattern(); - this.Given(x => x.GivenTheFollowingFileRoute(fileRoute)) - .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("country", "^a text without placeholders$")) - .BDDfy(); + // Assert + ThenTheFollowingIsReturned("country", "^a text without placeholders$"); } [Fact] public void Should_create_pattern_with_placeholder_in_the_beginning() { + // Arrange var fileRoute = new FileRoute { UpstreamHeaderTemplates = new Dictionary @@ -64,16 +67,19 @@ public void Should_create_pattern_with_placeholder_in_the_beginning() ["country"] = "{header:start}rest of the text", }, }; + GivenTheFollowingFileRoute(fileRoute); - this.Given(x => x.GivenTheFollowingFileRoute(fileRoute)) - .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("country", "^(?i)(?.+)rest of the text$")) - .BDDfy(); + // Act + WhenICreateTheTemplatePattern(); + + // Assert + ThenTheFollowingIsReturned("country", "^(?i)(?.+)rest of the text$"); } [Fact] public void Should_create_pattern_with_placeholder_at_the_end() { + // Arrange var fileRoute = new FileRoute { UpstreamHeaderTemplates = new Dictionary @@ -81,16 +87,19 @@ public void Should_create_pattern_with_placeholder_at_the_end() ["country"] = "rest of the text{header:end}", }, }; + GivenTheFollowingFileRoute(fileRoute); + + // Act + WhenICreateTheTemplatePattern(); - this.Given(x => x.GivenTheFollowingFileRoute(fileRoute)) - .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("country", "^(?i)rest of the text(?.+)$")) - .BDDfy(); + // Assert + ThenTheFollowingIsReturned("country", "^(?i)rest of the text(?.+)$"); } [Fact] public void Should_create_pattern_with_placeholder_only() { + // Arrange var fileRoute = new FileRoute { UpstreamHeaderTemplates = new Dictionary @@ -99,15 +108,19 @@ public void Should_create_pattern_with_placeholder_only() }, }; - this.Given(x => x.GivenTheFollowingFileRoute(fileRoute)) - .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("country", "^(?i)(?.+)$")) - .BDDfy(); + GivenTheFollowingFileRoute(fileRoute); + + // Act + WhenICreateTheTemplatePattern(); + + // Assert + ThenTheFollowingIsReturned("country", "^(?i)(?.+)$"); } [Fact] public void Should_crate_pattern_with_more_placeholders() { + // Arrange var fileRoute = new FileRoute { UpstreamHeaderTemplates = new Dictionary @@ -115,11 +128,13 @@ public void Should_crate_pattern_with_more_placeholders() ["country"] = "any text {header:cc} and other {header:version} and {header:bob} the end", }, }; + GivenTheFollowingFileRoute(fileRoute); + + // Act + WhenICreateTheTemplatePattern(); - this.Given(x => x.GivenTheFollowingFileRoute(fileRoute)) - .When(x => x.WhenICreateTheTemplatePattern()) - .Then(x => x.ThenTheFollowingIsReturned("country", "^(?i)any text (?.+) and other (?.+) and (?.+) the end$")) - .BDDfy(); + // Assert + ThenTheFollowingIsReturned("country", "^(?i)any text (?.+) and other (?.+) and (?.+) the end$"); } private void GivenTheFollowingFileRoute(FileRoute fileRoute) diff --git a/test/Ocelot.UnitTests/Configuration/Validation/FileConfigurationFluentValidatorTests.cs b/test/Ocelot.UnitTests/Configuration/Validation/FileConfigurationFluentValidatorTests.cs index 6bbf98ab91..3d1bab26bd 100644 --- a/test/Ocelot.UnitTests/Configuration/Validation/FileConfigurationFluentValidatorTests.cs +++ b/test/Ocelot.UnitTests/Configuration/Validation/FileConfigurationFluentValidatorTests.cs @@ -749,198 +749,91 @@ public void Configuration_is_not_valid_when_host_and_port_is_empty() } [Fact] - public void configuration_is_not_valid_when_upstream_headers_the_same() - { - this.Given(x => x.GivenAConfiguration(new FileConfiguration - { - Routes = new List - { - new() - { - DownstreamPathTemplate = "/api/products/", - UpstreamPathTemplate = "/asdf/", - DownstreamHostAndPorts = new List - { - new() - { - Host = "bbc.co.uk", - }, - }, - UpstreamHttpMethod = new List {"Get"}, - UpstreamHeaderTemplates = new Dictionary - { - { "header1", "value1" }, - { "header2", "value2" }, - }, - }, - new() - { - DownstreamPathTemplate = "/www/test/", - UpstreamPathTemplate = "/asdf/", - DownstreamHostAndPorts = new List - { - new() - { - Host = "bbc.co.uk", - }, - }, - UpstreamHttpMethod = new List {"Get"}, - UpstreamHeaderTemplates = new Dictionary - { - { "header2", "value2" }, - { "header1", "value1" }, - }, - }, - }, - })) - .When(x => x.WhenIValidateTheConfiguration()) - .Then(x => x.ThenTheResultIsNotValid()) - .And(x => x.ThenTheErrorMessageAtPositionIs(0, "route /asdf/ has duplicate")) - .BDDfy(); + public void Configuration_is_not_valid_when_upstream_headers_the_same() + { + // Arrange + var route1 = GivenRouteWithUpstreamHeaderTemplates("/asdf/", "/api/products/", new() + { + { "header1", "value1" }, + { "header2", "value2" }, + }); + var route2 = GivenRouteWithUpstreamHeaderTemplates("/asdf/", "/www/test/", new() + { + { "header2", "value2" }, + { "header1", "value1" }, + }); + GivenAConfiguration(route1, route2); + + // Act + WhenIValidateTheConfiguration(); + + // Assert + ThenTheResultIsNotValid(); + ThenTheErrorMessageAtPositionIs(0, "route /asdf/ has duplicate"); } [Fact] - public void configuration_is_valid_when_upstream_headers_not_the_same() + public void Configuration_is_valid_when_upstream_headers_not_the_same() { - this.Given(x => x.GivenAConfiguration(new FileConfiguration - { - Routes = new List - { - new() - { - DownstreamPathTemplate = "/api/products/", - UpstreamPathTemplate = "/asdf/", - DownstreamHostAndPorts = new List - { - new() - { - Host = "bbc.co.uk", - }, - }, - UpstreamHttpMethod = new List {"Get"}, - UpstreamHeaderTemplates = new Dictionary - { - { "header1", "value1" }, - { "header2", "value2" }, - }, - }, - new() - { - DownstreamPathTemplate = "/www/test/", - UpstreamPathTemplate = "/asdf/", - DownstreamHostAndPorts = new List - { - new() - { - Host = "bbc.co.uk", - }, - }, - UpstreamHttpMethod = new List {"Get"}, - UpstreamHeaderTemplates = new Dictionary - { - { "header2", "value2" }, - { "header1", "valueDIFFERENT" }, - }, - }, - }, - })) - .When(x => x.WhenIValidateTheConfiguration()) - .Then(x => x.ThenTheResultIsValid()) - .BDDfy(); + // Arrange + var route1 = GivenRouteWithUpstreamHeaderTemplates("/asdf/", "/api/products/", new() + { + { "header1", "value1" }, + { "header2", "value2" }, + }); + var route2 = GivenRouteWithUpstreamHeaderTemplates("/asdf/", "/www/test/", new() + { + { "header2", "value2" }, + { "header1", "valueDIFFERENT" }, + }); + GivenAConfiguration(route1, route2); + + // Act + WhenIValidateTheConfiguration(); + + // Assert + ThenTheResultIsValid(); } [Fact] - public void configuration_is_valid_when_upstream_headers_count_not_the_same() + public void Configuration_is_valid_when_upstream_headers_count_not_the_same() { - this.Given(x => x.GivenAConfiguration(new FileConfiguration - { - Routes = new List - { - new() - { - DownstreamPathTemplate = "/api/products/", - UpstreamPathTemplate = "/asdf/", - DownstreamHostAndPorts = new List - { - new() - { - Host = "bbc.co.uk", - }, - }, - UpstreamHttpMethod = new List {"Get"}, - UpstreamHeaderTemplates = new Dictionary - { - { "header1", "value1" }, - { "header2", "value2" }, - }, - }, - new() - { - DownstreamPathTemplate = "/www/test/", - UpstreamPathTemplate = "/asdf/", - DownstreamHostAndPorts = new List - { - new() - { - Host = "bbc.co.uk", - }, - }, - UpstreamHttpMethod = new List {"Get"}, - UpstreamHeaderTemplates = new Dictionary - { - { "header2", "value2" }, - }, - }, - }, - })) - .When(x => x.WhenIValidateTheConfiguration()) - .Then(x => x.ThenTheResultIsValid()) - .BDDfy(); + // Arrange + var route1 = GivenRouteWithUpstreamHeaderTemplates("/asdf/", "/api/products/", new() + { + { "header1", "value1" }, + { "header2", "value2" }, + }); + var route2 = GivenRouteWithUpstreamHeaderTemplates("/asdf/", "/www/test/", new() + { + { "header2", "value2" }, + }); + GivenAConfiguration(route1, route2); + + // Act + WhenIValidateTheConfiguration(); + + // Assert + ThenTheResultIsValid(); } [Fact] - public void configuration_is_valid_when_one_upstream_headers_empty_and_other_not_empty() + public void Configuration_is_valid_when_one_upstream_headers_empty_and_other_not_empty() { - this.Given(x => x.GivenAConfiguration(new FileConfiguration - { - Routes = new List - { - new() - { - DownstreamPathTemplate = "/api/products/", - UpstreamPathTemplate = "/asdf/", - DownstreamHostAndPorts = new List - { - new() - { - Host = "bbc.co.uk", - }, - }, - UpstreamHttpMethod = new List {"Get"}, - UpstreamHeaderTemplates = new Dictionary - { - { "header1", "value1" }, - { "header2", "value2" }, - }, - }, - new() - { - DownstreamPathTemplate = "/www/test/", - UpstreamPathTemplate = "/asdf/", - DownstreamHostAndPorts = new List - { - new() - { - Host = "bbc.co.uk", - }, - }, - UpstreamHttpMethod = new List {"Get"}, - }, - }, - })) - .When(x => x.WhenIValidateTheConfiguration()) - .Then(x => x.ThenTheResultIsValid()) - .BDDfy(); + // Arrange + var route1 = GivenRouteWithUpstreamHeaderTemplates("/asdf/", "/api/products/", new() + { + { "header1", "value1" }, + { "header2", "value2" }, + }); + var route2 = GivenRouteWithUpstreamHeaderTemplates("/asdf/", "/www/test/", []); + GivenAConfiguration(route1, route2); + + // Act + WhenIValidateTheConfiguration(); + + // Assert + ThenTheResultIsValid(); } [Theory] @@ -1027,6 +920,15 @@ public void Configuration_is_invalid_when_placeholder_is_used_twice_in_downstrea DownstreamPathTemplate = "/", DownstreamScheme = Uri.UriSchemeHttp, ServiceName = "test", + }; + + private static FileRoute GivenRouteWithUpstreamHeaderTemplates(string upstream, string downstream, Dictionary templates) => new() + { + UpstreamPathTemplate = upstream, + DownstreamPathTemplate = downstream, + DownstreamHostAndPorts = [new("bbc.co.uk", 123)], + UpstreamHttpMethod = ["Get"], + UpstreamHeaderTemplates = templates, }; private void GivenAConfiguration(FileConfiguration fileConfiguration) => _fileConfiguration = fileConfiguration; @@ -1125,12 +1027,10 @@ private class TestHandler : AuthenticationHandler // It can be set directly or by registering a provider in the dependency injection container. #if NET8_0_OR_GREATER public TestHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder) - { - } + { } #else public TestHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) - { - } + { } #endif protected override Task HandleAuthenticateAsync() diff --git a/test/Ocelot.UnitTests/DownstreamRouteFinder/DownstreamRouteFinderTests.cs b/test/Ocelot.UnitTests/DownstreamRouteFinder/DownstreamRouteFinderTests.cs index d1a1640f83..d4538ee3ac 100644 --- a/test/Ocelot.UnitTests/DownstreamRouteFinder/DownstreamRouteFinderTests.cs +++ b/test/Ocelot.UnitTests/DownstreamRouteFinder/DownstreamRouteFinderTests.cs @@ -716,10 +716,10 @@ public void should_return_route_when_host_matches_but_null_host_on_same_path_fir } [Fact] - public void should_return_route_when_upstream_headers_match() - { + public void Should_return_route_when_upstream_headers_match() + { + // Arrange var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); - var upstreamHeaders = new Dictionary() { ["header1"] = "headerValue1", @@ -734,91 +734,94 @@ public void should_return_route_when_upstream_headers_match() var urlPlaceholders = new List { new PlaceholderNameAndValue("url", "urlValue") }; var headerPlaceholders = new List { new PlaceholderNameAndValue("header", "headerValue") }; - this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/")) - .And(x => GivenTheUpstreamHeadersIs(upstreamHeaders)) - .And(x => x.GivenTheTemplateVariableAndNameFinderReturns( - new OkResponse>(urlPlaceholders))) - .And(x => x.GivenTheHeaderPlaceholderAndNameFinderReturns(headerPlaceholders)) - .And(x => x.GivenTheConfigurationIs(new List - { - new RouteBuilder() - .WithDownstreamRoute(new DownstreamRouteBuilder() - .WithDownstreamPathTemplate("someDownstreamPath") - .WithUpstreamHttpMethod(new List { "Get" }) - .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) - .Build()) - .WithUpstreamHttpMethod(new List { "Get" }) - .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) - .WithUpstreamHeaders(upstreamHeadersConfig) - .Build(), - }, string.Empty, serviceProviderConfig - )) - .And(x => x.GivenTheUrlMatcherReturns(new OkResponse(new UrlMatch(true)))) - .And(x => x.GivenTheHeadersMatcherReturns(true)) - .And(x => x.GivenTheUpstreamHttpMethodIs("Get")) - .When(x => x.WhenICallTheFinder()) - .Then( - x => x.ThenTheFollowingIsReturned(new DownstreamRouteHolder( - urlPlaceholders.Union(headerPlaceholders).ToList(), - new RouteBuilder() - .WithDownstreamRoute(new DownstreamRouteBuilder() - .WithDownstreamPathTemplate("someDownstreamPath") - .WithUpstreamHttpMethod(new List { "Get" }) - .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) - .Build()) - .WithUpstreamHttpMethod(new List { "Get" }) + GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/"); + GivenTheUpstreamHeadersIs(upstreamHeaders); + GivenTheTemplateVariableAndNameFinderReturns(new OkResponse>(urlPlaceholders)); + GivenTheHeaderPlaceholderAndNameFinderReturns(headerPlaceholders); + GivenTheConfigurationIs( + [ + new RouteBuilder() + .WithDownstreamRoute(new DownstreamRouteBuilder() + .WithDownstreamPathTemplate("someDownstreamPath") + .WithUpstreamHttpMethod(["Get"]) .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) - .Build() - ))) - .And(x => x.ThenTheUrlMatcherIsCalledCorrectly()) - .BDDfy(); + .Build()) + .WithUpstreamHttpMethod(["Get"]) + .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) + .WithUpstreamHeaders(upstreamHeadersConfig) + .Build(), + ], string.Empty, serviceProviderConfig); + GivenTheUrlMatcherReturns(new OkResponse(new UrlMatch(true))); + GivenTheHeadersMatcherReturns(true); + GivenTheUpstreamHttpMethodIs("Get"); + + // Act + WhenICallTheFinder(); + + // Assert + ThenTheFollowingIsReturned(new DownstreamRouteHolder( + urlPlaceholders.Union(headerPlaceholders).ToList(), + new RouteBuilder() + .WithDownstreamRoute(new DownstreamRouteBuilder() + .WithDownstreamPathTemplate("someDownstreamPath") + .WithUpstreamHttpMethod(["Get"]) + .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) + .Build()) + .WithUpstreamHttpMethod(["Get"]) + .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) + .Build() + )); + ThenTheUrlMatcherIsCalledCorrectly(); } [Fact] - public void should_not_return_route_when_upstream_headers_dont_match() + public void Should_not_return_route_when_upstream_headers_dont_match() { + // Arrange var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); - var upstreamHeadersConfig = new Dictionary() { ["header1"] = new UpstreamHeaderTemplate("headerValue1", "headerValue1"), ["header2"] = new UpstreamHeaderTemplate("headerValue2", "headerValue2"), }; - this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/")) - .And(x => GivenTheUpstreamHeadersIs(new Dictionary() { { "header1", "headerValue1" } })) - .And(x => x.GivenTheTemplateVariableAndNameFinderReturns(new OkResponse>(new List()))) - .And(x => x.GivenTheHeaderPlaceholderAndNameFinderReturns(new List())) - .And(x => x.GivenTheConfigurationIs(new List + GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/"); + GivenTheUpstreamHeadersIs(new Dictionary() { { "header1", "headerValue1" } }); + GivenTheTemplateVariableAndNameFinderReturns(new OkResponse>(new List())); + GivenTheHeaderPlaceholderAndNameFinderReturns(new List()); + GivenTheConfigurationIs(new List { new RouteBuilder() .WithDownstreamRoute(new DownstreamRouteBuilder() .WithDownstreamPathTemplate("someDownstreamPath") - .WithUpstreamHttpMethod(new List { "Get" }) + .WithUpstreamHttpMethod(["Get"]) .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) .Build()) - .WithUpstreamHttpMethod(new List { "Get" }) + .WithUpstreamHttpMethod(["Get"]) .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) .WithUpstreamHeaders(upstreamHeadersConfig) .Build(), new RouteBuilder() .WithDownstreamRoute(new DownstreamRouteBuilder() .WithDownstreamPathTemplate("someDownstreamPath") - .WithUpstreamHttpMethod(new List { "Get" }) + .WithUpstreamHttpMethod(["Get"]) .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) .Build()) - .WithUpstreamHttpMethod(new List { "Get" }) + .WithUpstreamHttpMethod(["Get"]) .WithUpstreamPathTemplate(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath")) .WithUpstreamHeaders(upstreamHeadersConfig) .Build(), - }, string.Empty, serviceProviderConfig - )) - .And(x => x.GivenTheUrlMatcherReturns(new OkResponse(new UrlMatch(true)))) - .And(x => x.GivenTheHeadersMatcherReturns(false)) - .And(x => x.GivenTheUpstreamHttpMethodIs("Get")) - .When(x => x.WhenICallTheFinder()) - .Then(x => x.ThenAnErrorResponseIsReturned()) - .BDDfy(); + }, string.Empty, serviceProviderConfig + ); + GivenTheUrlMatcherReturns(new OkResponse(new UrlMatch(true))); + GivenTheHeadersMatcherReturns(false); + GivenTheUpstreamHttpMethodIs("Get"); + + // Act + WhenICallTheFinder(); + + // Assert + ThenAnErrorResponseIsReturned(); } private void GivenTheUpstreamHostIs(string upstreamHost) diff --git a/test/Ocelot.UnitTests/DownstreamRouteFinder/HeaderMatcher/HeaderPlaceholderNameAndValueFinderTests.cs b/test/Ocelot.UnitTests/DownstreamRouteFinder/HeaderMatcher/HeaderPlaceholderNameAndValueFinderTests.cs index 13d8f40fdc..39d8146244 100644 --- a/test/Ocelot.UnitTests/DownstreamRouteFinder/HeaderMatcher/HeaderPlaceholderNameAndValueFinderTests.cs +++ b/test/Ocelot.UnitTests/DownstreamRouteFinder/HeaderMatcher/HeaderPlaceholderNameAndValueFinderTests.cs @@ -1,11 +1,6 @@ using Ocelot.DownstreamRouteFinder.HeaderMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.Values; -using Shouldly; -using System.Collections.Generic; -using System.Linq; -using TestStack.BDDfy; -using Xunit; namespace Ocelot.UnitTests.DownstreamRouteFinder.HeaderMatcher;