reorganised project so its a bit more vertical for features

This commit is contained in:
TomPallister
2016-10-18 18:52:43 +01:00
parent 2e6640c6ef
commit f79b76b414
77 changed files with 324 additions and 298 deletions

View File

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Library.Configuration.Builder;
using Ocelot.Library.DownstreamRouteFinder;
using Ocelot.Library.DownstreamRouteFinder.Finder;
using Ocelot.Library.DownstreamRouteFinder.Middleware;
using Ocelot.Library.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Library.Responses;
using Ocelot.Library.ScopedData;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamRouteFinder
{
public class DownstreamRouteFinderMiddlewareTests : IDisposable
{
private readonly Mock<IDownstreamRouteFinder> _downstreamRouteFinder;
private readonly Mock<IScopedRequestDataRepository> _scopedRepository;
private readonly string _url;
private readonly TestServer _server;
private readonly HttpClient _client;
private Response<DownstreamRoute> _downstreamRoute;
private HttpResponseMessage _result;
public DownstreamRouteFinderMiddlewareTests()
{
_url = "http://localhost:51879";
_downstreamRouteFinder = new Mock<IDownstreamRouteFinder>();
_scopedRepository = new Mock<IScopedRequestDataRepository>();
var builder = new WebHostBuilder()
.ConfigureServices(x =>
{
x.AddSingleton(_downstreamRouteFinder.Object);
x.AddSingleton(_scopedRepository.Object);
})
.UseUrls(_url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(_url)
.Configure(app =>
{
app.UseDownstreamRouteFinderMiddleware();
});
_server = new TestServer(builder);
_client = _server.CreateClient();
}
[Fact]
public void happy_path()
{
this.Given(x => x.GivenTheDownStreamRouteFinderReturns(new DownstreamRoute(new List<TemplateVariableNameAndValue>(), new ReRouteBuilder().WithDownstreamTemplate("any old string").Build())))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
.BDDfy();
}
private void ThenTheScopedDataRepositoryIsCalledCorrectly()
{
_scopedRepository
.Verify(x => x.Add("DownstreamRoute", _downstreamRoute.Data), Times.Once());
}
private void WhenICallTheMiddleware()
{
_result = _client.GetAsync(_url).Result;
}
private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
{
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
_downstreamRouteFinder
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>()))
.Returns(_downstreamRoute);
}
public void Dispose()
{
_client.Dispose();
_server.Dispose();
}
}
}

View File

@ -2,6 +2,8 @@
using Moq;
using Ocelot.Library.Configuration.Builder;
using Ocelot.Library.Configuration.Provider;
using Ocelot.Library.DownstreamRouteFinder.Finder;
using Ocelot.Library.DownstreamRouteFinder.UrlMatcher;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
@ -11,7 +13,6 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
using Library.Configuration;
using Library.DownstreamRouteFinder;
using Library.Responses;
using Library.UrlMatcher;
public class DownstreamRouteFinderTests
{
@ -30,7 +31,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
_mockConfig = new Mock<IOcelotConfigurationProvider>();
_mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>();
_finder = new Mock<ITemplateVariableNameAndValueFinder>();
_downstreamRouteFinder = new DownstreamRouteFinder(_mockConfig.Object, _mockMatcher.Object, _finder.Object);
_downstreamRouteFinder = new Library.DownstreamRouteFinder.Finder.DownstreamRouteFinder(_mockConfig.Object, _mockMatcher.Object, _finder.Object);
}
[Fact]

View File

@ -0,0 +1,156 @@
using Ocelot.Library.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Library.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
{
public class RegExUrlMatcherTests
{
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
private string _downstreamUrlPath;
private string _downstreamPathTemplate;
private Response<UrlMatch> _result;
public RegExUrlMatcherTests()
{
_urlMatcher = new RegExUrlMatcher();
}
[Fact]
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/.*$"))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
public void should_not_find_match()
{
this.Given(x => x.GivenIHaveAUpstreamPath("/api/values"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("/$"))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsFalse())
.BDDfy();
}
[Fact]
public void can_match_down_stream_url()
{
this.Given(x => x.GivenIHaveAUpstreamPath(""))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("$"))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_no_slash()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_one_slash()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
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/.*$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
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/.*/.*$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
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/.*$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
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/.*$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
}
[Fact]
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/$"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.BDDfy();
}
private void GivenIHaveAUpstreamPath(string downstreamPath)
{
_downstreamUrlPath = downstreamPath;
}
private void GivenIHaveAnUpstreamUrlTemplatePattern(string downstreamUrlTemplate)
{
_downstreamPathTemplate = downstreamUrlTemplate;
}
private void WhenIMatchThePaths()
{
_result = _urlMatcher.Match(_downstreamUrlPath, _downstreamPathTemplate);
}
private void ThenTheResultIsTrue()
{
_result.Data.Match.ShouldBeTrue();
}
private void ThenTheResultIsFalse()
{
_result.Data.Match.ShouldBeFalse();
}
}
}

View File

@ -0,0 +1,168 @@
using System.Collections.Generic;
using System.Linq;
using Ocelot.Library.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Library.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
{
public class UrlPathToUrlTemplateMatcherTests
{
private readonly ITemplateVariableNameAndValueFinder _finder;
private string _downstreamUrlPath;
private string _downstreamPathTemplate;
private Response<List<TemplateVariableNameAndValue>> _result;
public UrlPathToUrlTemplateMatcherTests()
{
_finder = new TemplateVariableNameAndValueFinder();
}
[Fact]
public void can_match_down_stream_url()
{
this.Given(x => x.GivenIHaveAUpstreamPath(""))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate(""))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_no_slash()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_one_slash()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template()
{
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
{
var expectedTemplates = new List<TemplateVariableNameAndValue>
{
new TemplateVariableNameAndValue("{productId}", "1")
};
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders()
{
var expectedTemplates = new List<TemplateVariableNameAndValue>
{
new TemplateVariableNameAndValue("{productId}", "1"),
new TemplateVariableNameAndValue("{categoryId}", "2")
};
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/{categoryId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something()
{
var expectedTemplates = new List<TemplateVariableNameAndValue>
{
new TemplateVariableNameAndValue("{productId}", "1"),
new TemplateVariableNameAndValue("{categoryId}", "2")
};
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something()
{
var expectedTemplates = new List<TemplateVariableNameAndValue>
{
new TemplateVariableNameAndValue("{productId}", "1"),
new TemplateVariableNameAndValue("{categoryId}", "2"),
new TemplateVariableNameAndValue("{variantId}", "123")
};
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders()
{
var expectedTemplates = new List<TemplateVariableNameAndValue>
{
new TemplateVariableNameAndValue("{productId}", "1"),
new TemplateVariableNameAndValue("{categoryId}", "2")
};
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
private void ThenTheTemplatesVariablesAre(List<TemplateVariableNameAndValue> expectedResults)
{
foreach (var expectedResult in expectedResults)
{
var result = _result.Data
.First(t => t.TemplateVariableName == expectedResult.TemplateVariableName);
result.TemplateVariableValue.ShouldBe(expectedResult.TemplateVariableValue);
}
}
private void GivenIHaveAUpstreamPath(string downstreamPath)
{
_downstreamUrlPath = downstreamPath;
}
private void GivenIHaveAnUpstreamUrlTemplate(string downstreamUrlTemplate)
{
_downstreamPathTemplate = downstreamUrlTemplate;
}
private void WhenIFindTheUrlVariableNamesAndValues()
{
_result = _finder.Find(_downstreamUrlPath, _downstreamPathTemplate);
}
}
}