using System.Collections.Generic; using Moq; using Ocelot.Configuration; using Ocelot.Configuration.Builder; using Ocelot.Configuration.Provider; using Ocelot.DownstreamRouteFinder; using Ocelot.DownstreamRouteFinder.Finder; using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.Responses; using Shouldly; using TestStack.BDDfy; using Xunit; namespace Ocelot.UnitTests.DownstreamRouteFinder { public class DownstreamRouteFinderTests { private readonly IDownstreamRouteFinder _downstreamRouteFinder; private readonly Mock _mockConfig; private readonly Mock _mockMatcher; private readonly Mock _finder; private string _upstreamUrlPath; private Response _result; private List _reRoutesConfig; private Response _match; private string _upstreamHttpMethod; public DownstreamRouteFinderTests() { _mockConfig = new Mock(); _mockMatcher = new Mock(); _finder = new Mock(); _downstreamRouteFinder = new Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder(_mockConfig.Object, _mockMatcher.Object, _finder.Object); } [Fact] public void should_return_route() { this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath")) .And( x => x.GivenTheTemplateVariableAndNameFinderReturns( new OkResponse>(new List()))) .And(x => x.GivenTheConfigurationIs(new List { new ReRouteBuilder() .WithDownstreamTemplate("someDownstreamPath") .WithUpstreamTemplate("someUpstreamPath") .WithUpstreamHttpMethod("Get") .WithUpstreamTemplatePattern("someUpstreamPath") .Build() } )) .And(x => x.GivenTheUrlMatcherReturns(new OkResponse(new UrlMatch(true)))) .And(x => x.GivenTheUpstreamHttpMethodIs("Get")) .When(x => x.WhenICallTheFinder()) .Then( x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List(), new ReRouteBuilder() .WithDownstreamTemplate("someDownstreamPath") .Build() ))) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly()) .BDDfy(); } [Fact] public void should_return_correct_route_for_http_verb() { this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath")) .And( x => x.GivenTheTemplateVariableAndNameFinderReturns( new OkResponse>(new List()))) .And(x => x.GivenTheConfigurationIs(new List { new ReRouteBuilder() .WithDownstreamTemplate("someDownstreamPath") .WithUpstreamTemplate("someUpstreamPath") .WithUpstreamHttpMethod("Get") .WithUpstreamTemplatePattern("") .Build(), new ReRouteBuilder() .WithDownstreamTemplate("someDownstreamPathForAPost") .WithUpstreamTemplate("someUpstreamPath") .WithUpstreamHttpMethod("Post") .WithUpstreamTemplatePattern("") .Build() } )) .And(x => x.GivenTheUrlMatcherReturns(new OkResponse(new UrlMatch(true)))) .And(x => x.GivenTheUpstreamHttpMethodIs("Post")) .When(x => x.WhenICallTheFinder()) .Then( x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List(), new ReRouteBuilder() .WithDownstreamTemplate("someDownstreamPathForAPost") .Build() ))) .BDDfy(); } [Fact] public void should_not_return_route() { this.Given(x => x.GivenThereIsAnUpstreamUrlPath("somePath")) .And(x => x.GivenTheConfigurationIs(new List { new ReRouteBuilder() .WithDownstreamTemplate("somPath") .WithUpstreamTemplate("somePath") .WithUpstreamHttpMethod("Get") .WithUpstreamTemplatePattern("somePath") .Build(), } )) .And(x => x.GivenTheUrlMatcherReturns(new OkResponse(new UrlMatch(false)))) .And(x => x.GivenTheUpstreamHttpMethodIs("Get")) .When(x => x.WhenICallTheFinder()) .Then( x => x.ThenAnErrorResponseIsReturned()) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly()) .BDDfy(); } private void GivenTheTemplateVariableAndNameFinderReturns(Response> response) { _finder .Setup(x => x.Find(It.IsAny(), It.IsAny())) .Returns(response); } private void GivenTheUpstreamHttpMethodIs(string upstreamHttpMethod) { _upstreamHttpMethod = upstreamHttpMethod; } private void ThenAnErrorResponseIsReturned() { _result.IsError.ShouldBeTrue(); } private void ThenTheUrlMatcherIsCalledCorrectly() { _mockMatcher .Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamTemplate), Times.Once); } private void GivenTheUrlMatcherReturns(Response match) { _match = match; _mockMatcher .Setup(x => x.Match(It.IsAny(), It.IsAny())) .Returns(_match); } private void GivenTheConfigurationIs(List reRoutesConfig) { _reRoutesConfig = reRoutesConfig; _mockConfig .Setup(x => x.Get()) .Returns(new OkResponse(new OcelotConfiguration(_reRoutesConfig))); } private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath) { _upstreamUrlPath = upstreamUrlPath; } private void WhenICallTheFinder() { _result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod); } private void ThenTheFollowingIsReturned(DownstreamRoute expected) { _result.Data.ReRoute.DownstreamTemplate.ShouldBe(expected.ReRoute.DownstreamTemplate); for (int i = 0; i < _result.Data.TemplateVariableNameAndValues.Count; i++) { _result.Data.TemplateVariableNameAndValues[i].TemplateVariableName.ShouldBe( expected.TemplateVariableNameAndValues[i].TemplateVariableName); _result.Data.TemplateVariableNameAndValues[i].TemplateVariableValue.ShouldBe( expected.TemplateVariableNameAndValues[i].TemplateVariableValue); } _result.IsError.ShouldBeFalse(); } } }