Added support for query string parameters in upstream path template (#467)

This commit is contained in:
Tom Pallister
2018-07-12 19:26:23 +01:00
committed by GitHub
parent 19ea93d10e
commit 8f4ae03290
24 changed files with 664 additions and 143 deletions

View File

@ -599,7 +599,7 @@
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1, false))
.WithLoadBalancerKey("/api/products/{productId}|Get|")
.Build();
@ -628,7 +628,7 @@
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1, false))
.Build()
}))
.BDDfy();
@ -922,7 +922,7 @@
{
_upstreamTemplatePatternCreator
.Setup(x => x.Create(It.IsAny<FileReRoute>()))
.Returns(new UpstreamPathTemplate(pattern, 1));
.Returns(new UpstreamPathTemplate(pattern, 1, false));
}
private void ThenTheRequestIdKeyCreatorIsCalledCorrectly()

View File

@ -10,7 +10,7 @@ namespace Ocelot.UnitTests.Configuration
public class UpstreamTemplatePatternCreatorTests
{
private FileReRoute _fileReRoute;
private UpstreamTemplatePatternCreator _creator;
private readonly UpstreamTemplatePatternCreator _creator;
private UpstreamPathTemplate _result;
public UpstreamTemplatePatternCreatorTests()
@ -191,6 +191,36 @@ namespace Ocelot.UnitTests.Configuration
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_query_string()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/.+/updates\\?unitId=.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_query_string_with_multiple_params()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}&productId={productId}"
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/.+/updates\\?unitId=.+&productId=.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
{
_fileReRoute = fileReRoute;

View File

@ -28,6 +28,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private IInternalConfiguration _configuration;
private Mock<IQoSOptionsCreator> _qosOptionsCreator;
private Response<DownstreamRoute> _resultTwo;
private string _upstreamQuery;
public DownstreamRouteCreatorTests()
{
@ -247,12 +248,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void WhenICreate()
{
_result = _creator.Get(_upstreamUrlPath, _upstreamHttpMethod, _configuration, _upstreamHost);
_result = _creator.Get(_upstreamUrlPath, _upstreamQuery, _upstreamHttpMethod, _configuration, _upstreamHost);
}
private void WhenICreateAgain()
{
_resultTwo = _creator.Get(_upstreamUrlPath, _upstreamHttpMethod, _configuration, _upstreamHost);
_resultTwo = _creator.Get(_upstreamUrlPath, _upstreamQuery, _upstreamHttpMethod, _configuration, _upstreamHost);
}
private void ThenTheDownstreamRoutesAreTheSameReference()

View File

@ -86,7 +86,7 @@
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
_finder
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IInternalConfiguration>(), It.IsAny<string>()))
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IInternalConfiguration>(), It.IsAny<string>()))
.Returns(_downstreamRoute);
}

View File

