mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 02:42:52 +08:00
parent
00a600064d
commit
b0bdeb9402
@ -1,84 +1,93 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Values;
|
using Ocelot.Values;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Creator
|
namespace Ocelot.Configuration.Creator
|
||||||
{
|
{
|
||||||
public class UpstreamTemplatePatternCreator : IUpstreamTemplatePatternCreator
|
public class UpstreamTemplatePatternCreator : IUpstreamTemplatePatternCreator
|
||||||
{
|
{
|
||||||
private const string RegExMatchOneOrMoreOfEverything = ".+";
|
private const string RegExMatchOneOrMoreOfEverything = ".+";
|
||||||
private const string RegExMatchEndString = "$";
|
private const string RegExMatchOneOrMoreOfEverythingUntilNextForwardSlash = "[^/]+";
|
||||||
private const string RegExIgnoreCase = "(?i)";
|
private const string RegExMatchEndString = "$";
|
||||||
private const string RegExForwardSlashOnly = "^/$";
|
private const string RegExIgnoreCase = "(?i)";
|
||||||
private const string RegExForwardSlashAndOnePlaceHolder = "^/.*";
|
private const string RegExForwardSlashOnly = "^/$";
|
||||||
|
private const string RegExForwardSlashAndOnePlaceHolder = "^/.*";
|
||||||
public UpstreamPathTemplate Create(IReRoute reRoute)
|
|
||||||
{
|
public UpstreamPathTemplate Create(IReRoute reRoute)
|
||||||
|
{
|
||||||
var upstreamTemplate = reRoute.UpstreamPathTemplate;
|
var upstreamTemplate = reRoute.UpstreamPathTemplate;
|
||||||
|
|
||||||
|
var placeholders = new List<string>();
|
||||||
var placeholders = new List<string>();
|
|
||||||
|
for (var i = 0; i < upstreamTemplate.Length; i++)
|
||||||
for (var i = 0; i < upstreamTemplate.Length; i++)
|
{
|
||||||
{
|
if (IsPlaceHolder(upstreamTemplate, i))
|
||||||
if (IsPlaceHolder(upstreamTemplate, i))
|
{
|
||||||
{
|
var postitionOfPlaceHolderClosingBracket = upstreamTemplate.IndexOf('}', i);
|
||||||
var postitionOfPlaceHolderClosingBracket = upstreamTemplate.IndexOf('}', i);
|
var difference = postitionOfPlaceHolderClosingBracket - i + 1;
|
||||||
var difference = postitionOfPlaceHolderClosingBracket - i + 1;
|
var placeHolderName = upstreamTemplate.Substring(i, difference);
|
||||||
var placeHolderName = upstreamTemplate.Substring(i, difference);
|
placeholders.Add(placeHolderName);
|
||||||
placeholders.Add(placeHolderName);
|
|
||||||
|
//hack to handle /{url} case
|
||||||
//hack to handle /{url} case
|
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
|
||||||
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
|
{
|
||||||
{
|
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0, false);
|
||||||
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0, false);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var containsQueryString = false;
|
var containsQueryString = false;
|
||||||
|
|
||||||
if (upstreamTemplate.Contains("?"))
|
if (upstreamTemplate.Contains("?"))
|
||||||
{
|
{
|
||||||
containsQueryString = true;
|
containsQueryString = true;
|
||||||
upstreamTemplate = upstreamTemplate.Replace("?", "\\?");
|
upstreamTemplate = upstreamTemplate.Replace("?", "\\?");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var placeholder in placeholders)
|
for (int i = 0; i < placeholders.Count; i++)
|
||||||
{
|
{
|
||||||
upstreamTemplate = upstreamTemplate.Replace(placeholder, RegExMatchOneOrMoreOfEverything);
|
var indexOfPlaceholder = upstreamTemplate.IndexOf(placeholders[i]);
|
||||||
}
|
var indexOfNextForwardSlash = upstreamTemplate.IndexOf("/", indexOfPlaceholder);
|
||||||
|
if(indexOfNextForwardSlash < indexOfPlaceholder || (containsQueryString && upstreamTemplate.IndexOf("?") < upstreamTemplate.IndexOf(placeholders[i])))
|
||||||
if (upstreamTemplate == "/")
|
{
|
||||||
{
|
upstreamTemplate = upstreamTemplate.Replace(placeholders[i], RegExMatchOneOrMoreOfEverything);
|
||||||
return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority, containsQueryString);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
if(upstreamTemplate.EndsWith("/"))
|
upstreamTemplate = upstreamTemplate.Replace(placeholders[i], RegExMatchOneOrMoreOfEverythingUntilNextForwardSlash);
|
||||||
{
|
}
|
||||||
upstreamTemplate = upstreamTemplate.Remove(upstreamTemplate.Length -1, 1) + "(/|)";
|
}
|
||||||
}
|
|
||||||
|
if (upstreamTemplate == "/")
|
||||||
var route = reRoute.ReRouteIsCaseSensitive
|
{
|
||||||
? $"^{upstreamTemplate}{RegExMatchEndString}"
|
return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority, containsQueryString);
|
||||||
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
|
}
|
||||||
|
|
||||||
return new UpstreamPathTemplate(route, reRoute.Priority, containsQueryString);
|
if(upstreamTemplate.EndsWith("/"))
|
||||||
}
|
{
|
||||||
|
upstreamTemplate = upstreamTemplate.Remove(upstreamTemplate.Length -1, 1) + "(/|)";
|
||||||
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)
|
}
|
||||||
{
|
|
||||||
if(upstreamTemplate.Substring(0, 2) == "/{" && placeholders.Count == 1 && upstreamTemplate.Length == postitionOfPlaceHolderClosingBracket + 1)
|
var route = reRoute.ReRouteIsCaseSensitive
|
||||||
{
|
? $"^{upstreamTemplate}{RegExMatchEndString}"
|
||||||
return true;
|
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
|
||||||
}
|
|
||||||
|
return new UpstreamPathTemplate(route, reRoute.Priority, containsQueryString);
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)
|
||||||
private bool IsPlaceHolder(string upstreamTemplate, int i)
|
{
|
||||||
{
|
if(upstreamTemplate.Substring(0, 2) == "/{" && placeholders.Count == 1 && upstreamTemplate.Length == postitionOfPlaceHolderClosingBracket + 1)
|
||||||
return upstreamTemplate[i] == '{';
|
{
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsPlaceHolder(string upstreamTemplate, int i)
|
||||||
|
{
|
||||||
|
return upstreamTemplate[i] == '{';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -21,6 +21,41 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_not_match_forward_slash_in_pattern_before_next_forward_slash()
|
||||||
|
{
|
||||||
|
var port = 31879;
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/api/v{apiVersion}/cards",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
UpstreamPathTemplate = "/api/v{apiVersion}/cards",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = port,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Priority = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/api/v1/aaaaaaaaa/cards", 200, "Hello from Laura"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/api/v1/aaaaaaaaa/cards"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_404_when_no_configuration_at_all()
|
public void should_return_response_404_when_no_configuration_at_all()
|
||||||
{
|
{
|
||||||
|
@ -1,244 +1,260 @@
|
|||||||
using Ocelot.Configuration.Creator;
|
using Ocelot.Configuration.Creator;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Values;
|
using Ocelot.Values;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
namespace Ocelot.UnitTests.Configuration
|
||||||
{
|
{
|
||||||
public class UpstreamTemplatePatternCreatorTests
|
public class UpstreamTemplatePatternCreatorTests
|
||||||
{
|
{
|
||||||
private FileReRoute _fileReRoute;
|
private FileReRoute _fileReRoute;
|
||||||
private readonly UpstreamTemplatePatternCreator _creator;
|
private readonly UpstreamTemplatePatternCreator _creator;
|
||||||
private UpstreamPathTemplate _result;
|
private UpstreamPathTemplate _result;
|
||||||
|
|
||||||
public UpstreamTemplatePatternCreatorTests()
|
public UpstreamTemplatePatternCreatorTests()
|
||||||
{
|
{
|
||||||
_creator = new UpstreamTemplatePatternCreator();
|
_creator = new UpstreamTemplatePatternCreator();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_use_re_route_priority()
|
public void should_match_up_to_next_slash()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/orders/{catchAll}",
|
UpstreamPathTemplate = "/api/v{apiVersion}/cards",
|
||||||
Priority = 0
|
Priority = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/orders/.+$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/v[^/]+/cards$"))
|
||||||
.And(x => ThenThePriorityIs(0))
|
.And(x => ThenThePriorityIs(0))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_use_zero_priority()
|
public void should_use_re_route_priority()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/{catchAll}",
|
UpstreamPathTemplate = "/orders/{catchAll}",
|
||||||
Priority = 1
|
Priority = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/orders/.+$"))
|
||||||
.And(x => ThenThePriorityIs(0))
|
.And(x => ThenThePriorityIs(0))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
|
public void should_use_zero_priority()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
UpstreamPathTemplate = "/{catchAll}",
|
||||||
ReRouteIsCaseSensitive = false
|
Priority = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.+$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
||||||
.And(x => ThenThePriorityIs(1))
|
.And(x => ThenThePriorityIs(0))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_match_forward_slash_or_no_forward_slash_if_template_end_with_forward_slash()
|
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/PRODUCTS/",
|
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||||
ReRouteIsCaseSensitive = false
|
ReRouteIsCaseSensitive = false
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.+$"))
|
||||||
.And(x => ThenThePriorityIs(1))
|
.And(x => ThenThePriorityIs(1))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
|
public void should_match_forward_slash_or_no_forward_slash_if_template_end_with_forward_slash()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
UpstreamPathTemplate = "/PRODUCTS/",
|
||||||
ReRouteIsCaseSensitive = true
|
ReRouteIsCaseSensitive = false
|
||||||
};
|
};
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.+$"))
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.And(x => ThenThePriorityIs(1))
|
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
|
||||||
.BDDfy();
|
.And(x => ThenThePriorityIs(1))
|
||||||
}
|
.BDDfy();
|
||||||
|
}
|
||||||
[Fact]
|
|
||||||
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
|
[Fact]
|
||||||
{
|
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
|
||||||
var fileReRoute = new FileReRoute
|
{
|
||||||
{
|
var fileReRoute = new FileReRoute
|
||||||
UpstreamPathTemplate = "/api/products/{productId}",
|
{
|
||||||
ReRouteIsCaseSensitive = true
|
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||||
};
|
ReRouteIsCaseSensitive = true
|
||||||
|
};
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.+$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.+$"))
|
||||||
.And(x => ThenThePriorityIs(1))
|
.And(x => ThenThePriorityIs(1))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
|
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
|
UpstreamPathTemplate = "/api/products/{productId}",
|
||||||
ReRouteIsCaseSensitive = true
|
ReRouteIsCaseSensitive = true
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.+/variants/.+$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.+$"))
|
||||||
.And(x => ThenThePriorityIs(1))
|
.And(x => ThenThePriorityIs(1))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
|
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
|
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
|
||||||
ReRouteIsCaseSensitive = true
|
ReRouteIsCaseSensitive = true
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.+/variants/.+(/|)$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/.+$"))
|
||||||
.And(x => ThenThePriorityIs(1))
|
.And(x => ThenThePriorityIs(1))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_create_template_pattern_that_matches_to_end_of_string()
|
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/"
|
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
|
||||||
};
|
ReRouteIsCaseSensitive = true
|
||||||
|
};
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.And(x => ThenThePriorityIs(1))
|
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/[^/]+(/|)$"))
|
||||||
.BDDfy();
|
.And(x => ThenThePriorityIs(1))
|
||||||
}
|
.BDDfy();
|
||||||
|
}
|
||||||
[Fact]
|
|
||||||
public void should_create_template_pattern_that_matches_to_end_of_string_when_slash_and_placeholder()
|
[Fact]
|
||||||
{
|
public void should_create_template_pattern_that_matches_to_end_of_string()
|
||||||
var fileReRoute = new FileReRoute
|
{
|
||||||
{
|
var fileReRoute = new FileReRoute
|
||||||
UpstreamPathTemplate = "/{url}"
|
{
|
||||||
};
|
UpstreamPathTemplate = "/"
|
||||||
|
};
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.And(x => ThenThePriorityIs(0))
|
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
|
||||||
.BDDfy();
|
.And(x => ThenThePriorityIs(1))
|
||||||
}
|
.BDDfy();
|
||||||
|
}
|
||||||
[Fact]
|
|
||||||
public void should_create_template_pattern_that_starts_with_placeholder_then_has_another_later()
|
[Fact]
|
||||||
{
|
public void should_create_template_pattern_that_matches_to_end_of_string_when_slash_and_placeholder()
|
||||||
var fileReRoute = new FileReRoute
|
{
|
||||||
{
|
var fileReRoute = new FileReRoute
|
||||||
UpstreamPathTemplate = "/{productId}/products/variants/{variantId}/",
|
{
|
||||||
ReRouteIsCaseSensitive = true
|
UpstreamPathTemplate = "/{url}"
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^/.+/products/variants/.+(/|)$"))
|
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
||||||
.And(x => ThenThePriorityIs(1))
|
.And(x => ThenThePriorityIs(0))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_create_template_pattern_that_matches_query_string()
|
public void should_create_template_pattern_that_starts_with_placeholder_then_has_another_later()
|
||||||
{
|
{
|
||||||
var fileReRoute = new FileReRoute
|
var fileReRoute = new FileReRoute
|
||||||
{
|
{
|
||||||
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"
|
UpstreamPathTemplate = "/{productId}/products/variants/{variantId}/",
|
||||||
};
|
ReRouteIsCaseSensitive = true
|
||||||
|
};
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/.+/updates\\?unitId=.+$"))
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.And(x => ThenThePriorityIs(1))
|
.Then(x => x.ThenTheFollowingIsReturned("^/[^/]+/products/variants/[^/]+(/|)$"))
|
||||||
.BDDfy();
|
.And(x => ThenThePriorityIs(1))
|
||||||
}
|
.BDDfy();
|
||||||
|
}
|
||||||
[Fact]
|
|
||||||
public void should_create_template_pattern_that_matches_query_string_with_multiple_params()
|
[Fact]
|
||||||
{
|
public void should_create_template_pattern_that_matches_query_string()
|
||||||
var fileReRoute = new FileReRoute
|
{
|
||||||
{
|
var fileReRoute = new FileReRoute
|
||||||
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}&productId={productId}"
|
{
|
||||||
};
|
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"
|
||||||
|
};
|
||||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
|
||||||
.When(x => x.WhenICreateTheTemplatePattern())
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/.+/updates\\?unitId=.+&productId=.+$"))
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
.And(x => ThenThePriorityIs(1))
|
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+$"))
|
||||||
.BDDfy();
|
.And(x => ThenThePriorityIs(1))
|
||||||
}
|
.BDDfy();
|
||||||
|
}
|
||||||
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
|
||||||
{
|
[Fact]
|
||||||
_fileReRoute = fileReRoute;
|
public void should_create_template_pattern_that_matches_query_string_with_multiple_params()
|
||||||
}
|
{
|
||||||
|
var fileReRoute = new FileReRoute
|
||||||
private void WhenICreateTheTemplatePattern()
|
{
|
||||||
{
|
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}&productId={productId}"
|
||||||
_result = _creator.Create(_fileReRoute);
|
};
|
||||||
}
|
|
||||||
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
private void ThenTheFollowingIsReturned(string expected)
|
.When(x => x.WhenICreateTheTemplatePattern())
|
||||||
{
|
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+&productId=.+$"))
|
||||||
_result.Template.ShouldBe(expected);
|
.And(x => ThenThePriorityIs(1))
|
||||||
}
|
.BDDfy();
|
||||||
|
}
|
||||||
private void ThenThePriorityIs(int v)
|
|
||||||
{
|
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
||||||
_result.Priority.ShouldBe(v);
|
{
|
||||||
}
|
_fileReRoute = fileReRoute;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private void WhenICreateTheTemplatePattern()
|
||||||
|
{
|
||||||
|
_result = _creator.Create(_fileReRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheFollowingIsReturned(string expected)
|
||||||
|
{
|
||||||
|
_result.Template.ShouldBe(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenThePriorityIs(int v)
|
||||||
|
{
|
||||||
|
_result.Priority.ShouldBe(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,271 +1,291 @@
|
|||||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
||||||
{
|
{
|
||||||
public class RegExUrlMatcherTests
|
public class RegExUrlMatcherTests
|
||||||
{
|
{
|
||||||
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
|
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
|
||||||
private string _path;
|
private string _path;
|
||||||
private string _downstreamPathTemplate;
|
private string _downstreamPathTemplate;
|
||||||
private Response<UrlMatch> _result;
|
private Response<UrlMatch> _result;
|
||||||
private string _queryString;
|
private string _queryString;
|
||||||
private bool _containsQueryString;
|
private bool _containsQueryString;
|
||||||
|
|
||||||
public RegExUrlMatcherTests()
|
public RegExUrlMatcherTests()
|
||||||
{
|
{
|
||||||
_urlMatcher = new RegExUrlMatcher();
|
_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]
|
[Fact]
|
||||||
public void should_match_query_string()
|
public void should_not_match()
|
||||||
{
|
{
|
||||||
const string regExForwardSlashAndOnePlaceHolder = "^(?i)/api/subscriptions/.+/updates\\?unitId=.+$";
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/v1/aaaaaaaaa/cards"))
|
||||||
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/api/v[^/]+/cards$"))
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/subscriptions/1/updates"))
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.And(_ => GivenIHaveAQueryString("?unitId=2"))
|
.And(x => x.ThenTheResultIsFalse())
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
|
.BDDfy();
|
||||||
.And(_ => GivenThereIsAQueryInTemplate())
|
}
|
||||||
.When(x => x.WhenIMatchThePaths())
|
|
||||||
.And(x => x.ThenTheResultIsTrue())
|
[Fact]
|
||||||
.BDDfy();
|
public void should_match()
|
||||||
}
|
{
|
||||||
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/v1/cards"))
|
||||||
[Fact]
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/api/v[^/]+/cards$"))
|
||||||
public void should_match_query_string_with_multiple_params()
|
.When(x => x.WhenIMatchThePaths())
|
||||||
{
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
const string regExForwardSlashAndOnePlaceHolder = "^(?i)/api/subscriptions/.+/updates\\?unitId=.+&productId=.+$";
|
.BDDfy();
|
||||||
|
}
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/subscriptions/1/updates?unitId=2"))
|
|
||||||
.And(_ => GivenIHaveAQueryString("?unitId=2&productId=2"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
|
public void should_match_path_with_no_query_string()
|
||||||
.And(_ => GivenThereIsAQueryInTemplate())
|
{
|
||||||
.When(x => x.WhenIMatchThePaths())
|
const string regExForwardSlashAndOnePlaceHolder = "^(?i)/newThing$";
|
||||||
.And(x => x.ThenTheResultIsTrue())
|
|
||||||
.BDDfy();
|
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))
|
||||||
[Fact]
|
.When(x => x.WhenIMatchThePaths())
|
||||||
public void should_not_match_slash_becaue_we_need_to_match_something_after_it()
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
{
|
.BDDfy();
|
||||||
const string regExForwardSlashAndOnePlaceHolder = "^/[0-9a-zA-Z].+";
|
}
|
||||||
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
|
public void should_match_query_string()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.And(x => x.ThenTheResultIsFalse())
|
const string regExForwardSlashAndOnePlaceHolder = "^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+$";
|
||||||
.BDDfy();
|
|
||||||
}
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/subscriptions/1/updates"))
|
||||||
|
.And(_ => GivenIHaveAQueryString("?unitId=2"))
|
||||||
[Fact]
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
|
||||||
public void should_not_match_forward_slash_only_regex()
|
.And(_ => GivenThereIsAQueryInTemplate())
|
||||||
{
|
.When(x => x.WhenIMatchThePaths())
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/working/"))
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
.BDDfy();
|
||||||
.When(x => x.WhenIMatchThePaths())
|
}
|
||||||
.And(x => x.ThenTheResultIsFalse())
|
|
||||||
.BDDfy();
|
[Fact]
|
||||||
}
|
public void should_match_query_string_with_multiple_params()
|
||||||
|
{
|
||||||
[Fact]
|
const string regExForwardSlashAndOnePlaceHolder = "^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+&productId=.+$";
|
||||||
public void should_not_match_issue_134()
|
|
||||||
{
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/subscriptions/1/updates?unitId=2"))
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/vacancy/1/"))
|
.And(_ => GivenIHaveAQueryString("?unitId=2&productId=2"))
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/.+/$"))
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
|
||||||
.When(x => x.WhenIMatchThePaths())
|
.And(_ => GivenThereIsAQueryInTemplate())
|
||||||
.And(x => x.ThenTheResultIsFalse())
|
.When(x => x.WhenIMatchThePaths())
|
||||||
.BDDfy();
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
}
|
.BDDfy();
|
||||||
|
}
|
||||||
[Fact]
|
|
||||||
public void should_match_forward_slash_only_regex()
|
[Fact]
|
||||||
{
|
public void should_not_match_slash_becaue_we_need_to_match_something_after_it()
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
{
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
const string regExForwardSlashAndOnePlaceHolder = "^/[0-9a-zA-Z].+";
|
||||||
.When(x => x.WhenIMatchThePaths())
|
|
||||||
.And(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(regExForwardSlashAndOnePlaceHolder))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.And(x => x.ThenTheResultIsFalse())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void should_find_match_when_template_smaller_than_valid_path()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/products/2354325435624623464235"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/api/products/.+$"))
|
public void should_not_match_forward_slash_only_regex()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.And(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("/working/"))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.And(x => x.ThenTheResultIsFalse())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void should_not_find_match()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/values"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
public void should_not_match_issue_134()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.And(x => x.ThenTheResultIsFalse())
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/vacancy/1/"))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/[^/]+/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.And(x => x.ThenTheResultIsFalse())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void can_match_down_stream_url()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath(""))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^$"))
|
public void should_match_forward_slash_only_regex()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.And(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void can_match_down_stream_url_with_no_slash()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api"))
|
[Fact]
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api$"))
|
public void should_find_match_when_template_smaller_than_valid_path()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/products/2354325435624623464235"))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/api/products/.+$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void can_match_down_stream_url_with_one_slash()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/"))
|
[Fact]
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/$"))
|
public void should_not_find_match()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("/api/values"))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.And(x => x.ThenTheResultIsFalse())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void can_match_down_stream_url_with_downstream_template()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/"))
|
[Fact]
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/$"))
|
public void can_match_down_stream_url()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath(""))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.And(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1"))
|
[Fact]
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+$"))
|
public void can_match_down_stream_url_with_no_slash()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("api"))
|
||||||
.BDDfy();
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2"))
|
[Fact]
|
||||||
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/.+$"))
|
public void can_match_down_stream_url_with_one_slash()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/"))
|
||||||
.BDDfy();
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
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"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/categories/.+$"))
|
public void can_match_down_stream_url_with_downstream_template()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/"))
|
||||||
.BDDfy();
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
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"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/categories/.+/variant/.+$"))
|
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1"))
|
||||||
.BDDfy();
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
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/"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/categories/.+/variant/$"))
|
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2"))
|
||||||
.BDDfy();
|
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/[^/]+/.+$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void should_ignore_case_sensitivity()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)api/product/products/.+/categories/.+/variant/$"))
|
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsTrue())
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2"))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/[^/]+/categories/.+$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
[Fact]
|
.BDDfy();
|
||||||
public void should_respect_case_sensitivity()
|
}
|
||||||
{
|
|
||||||
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
[Fact]
|
||||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.+/categories/.+/variant/$"))
|
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something()
|
||||||
.When(x => x.WhenIMatchThePaths())
|
{
|
||||||
.Then(x => x.ThenTheResultIsFalse())
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123"))
|
||||||
.BDDfy();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/[^/]+/categories/[^/]+/variant/.+$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
private void GivenIHaveAUpstreamPath(string path)
|
.BDDfy();
|
||||||
{
|
}
|
||||||
_path = path;
|
|
||||||
}
|
[Fact]
|
||||||
|
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders()
|
||||||
private void GivenIHaveAQueryString(string queryString)
|
{
|
||||||
{
|
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/"))
|
||||||
_queryString = queryString;
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/[^/]+/categories/[^/]+/variant/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
private void GivenIHaveAnUpstreamUrlTemplatePattern(string downstreamUrlTemplate)
|
.BDDfy();
|
||||||
{
|
}
|
||||||
_downstreamPathTemplate = downstreamUrlTemplate;
|
|
||||||
}
|
[Fact]
|
||||||
|
public void should_ignore_case_sensitivity()
|
||||||
private void WhenIMatchThePaths()
|
{
|
||||||
{
|
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
||||||
_result = _urlMatcher.Match(_path, _queryString, _downstreamPathTemplate, _containsQueryString);
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)api/product/products/[^/]+/categories/[^/]+/variant/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsTrue())
|
||||||
private void ThenTheResultIsTrue()
|
.BDDfy();
|
||||||
{
|
}
|
||||||
_result.Data.Match.ShouldBeTrue();
|
|
||||||
}
|
[Fact]
|
||||||
|
public void should_respect_case_sensitivity()
|
||||||
private void ThenTheResultIsFalse()
|
{
|
||||||
{
|
this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/"))
|
||||||
_result.Data.Match.ShouldBeFalse();
|
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/[^/]+/categories/[^/]+/variant/$"))
|
||||||
}
|
.When(x => x.WhenIMatchThePaths())
|
||||||
|
.Then(x => x.ThenTheResultIsFalse())
|
||||||
private void GivenThereIsAQueryInTemplate()
|
.BDDfy();
|
||||||
{
|
}
|
||||||
_containsQueryString = true;
|
|
||||||
}
|
private void GivenIHaveAUpstreamPath(string path)
|
||||||
}
|
{
|
||||||
}
|
_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenIHaveAQueryString(string queryString)
|
||||||
|
{
|
||||||
|
_queryString = queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenIHaveAnUpstreamUrlTemplatePattern(string downstreamUrlTemplate)
|
||||||
|
{
|
||||||
|
_downstreamPathTemplate = downstreamUrlTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIMatchThePaths()
|
||||||
|
{
|
||||||
|
_result = _urlMatcher.Match(_path, _queryString, _downstreamPathTemplate, _containsQueryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheResultIsTrue()
|
||||||
|
{
|
||||||
|
_result.Data.Match.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheResultIsFalse()
|
||||||
|
{
|
||||||
|
_result.Data.Match.ShouldBeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAQueryInTemplate()
|
||||||
|
{
|
||||||
|
_containsQueryString = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user