refactoring ocelot config creation process

This commit is contained in:
Tom Gardham-Pallister
2017-03-01 07:54:07 +00:00
parent 1d216f6863
commit c85ea41951
12 changed files with 517 additions and 280 deletions

View File

@ -0,0 +1,74 @@
using System.Collections.Generic;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class AuthenticationOptionsCreatorTests
{
private AuthenticationOptionsCreator _authOptionsCreator;
private FileReRoute _fileReRoute;
private AuthenticationOptions _result;
public AuthenticationOptionsCreatorTests()
{
_authOptionsCreator = new AuthenticationOptionsCreator();
}
[Fact]
public void should_return_auth_options()
{
var fileReRoute = new FileReRoute()
{
AuthenticationOptions = new FileAuthenticationOptions
{
Provider = "Geoff",
ProviderRootUrl = "http://www.bbc.co.uk/",
ScopeName = "Laura",
RequireHttps = true,
AdditionalScopes = new List<string> {"cheese"},
ScopeSecret = "secret"
}
};
var expected = new AuthenticationOptionsBuilder()
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
.WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
.WithScopeName(fileReRoute.AuthenticationOptions?.ScopeName)
.WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
.WithAdditionalScopes(fileReRoute.AuthenticationOptions?.AdditionalScopes)
.WithScopeSecret(fileReRoute.AuthenticationOptions?.ScopeSecret)
.Build();
this.Given(x => x.GivenTheFollowing(fileReRoute))
.When(x => x.WhenICreateTheAuthenticationOptions())
.Then(x => x.ThenTheFollowingIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowing(FileReRoute fileReRoute)
{
_fileReRoute = fileReRoute;
}
private void WhenICreateTheAuthenticationOptions()
{
_result = _authOptionsCreator.Create(_fileReRoute);
}
private void ThenTheFollowingIsReturned(AuthenticationOptions expected)
{
_result.AdditionalScopes.ShouldBe(expected.AdditionalScopes);
_result.Provider.ShouldBe(expected.Provider);
_result.ProviderRootUrl.ShouldBe(expected.ProviderRootUrl);
_result.RequireHttps.ShouldBe(expected.RequireHttps);
_result.ScopeName.ShouldBe(expected.ScopeName);
_result.ScopeSecret.ShouldBe(expected.ScopeSecret);
}
}
}

View File

@ -0,0 +1,110 @@
using System.Collections.Generic;
using System.Linq;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.Parser;
using Ocelot.Errors;
using Ocelot.Logging;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class ClaimsToThingCreatorTests
{
private readonly Mock<IClaimToThingConfigurationParser> _configParser;
private Dictionary<string,string> _claimsToThings;
private ClaimsToThingCreator _claimsToThingsCreator;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private List<ClaimToThing> _result;
private Mock<IOcelotLogger> _logger;
public ClaimsToThingCreatorTests()
{
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory
.Setup(x => x.CreateLogger<ClaimsToThingCreator>())
.Returns(_logger.Object);
_configParser = new Mock<IClaimToThingConfigurationParser>();
_claimsToThingsCreator = new ClaimsToThingCreator(_configParser.Object, _loggerFactory.Object);
}
[Fact]
public void should_return_claims_to_things()
{
var userInput = new Dictionary<string,string>()
{
{"CustomerId", "Claims[CustomerId] > value"}
};
var claimsToThing = new OkResponse<ClaimToThing>(new ClaimToThing("CustomerId", "CustomerId", "", 0));
this.Given(x => x.GivenTheFollowingDictionary(userInput))
.And(x => x.GivenTheConfigHeaderExtractorReturns(claimsToThing))
.When(x => x.WhenIGetTheThings())
.Then(x => x.ThenTheConfigParserIsCalledCorrectly())
.And(x => x.ThenClaimsToThingsAreReturned())
.BDDfy();
}
[Fact]
public void should_log_error_if_cannot_parse_claim_to_thing()
{
var userInput = new Dictionary<string,string>()
{
{"CustomerId", "Claims[CustomerId] > value"}
};
var claimsToThing = new ErrorResponse<ClaimToThing>(It.IsAny<Error>());
this.Given(x => x.GivenTheFollowingDictionary(userInput))
.And(x => x.GivenTheConfigHeaderExtractorReturns(claimsToThing))
.When(x => x.WhenIGetTheThings())
.Then(x => x.ThenTheConfigParserIsCalledCorrectly())
.And(x => x.ThenNoClaimsToThingsAreReturned())
.BDDfy();
}
private void ThenTheLoggerIsCalledCorrectly()
{
_logger
.Verify(x => x.LogDebug(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
}
private void ThenClaimsToThingsAreReturned()
{
_result.Count.ShouldBeGreaterThan(0);
}
private void GivenTheFollowingDictionary(Dictionary<string,string> claimsToThings)
{
_claimsToThings = claimsToThings;
}
private void GivenTheConfigHeaderExtractorReturns(Response<ClaimToThing> expected)
{
_configParser
.Setup(x => x.Extract(It.IsAny<string>(), It.IsAny<string>()))
.Returns(expected);
}
private void ThenNoClaimsToThingsAreReturned()
{
_result.Count.ShouldBe(0);
}
private void WhenIGetTheThings()
{
_result = _claimsToThingsCreator.Create(_claimsToThings);
}
private void ThenTheConfigParserIsCalledCorrectly()
{
_configParser
.Verify(x => x.Extract(_claimsToThings.First().Key, _claimsToThings.First().Value), Times.Once);
}
}
}

View File

@ -23,7 +23,6 @@ namespace Ocelot.UnitTests.Configuration
private readonly Mock<IConfigurationValidator> _validator;
private Response<IOcelotConfiguration> _config;
private FileConfiguration _fileConfiguration;
private readonly Mock<IClaimToThingConfigurationParser> _configParser;
private readonly Mock<ILogger<FileOcelotConfigurationCreator>> _logger;
private readonly FileOcelotConfigurationCreator _ocelotConfigurationCreator;
private readonly Mock<ILoadBalancerFactory> _loadBalancerFactory;
@ -32,6 +31,9 @@ namespace Ocelot.UnitTests.Configuration
private readonly Mock<IQoSProviderFactory> _qosProviderFactory;
private readonly Mock<IQosProviderHouse> _qosProviderHouse;
private readonly Mock<IQoSProvider> _qosProvider;
private Mock<IClaimsToThingCreator> _claimsToThingCreator;
private Mock<IAuthenticationOptionsCreator> _authOptionsCreator;
private Mock<IUpstreamTemplatePatternCreator> _upstreamTemplatePatternCreator;
public FileConfigurationCreatorTests()
{
@ -39,16 +41,20 @@ namespace Ocelot.UnitTests.Configuration
_qosProviderHouse = new Mock<IQosProviderHouse>();
_qosProvider = new Mock<IQoSProvider>();
_logger = new Mock<ILogger<FileOcelotConfigurationCreator>>();
_configParser = new Mock<IClaimToThingConfigurationParser>();
_validator = new Mock<IConfigurationValidator>();
_fileConfig = new Mock<IOptions<FileConfiguration>>();
_loadBalancerFactory = new Mock<ILoadBalancerFactory>();
_loadBalancerHouse = new Mock<ILoadBalancerHouse>();
_loadBalancer = new Mock<ILoadBalancer>();
_claimsToThingCreator = new Mock<IClaimsToThingCreator>();
_authOptionsCreator = new Mock<IAuthenticationOptionsCreator>();
_upstreamTemplatePatternCreator = new Mock<IUpstreamTemplatePatternCreator>();
_ocelotConfigurationCreator = new FileOcelotConfigurationCreator(
_fileConfig.Object, _validator.Object, _configParser.Object, _logger.Object,
_fileConfig.Object, _validator.Object, _logger.Object,
_loadBalancerFactory.Object, _loadBalancerHouse.Object,
_qosProviderFactory.Object, _qosProviderHouse.Object);
_qosProviderFactory.Object, _qosProviderHouse.Object, _claimsToThingCreator.Object,
_authOptionsCreator.Object, _upstreamTemplatePatternCreator.Object);
}
[Fact]
@ -130,7 +136,6 @@ namespace Ocelot.UnitTests.Configuration
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.Build()
}))
.BDDfy();
@ -161,7 +166,6 @@ namespace Ocelot.UnitTests.Configuration
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.Build()
}))
.BDDfy();
@ -200,7 +204,6 @@ namespace Ocelot.UnitTests.Configuration
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.WithServiceProviderConfiguraion(new ServiceProviderConfiguraionBuilder()
.WithUseServiceDiscovery(true)
.WithServiceDiscoveryProvider("consul")
@ -236,7 +239,6 @@ namespace Ocelot.UnitTests.Configuration
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.WithServiceProviderConfiguraion(new ServiceProviderConfiguraionBuilder()
.WithUseServiceDiscovery(false)
.Build())
@ -246,7 +248,7 @@ namespace Ocelot.UnitTests.Configuration
}
[Fact]
public void should_use_reroute_case_sensitivity_value()
public void should_call_template_pattern_creator_correctly()
{
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
@ -262,6 +264,7 @@ namespace Ocelot.UnitTests.Configuration
}
}))
.And(x => x.GivenTheConfigIsValid())
.And(x => x.GivenTheUpstreamTemplatePatternCreatorReturns("(?i)/api/products/.*/$"))
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
@ -275,65 +278,6 @@ namespace Ocelot.UnitTests.Configuration
.BDDfy();
}
[Fact]
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
{
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get"
}
}
}))
.And(x => x.GivenTheConfigIsValid())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.Build()
}))
.BDDfy();
}
[Fact]
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
{
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
}
}
}))
.And(x => x.GivenTheConfigIsValid())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.Build()
}))
.BDDfy();
}
[Fact]
public void should_set_global_request_id_key()
{
@ -362,43 +306,12 @@ namespace Ocelot.UnitTests.Configuration
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.WithRequestIdKey("blahhhh")
.Build()
}))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
{
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
}
}
}))
.And(x => x.GivenTheConfigIsValid())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.Build()
}))
.BDDfy();
}
[Fact]
public void should_create_with_headers_to_extract()
{
@ -417,7 +330,6 @@ namespace Ocelot.UnitTests.Configuration
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.WithAuthenticationOptions(authenticationOptions)
.WithClaimsToHeaders(new List<ClaimToThing>
{
@ -453,20 +365,17 @@ namespace Ocelot.UnitTests.Configuration
}
}))
.And(x => x.GivenTheConfigIsValid())
.And(x => x.GivenTheConfigHeaderExtractorReturns(new ClaimToThing("CustomerId", "CustomerId", "", 0)))
.And(x => x.GivenTheAuthOptionsCreatorReturns(authenticationOptions))
.And(x => x.GivenTheClaimsToThingCreatorReturns(new List<ClaimToThing>{new ClaimToThing("CustomerId", "CustomerId", "", 0)}))
.And(x => x.GivenTheLoadBalancerFactoryReturns())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(expected))
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
.BDDfy();
}
private void GivenTheConfigHeaderExtractorReturns(ClaimToThing expected)
{
_configParser
.Setup(x => x.Extract(It.IsAny<string>(), It.IsAny<string>()))
.Returns(new OkResponse<ClaimToThing>(expected));
}
[Fact]
public void should_create_with_authentication_properties()
@ -486,7 +395,6 @@ namespace Ocelot.UnitTests.Configuration
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.WithAuthenticationOptions(authenticationOptions)
.Build()
};
@ -514,100 +422,12 @@ namespace Ocelot.UnitTests.Configuration
}
}))
.And(x => x.GivenTheConfigIsValid())
.And(x => x.GivenTheAuthOptionsCreatorReturns(authenticationOptions))
.And(x => x.GivenTheLoadBalancerFactoryReturns())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(expected))
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
{
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
}
}
}))
.And(x => x.GivenTheConfigIsValid())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}/variants/{variantId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/variants/.*/$")
.Build()
}))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
{
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
}
}
}))
.And(x => x.GivenTheConfigIsValid())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}/variants/{variantId}/")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/variants/.*/$")
.Build()
}))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_to_end_of_string()
{
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
UpstreamPathTemplate = "/",
DownstreamPathTemplate = "/api/products/",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
}
}
}))
.And(x => x.GivenTheConfigIsValid())
.When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/api/products/")
.WithUpstreamPathTemplate("/")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("^/$")
.Build()
}))
.And(x => x.ThenTheAuthOptionsCreatorIsCalledCorrectly())
.BDDfy();
}
@ -642,6 +462,9 @@ namespace Ocelot.UnitTests.Configuration
result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
result.UpstreamPathTemplate.Value.ShouldBe(expected.UpstreamPathTemplate.Value);
result.UpstreamTemplatePattern.ShouldBe(expected.UpstreamTemplatePattern);
result.ClaimsToClaims.Count.ShouldBe(expected.ClaimsToClaims.Count);
result.ClaimsToHeaders.Count.ShouldBe(expected.ClaimsToHeaders.Count);
result.ClaimsToQueries.Count.ShouldBe(expected.ClaimsToQueries.Count);
}
}
@ -699,5 +522,32 @@ namespace Ocelot.UnitTests.Configuration
_qosProviderHouse
.Verify(x => x.Add(It.IsAny<string>(), _qosProvider.Object), Times.Once);
}
private void GivenTheClaimsToThingCreatorReturns(List<ClaimToThing> claimsToThing)
{
_claimsToThingCreator
.Setup(x => x.Create(_fileConfiguration.ReRoutes[0].AddHeadersToRequest))
.Returns(claimsToThing);
}
private void GivenTheAuthOptionsCreatorReturns(AuthenticationOptions authOptions)
{
_authOptionsCreator
.Setup(x => x.Create(It.IsAny<FileReRoute>()))
.Returns(authOptions);
}
private void ThenTheAuthOptionsCreatorIsCalledCorrectly()
{
_authOptionsCreator
.Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once);
}
private void GivenTheUpstreamTemplatePatternCreatorReturns(string pattern)
{
_upstreamTemplatePatternCreator
.Setup(x => x.Create(It.IsAny<FileReRoute>()))
.Returns(pattern);
}
}
}

View File

@ -0,0 +1,122 @@
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class UpstreamTemplatePatternCreatorTests
{
private FileReRoute _fileReRoute;
private UpstreamTemplatePatternCreator _creator;
private string _result;
public UpstreamTemplatePatternCreatorTests()
{
_creator = new UpstreamTemplatePatternCreator();
}
[Fact]
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/PRODUCTS/{productId}",
ReRouteIsCaseSensitive = false
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("(?i)/PRODUCTS/.*/$"))
.BDDfy();
}
[Fact]
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/PRODUCTS/{productId}",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("/PRODUCTS/.*/$"))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/$"))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/variants/.*/$"))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/variants/.*/$"))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_to_end_of_string()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/"
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
.BDDfy();
}
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
{
_fileReRoute = fileReRoute;
}
private void WhenICreateTheTemplatePattern()
{
_result = _creator.Create(_fileReRoute);
}
private void ThenTheFollowingIsReturned(string expected)
{
_result.ShouldBe(expected);
}
}
}