@ -25,6 +25,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private Response<UrlMatch> _match;
private string _upstreamHttpMethod;
private string _upstreamHost;
private string _upstreamQuery;
public DownstreamRouteFinderTests()
{
@ -48,22 +49,22 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.Build(),
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false))
.Build()
}, string.Empty, serviceProviderConfig))
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
@ -73,13 +74,13 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.Build())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.Build()
)))
.BDDfy();
@ -100,22 +101,22 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false))
.Build(),
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.Build()
}, string.Empty, serviceProviderConfig))
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
@ -125,10 +126,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.Build())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.Build()
)))
@ -151,11 +152,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
}, string.Empty, serviceProviderConfig
))
@ -169,10 +170,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
)))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -195,11 +196,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
}, string.Empty, serviceProviderConfig
))
@ -213,10 +214,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
)))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher"))
@ -240,11 +241,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
}, string.Empty, serviceProviderConfig
))
@ -257,10 +258,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
)))
.BDDfy();
@ -283,22 +284,22 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build(),
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build()
}, string.Empty, serviceProviderConfig
))
@ -311,10 +312,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build()
)))
.BDDfy();
@ -333,11 +334,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("somPath")
.WithUpstreamPathTemplate("somePath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1, false))
.Build())
.WithUpstreamPathTemplate("somePath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1, false))
.Build(),
}, string.Empty, serviceProviderConfig
))
@ -367,11 +368,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build()
}, string.Empty, serviceProviderConfig
))
@ -384,10 +385,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build()
)))
.BDDfy();
@ -410,11 +411,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build()
}, string.Empty, serviceProviderConfig
))
@ -427,10 +428,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build()
)))
.BDDfy();
@ -453,11 +454,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false))
.Build()
}, string.Empty, serviceProviderConfig
))
@ -486,12 +487,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build()
}, string.Empty, serviceProviderConfig
@ -506,10 +507,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
)))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -533,11 +534,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
}, string.Empty, serviceProviderConfig
))
@ -551,10 +552,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
)))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -576,12 +577,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build(),
new ReRouteBuilder()
@ -589,12 +590,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { }) // empty list of methods
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { }) // empty list of methods
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build()
}, string.Empty, serviceProviderConfig
@ -622,12 +623,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build()
}, string.Empty, serviceProviderConfig
@ -655,12 +656,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build()
}, string.Empty, serviceProviderConfig
@ -689,23 +690,23 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("THENULLPATH")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build(),
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.WithUpstreamHost("MATCH")
.Build()
}, string.Empty, serviceProviderConfig
@ -720,10 +721,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false))
.Build()
)))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly(2))
@ -738,7 +739,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void GivenTheTemplateVariableAndNameFinderReturns(Response<List<PlaceholderNameAndValue>> response)
{
_finder
.Setup(x => x.Find(It.IsAny<string>(), It.IsAny<string>()))
.Setup(x => x.Find(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Returns(response);
}
@ -755,32 +756,32 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheUrlMatcherIsCalledCorrectly()
{
_mockMatcher
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
.Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamPathTemplate.Value, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Once);
}
private void ThenTheUrlMatcherIsCalledCorrectly(int times)
{
_mockMatcher
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Exactly(times));
.Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamPathTemplate.Value, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Exactly(times));
}
private void ThenTheUrlMatcherIsCalledCorrectly(string expectedUpstreamUrlPath)
{
_mockMatcher
.Verify(x => x.Match(expectedUpstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
.Verify(x => x.Match(expectedUpstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamPathTemplate.Value, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Once);
}
private void ThenTheUrlMatcherIsNotCalled()
{
_mockMatcher
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Never);
.Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamPathTemplate.Value, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Never);
}
private void GivenTheUrlMatcherReturns(Response<UrlMatch> match)
{
_match = match;
_mockMatcher
.Setup(x => x.Match(It.IsAny<string>(), It.IsAny<string>()))
.Setup(x => x.Match(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
.Returns(_match);
}
@ -797,7 +798,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void WhenICallTheFinder()
{
_result = _downstreamRouteFinder.Get(_upstreamUrlPath, _upstreamHttpMethod, _config, _upstreamHost);
_result = _downstreamRouteFinder.Get(_upstreamUrlPath, _upstreamQuery, _upstreamHttpMethod, _config, _upstreamHost);
}
private void ThenTheFollowingIsReturned(DownstreamRoute expected)

View File

@ -9,22 +9,65 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public class RegExUrlMatcherTests
{
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
private string _downstreamUrlPath;
private string _path;
private string _downstreamPathTemplate;
private Response<UrlMatch> _result;
private string _queryString;
private bool _containsQueryString;
public RegExUrlMatcherTests()
{
_urlMatcher = new RegExUrlMatcher();
}
[Fact]
public void should_match_path_with_no_query_string()
{
const string regExForwardSlashAndOnePlaceHolder = "^(?i)/newThing$";
this.Given(x => x.GivenIHaveAUpstreamPath("/newThing"))
.And(_ => GivenIHaveAQueryString("?DeviceType=IphoneApp&Browser=moonpigIphone&BrowserString=-&CountryCode=123&DeviceName=iPhone 5 (GSM+CDMA)&OperatingSystem=iPhone OS 7.1.2&BrowserVersion=3708AdHoc&ipAddress=-"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
public void should_match_query_string()
{
const string regExForwardSlashAndOnePlaceHolder = "^(?i)/api/subscriptions/.+/updates\\?unitId=.+$";
this.Given(x => x.GivenIHaveAUpstreamPath("/api/subscriptions/1/updates"))
.And(_ => GivenIHaveAQueryString("?unitId=2"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
.And(_ => GivenThereIsAQueryInTemplate())
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
public void should_match_query_string_with_multiple_params()
{
const string regExForwardSlashAndOnePlaceHolder = "^(?i)/api/subscriptions/.+/updates\\?unitId=.+&productId=.+$";
this.Given(x => x.GivenIHaveAUpstreamPath("/api/subscriptions/1/updates?unitId=2"))
.And(_ => GivenIHaveAQueryString("?unitId=2&productId=2"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
.And(_ => GivenThereIsAQueryInTemplate())
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
public void should_not_match_slash_becaue_we_need_to_match_something_after_it()
{
const string RegExForwardSlashAndOnePlaceHolder = "^/[0-9a-zA-Z].*";
const string regExForwardSlashAndOnePlaceHolder = "^/[0-9a-zA-Z].+";
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(RegExForwardSlashAndOnePlaceHolder))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsFalse())
.BDDfy();
@ -44,7 +87,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void should_not_match_issue_134()
{
this.Given(x => x.GivenIHaveAUpstreamPath("/api/vacancy/1/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/.*/$"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/.+/$"))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsFalse())
.BDDfy();
@ -64,7 +107,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void should_find_match_when_template_smaller_than_valid_path()
{
this.Given(x => x.GivenIHaveAUpstreamPath("/api/products/2354325435624623464235"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/api/products/.*$"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/api/products/.+$"))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue())
.BDDfy();
@ -124,7 +167,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*$"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
@ -134,7 +177,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/.*$"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/.+$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
@ -144,7 +187,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*$"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/categories/.+$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
@ -154,7 +197,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/.*$"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/categories/.+/variant/.+$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
@ -164,7 +207,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/$"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/categories/.+/variant/$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
@ -174,7 +217,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void should_ignore_case_sensitivity()
{
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)api/product/products/.*/categories/.*/variant/$"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)api/product/products/.+/categories/.+/variant/$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
@ -184,15 +227,20 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
public void should_respect_case_sensitivity()
{
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/$"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/categories/.+/variant/$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsFalse())
.BDDfy();
}
private void GivenIHaveAUpstreamPath(string downstreamPath)
private void GivenIHaveAUpstreamPath(string path)
{
_downstreamUrlPath = downstreamPath;
_path = path;
}
private void GivenIHaveAQueryString(string queryString)
{
_queryString = queryString;
}
private void GivenIHaveAnUpstreamUrlTemplatePattern(string downstreamUrlTemplate)
@ -202,7 +250,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
private void WhenIMatchThePaths()
{
_result = _urlMatcher.Match(_downstreamUrlPath, _downstreamPathTemplate);
_result = _urlMatcher.Match(_path, _queryString, _downstreamPathTemplate, _containsQueryString);
}
private void ThenTheResultIsTrue()
@ -214,5 +262,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
{
_result.Data.Match.ShouldBeFalse();
}
private void GivenThereIsAQueryInTemplate()
{
_containsQueryString = true;
}
}
}
}

View File

@ -14,6 +14,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
private string _downstreamUrlPath;
private string _downstreamPathTemplate;
private Response<List<PlaceholderNameAndValue>> _result;
private string _query;
public UrlPathPlaceholderNameAndValueFinderTests()
{
@ -114,6 +115,91 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
.BDDfy();
}
[Fact]
public void should_find_query_string()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{productId}", "1")
};
this.Given(x => x.GivenIHaveAUpstreamPath("/products"))
.And(x => x.GivenIHaveAQuery("?productId=1"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products?productId={productId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void should_find_query_string_dont_include_hardcoded()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{productId}", "1")
};
this.Given(x => x.GivenIHaveAUpstreamPath("/products"))
.And(x => x.GivenIHaveAQuery("?productId=1&categoryId=2"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products?productId={productId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void should_find_multiple_query_string()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{productId}", "1"),
new PlaceholderNameAndValue("{categoryId}", "2")
};
this.Given(x => x.GivenIHaveAUpstreamPath("/products"))
.And(x => x.GivenIHaveAQuery("?productId=1&categoryId=2"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products?productId={productId}&categoryId={categoryId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void should_find_multiple_query_string_and_path()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{productId}", "1"),
new PlaceholderNameAndValue("{categoryId}", "2"),
new PlaceholderNameAndValue("{account}", "3")
};
this.Given(x => x.GivenIHaveAUpstreamPath("/products/3"))
.And(x => x.GivenIHaveAQuery("?productId=1&categoryId=2"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products/{account}?productId={productId}&categoryId={categoryId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void should_find_multiple_query_string_and_path_that_ends_with_slash()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{productId}", "1"),
new PlaceholderNameAndValue("{categoryId}", "2"),
new PlaceholderNameAndValue("{account}", "3")
};
this.Given(x => x.GivenIHaveAUpstreamPath("/products/3/"))
.And(x => x.GivenIHaveAQuery("?productId=1&categoryId=2"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products/{account}/?productId={productId}&categoryId={categoryId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_no_slash()
{
@ -260,7 +346,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
private void WhenIFindTheUrlVariableNamesAndValues()
{
_result = _finder.Find(_downstreamUrlPath, _downstreamPathTemplate);
_result = _finder.Find(_downstreamUrlPath, _query, _downstreamPathTemplate);
}
private void GivenIHaveAQuery(string query)
{
_query = query;
}
}
}

View File

@ -72,6 +72,103 @@
.BDDfy();
}
[Fact]
public void should_replace_query_string()
{
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithDownstreamScheme("https")
.Build();
var config = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheDownStreamRouteIs(
new DownstreamRoute(
new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{subscriptionId}", "1"),
new PlaceholderNameAndValue("{unitId}", "2")
},
new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2"))
.And(x => GivenTheServiceProviderConfigIs(config))
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates"))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates"))
.And(x => ThenTheQueryStringIs(""))
.BDDfy();
}
[Fact]
public void should_replace_query_string_but_leave_non_placeholder_queries()
{
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithDownstreamScheme("https")
.Build();
var config = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheDownStreamRouteIs(
new DownstreamRoute(
new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{subscriptionId}", "1"),
new PlaceholderNameAndValue("{unitId}", "2")
},
new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2&productId=2"))
.And(x => GivenTheServiceProviderConfigIs(config))
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates"))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates?productId=2"))
.And(x => ThenTheQueryStringIs("?productId=2"))
.BDDfy();
}
[Fact]
public void should_replace_query_string_exact_match()
{
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/api/units/{subscriptionId}/{unitId}/updates/{unitIdIty}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithDownstreamScheme("https")
.Build();
var config = new ServiceProviderConfigurationBuilder()
.Build();
this.Given(x => x.GivenTheDownStreamRouteIs(
new DownstreamRoute(
new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{subscriptionId}", "1"),
new PlaceholderNameAndValue("{unitId}", "2"),
new PlaceholderNameAndValue("{unitIdIty}", "3")
},
new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())))
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/api/subscriptions/1/updates?unitId=2?unitIdIty=3"))
.And(x => GivenTheServiceProviderConfigIs(config))
.And(x => x.GivenTheUrlReplacerWillReturn("api/units/1/2/updates/3"))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:5000/api/units/1/2/updates/3"))
.And(x => ThenTheQueryStringIs(""))
.BDDfy();
}
[Fact]
public void should_not_create_service_fabric_url()
{