mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 14:08:15 +08:00
hacked together load balancing reroutes in fileconfig (#211)
* hacked together load balancing reroutes in fileconfig * some renaming and refactoring * more renames * hacked away the old config json * test for issue 213 * renamed key * dont share ports * oops * updated docs * mvoed docs around * port being used
This commit is contained in:
@ -1,70 +1,70 @@
|
||||
namespace Ocelot.UnitTests.Authentication
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Authentication.Middleware;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class AuthenticationMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public AuthenticationMiddlewareTests()
|
||||
{
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_next_middleware_if_route_is_not_authenticated()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build())))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheUserIsAuthenticated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthenticationMiddleware();
|
||||
|
||||
app.Run(async x =>
|
||||
{
|
||||
await x.Response.WriteAsync("The user is authenticated");
|
||||
});
|
||||
}
|
||||
|
||||
private void ThenTheUserIsAuthenticated()
|
||||
{
|
||||
var content = ResponseMessage.Content.ReadAsStringAsync().Result;
|
||||
content.ShouldBe("The user is authenticated");
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Authentication
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Authentication.Middleware;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class AuthenticationMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public AuthenticationMiddlewareTests()
|
||||
{
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_next_middleware_if_route_is_not_authenticated()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build())))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheUserIsAuthenticated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthenticationMiddleware();
|
||||
|
||||
app.Run(async x =>
|
||||
{
|
||||
await x.Response.WriteAsync("The user is authenticated");
|
||||
});
|
||||
}
|
||||
|
||||
private void ThenTheUserIsAuthenticated()
|
||||
{
|
||||
var content = ResponseMessage.Content.ReadAsStringAsync().Result;
|
||||
content.ShouldBe("The user is authenticated");
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,82 +1,82 @@
|
||||
namespace Ocelot.UnitTests.Authorization
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Authorisation.Middleware;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class AuthorisationMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IClaimsAuthoriser> _authService;
|
||||
private readonly Mock<IScopesAuthoriser> _authScopesService;
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public AuthorisationMiddlewareTests()
|
||||
{
|
||||
_authService = new Mock<IClaimsAuthoriser>();
|
||||
_authScopesService = new Mock<IScopesAuthoriser>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_authorisation_service()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithIsAuthorised(true)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheAuthServiceReturns(new OkResponse<bool>(true)))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAuthServiceIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_authService.Object);
|
||||
services.AddSingleton(_authScopesService.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthorisationMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheAuthServiceReturns(Response<bool> expected)
|
||||
{
|
||||
_authService
|
||||
.Setup(x => x.Authorise(It.IsAny<ClaimsPrincipal>(), It.IsAny<Dictionary<string, string>>()))
|
||||
.Returns(expected);
|
||||
}
|
||||
|
||||
private void ThenTheAuthServiceIsCalledCorrectly()
|
||||
{
|
||||
_authService
|
||||
.Verify(x => x.Authorise(It.IsAny<ClaimsPrincipal>(),
|
||||
It.IsAny<Dictionary<string, string>>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Authorization
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Authorisation.Middleware;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class AuthorisationMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IClaimsAuthoriser> _authService;
|
||||
private readonly Mock<IScopesAuthoriser> _authScopesService;
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public AuthorisationMiddlewareTests()
|
||||
{
|
||||
_authService = new Mock<IClaimsAuthoriser>();
|
||||
_authScopesService = new Mock<IScopesAuthoriser>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_authorisation_service()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithIsAuthorised(true)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => x.GivenTheAuthServiceReturns(new OkResponse<bool>(true)))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAuthServiceIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_authService.Object);
|
||||
services.AddSingleton(_authScopesService.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthorisationMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheAuthServiceReturns(Response<bool> expected)
|
||||
{
|
||||
_authService
|
||||
.Setup(x => x.Authorise(It.IsAny<ClaimsPrincipal>(), It.IsAny<Dictionary<string, string>>()))
|
||||
.Returns(expected);
|
||||
}
|
||||
|
||||
private void ThenTheAuthServiceIsCalledCorrectly()
|
||||
{
|
||||
_authService
|
||||
.Verify(x => x.Authorise(It.IsAny<ClaimsPrincipal>(),
|
||||
It.IsAny<Dictionary<string, string>>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,79 +1,79 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Authorization
|
||||
{
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
|
||||
public class ClaimsAuthoriserTests
|
||||
{
|
||||
private readonly ClaimsAuthoriser _claimsAuthoriser;
|
||||
private ClaimsPrincipal _claimsPrincipal;
|
||||
private Dictionary<string, string> _requirement;
|
||||
private Response<bool> _result;
|
||||
|
||||
public ClaimsAuthoriserTests()
|
||||
{
|
||||
_claimsAuthoriser = new ClaimsAuthoriser(new ClaimsParser());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_authorise_user()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
||||
{
|
||||
new Claim("UserType", "registered")
|
||||
}))))
|
||||
.And(x => x.GivenARouteClaimsRequirement(new Dictionary<string, string>
|
||||
{
|
||||
{"UserType", "registered"}
|
||||
}))
|
||||
.When(x => x.WhenICallTheAuthoriser())
|
||||
.Then(x => x.ThenTheUserIsAuthorised())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_authorise_user()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>()))))
|
||||
.And(x => x.GivenARouteClaimsRequirement(new Dictionary<string, string>
|
||||
{
|
||||
{ "UserType", "registered" }
|
||||
}))
|
||||
.When(x => x.WhenICallTheAuthoriser())
|
||||
.Then(x => x.ThenTheUserIsntAuthorised())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAClaimsPrincipal(ClaimsPrincipal claimsPrincipal)
|
||||
{
|
||||
_claimsPrincipal = claimsPrincipal;
|
||||
}
|
||||
|
||||
private void GivenARouteClaimsRequirement(Dictionary<string, string> requirement)
|
||||
{
|
||||
_requirement = requirement;
|
||||
}
|
||||
|
||||
private void WhenICallTheAuthoriser()
|
||||
{
|
||||
_result = _claimsAuthoriser.Authorise(_claimsPrincipal, _requirement);
|
||||
}
|
||||
|
||||
private void ThenTheUserIsAuthorised()
|
||||
{
|
||||
_result.Data.ShouldBe(true);
|
||||
}
|
||||
|
||||
private void ThenTheUserIsntAuthorised()
|
||||
{
|
||||
_result.Data.ShouldBe(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Authorization
|
||||
{
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
|
||||
public class ClaimsAuthoriserTests
|
||||
{
|
||||
private readonly ClaimsAuthoriser _claimsAuthoriser;
|
||||
private ClaimsPrincipal _claimsPrincipal;
|
||||
private Dictionary<string, string> _requirement;
|
||||
private Response<bool> _result;
|
||||
|
||||
public ClaimsAuthoriserTests()
|
||||
{
|
||||
_claimsAuthoriser = new ClaimsAuthoriser(new ClaimsParser());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_authorise_user()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
||||
{
|
||||
new Claim("UserType", "registered")
|
||||
}))))
|
||||
.And(x => x.GivenARouteClaimsRequirement(new Dictionary<string, string>
|
||||
{
|
||||
{"UserType", "registered"}
|
||||
}))
|
||||
.When(x => x.WhenICallTheAuthoriser())
|
||||
.Then(x => x.ThenTheUserIsAuthorised())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_authorise_user()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimsPrincipal(new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>()))))
|
||||
.And(x => x.GivenARouteClaimsRequirement(new Dictionary<string, string>
|
||||
{
|
||||
{ "UserType", "registered" }
|
||||
}))
|
||||
.When(x => x.WhenICallTheAuthoriser())
|
||||
.Then(x => x.ThenTheUserIsntAuthorised())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAClaimsPrincipal(ClaimsPrincipal claimsPrincipal)
|
||||
{
|
||||
_claimsPrincipal = claimsPrincipal;
|
||||
}
|
||||
|
||||
private void GivenARouteClaimsRequirement(Dictionary<string, string> requirement)
|
||||
{
|
||||
_requirement = requirement;
|
||||
}
|
||||
|
||||
private void WhenICallTheAuthoriser()
|
||||
{
|
||||
_result = _claimsAuthoriser.Authorise(_claimsPrincipal, _requirement);
|
||||
}
|
||||
|
||||
private void ThenTheUserIsAuthorised()
|
||||
{
|
||||
_result.Data.ShouldBe(true);
|
||||
}
|
||||
|
||||
private void ThenTheUserIsntAuthorised()
|
||||
{
|
||||
_result.Data.ShouldBe(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,103 +1,103 @@
|
||||
using System;
|
||||
using CacheManager.Core;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
public class CacheManagerCacheTests
|
||||
{
|
||||
private OcelotCacheManagerCache<string> _ocelotOcelotCacheManager;
|
||||
private Mock<ICacheManager<string>> _mockCacheManager;
|
||||
private string _key;
|
||||
private string _value;
|
||||
private string _resultGet;
|
||||
private TimeSpan _ttlSeconds;
|
||||
private string _region;
|
||||
|
||||
public CacheManagerCacheTests()
|
||||
{
|
||||
_mockCacheManager = new Mock<ICacheManager<string>>();
|
||||
_ocelotOcelotCacheManager = new OcelotCacheManagerCache<string>(_mockCacheManager.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_from_cache()
|
||||
{
|
||||
this.Given(x => x.GivenTheFollowingIsCached("someKey", "someRegion", "someValue"))
|
||||
.When(x => x.WhenIGetFromTheCache())
|
||||
.Then(x => x.ThenTheResultIs("someValue"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_to_cache()
|
||||
{
|
||||
this.When(x => x.WhenIAddToTheCache("someKey", "someValue", TimeSpan.FromSeconds(1)))
|
||||
.Then(x => x.ThenTheCacheIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_delete_key_from_cache()
|
||||
{
|
||||
this.Given(_ => GivenTheFollowingRegion("fookey"))
|
||||
.When(_ => WhenIDeleteTheRegion("fookey"))
|
||||
.Then(_ => ThenTheRegionIsDeleted("fookey"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenIDeleteTheRegion(string region)
|
||||
{
|
||||
_ocelotOcelotCacheManager.ClearRegion(region);
|
||||
}
|
||||
|
||||
private void ThenTheRegionIsDeleted(string region)
|
||||
{
|
||||
_mockCacheManager
|
||||
.Verify(x => x.ClearRegion(region), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingRegion(string key)
|
||||
{
|
||||
_ocelotOcelotCacheManager.Add(key, "doesnt matter", TimeSpan.FromSeconds(10), "region");
|
||||
}
|
||||
|
||||
private void WhenIAddToTheCache(string key, string value, TimeSpan ttlSeconds)
|
||||
{
|
||||
_key = key;
|
||||
_value = value;
|
||||
_ttlSeconds = ttlSeconds;
|
||||
_ocelotOcelotCacheManager.Add(_key, _value, _ttlSeconds, "region");
|
||||
}
|
||||
|
||||
private void ThenTheCacheIsCalledCorrectly()
|
||||
{
|
||||
_mockCacheManager
|
||||
.Verify(x => x.Add(It.IsAny<CacheItem<string>>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(string expected)
|
||||
{
|
||||
_resultGet.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void WhenIGetFromTheCache()
|
||||
{
|
||||
_resultGet = _ocelotOcelotCacheManager.Get(_key, _region);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingIsCached(string key, string region, string value)
|
||||
{
|
||||
_key = key;
|
||||
_value = value;
|
||||
_region = region;
|
||||
_mockCacheManager
|
||||
.Setup(x => x.Get<string>(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using CacheManager.Core;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
public class CacheManagerCacheTests
|
||||
{
|
||||
private OcelotCacheManagerCache<string> _ocelotOcelotCacheManager;
|
||||
private Mock<ICacheManager<string>> _mockCacheManager;
|
||||
private string _key;
|
||||
private string _value;
|
||||
private string _resultGet;
|
||||
private TimeSpan _ttlSeconds;
|
||||
private string _region;
|
||||
|
||||
public CacheManagerCacheTests()
|
||||
{
|
||||
_mockCacheManager = new Mock<ICacheManager<string>>();
|
||||
_ocelotOcelotCacheManager = new OcelotCacheManagerCache<string>(_mockCacheManager.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_from_cache()
|
||||
{
|
||||
this.Given(x => x.GivenTheFollowingIsCached("someKey", "someRegion", "someValue"))
|
||||
.When(x => x.WhenIGetFromTheCache())
|
||||
.Then(x => x.ThenTheResultIs("someValue"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_to_cache()
|
||||
{
|
||||
this.When(x => x.WhenIAddToTheCache("someKey", "someValue", TimeSpan.FromSeconds(1)))
|
||||
.Then(x => x.ThenTheCacheIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_delete_key_from_cache()
|
||||
{
|
||||
this.Given(_ => GivenTheFollowingRegion("fookey"))
|
||||
.When(_ => WhenIDeleteTheRegion("fookey"))
|
||||
.Then(_ => ThenTheRegionIsDeleted("fookey"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenIDeleteTheRegion(string region)
|
||||
{
|
||||
_ocelotOcelotCacheManager.ClearRegion(region);
|
||||
}
|
||||
|
||||
private void ThenTheRegionIsDeleted(string region)
|
||||
{
|
||||
_mockCacheManager
|
||||
.Verify(x => x.ClearRegion(region), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingRegion(string key)
|
||||
{
|
||||
_ocelotOcelotCacheManager.Add(key, "doesnt matter", TimeSpan.FromSeconds(10), "region");
|
||||
}
|
||||
|
||||
private void WhenIAddToTheCache(string key, string value, TimeSpan ttlSeconds)
|
||||
{
|
||||
_key = key;
|
||||
_value = value;
|
||||
_ttlSeconds = ttlSeconds;
|
||||
_ocelotOcelotCacheManager.Add(_key, _value, _ttlSeconds, "region");
|
||||
}
|
||||
|
||||
private void ThenTheCacheIsCalledCorrectly()
|
||||
{
|
||||
_mockCacheManager
|
||||
.Verify(x => x.Add(It.IsAny<CacheItem<string>>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(string expected)
|
||||
{
|
||||
_resultGet.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void WhenIGetFromTheCache()
|
||||
{
|
||||
_resultGet = _ocelotOcelotCacheManager.Get(_key, _region);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingIsCached(string key, string region, string value)
|
||||
{
|
||||
_key = key;
|
||||
_value = value;
|
||||
_region = region;
|
||||
_mockCacheManager
|
||||
.Setup(x => x.Get<string>(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,130 +1,130 @@
|
||||
namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Cache.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class OutputCacheMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
|
||||
private CachedResponse _response;
|
||||
|
||||
public OutputCacheMiddlewareTests()
|
||||
{
|
||||
_cacheManager = new Mock<IOcelotCache<CachedResponse>>();
|
||||
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_returned_cached_item_when_it_is_in_cache()
|
||||
{
|
||||
var cachedResponse = new CachedResponse();
|
||||
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.And(x => x.GivenThereIsADownstreamUrl())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_continue_with_pipeline_and_cache_response()
|
||||
{
|
||||
this.Given(x => x.GivenResponseIsNotCached())
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.And(x => x.GivenThereAreNoErrors())
|
||||
.And(x => x.GivenThereIsADownstreamUrl())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheAddIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_cacheManager.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
services.AddSingleton<IRegionCreator, RegionCreator>();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseOutputCacheMiddleware();
|
||||
}
|
||||
|
||||
private void GivenThereIsACachedResponse(CachedResponse response)
|
||||
{
|
||||
_response = response;
|
||||
_cacheManager
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(_response);
|
||||
}
|
||||
|
||||
private void GivenResponseIsNotCached()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
|
||||
.Returns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage()));
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRouteIs()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithIsCached(true)
|
||||
.WithCacheOptions(new CacheOptions(100, "kanken"))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
|
||||
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
|
||||
}
|
||||
|
||||
private void GivenThereAreNoErrors()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<bool>("OcelotMiddlewareError"))
|
||||
.Returns(new OkResponse<bool>(false));
|
||||
}
|
||||
|
||||
private void GivenThereIsADownstreamUrl()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<string>("DownstreamUrl"))
|
||||
.Returns(new OkResponse<string>("anything"));
|
||||
}
|
||||
|
||||
private void ThenTheCacheGetIsCalledCorrectly()
|
||||
{
|
||||
_cacheManager
|
||||
.Verify(x => x.Get(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheCacheAddIsCalledCorrectly()
|
||||
{
|
||||
_cacheManager
|
||||
.Verify(x => x.Add(It.IsAny<string>(), It.IsAny<CachedResponse>(), It.IsAny<TimeSpan>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Cache.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class OutputCacheMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
|
||||
private CachedResponse _response;
|
||||
|
||||
public OutputCacheMiddlewareTests()
|
||||
{
|
||||
_cacheManager = new Mock<IOcelotCache<CachedResponse>>();
|
||||
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_returned_cached_item_when_it_is_in_cache()
|
||||
{
|
||||
var cachedResponse = new CachedResponse();
|
||||
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.And(x => x.GivenThereIsADownstreamUrl())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_continue_with_pipeline_and_cache_response()
|
||||
{
|
||||
this.Given(x => x.GivenResponseIsNotCached())
|
||||
.And(x => x.GivenTheDownstreamRouteIs())
|
||||
.And(x => x.GivenThereAreNoErrors())
|
||||
.And(x => x.GivenThereIsADownstreamUrl())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheCacheAddIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_cacheManager.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
services.AddSingleton<IRegionCreator, RegionCreator>();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseOutputCacheMiddleware();
|
||||
}
|
||||
|
||||
private void GivenThereIsACachedResponse(CachedResponse response)
|
||||
{
|
||||
_response = response;
|
||||
_cacheManager
|
||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(_response);
|
||||
}
|
||||
|
||||
private void GivenResponseIsNotCached()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
|
||||
.Returns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage()));
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRouteIs()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithIsCached(true)
|
||||
.WithCacheOptions(new CacheOptions(100, "kanken"))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
|
||||
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
|
||||
}
|
||||
|
||||
private void GivenThereAreNoErrors()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<bool>("OcelotMiddlewareError"))
|
||||
.Returns(new OkResponse<bool>(false));
|
||||
}
|
||||
|
||||
private void GivenThereIsADownstreamUrl()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<string>("DownstreamUrl"))
|
||||
.Returns(new OkResponse<string>("anything"));
|
||||
}
|
||||
|
||||
private void ThenTheCacheGetIsCalledCorrectly()
|
||||
{
|
||||
_cacheManager
|
||||
.Verify(x => x.Get(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheCacheAddIsCalledCorrectly()
|
||||
{
|
||||
_cacheManager
|
||||
.Verify(x => x.Add(It.IsAny<string>(), It.IsAny<CachedResponse>(), It.IsAny<TimeSpan>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,65 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
public class RegionCreatorTests
|
||||
{
|
||||
private string _result;
|
||||
private FileReRoute _reRoute;
|
||||
|
||||
[Fact]
|
||||
public void should_create_region()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
UpstreamPathTemplate = "/testdummy"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoute(reRoute))
|
||||
.When(_ => WhenICreateTheRegion())
|
||||
.Then(_ => ThenTheRegionIs("Gettestdummy"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_region()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
FileCacheOptions = new FileCacheOptions
|
||||
{
|
||||
Region = "region"
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoute(reRoute))
|
||||
.When(_ => WhenICreateTheRegion())
|
||||
.Then(_ => ThenTheRegionIs("region"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateTheRegion()
|
||||
{
|
||||
RegionCreator regionCreator = new RegionCreator();
|
||||
_result = regionCreator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheRegionIs(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
public class RegionCreatorTests
|
||||
{
|
||||
private string _result;
|
||||
private FileReRoute _reRoute;
|
||||
|
||||
[Fact]
|
||||
public void should_create_region()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
UpstreamPathTemplate = "/testdummy"
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoute(reRoute))
|
||||
.When(_ => WhenICreateTheRegion())
|
||||
.Then(_ => ThenTheRegionIs("Gettestdummy"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_region()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
FileCacheOptions = new FileCacheOptions
|
||||
{
|
||||
Region = "region"
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(_ => GivenTheReRoute(reRoute))
|
||||
.When(_ => WhenICreateTheRegion())
|
||||
.Then(_ => ThenTheRegionIs("region"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateTheRegion()
|
||||
{
|
||||
RegionCreator regionCreator = new RegionCreator();
|
||||
_result = regionCreator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheRegionIs(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,144 +1,144 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Claims;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Claims
|
||||
{
|
||||
public class AddClaimsToRequestTests
|
||||
{
|
||||
private readonly AddClaimsToRequest _addClaimsToRequest;
|
||||
private readonly Mock<IClaimsParser> _parser;
|
||||
private List<ClaimToThing> _claimsToThings;
|
||||
private HttpContext _context;
|
||||
private Response _result;
|
||||
private Response<string> _claimValue;
|
||||
|
||||
public AddClaimsToRequestTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_addClaimsToRequest = new AddClaimsToRequest(_parser.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_claims_to_context()
|
||||
{
|
||||
var context = new DefaultHttpContext
|
||||
{
|
||||
User = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
}))
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenClaimsToThings(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("claim-key", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenHttpContext(context))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddClaimsToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void if_claims_exists_should_replace_it()
|
||||
{
|
||||
var context = new DefaultHttpContext
|
||||
{
|
||||
User = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
||||
{
|
||||
new Claim("existing-key", "data"),
|
||||
new Claim("new-key", "data")
|
||||
})),
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenClaimsToThings(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("existing-key", "new-key", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenHttpContext(context))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddClaimsToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
this.Given(
|
||||
x => x.GivenClaimsToThings(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenHttpContext(new DefaultHttpContext()))
|
||||
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.When(x => x.WhenIAddClaimsToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
private void GivenClaimsToThings(List<ClaimToThing> configuration)
|
||||
{
|
||||
_claimsToThings = configuration;
|
||||
}
|
||||
|
||||
private void GivenHttpContext(HttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private void GivenTheClaimParserReturns(Response<string> claimValue)
|
||||
{
|
||||
_claimValue = claimValue;
|
||||
_parser
|
||||
.Setup(
|
||||
x =>
|
||||
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<int>()))
|
||||
.Returns(_claimValue);
|
||||
}
|
||||
|
||||
private void WhenIAddClaimsToTheRequest()
|
||||
{
|
||||
_result = _addClaimsToRequest.SetClaimsOnContext(_claimsToThings, _context);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsSuccess()
|
||||
{
|
||||
_result.IsError.ShouldBe(false);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsError()
|
||||
{
|
||||
|
||||
_result.IsError.ShouldBe(true);
|
||||
}
|
||||
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError()
|
||||
: base("blahh", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Claims;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Claims
|
||||
{
|
||||
public class AddClaimsToRequestTests
|
||||
{
|
||||
private readonly AddClaimsToRequest _addClaimsToRequest;
|
||||
private readonly Mock<IClaimsParser> _parser;
|
||||
private List<ClaimToThing> _claimsToThings;
|
||||
private HttpContext _context;
|
||||
private Response _result;
|
||||
private Response<string> _claimValue;
|
||||
|
||||
public AddClaimsToRequestTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_addClaimsToRequest = new AddClaimsToRequest(_parser.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_claims_to_context()
|
||||
{
|
||||
var context = new DefaultHttpContext
|
||||
{
|
||||
User = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
}))
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenClaimsToThings(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("claim-key", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenHttpContext(context))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddClaimsToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void if_claims_exists_should_replace_it()
|
||||
{
|
||||
var context = new DefaultHttpContext
|
||||
{
|
||||
User = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
|
||||
{
|
||||
new Claim("existing-key", "data"),
|
||||
new Claim("new-key", "data")
|
||||
})),
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenClaimsToThings(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("existing-key", "new-key", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenHttpContext(context))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddClaimsToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
this.Given(
|
||||
x => x.GivenClaimsToThings(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenHttpContext(new DefaultHttpContext()))
|
||||
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.When(x => x.WhenIAddClaimsToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
private void GivenClaimsToThings(List<ClaimToThing> configuration)
|
||||
{
|
||||
_claimsToThings = configuration;
|
||||
}
|
||||
|
||||
private void GivenHttpContext(HttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private void GivenTheClaimParserReturns(Response<string> claimValue)
|
||||
{
|
||||
_claimValue = claimValue;
|
||||
_parser
|
||||
.Setup(
|
||||
x =>
|
||||
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<int>()))
|
||||
.Returns(_claimValue);
|
||||
}
|
||||
|
||||
private void WhenIAddClaimsToTheRequest()
|
||||
{
|
||||
_result = _addClaimsToRequest.SetClaimsOnContext(_claimsToThings, _context);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsSuccess()
|
||||
{
|
||||
_result.IsError.ShouldBe(false);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsError()
|
||||
{
|
||||
|
||||
_result.IsError.ShouldBe(true);
|
||||
}
|
||||
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError()
|
||||
: base("blahh", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,87 +1,87 @@
|
||||
namespace Ocelot.UnitTests.Claims
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Claims;
|
||||
using Ocelot.Claims.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ClaimsBuilderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IAddClaimsToRequest> _addHeaders;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public ClaimsBuilderMiddlewareTests()
|
||||
{
|
||||
_addHeaders = new Mock<IAddClaimsToRequest>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_claims_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToClaims(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("sub", "UserType", "|", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddClaimsToRequestReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheClaimsToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_addHeaders.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseClaimsBuilderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheAddClaimsToRequestReturns()
|
||||
{
|
||||
_addHeaders
|
||||
.Setup(x => x.SetClaimsOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<HttpContext>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheClaimsToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addHeaders
|
||||
.Verify(x => x.SetClaimsOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<HttpContext>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Claims
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Claims;
|
||||
using Ocelot.Claims.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ClaimsBuilderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IAddClaimsToRequest> _addHeaders;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public ClaimsBuilderMiddlewareTests()
|
||||
{
|
||||
_addHeaders = new Mock<IAddClaimsToRequest>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_claims_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToClaims(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("sub", "UserType", "|", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddClaimsToRequestReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheClaimsToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_addHeaders.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseClaimsBuilderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheAddClaimsToRequestReturns()
|
||||
{
|
||||
_addHeaders
|
||||
.Setup(x => x.SetClaimsOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<HttpContext>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheClaimsToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addHeaders
|
||||
.Verify(x => x.SetClaimsOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<HttpContext>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class AuthenticationOptionsCreatorTests
|
||||
{
|
||||
private readonly AuthenticationOptionsCreator _authOptionsCreator;
|
||||
private FileReRoute _fileReRoute;
|
||||
private AuthenticationOptions _result;
|
||||
|
||||
public AuthenticationOptionsCreatorTests()
|
||||
{
|
||||
_authOptionsCreator = new AuthenticationOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_auth_options()
|
||||
{
|
||||
var fileReRoute = new FileReRoute()
|
||||
{
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "Test",
|
||||
AllowedScopes = new List<string> { "cheese" },
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new AuthenticationOptionsBuilder()
|
||||
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
||||
.WithAuthenticationProviderKey("Test")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowing(fileReRoute))
|
||||
.When(x => x.WhenICreateTheAuthenticationOptions())
|
||||
.Then(x => x.ThenTheFollowingConfigIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateTheAuthenticationOptions()
|
||||
{
|
||||
_result = _authOptionsCreator.Create(_fileReRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingConfigIsReturned(AuthenticationOptions expected)
|
||||
{
|
||||
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||
_result.AuthenticationProviderKey.ShouldBe(expected.AuthenticationProviderKey);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class AuthenticationOptionsCreatorTests
|
||||
{
|
||||
private readonly AuthenticationOptionsCreator _authOptionsCreator;
|
||||
private FileReRoute _fileReRoute;
|
||||
private AuthenticationOptions _result;
|
||||
|
||||
public AuthenticationOptionsCreatorTests()
|
||||
{
|
||||
_authOptionsCreator = new AuthenticationOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_auth_options()
|
||||
{
|
||||
var fileReRoute = new FileReRoute()
|
||||
{
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "Test",
|
||||
AllowedScopes = new List<string> { "cheese" },
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new AuthenticationOptionsBuilder()
|
||||
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
|
||||
.WithAuthenticationProviderKey("Test")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowing(fileReRoute))
|
||||
.When(x => x.WhenICreateTheAuthenticationOptions())
|
||||
.Then(x => x.ThenTheFollowingConfigIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void WhenICreateTheAuthenticationOptions()
|
||||
{
|
||||
_result = _authOptionsCreator.Create(_fileReRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingConfigIsReturned(AuthenticationOptions expected)
|
||||
{
|
||||
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||
_result.AuthenticationProviderKey.ShouldBe(expected.AuthenticationProviderKey);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,117 +1,117 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Parser;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ClaimToThingConfigurationParserTests
|
||||
{
|
||||
private Dictionary<string, string> _dictionary;
|
||||
private readonly IClaimToThingConfigurationParser _claimToThingConfigurationParser;
|
||||
private Response<ClaimToThing> _result;
|
||||
|
||||
public ClaimToThingConfigurationParserTests()
|
||||
{
|
||||
_claimToThingConfigurationParser = new ClaimToThingConfigurationParser();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void returns_no_instructions_error()
|
||||
{
|
||||
this.Given(x => x.GivenTheDictionaryIs(new Dictionary<string, string>()
|
||||
{
|
||||
{"CustomerId", ""},
|
||||
}))
|
||||
.When(x => x.WhenICallTheExtractor())
|
||||
.Then(
|
||||
x =>
|
||||
x.ThenAnErrorIsReturned(new ErrorResponse<ClaimToThing>(
|
||||
new List<Error>
|
||||
{
|
||||
new NoInstructionsError(">")
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void returns_no_instructions_not_for_claims_error()
|
||||
{
|
||||
this.Given(x => x.GivenTheDictionaryIs(new Dictionary<string, string>()
|
||||
{
|
||||
{"CustomerId", "Cheese[CustomerId] > value"},
|
||||
}))
|
||||
.When(x => x.WhenICallTheExtractor())
|
||||
.Then(
|
||||
x =>
|
||||
x.ThenAnErrorIsReturned(new ErrorResponse<ClaimToThing>(
|
||||
new List<Error>
|
||||
{
|
||||
new InstructionNotForClaimsError()
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_parse_entry_to_work_out_properties_with_key()
|
||||
{
|
||||
this.Given(x => x.GivenTheDictionaryIs(new Dictionary<string, string>()
|
||||
{
|
||||
{"CustomerId", "Claims[CustomerId] > value"},
|
||||
}))
|
||||
.When(x => x.WhenICallTheExtractor())
|
||||
.Then(
|
||||
x =>
|
||||
x.ThenTheClaimParserPropertiesAreReturned(
|
||||
new OkResponse<ClaimToThing>(
|
||||
new ClaimToThing("CustomerId", "CustomerId", "", 0))))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_parse_entry_to_work_out_properties_with_key_delimiter_and_index()
|
||||
{
|
||||
this.Given(x => x.GivenTheDictionaryIs(new Dictionary<string, string>()
|
||||
{
|
||||
{"UserId", "Claims[Subject] > value[0] > |"},
|
||||
}))
|
||||
.When(x => x.WhenICallTheExtractor())
|
||||
.Then(
|
||||
x =>
|
||||
x.ThenTheClaimParserPropertiesAreReturned(
|
||||
new OkResponse<ClaimToThing>(
|
||||
new ClaimToThing("UserId", "Subject", "|", 0))))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned(Response<ClaimToThing> expected)
|
||||
{
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
_result.Errors[0].ShouldBeOfType(expected.Errors[0].GetType());
|
||||
}
|
||||
|
||||
private void ThenTheClaimParserPropertiesAreReturned(Response<ClaimToThing> expected)
|
||||
{
|
||||
_result.Data.NewKey.ShouldBe(expected.Data.NewKey);
|
||||
_result.Data.Delimiter.ShouldBe(expected.Data.Delimiter);
|
||||
_result.Data.Index.ShouldBe(expected.Data.Index);
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
|
||||
private void WhenICallTheExtractor()
|
||||
{
|
||||
var first = _dictionary.First();
|
||||
_result = _claimToThingConfigurationParser.Extract(first.Key, first.Value);
|
||||
}
|
||||
|
||||
private void GivenTheDictionaryIs(Dictionary<string, string> dictionary)
|
||||
{
|
||||
_dictionary = dictionary;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Parser;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ClaimToThingConfigurationParserTests
|
||||
{
|
||||
private Dictionary<string, string> _dictionary;
|
||||
private readonly IClaimToThingConfigurationParser _claimToThingConfigurationParser;
|
||||
private Response<ClaimToThing> _result;
|
||||
|
||||
public ClaimToThingConfigurationParserTests()
|
||||
{
|
||||
_claimToThingConfigurationParser = new ClaimToThingConfigurationParser();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void returns_no_instructions_error()
|
||||
{
|
||||
this.Given(x => x.GivenTheDictionaryIs(new Dictionary<string, string>()
|
||||
{
|
||||
{"CustomerId", ""},
|
||||
}))
|
||||
.When(x => x.WhenICallTheExtractor())
|
||||
.Then(
|
||||
x =>
|
||||
x.ThenAnErrorIsReturned(new ErrorResponse<ClaimToThing>(
|
||||
new List<Error>
|
||||
{
|
||||
new NoInstructionsError(">")
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void returns_no_instructions_not_for_claims_error()
|
||||
{
|
||||
this.Given(x => x.GivenTheDictionaryIs(new Dictionary<string, string>()
|
||||
{
|
||||
{"CustomerId", "Cheese[CustomerId] > value"},
|
||||
}))
|
||||
.When(x => x.WhenICallTheExtractor())
|
||||
.Then(
|
||||
x =>
|
||||
x.ThenAnErrorIsReturned(new ErrorResponse<ClaimToThing>(
|
||||
new List<Error>
|
||||
{
|
||||
new InstructionNotForClaimsError()
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_parse_entry_to_work_out_properties_with_key()
|
||||
{
|
||||
this.Given(x => x.GivenTheDictionaryIs(new Dictionary<string, string>()
|
||||
{
|
||||
{"CustomerId", "Claims[CustomerId] > value"},
|
||||
}))
|
||||
.When(x => x.WhenICallTheExtractor())
|
||||
.Then(
|
||||
x =>
|
||||
x.ThenTheClaimParserPropertiesAreReturned(
|
||||
new OkResponse<ClaimToThing>(
|
||||
new ClaimToThing("CustomerId", "CustomerId", "", 0))))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_parse_entry_to_work_out_properties_with_key_delimiter_and_index()
|
||||
{
|
||||
this.Given(x => x.GivenTheDictionaryIs(new Dictionary<string, string>()
|
||||
{
|
||||
{"UserId", "Claims[Subject] > value[0] > |"},
|
||||
}))
|
||||
.When(x => x.WhenICallTheExtractor())
|
||||
.Then(
|
||||
x =>
|
||||
x.ThenTheClaimParserPropertiesAreReturned(
|
||||
new OkResponse<ClaimToThing>(
|
||||
new ClaimToThing("UserId", "Subject", "|", 0))))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned(Response<ClaimToThing> expected)
|
||||
{
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
_result.Errors[0].ShouldBeOfType(expected.Errors[0].GetType());
|
||||
}
|
||||
|
||||
private void ThenTheClaimParserPropertiesAreReturned(Response<ClaimToThing> expected)
|
||||
{
|
||||
_result.Data.NewKey.ShouldBe(expected.Data.NewKey);
|
||||
_result.Data.Delimiter.ShouldBe(expected.Data.Delimiter);
|
||||
_result.Data.Index.ShouldBe(expected.Data.Index);
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
|
||||
private void WhenICallTheExtractor()
|
||||
{
|
||||
var first = _dictionary.First();
|
||||
_result = _claimToThingConfigurationParser.Extract(first.Key, first.Value);
|
||||
}
|
||||
|
||||
private void GivenTheDictionaryIs(Dictionary<string, string> dictionary)
|
||||
{
|
||||
_dictionary = dictionary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,110 +1,110 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.Parser;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ClaimsToThingCreatorTests
|
||||
{
|
||||
private readonly Mock<IClaimToThingConfigurationParser> _configParser;
|
||||
private Dictionary<string,string> _claimsToThings;
|
||||
private ClaimsToThingCreator _claimsToThingsCreator;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private List<ClaimToThing> _result;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
|
||||
public ClaimsToThingCreatorTests()
|
||||
{
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory
|
||||
.Setup(x => x.CreateLogger<ClaimsToThingCreator>())
|
||||
.Returns(_logger.Object);
|
||||
_configParser = new Mock<IClaimToThingConfigurationParser>();
|
||||
_claimsToThingsCreator = new ClaimsToThingCreator(_configParser.Object, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_claims_to_things()
|
||||
{
|
||||
var userInput = new Dictionary<string,string>()
|
||||
{
|
||||
{"CustomerId", "Claims[CustomerId] > value"}
|
||||
};
|
||||
|
||||
var claimsToThing = new OkResponse<ClaimToThing>(new ClaimToThing("CustomerId", "CustomerId", "", 0));
|
||||
|
||||
this.Given(x => x.GivenTheFollowingDictionary(userInput))
|
||||
.And(x => x.GivenTheConfigHeaderExtractorReturns(claimsToThing))
|
||||
.When(x => x.WhenIGetTheThings())
|
||||
.Then(x => x.ThenTheConfigParserIsCalledCorrectly())
|
||||
.And(x => x.ThenClaimsToThingsAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_log_error_if_cannot_parse_claim_to_thing()
|
||||
{
|
||||
var userInput = new Dictionary<string,string>()
|
||||
{
|
||||
{"CustomerId", "Claims[CustomerId] > value"}
|
||||
};
|
||||
|
||||
var claimsToThing = new ErrorResponse<ClaimToThing>(It.IsAny<Error>());
|
||||
|
||||
this.Given(x => x.GivenTheFollowingDictionary(userInput))
|
||||
.And(x => x.GivenTheConfigHeaderExtractorReturns(claimsToThing))
|
||||
.When(x => x.WhenIGetTheThings())
|
||||
.Then(x => x.ThenTheConfigParserIsCalledCorrectly())
|
||||
.And(x => x.ThenNoClaimsToThingsAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheLoggerIsCalledCorrectly()
|
||||
{
|
||||
_logger
|
||||
.Verify(x => x.LogDebug(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenClaimsToThingsAreReturned()
|
||||
{
|
||||
_result.Count.ShouldBeGreaterThan(0);
|
||||
}
|
||||
private void GivenTheFollowingDictionary(Dictionary<string,string> claimsToThings)
|
||||
{
|
||||
_claimsToThings = claimsToThings;
|
||||
}
|
||||
|
||||
private void GivenTheConfigHeaderExtractorReturns(Response<ClaimToThing> expected)
|
||||
{
|
||||
_configParser
|
||||
.Setup(x => x.Extract(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(expected);
|
||||
}
|
||||
|
||||
private void ThenNoClaimsToThingsAreReturned()
|
||||
{
|
||||
_result.Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
private void WhenIGetTheThings()
|
||||
{
|
||||
_result = _claimsToThingsCreator.Create(_claimsToThings);
|
||||
}
|
||||
|
||||
private void ThenTheConfigParserIsCalledCorrectly()
|
||||
{
|
||||
_configParser
|
||||
.Verify(x => x.Extract(_claimsToThings.First().Key, _claimsToThings.First().Value), Times.Once);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.Parser;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ClaimsToThingCreatorTests
|
||||
{
|
||||
private readonly Mock<IClaimToThingConfigurationParser> _configParser;
|
||||
private Dictionary<string,string> _claimsToThings;
|
||||
private ClaimsToThingCreator _claimsToThingsCreator;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private List<ClaimToThing> _result;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
|
||||
public ClaimsToThingCreatorTests()
|
||||
{
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory
|
||||
.Setup(x => x.CreateLogger<ClaimsToThingCreator>())
|
||||
.Returns(_logger.Object);
|
||||
_configParser = new Mock<IClaimToThingConfigurationParser>();
|
||||
_claimsToThingsCreator = new ClaimsToThingCreator(_configParser.Object, _loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_claims_to_things()
|
||||
{
|
||||
var userInput = new Dictionary<string,string>()
|
||||
{
|
||||
{"CustomerId", "Claims[CustomerId] > value"}
|
||||
};
|
||||
|
||||
var claimsToThing = new OkResponse<ClaimToThing>(new ClaimToThing("CustomerId", "CustomerId", "", 0));
|
||||
|
||||
this.Given(x => x.GivenTheFollowingDictionary(userInput))
|
||||
.And(x => x.GivenTheConfigHeaderExtractorReturns(claimsToThing))
|
||||
.When(x => x.WhenIGetTheThings())
|
||||
.Then(x => x.ThenTheConfigParserIsCalledCorrectly())
|
||||
.And(x => x.ThenClaimsToThingsAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_log_error_if_cannot_parse_claim_to_thing()
|
||||
{
|
||||
var userInput = new Dictionary<string,string>()
|
||||
{
|
||||
{"CustomerId", "Claims[CustomerId] > value"}
|
||||
};
|
||||
|
||||
var claimsToThing = new ErrorResponse<ClaimToThing>(It.IsAny<Error>());
|
||||
|
||||
this.Given(x => x.GivenTheFollowingDictionary(userInput))
|
||||
.And(x => x.GivenTheConfigHeaderExtractorReturns(claimsToThing))
|
||||
.When(x => x.WhenIGetTheThings())
|
||||
.Then(x => x.ThenTheConfigParserIsCalledCorrectly())
|
||||
.And(x => x.ThenNoClaimsToThingsAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheLoggerIsCalledCorrectly()
|
||||
{
|
||||
_logger
|
||||
.Verify(x => x.LogDebug(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenClaimsToThingsAreReturned()
|
||||
{
|
||||
_result.Count.ShouldBeGreaterThan(0);
|
||||
}
|
||||
private void GivenTheFollowingDictionary(Dictionary<string,string> claimsToThings)
|
||||
{
|
||||
_claimsToThings = claimsToThings;
|
||||
}
|
||||
|
||||
private void GivenTheConfigHeaderExtractorReturns(Response<ClaimToThing> expected)
|
||||
{
|
||||
_configParser
|
||||
.Setup(x => x.Extract(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(expected);
|
||||
}
|
||||
|
||||
private void ThenNoClaimsToThingsAreReturned()
|
||||
{
|
||||
_result.Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
private void WhenIGetTheThings()
|
||||
{
|
||||
_result = _claimsToThingsCreator.Create(_claimsToThings);
|
||||
}
|
||||
|
||||
private void ThenTheConfigParserIsCalledCorrectly()
|
||||
{
|
||||
_configParser
|
||||
.Verify(x => x.Extract(_claimsToThings.First().Key, _claimsToThings.First().Value), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,89 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using static Ocelot.UnitTests.Wait;
|
||||
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ConsulFileConfigurationPollerTests : IDisposable
|
||||
{
|
||||
private ConsulFileConfigurationPoller _poller;
|
||||
private Mock<IOcelotLoggerFactory> _factory;
|
||||
private Mock<IFileConfigurationRepository> _repo;
|
||||
private Mock<IFileConfigurationSetter> _setter;
|
||||
private FileConfiguration _fileConfig;
|
||||
|
||||
public ConsulFileConfigurationPollerTests()
|
||||
{
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
_factory = new Mock<IOcelotLoggerFactory>();
|
||||
_factory.Setup(x => x.CreateLogger<ConsulFileConfigurationPoller>()).Returns(logger.Object);
|
||||
_repo = new Mock<IFileConfigurationRepository>();
|
||||
_setter = new Mock<IFileConfigurationSetter>();
|
||||
_fileConfig = new FileConfiguration();
|
||||
_repo.Setup(x => x.Get()).ReturnsAsync(new OkResponse<FileConfiguration>(_fileConfig));
|
||||
_poller = new ConsulFileConfigurationPoller(_factory.Object, _repo.Object, _setter.Object);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
_poller.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_start()
|
||||
{
|
||||
this.Given(x => ThenTheSetterIsCalled(_fileConfig))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_setter_when_gets_new_config()
|
||||
{
|
||||
|
||||
var newConfig = new FileConfiguration {
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHost = "test"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => WhenTheConfigIsChangedInConsul(newConfig))
|
||||
.Then(x => ThenTheSetterIsCalled(newConfig))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenTheConfigIsChangedInConsul(FileConfiguration newConfig)
|
||||
{
|
||||
_repo.Setup(x => x.Get()).ReturnsAsync(new OkResponse<FileConfiguration>(newConfig));
|
||||
}
|
||||
|
||||
private void ThenTheSetterIsCalled(FileConfiguration fileConfig)
|
||||
{
|
||||
var result = WaitFor(2000).Until(() => {
|
||||
try
|
||||
{
|
||||
_setter.Verify(x => x.Set(fileConfig), Times.Once);
|
||||
return true;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
result.ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using static Ocelot.UnitTests.Wait;
|
||||
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ConsulFileConfigurationPollerTests : IDisposable
|
||||
{
|
||||
private ConsulFileConfigurationPoller _poller;
|
||||
private Mock<IOcelotLoggerFactory> _factory;
|
||||
private Mock<IFileConfigurationRepository> _repo;
|
||||
private Mock<IFileConfigurationSetter> _setter;
|
||||
private FileConfiguration _fileConfig;
|
||||
|
||||
public ConsulFileConfigurationPollerTests()
|
||||
{
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
_factory = new Mock<IOcelotLoggerFactory>();
|
||||
_factory.Setup(x => x.CreateLogger<ConsulFileConfigurationPoller>()).Returns(logger.Object);
|
||||
_repo = new Mock<IFileConfigurationRepository>();
|
||||
_setter = new Mock<IFileConfigurationSetter>();
|
||||
_fileConfig = new FileConfiguration();
|
||||
_repo.Setup(x => x.Get()).ReturnsAsync(new OkResponse<FileConfiguration>(_fileConfig));
|
||||
_poller = new ConsulFileConfigurationPoller(_factory.Object, _repo.Object, _setter.Object);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
_poller.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_start()
|
||||
{
|
||||
this.Given(x => ThenTheSetterIsCalled(_fileConfig))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_setter_when_gets_new_config()
|
||||
{
|
||||
|
||||
var newConfig = new FileConfiguration {
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => WhenTheConfigIsChangedInConsul(newConfig))
|
||||
.Then(x => ThenTheSetterIsCalled(newConfig))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenTheConfigIsChangedInConsul(FileConfiguration newConfig)
|
||||
{
|
||||
_repo.Setup(x => x.Get()).ReturnsAsync(new OkResponse<FileConfiguration>(newConfig));
|
||||
}
|
||||
|
||||
private void ThenTheSetterIsCalled(FileConfiguration fileConfig)
|
||||
{
|
||||
var result = WaitFor(2000).Until(() => {
|
||||
try
|
||||
{
|
||||
_setter.Verify(x => x.Set(fileConfig), Times.Once);
|
||||
return true;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
result.ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,122 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class DownstreamAddressesCreatorTests
|
||||
{
|
||||
public DownstreamAddressesCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private List<DownstreamHostAndPort> _result;
|
||||
|
||||
public DownstreamAddressesCreatorTests()
|
||||
{
|
||||
_creator = new DownstreamAddressesCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_do_nothing()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
};
|
||||
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingReRoute(reRoute))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_addresses_from_old_downstream_path_and_port()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test",
|
||||
Port = 80
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
new DownstreamHostAndPort("test", 80),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingReRoute(reRoute))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_downstream_addresses_from_downstream_host_and_ports()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "test",
|
||||
Port = 80
|
||||
},
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "west",
|
||||
Port = 443
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new List<DownstreamHostAndPort>
|
||||
{
|
||||
new DownstreamHostAndPort("test", 80),
|
||||
new DownstreamHostAndPort("west", 443)
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheFollowingReRoute(reRoute))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => TheThenFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void TheThenFollowingIsReturned(List<DownstreamHostAndPort> expecteds)
|
||||
{
|
||||
_result.Count.ShouldBe(expecteds.Count);
|
||||
|
||||
for (int i = 0; i < _result.Count; i++)
|
||||
{
|
||||
var result = _result[i];
|
||||
var expected = expecteds[i];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
using System;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.UnitTests.TestData;
|
||||
@ -40,6 +41,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
private Mock<IHttpHandlerOptionsCreator> _httpHandlerOptionsCreator;
|
||||
private Mock<IAdministrationPath> _adminPath;
|
||||
private readonly Mock<IHeaderFindAndReplaceCreator> _headerFindAndReplaceCreator;
|
||||
private readonly Mock<IDownstreamAddressesCreator> _downstreamAddressesCreator;
|
||||
|
||||
public FileConfigurationCreatorTests()
|
||||
{
|
||||
@ -58,6 +60,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
_httpHandlerOptionsCreator = new Mock<IHttpHandlerOptionsCreator>();
|
||||
_adminPath = new Mock<IAdministrationPath>();
|
||||
_headerFindAndReplaceCreator = new Mock<IHeaderFindAndReplaceCreator>();
|
||||
_downstreamAddressesCreator = new Mock<IDownstreamAddressesCreator>();
|
||||
|
||||
_ocelotConfigurationCreator = new FileOcelotConfigurationCreator(
|
||||
_fileConfig.Object,
|
||||
@ -74,7 +77,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
_regionCreator.Object,
|
||||
_httpHandlerOptionsCreator.Object,
|
||||
_adminPath.Object,
|
||||
_headerFindAndReplaceCreator.Object);
|
||||
_headerFindAndReplaceCreator.Object,
|
||||
_downstreamAddressesCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -94,6 +98,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheFollowingIsReturned(serviceProviderConfig))
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
@ -113,7 +118,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHost = "127.0.0.1",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
@ -125,6 +136,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
},
|
||||
}))
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => x.GivenTheFollowingRegionIsReturned("region"))
|
||||
@ -146,7 +158,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHost = "127.0.0.1",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
@ -154,6 +172,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
},
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
@ -180,7 +199,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHost = "127.0.0.1",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
@ -194,6 +219,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
},
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(serviceOptions))
|
||||
.And(x => x.GivenTheQosOptionsCreatorReturns(expected))
|
||||
@ -214,7 +240,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHost = "127.0.0.1",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
@ -222,13 +254,14 @@ namespace Ocelot.UnitTests.Configuration
|
||||
},
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamHost("127.0.0.1")
|
||||
.WithDownstreamAddresses(new List<DownstreamHostAndPort>(){new DownstreamHostAndPort("127.0.0.1", 80) })
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
@ -257,6 +290,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
},
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
@ -300,6 +334,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
@ -336,6 +371,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
@ -371,6 +407,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.And(x => x.GivenTheUpstreamTemplatePatternCreatorReturns("(?i)/api/products/.*/$"))
|
||||
@ -411,6 +448,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
}
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.And(x => x.GivenTheRequestIdCreatorReturns("blahhhh"))
|
||||
@ -441,7 +479,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHost = "127.0.0.1",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" }
|
||||
@ -449,6 +493,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
},
|
||||
}))
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => x.GivenTheFollowingHttpHandlerOptionsAreReturned(httpHandlerOptions))
|
||||
@ -484,6 +529,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(fileConfig))
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheAuthOptionsCreatorReturns(authenticationOptions))
|
||||
@ -519,6 +565,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(fileConfig))
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
@ -536,6 +583,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
var errors = new List<Error> {new FileValidationFailedError("some message")};
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration()))
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => x.GivenTheConfigIsInvalid(errors))
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
.Then(x => x.ThenTheErrorsAreReturned(errors))
|
||||
@ -719,5 +767,10 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
_httpHandlerOptionsCreator.Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once());
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamAddresses()
|
||||
{
|
||||
_downstreamAddressesCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(new List<DownstreamHostAndPort>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.Configuration.Repository;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class FileConfigurationProviderTests
|
||||
{
|
||||
private readonly IFileConfigurationProvider _provider;
|
||||
private Mock<IFileConfigurationRepository> _repo;
|
||||
private FileConfiguration _result;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
|
||||
public FileConfigurationProviderTests()
|
||||
{
|
||||
_repo = new Mock<IFileConfigurationRepository>();
|
||||
_provider = new FileConfigurationProvider(_repo.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration()
|
||||
{
|
||||
var config = new FileConfiguration();
|
||||
|
||||
this.Given(x => x.GivenTheConfigurationIs(config))
|
||||
.When(x => x.WhenIGetTheReRoutes())
|
||||
.Then(x => x.ThenTheRepoIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
_repo
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(new OkResponse<FileConfiguration>(fileConfiguration));
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRoutes()
|
||||
{
|
||||
_result = _provider.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheRepoIsCalledCorrectly()
|
||||
{
|
||||
_repo
|
||||
.Verify(x => x.Get(), Times.Once);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.Configuration.Repository;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class FileConfigurationProviderTests
|
||||
{
|
||||
private readonly IFileConfigurationProvider _provider;
|
||||
private Mock<IFileConfigurationRepository> _repo;
|
||||
private FileConfiguration _result;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
|
||||
public FileConfigurationProviderTests()
|
||||
{
|
||||
_repo = new Mock<IFileConfigurationRepository>();
|
||||
_provider = new FileConfigurationProvider(_repo.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration()
|
||||
{
|
||||
var config = new FileConfiguration();
|
||||
|
||||
this.Given(x => x.GivenTheConfigurationIs(config))
|
||||
.When(x => x.WhenIGetTheReRoutes())
|
||||
.Then(x => x.ThenTheRepoIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
_repo
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(new OkResponse<FileConfiguration>(fileConfiguration));
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRoutes()
|
||||
{
|
||||
_result = _provider.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheRepoIsCalledCorrectly()
|
||||
{
|
||||
_repo
|
||||
.Verify(x => x.Get(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,199 +1,225 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Ocelot.Configuration.Repository;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class FileConfigurationRepositoryTests
|
||||
{
|
||||
private readonly Mock<IHostingEnvironment> _hostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
private IFileConfigurationRepository _repo;
|
||||
private FileConfiguration _result;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private string _environmentName = "DEV";
|
||||
|
||||
public FileConfigurationRepositoryTests()
|
||||
{
|
||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||
_repo = new FileConfigurationRepository(_hostingEnvironment.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForGet();
|
||||
|
||||
this.Given(x => x.GivenTheConfigurationIs(config))
|
||||
.When(x => x.WhenIGetTheReRoutes())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration_if_environment_name_is_unavailable()
|
||||
{
|
||||
var config = FakeFileConfigurationForGet();
|
||||
|
||||
this.Given(x => x.GivenTheEnvironmentNameIsUnavailable())
|
||||
.And(x => x.GivenTheConfigurationIs(config))
|
||||
.When(x => x.WhenIGetTheReRoutes())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
|
||||
this.Given(x => GivenIHaveAConfiguration(config))
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.Then(x => ThenTheConfigurationIsStoredAs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_file_configuration_if_environment_name_is_unavailable()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
this.Given(x => GivenIHaveAConfiguration(config))
|
||||
.And(x => GivenTheEnvironmentNameIsUnavailable())
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.Then(x => ThenTheConfigurationIsStoredAs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheEnvironmentNameIsUnavailable()
|
||||
{
|
||||
_environmentName = null;
|
||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||
_repo = new FileConfigurationRepository(_hostingEnvironment.Object);
|
||||
}
|
||||
|
||||
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void WhenISetTheConfiguration()
|
||||
{
|
||||
_repo.Set(_fileConfiguration);
|
||||
_result = _repo.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsStoredAs(FileConfiguration expected)
|
||||
{
|
||||
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expected.GlobalConfiguration.RequestIdKey);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
|
||||
for(var i = 0; i < _result.ReRoutes.Count; i++)
|
||||
{
|
||||
_result.ReRoutes[i].DownstreamHost.ShouldBe(expected.ReRoutes[i].DownstreamHost);
|
||||
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expected.ReRoutes[i].DownstreamPathTemplate);
|
||||
_result.ReRoutes[i].DownstreamPort.ShouldBe(expected.ReRoutes[i].DownstreamPort);
|
||||
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expected.ReRoutes[i].DownstreamScheme);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||
{
|
||||
var configurationPath = $"{AppContext.BaseDirectory}/configuration{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||
|
||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
||||
|
||||
if (File.Exists(configurationPath))
|
||||
{
|
||||
File.Delete(configurationPath);
|
||||
}
|
||||
|
||||
File.WriteAllText(configurationPath, jsonConfiguration);
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRoutes()
|
||||
{
|
||||
_result = _repo.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(FileConfiguration expected)
|
||||
{
|
||||
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expected.GlobalConfiguration.RequestIdKey);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
|
||||
for(var i = 0; i < _result.ReRoutes.Count; i++)
|
||||
{
|
||||
_result.ReRoutes[i].DownstreamHost.ShouldBe(expected.ReRoutes[i].DownstreamHost);
|
||||
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expected.ReRoutes[i].DownstreamPathTemplate);
|
||||
_result.ReRoutes[i].DownstreamPort.ShouldBe(expected.ReRoutes[i].DownstreamPort);
|
||||
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expected.ReRoutes[i].DownstreamScheme);
|
||||
}
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfigurationForSet()
|
||||
{
|
||||
var reRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHost = "123.12.12.12",
|
||||
DownstreamPort = 80,
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/asdfs/test/{test}"
|
||||
}
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
ReRoutes = reRoutes
|
||||
};
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfigurationForGet()
|
||||
{
|
||||
var reRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHost = "localhost",
|
||||
DownstreamPort = 80,
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/test/test/{test}"
|
||||
}
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
ReRoutes = reRoutes
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Ocelot.Configuration.Repository;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class FileConfigurationRepositoryTests
|
||||
{
|
||||
private readonly Mock<IHostingEnvironment> _hostingEnvironment = new Mock<IHostingEnvironment>();
|
||||
private IFileConfigurationRepository _repo;
|
||||
private FileConfiguration _result;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private string _environmentName = "DEV";
|
||||
|
||||
public FileConfigurationRepositoryTests()
|
||||
{
|
||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||
_repo = new FileConfigurationRepository(_hostingEnvironment.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForGet();
|
||||
|
||||
this.Given(x => x.GivenTheConfigurationIs(config))
|
||||
.When(x => x.WhenIGetTheReRoutes())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_file_configuration_if_environment_name_is_unavailable()
|
||||
{
|
||||
var config = FakeFileConfigurationForGet();
|
||||
|
||||
this.Given(x => x.GivenTheEnvironmentNameIsUnavailable())
|
||||
.And(x => x.GivenTheConfigurationIs(config))
|
||||
.When(x => x.WhenIGetTheReRoutes())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_file_configuration()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
|
||||
this.Given(x => GivenIHaveAConfiguration(config))
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.Then(x => ThenTheConfigurationIsStoredAs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_file_configuration_if_environment_name_is_unavailable()
|
||||
{
|
||||
var config = FakeFileConfigurationForSet();
|
||||
this.Given(x => GivenIHaveAConfiguration(config))
|
||||
.And(x => GivenTheEnvironmentNameIsUnavailable())
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.Then(x => ThenTheConfigurationIsStoredAs(config))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheEnvironmentNameIsUnavailable()
|
||||
{
|
||||
_environmentName = null;
|
||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||
_repo = new FileConfigurationRepository(_hostingEnvironment.Object);
|
||||
}
|
||||
|
||||
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void WhenISetTheConfiguration()
|
||||
{
|
||||
_repo.Set(_fileConfiguration);
|
||||
_result = _repo.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsStoredAs(FileConfiguration expecteds)
|
||||
{
|
||||
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
|
||||
for(var i = 0; i < _result.ReRoutes.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
|
||||
{
|
||||
var result = _result.ReRoutes[i].DownstreamHostAndPorts[j];
|
||||
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
|
||||
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
|
||||
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||
{
|
||||
var configurationPath = $"{AppContext.BaseDirectory}/configuration{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||
|
||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
||||
|
||||
if (File.Exists(configurationPath))
|
||||
{
|
||||
File.Delete(configurationPath);
|
||||
}
|
||||
|
||||
File.WriteAllText(configurationPath, jsonConfiguration);
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRoutes()
|
||||
{
|
||||
_result = _repo.Get().Result.Data;
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(FileConfiguration expecteds)
|
||||
{
|
||||
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
||||
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
||||
|
||||
for(var i = 0; i < _result.ReRoutes.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
|
||||
{
|
||||
var result = _result.ReRoutes[i].DownstreamHostAndPorts[j];
|
||||
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
|
||||
|
||||
result.Host.ShouldBe(expected.Host);
|
||||
result.Port.ShouldBe(expected.Port);
|
||||
}
|
||||
|
||||
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
|
||||
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
|
||||
}
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfigurationForSet()
|
||||
{
|
||||
var reRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "123.12.12.12",
|
||||
Port = 80,
|
||||
}
|
||||
},
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/asdfs/test/{test}"
|
||||
}
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
ReRoutes = reRoutes
|
||||
};
|
||||
}
|
||||
|
||||
private FileConfiguration FakeFileConfigurationForGet()
|
||||
{
|
||||
var reRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 80,
|
||||
}
|
||||
},
|
||||
DownstreamScheme = "https",
|
||||
DownstreamPathTemplate = "/test/test/{test}"
|
||||
}
|
||||
};
|
||||
|
||||
var globalConfiguration = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Port = 198,
|
||||
Host = "blah"
|
||||
}
|
||||
};
|
||||
|
||||
return new FileConfiguration
|
||||
{
|
||||
GlobalConfiguration = globalConfiguration,
|
||||
ReRoutes = reRoutes
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,113 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class FileConfigurationSetterTests
|
||||
{
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private FileConfigurationSetter _configSetter;
|
||||
private Mock<IOcelotConfigurationRepository> _configRepo;
|
||||
private Mock<IOcelotConfigurationCreator> _configCreator;
|
||||
private Response<IOcelotConfiguration> _configuration;
|
||||
private object _result;
|
||||
private Mock<IFileConfigurationRepository> _repo;
|
||||
|
||||
public FileConfigurationSetterTests()
|
||||
{
|
||||
_repo = new Mock<IFileConfigurationRepository>();
|
||||
_configRepo = new Mock<IOcelotConfigurationRepository>();
|
||||
_configCreator = new Mock<IOcelotConfigurationCreator>();
|
||||
_configSetter = new FileConfigurationSetter(_configRepo.Object, _configCreator.Object, _repo.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_configuration()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
var config = new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf");
|
||||
|
||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||
.And(x => GivenTheRepoReturns(new OkResponse()))
|
||||
.And(x => GivenTheCreatorReturns(new OkResponse<IOcelotConfiguration>(config)))
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.Then(x => ThenTheConfigurationRepositoryIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_unable_to_set_file_configuration()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||
.And(x => GivenTheRepoReturns(new ErrorResponse(It.IsAny<Error>())))
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.And(x => ThenAnErrorResponseIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_unable_to_set_ocelot_configuration()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||
.And(x => GivenTheRepoReturns(new OkResponse()))
|
||||
.And(x => GivenTheCreatorReturns(new ErrorResponse<IOcelotConfiguration>(It.IsAny<Error>())))
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.And(x => ThenAnErrorResponseIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheRepoReturns(Response response)
|
||||
{
|
||||
_repo
|
||||
.Setup(x => x.Set(It.IsAny<FileConfiguration>()))
|
||||
.ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void ThenAnErrorResponseIsReturned()
|
||||
{
|
||||
_result.ShouldBeOfType<ErrorResponse>();
|
||||
}
|
||||
|
||||
private void GivenTheCreatorReturns(Response<IOcelotConfiguration> configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_configCreator
|
||||
.Setup(x => x.Create(_fileConfiguration))
|
||||
.ReturnsAsync(_configuration);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingConfiguration(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void WhenISetTheConfiguration()
|
||||
{
|
||||
_result = _configSetter.Set(_fileConfiguration).Result;
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationRepositoryIsCalledCorrectly()
|
||||
{
|
||||
_configRepo
|
||||
.Verify(x => x.AddOrReplace(_configuration.Data), Times.Once);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class FileConfigurationSetterTests
|
||||
{
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private FileConfigurationSetter _configSetter;
|
||||
private Mock<IOcelotConfigurationRepository> _configRepo;
|
||||
private Mock<IOcelotConfigurationCreator> _configCreator;
|
||||
private Response<IOcelotConfiguration> _configuration;
|
||||
private object _result;
|
||||
private Mock<IFileConfigurationRepository> _repo;
|
||||
|
||||
public FileConfigurationSetterTests()
|
||||
{
|
||||
_repo = new Mock<IFileConfigurationRepository>();
|
||||
_configRepo = new Mock<IOcelotConfigurationRepository>();
|
||||
_configCreator = new Mock<IOcelotConfigurationCreator>();
|
||||
_configSetter = new FileConfigurationSetter(_configRepo.Object, _configCreator.Object, _repo.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_configuration()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
var config = new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf");
|
||||
|
||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||
.And(x => GivenTheRepoReturns(new OkResponse()))
|
||||
.And(x => GivenTheCreatorReturns(new OkResponse<IOcelotConfiguration>(config)))
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.Then(x => ThenTheConfigurationRepositoryIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_unable_to_set_file_configuration()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||
.And(x => GivenTheRepoReturns(new ErrorResponse(It.IsAny<Error>())))
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.And(x => ThenAnErrorResponseIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_unable_to_set_ocelot_configuration()
|
||||
{
|
||||
var fileConfig = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
|
||||
.And(x => GivenTheRepoReturns(new OkResponse()))
|
||||
.And(x => GivenTheCreatorReturns(new ErrorResponse<IOcelotConfiguration>(It.IsAny<Error>())))
|
||||
.When(x => WhenISetTheConfiguration())
|
||||
.And(x => ThenAnErrorResponseIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheRepoReturns(Response response)
|
||||
{
|
||||
_repo
|
||||
.Setup(x => x.Set(It.IsAny<FileConfiguration>()))
|
||||
.ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void ThenAnErrorResponseIsReturned()
|
||||
{
|
||||
_result.ShouldBeOfType<ErrorResponse>();
|
||||
}
|
||||
|
||||
private void GivenTheCreatorReturns(Response<IOcelotConfiguration> configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_configCreator
|
||||
.Setup(x => x.Create(_fileConfiguration))
|
||||
.ReturnsAsync(_configuration);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingConfiguration(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void WhenISetTheConfiguration()
|
||||
{
|
||||
_result = _configSetter.Set(_fileConfiguration).Result;
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationRepositoryIsCalledCorrectly()
|
||||
{
|
||||
_configRepo
|
||||
.Verify(x => x.AddOrReplace(_configuration.Data), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +1,33 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class HashCreationTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_create_hash_and_salt()
|
||||
{
|
||||
var password = "secret";
|
||||
|
||||
var salt = new byte[128 / 8];
|
||||
|
||||
using (var rng = RandomNumberGenerator.Create())
|
||||
{
|
||||
rng.GetBytes(salt);
|
||||
}
|
||||
|
||||
var storedSalt = Convert.ToBase64String(salt);
|
||||
|
||||
var storedHash = Convert.ToBase64String(KeyDerivation.Pbkdf2(
|
||||
password: password,
|
||||
salt: salt,
|
||||
prf: KeyDerivationPrf.HMACSHA256,
|
||||
iterationCount: 10000,
|
||||
numBytesRequested: 256 / 8));
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class HashCreationTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_create_hash_and_salt()
|
||||
{
|
||||
var password = "secret";
|
||||
|
||||
var salt = new byte[128 / 8];
|
||||
|
||||
using (var rng = RandomNumberGenerator.Create())
|
||||
{
|
||||
rng.GetBytes(salt);
|
||||
}
|
||||
|
||||
var storedSalt = Convert.ToBase64String(salt);
|
||||
|
||||
var storedHash = Convert.ToBase64String(KeyDerivation.Pbkdf2(
|
||||
password: password,
|
||||
salt: salt,
|
||||
prf: KeyDerivationPrf.HMACSHA256,
|
||||
iterationCount: 10000,
|
||||
numBytesRequested: 256 / 8));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,76 +1,76 @@
|
||||
using Ocelot.Configuration.Authentication;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class HashMatcherTests
|
||||
{
|
||||
private string _password;
|
||||
private string _hash;
|
||||
private string _salt;
|
||||
private bool _result;
|
||||
private HashMatcher _hashMatcher;
|
||||
|
||||
public HashMatcherTests()
|
||||
{
|
||||
_hashMatcher = new HashMatcher();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_hash()
|
||||
{
|
||||
var hash = "kE/mxd1hO9h9Sl2VhGhwJUd9xZEv4NP6qXoN39nIqM4=";
|
||||
var salt = "zzWITpnDximUNKYLiUam/w==";
|
||||
var password = "secret";
|
||||
|
||||
this.Given(x => GivenThePassword(password))
|
||||
.And(x => GivenTheHash(hash))
|
||||
.And(x => GivenTheSalt(salt))
|
||||
.When(x => WhenIMatch())
|
||||
.Then(x => ThenTheResultIs(true))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_hash()
|
||||
{
|
||||
var hash = "kE/mxd1hO9h9Sl2VhGhwJUd9xZEv4NP6qXoN39nIqM4=";
|
||||
var salt = "zzWITpnDximUNKYLiUam/w==";
|
||||
var password = "secret1";
|
||||
|
||||
this.Given(x => GivenThePassword(password))
|
||||
.And(x => GivenTheHash(hash))
|
||||
.And(x => GivenTheSalt(salt))
|
||||
.When(x => WhenIMatch())
|
||||
.Then(x => ThenTheResultIs(false))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThePassword(string password)
|
||||
{
|
||||
_password = password;
|
||||
}
|
||||
|
||||
private void GivenTheHash(string hash)
|
||||
{
|
||||
_hash = hash;
|
||||
}
|
||||
|
||||
private void GivenTheSalt(string salt)
|
||||
{
|
||||
_salt = salt;
|
||||
}
|
||||
|
||||
private void WhenIMatch()
|
||||
{
|
||||
_result = _hashMatcher.Match(_password, _salt, _hash);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(bool expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration.Authentication;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class HashMatcherTests
|
||||
{
|
||||
private string _password;
|
||||
private string _hash;
|
||||
private string _salt;
|
||||
private bool _result;
|
||||
private HashMatcher _hashMatcher;
|
||||
|
||||
public HashMatcherTests()
|
||||
{
|
||||
_hashMatcher = new HashMatcher();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_hash()
|
||||
{
|
||||
var hash = "kE/mxd1hO9h9Sl2VhGhwJUd9xZEv4NP6qXoN39nIqM4=";
|
||||
var salt = "zzWITpnDximUNKYLiUam/w==";
|
||||
var password = "secret";
|
||||
|
||||
this.Given(x => GivenThePassword(password))
|
||||
.And(x => GivenTheHash(hash))
|
||||
.And(x => GivenTheSalt(salt))
|
||||
.When(x => WhenIMatch())
|
||||
.Then(x => ThenTheResultIs(true))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_hash()
|
||||
{
|
||||
var hash = "kE/mxd1hO9h9Sl2VhGhwJUd9xZEv4NP6qXoN39nIqM4=";
|
||||
var salt = "zzWITpnDximUNKYLiUam/w==";
|
||||
var password = "secret1";
|
||||
|
||||
this.Given(x => GivenThePassword(password))
|
||||
.And(x => GivenTheHash(hash))
|
||||
.And(x => GivenTheSalt(salt))
|
||||
.When(x => WhenIMatch())
|
||||
.Then(x => ThenTheResultIs(false))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThePassword(string password)
|
||||
{
|
||||
_password = password;
|
||||
}
|
||||
|
||||
private void GivenTheHash(string hash)
|
||||
{
|
||||
_hash = hash;
|
||||
}
|
||||
|
||||
private void GivenTheSalt(string salt)
|
||||
{
|
||||
_salt = salt;
|
||||
}
|
||||
|
||||
private void WhenIMatch()
|
||||
{
|
||||
_result = _hashMatcher.Match(_password, _salt, _hash);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(bool expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,158 +1,158 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Middleware;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class HeaderFindAndReplaceCreatorTests
|
||||
{
|
||||
private HeaderFindAndReplaceCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private HeaderTransformations _result;
|
||||
private Mock<IBaseUrlFinder> _finder;
|
||||
|
||||
public HeaderFindAndReplaceCreatorTests()
|
||||
{
|
||||
_finder = new Mock<IBaseUrlFinder>();
|
||||
_creator = new HeaderFindAndReplaceCreator(_finder.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
UpstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Test", "Test, Chicken"},
|
||||
|
||||
{"Moop", "o, a"}
|
||||
},
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Pop", "West, East"},
|
||||
|
||||
{"Bop", "e, r"}
|
||||
}
|
||||
};
|
||||
|
||||
var upstream = new List<HeaderFindAndReplace>
|
||||
{
|
||||
new HeaderFindAndReplace("Test", "Test", "Chicken", 0),
|
||||
new HeaderFindAndReplace("Moop", "o", "a", 0)
|
||||
};
|
||||
|
||||
var downstream = new List<HeaderFindAndReplace>
|
||||
{
|
||||
new HeaderFindAndReplace("Pop", "West", "East", 0),
|
||||
new HeaderFindAndReplace("Bop", "e", "r", 0)
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingUpstreamIsReturned(upstream))
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_base_url_placeholder()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Location", "http://www.bbc.co.uk/, {BaseUrl}"},
|
||||
}
|
||||
};
|
||||
|
||||
var downstream = new List<HeaderFindAndReplace>
|
||||
{
|
||||
new HeaderFindAndReplace("Location", "http://www.bbc.co.uk/", "http://ocelot.com/", 0),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_use_base_url_partial_placeholder()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Location", "http://www.bbc.co.uk/pay, {BaseUrl}pay"},
|
||||
}
|
||||
};
|
||||
|
||||
var downstream = new List<HeaderFindAndReplace>
|
||||
{
|
||||
new HeaderFindAndReplace("Location", "http://www.bbc.co.uk/pay", "http://ocelot.com/pay", 0),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheBaseUrlIs(string baseUrl)
|
||||
{
|
||||
_finder.Setup(x => x.Find()).Returns(baseUrl);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingDownstreamIsReturned(List<HeaderFindAndReplace> downstream)
|
||||
{
|
||||
_result.Downstream.Count.ShouldBe(downstream.Count);
|
||||
|
||||
for (int i = 0; i < _result.Downstream.Count; i++)
|
||||
{
|
||||
var result = _result.Downstream[i];
|
||||
var expected = downstream[i];
|
||||
result.Find.ShouldBe(expected.Find);
|
||||
result.Index.ShouldBe(expected.Index);
|
||||
result.Key.ShouldBe(expected.Key);
|
||||
result.Replace.ShouldBe(expected.Replace);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingUpstreamIsReturned(List<HeaderFindAndReplace> expecteds)
|
||||
{
|
||||
_result.Upstream.Count.ShouldBe(expecteds.Count);
|
||||
|
||||
for (int i = 0; i < _result.Upstream.Count; i++)
|
||||
{
|
||||
var result = _result.Upstream[i];
|
||||
var expected = expecteds[i];
|
||||
result.Find.ShouldBe(expected.Find);
|
||||
result.Index.ShouldBe(expected.Index);
|
||||
result.Key.ShouldBe(expected.Key);
|
||||
result.Replace.ShouldBe(expected.Replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Middleware;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class HeaderFindAndReplaceCreatorTests
|
||||
{
|
||||
private HeaderFindAndReplaceCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private HeaderTransformations _result;
|
||||
private Mock<IBaseUrlFinder> _finder;
|
||||
|
||||
public HeaderFindAndReplaceCreatorTests()
|
||||
{
|
||||
_finder = new Mock<IBaseUrlFinder>();
|
||||
_creator = new HeaderFindAndReplaceCreator(_finder.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
UpstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Test", "Test, Chicken"},
|
||||
|
||||
{"Moop", "o, a"}
|
||||
},
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Pop", "West, East"},
|
||||
|
||||
{"Bop", "e, r"}
|
||||
}
|
||||
};
|
||||
|
||||
var upstream = new List<HeaderFindAndReplace>
|
||||
{
|
||||
new HeaderFindAndReplace("Test", "Test", "Chicken", 0),
|
||||
new HeaderFindAndReplace("Moop", "o", "a", 0)
|
||||
};
|
||||
|
||||
var downstream = new List<HeaderFindAndReplace>
|
||||
{
|
||||
new HeaderFindAndReplace("Pop", "West", "East", 0),
|
||||
new HeaderFindAndReplace("Bop", "e", "r", 0)
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingUpstreamIsReturned(upstream))
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_base_url_placeholder()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Location", "http://www.bbc.co.uk/, {BaseUrl}"},
|
||||
}
|
||||
};
|
||||
|
||||
var downstream = new List<HeaderFindAndReplace>
|
||||
{
|
||||
new HeaderFindAndReplace("Location", "http://www.bbc.co.uk/", "http://ocelot.com/", 0),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_use_base_url_partial_placeholder()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
DownstreamHeaderTransform = new Dictionary<string, string>
|
||||
{
|
||||
{"Location", "http://www.bbc.co.uk/pay, {BaseUrl}pay"},
|
||||
}
|
||||
};
|
||||
|
||||
var downstream = new List<HeaderFindAndReplace>
|
||||
{
|
||||
new HeaderFindAndReplace("Location", "http://www.bbc.co.uk/pay", "http://ocelot.com/pay", 0),
|
||||
};
|
||||
|
||||
this.Given(x => GivenTheReRoute(reRoute))
|
||||
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
|
||||
.When(x => WhenICreate())
|
||||
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheBaseUrlIs(string baseUrl)
|
||||
{
|
||||
_finder.Setup(x => x.Find()).Returns(baseUrl);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingDownstreamIsReturned(List<HeaderFindAndReplace> downstream)
|
||||
{
|
||||
_result.Downstream.Count.ShouldBe(downstream.Count);
|
||||
|
||||
for (int i = 0; i < _result.Downstream.Count; i++)
|
||||
{
|
||||
var result = _result.Downstream[i];
|
||||
var expected = downstream[i];
|
||||
result.Find.ShouldBe(expected.Find);
|
||||
result.Index.ShouldBe(expected.Index);
|
||||
result.Key.ShouldBe(expected.Key);
|
||||
result.Replace.ShouldBe(expected.Replace);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingUpstreamIsReturned(List<HeaderFindAndReplace> expecteds)
|
||||
{
|
||||
_result.Upstream.Count.ShouldBe(expecteds.Count);
|
||||
|
||||
for (int i = 0; i < _result.Upstream.Count; i++)
|
||||
{
|
||||
var result = _result.Upstream[i];
|
||||
var expected = expecteds[i];
|
||||
result.Find.ShouldBe(expected.Find);
|
||||
result.Index.ShouldBe(expected.Index);
|
||||
result.Key.ShouldBe(expected.Key);
|
||||
result.Replace.ShouldBe(expected.Replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class IdentityServerConfigurationCreatorTests
|
||||
{
|
||||
[Fact]
|
||||
public void happy_path_only_exists_for_test_coverage_even_uncle_bob_probably_wouldnt_test_this()
|
||||
{
|
||||
var result = IdentityServerConfigurationCreator.GetIdentityServerConfiguration("secret");
|
||||
result.ApiName.ShouldBe("admin");
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class IdentityServerConfigurationCreatorTests
|
||||
{
|
||||
[Fact]
|
||||
public void happy_path_only_exists_for_test_coverage_even_uncle_bob_probably_wouldnt_test_this()
|
||||
{
|
||||
var result = IdentityServerConfigurationCreator.GetIdentityServerConfiguration("secret");
|
||||
result.ApiName.ShouldBe("admin");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,101 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class InMemoryConfigurationRepositoryTests
|
||||
{
|
||||
private readonly InMemoryOcelotConfigurationRepository _repo;
|
||||
private IOcelotConfiguration _config;
|
||||
private Response _result;
|
||||
private Response<IOcelotConfiguration> _getResult;
|
||||
|
||||
public InMemoryConfigurationRepositoryTests()
|
||||
{
|
||||
_repo = new InMemoryOcelotConfigurationRepository();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_add_config()
|
||||
{
|
||||
this.Given(x => x.GivenTheConfigurationIs(new FakeConfig("initial", "adminath")))
|
||||
.When(x => x.WhenIAddOrReplaceTheConfig())
|
||||
.Then(x => x.ThenNoErrorsAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_get_config()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsASavedConfiguration())
|
||||
.When(x => x.WhenIGetTheConfiguration())
|
||||
.Then(x => x.ThenTheConfigurationIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsReturned()
|
||||
{
|
||||
_getResult.Data.ReRoutes[0].DownstreamPathTemplate.Value.ShouldBe("initial");
|
||||
}
|
||||
|
||||
private void WhenIGetTheConfiguration()
|
||||
{
|
||||
_getResult = _repo.Get().Result;
|
||||
}
|
||||
|
||||
private void GivenThereIsASavedConfiguration()
|
||||
{
|
||||
GivenTheConfigurationIs(new FakeConfig("initial", "adminath"));
|
||||
WhenIAddOrReplaceTheConfig();
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(IOcelotConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
private void WhenIAddOrReplaceTheConfig()
|
||||
{
|
||||
_result = _repo.AddOrReplace(_config).Result;
|
||||
}
|
||||
|
||||
private void ThenNoErrorsAreReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
||||
class FakeConfig : IOcelotConfiguration
|
||||
{
|
||||
private readonly string _downstreamTemplatePath;
|
||||
|
||||
public FakeConfig(string downstreamTemplatePath, string administrationPath)
|
||||
{
|
||||
_downstreamTemplatePath = downstreamTemplatePath;
|
||||
AdministrationPath = administrationPath;
|
||||
}
|
||||
|
||||
public List<ReRoute> ReRoutes => new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate(_downstreamTemplatePath)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build()
|
||||
};
|
||||
|
||||
public string AdministrationPath {get;}
|
||||
|
||||
public ServiceProviderConfiguration ServiceProviderConfiguration => throw new NotImplementedException();
|
||||
|
||||
public string RequestId {get;}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class InMemoryConfigurationRepositoryTests
|
||||
{
|
||||
private readonly InMemoryOcelotConfigurationRepository _repo;
|
||||
private IOcelotConfiguration _config;
|
||||
private Response _result;
|
||||
private Response<IOcelotConfiguration> _getResult;
|
||||
|
||||
public InMemoryConfigurationRepositoryTests()
|
||||
{
|
||||
_repo = new InMemoryOcelotConfigurationRepository();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_add_config()
|
||||
{
|
||||
this.Given(x => x.GivenTheConfigurationIs(new FakeConfig("initial", "adminath")))
|
||||
.When(x => x.WhenIAddOrReplaceTheConfig())
|
||||
.Then(x => x.ThenNoErrorsAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_get_config()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsASavedConfiguration())
|
||||
.When(x => x.WhenIGetTheConfiguration())
|
||||
.Then(x => x.ThenTheConfigurationIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheConfigurationIsReturned()
|
||||
{
|
||||
_getResult.Data.ReRoutes[0].DownstreamPathTemplate.Value.ShouldBe("initial");
|
||||
}
|
||||
|
||||
private void WhenIGetTheConfiguration()
|
||||
{
|
||||
_getResult = _repo.Get().Result;
|
||||
}
|
||||
|
||||
private void GivenThereIsASavedConfiguration()
|
||||
{
|
||||
GivenTheConfigurationIs(new FakeConfig("initial", "adminath"));
|
||||
WhenIAddOrReplaceTheConfig();
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(IOcelotConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
private void WhenIAddOrReplaceTheConfig()
|
||||
{
|
||||
_result = _repo.AddOrReplace(_config).Result;
|
||||
}
|
||||
|
||||
private void ThenNoErrorsAreReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
||||
class FakeConfig : IOcelotConfiguration
|
||||
{
|
||||
private readonly string _downstreamTemplatePath;
|
||||
|
||||
public FakeConfig(string downstreamTemplatePath, string administrationPath)
|
||||
{
|
||||
_downstreamTemplatePath = downstreamTemplatePath;
|
||||
AdministrationPath = administrationPath;
|
||||
}
|
||||
|
||||
public List<ReRoute> ReRoutes => new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate(_downstreamTemplatePath)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build()
|
||||
};
|
||||
|
||||
public string AdministrationPath {get;}
|
||||
|
||||
public ServiceProviderConfiguration ServiceProviderConfiguration => throw new NotImplementedException();
|
||||
|
||||
public string RequestId {get;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,80 +1,80 @@
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class OcelotConfigurationProviderTests
|
||||
{
|
||||
private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider;
|
||||
private readonly Mock<IOcelotConfigurationRepository> _configurationRepository;
|
||||
private Response<IOcelotConfiguration> _result;
|
||||
|
||||
public OcelotConfigurationProviderTests()
|
||||
{
|
||||
_configurationRepository = new Mock<IOcelotConfigurationRepository>();
|
||||
_ocelotConfigurationProvider = new OcelotConfigurationProvider(_configurationRepository.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_config()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, ""))))
|
||||
.When(x => x.WhenIGetTheConfig())
|
||||
.Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, ""))))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
this.Given(x => x.GivenTheRepoReturns(new ErrorResponse<IOcelotConfiguration>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.When(x => x.WhenIGetTheConfig())
|
||||
.Then(x => x.TheFollowingIsReturned(
|
||||
new ErrorResponse<IOcelotConfiguration>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheRepoReturns(Response<IOcelotConfiguration> config)
|
||||
{
|
||||
_configurationRepository
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(config);
|
||||
}
|
||||
|
||||
private void WhenIGetTheConfig()
|
||||
{
|
||||
_result = _ocelotConfigurationProvider.Get().Result;
|
||||
}
|
||||
|
||||
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)
|
||||
{
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError()
|
||||
: base("blamo", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.Configuration.Repository;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class OcelotConfigurationProviderTests
|
||||
{
|
||||
private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider;
|
||||
private readonly Mock<IOcelotConfigurationRepository> _configurationRepository;
|
||||
private Response<IOcelotConfiguration> _result;
|
||||
|
||||
public OcelotConfigurationProviderTests()
|
||||
{
|
||||
_configurationRepository = new Mock<IOcelotConfigurationRepository>();
|
||||
_ocelotConfigurationProvider = new OcelotConfigurationProvider(_configurationRepository.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_config()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, ""))))
|
||||
.When(x => x.WhenIGetTheConfig())
|
||||
.Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, ""))))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
this.Given(x => x.GivenTheRepoReturns(new ErrorResponse<IOcelotConfiguration>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.When(x => x.WhenIGetTheConfig())
|
||||
.Then(x => x.TheFollowingIsReturned(
|
||||
new ErrorResponse<IOcelotConfiguration>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheRepoReturns(Response<IOcelotConfiguration> config)
|
||||
{
|
||||
_configurationRepository
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(config);
|
||||
}
|
||||
|
||||
private void WhenIGetTheConfig()
|
||||
{
|
||||
_result = _ocelotConfigurationProvider.Get().Result;
|
||||
}
|
||||
|
||||
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)
|
||||
{
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError()
|
||||
: base("blamo", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +1,63 @@
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class QoSOptionsCreatorTests
|
||||
{
|
||||
private QoSOptionsCreator _creator;
|
||||
private FileReRoute _fileReRoute;
|
||||
private QoSOptions _result;
|
||||
|
||||
public QoSOptionsCreatorTests()
|
||||
{
|
||||
_creator = new QoSOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_qos_options()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
ExceptionsAllowedBeforeBreaking = 1,
|
||||
DurationOfBreak = 1,
|
||||
TimeoutValue = 1
|
||||
}
|
||||
};
|
||||
var expected = new QoSOptionsBuilder()
|
||||
.WithDurationOfBreak(1)
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.WithTimeoutValue(1)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(QoSOptions expected)
|
||||
{
|
||||
_result.DurationOfBreak.ShouldBe(expected.DurationOfBreak);
|
||||
_result.ExceptionsAllowedBeforeBreaking.ShouldBe(expected.ExceptionsAllowedBeforeBreaking);
|
||||
_result.TimeoutValue.ShouldBe(expected.TimeoutValue);
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class QoSOptionsCreatorTests
|
||||
{
|
||||
private QoSOptionsCreator _creator;
|
||||
private FileReRoute _fileReRoute;
|
||||
private QoSOptions _result;
|
||||
|
||||
public QoSOptionsCreatorTests()
|
||||
{
|
||||
_creator = new QoSOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_qos_options()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
ExceptionsAllowedBeforeBreaking = 1,
|
||||
DurationOfBreak = 1,
|
||||
TimeoutValue = 1
|
||||
}
|
||||
};
|
||||
var expected = new QoSOptionsBuilder()
|
||||
.WithDurationOfBreak(1)
|
||||
.WithExceptionsAllowedBeforeBreaking(1)
|
||||
.WithTimeoutValue(1)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(QoSOptions expected)
|
||||
{
|
||||
_result.DurationOfBreak.ShouldBe(expected.DurationOfBreak);
|
||||
_result.ExceptionsAllowedBeforeBreaking.ShouldBe(expected.ExceptionsAllowedBeforeBreaking);
|
||||
_result.TimeoutValue.ShouldBe(expected.TimeoutValue);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,108 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class RateLimitOptionsCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private bool _enabled;
|
||||
private RateLimitOptionsCreator _creator;
|
||||
private RateLimitOptions _result;
|
||||
|
||||
public RateLimitOptionsCreatorTests()
|
||||
{
|
||||
_creator = new RateLimitOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_rate_limit_options()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
ClientWhitelist = new List<string>(),
|
||||
Period = "Period",
|
||||
Limit = 1,
|
||||
PeriodTimespan = 1,
|
||||
EnableRateLimiting = true
|
||||
}
|
||||
};
|
||||
var fileGlobalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitOptions
|
||||
{
|
||||
ClientIdHeader = "ClientIdHeader",
|
||||
DisableRateLimitHeaders = true,
|
||||
QuotaExceededMessage = "QuotaExceededMessage",
|
||||
RateLimitCounterPrefix = "RateLimitCounterPrefix",
|
||||
HttpStatusCode = 200
|
||||
}
|
||||
};
|
||||
var expected = new RateLimitOptionsBuilder()
|
||||
.WithClientIdHeader("ClientIdHeader")
|
||||
.WithClientWhiteList(fileReRoute.RateLimitOptions.ClientWhitelist)
|
||||
.WithDisableRateLimitHeaders(true)
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithHttpStatusCode(200)
|
||||
.WithQuotaExceededMessage("QuotaExceededMessage")
|
||||
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
|
||||
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
||||
fileReRoute.RateLimitOptions.PeriodTimespan,
|
||||
fileReRoute.RateLimitOptions.Limit))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.And(x => x.GivenTheFollowingFileGlobalConfig(fileGlobalConfig))
|
||||
.And(x => x.GivenRateLimitingIsEnabled())
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
||||
{
|
||||
_fileGlobalConfig = fileGlobalConfig;
|
||||
}
|
||||
|
||||
private void GivenRateLimitingIsEnabled()
|
||||
{
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute, _fileGlobalConfig, _enabled);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(RateLimitOptions expected)
|
||||
{
|
||||
_result.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
|
||||
_result.ClientWhitelist.ShouldBe(expected.ClientWhitelist);
|
||||
_result.DisableRateLimitHeaders.ShouldBe(expected.DisableRateLimitHeaders);
|
||||
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
_result.HttpStatusCode.ShouldBe(expected.HttpStatusCode);
|
||||
_result.QuotaExceededMessage.ShouldBe(expected.QuotaExceededMessage);
|
||||
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
|
||||
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
|
||||
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
|
||||
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class RateLimitOptionsCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private bool _enabled;
|
||||
private RateLimitOptionsCreator _creator;
|
||||
private RateLimitOptions _result;
|
||||
|
||||
public RateLimitOptionsCreatorTests()
|
||||
{
|
||||
_creator = new RateLimitOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_rate_limit_options()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
ClientWhitelist = new List<string>(),
|
||||
Period = "Period",
|
||||
Limit = 1,
|
||||
PeriodTimespan = 1,
|
||||
EnableRateLimiting = true
|
||||
}
|
||||
};
|
||||
var fileGlobalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitOptions
|
||||
{
|
||||
ClientIdHeader = "ClientIdHeader",
|
||||
DisableRateLimitHeaders = true,
|
||||
QuotaExceededMessage = "QuotaExceededMessage",
|
||||
RateLimitCounterPrefix = "RateLimitCounterPrefix",
|
||||
HttpStatusCode = 200
|
||||
}
|
||||
};
|
||||
var expected = new RateLimitOptionsBuilder()
|
||||
.WithClientIdHeader("ClientIdHeader")
|
||||
.WithClientWhiteList(fileReRoute.RateLimitOptions.ClientWhitelist)
|
||||
.WithDisableRateLimitHeaders(true)
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithHttpStatusCode(200)
|
||||
.WithQuotaExceededMessage("QuotaExceededMessage")
|
||||
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
|
||||
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
||||
fileReRoute.RateLimitOptions.PeriodTimespan,
|
||||
fileReRoute.RateLimitOptions.Limit))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.And(x => x.GivenTheFollowingFileGlobalConfig(fileGlobalConfig))
|
||||
.And(x => x.GivenRateLimitingIsEnabled())
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
||||
{
|
||||
_fileGlobalConfig = fileGlobalConfig;
|
||||
}
|
||||
|
||||
private void GivenRateLimitingIsEnabled()
|
||||
{
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute, _fileGlobalConfig, _enabled);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(RateLimitOptions expected)
|
||||
{
|
||||
_result.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
|
||||
_result.ClientWhitelist.ShouldBe(expected.ClientWhitelist);
|
||||
_result.DisableRateLimitHeaders.ShouldBe(expected.DisableRateLimitHeaders);
|
||||
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
_result.HttpStatusCode.ShouldBe(expected.HttpStatusCode);
|
||||
_result.QuotaExceededMessage.ShouldBe(expected.QuotaExceededMessage);
|
||||
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
|
||||
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
|
||||
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
|
||||
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,84 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ReRouteOptionsCreatorTests
|
||||
{
|
||||
private ReRouteOptionsCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private ReRouteOptions _result;
|
||||
|
||||
public ReRouteOptionsCreatorTests()
|
||||
{
|
||||
_creator = new ReRouteOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_re_route_options()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true
|
||||
},
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
ExceptionsAllowedBeforeBreaking = 1,
|
||||
TimeoutValue = 1
|
||||
},
|
||||
AuthenticationOptions = new FileAuthenticationOptions()
|
||||
{
|
||||
AuthenticationProviderKey = "Test"
|
||||
},
|
||||
RouteClaimsRequirement = new Dictionary<string, string>()
|
||||
{
|
||||
{"",""}
|
||||
},
|
||||
FileCacheOptions = new FileCacheOptions
|
||||
{
|
||||
TtlSeconds = 1
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new ReRouteOptionsBuilder()
|
||||
.WithIsAuthenticated(true)
|
||||
.WithIsAuthorised(true)
|
||||
.WithIsCached(true)
|
||||
.WithIsQos(true)
|
||||
.WithRateLimiting(true)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowing(reRoute))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(ReRouteOptions expected)
|
||||
{
|
||||
_result.IsAuthenticated.ShouldBe(expected.IsAuthenticated);
|
||||
_result.IsAuthorised.ShouldBe(expected.IsAuthorised);
|
||||
_result.IsQos.ShouldBe(expected.IsQos);
|
||||
_result.IsCached.ShouldBe(expected.IsCached);
|
||||
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ReRouteOptionsCreatorTests
|
||||
{
|
||||
private ReRouteOptionsCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private ReRouteOptions _result;
|
||||
|
||||
public ReRouteOptionsCreatorTests()
|
||||
{
|
||||
_creator = new ReRouteOptionsCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_re_route_options()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
RateLimitOptions = new FileRateLimitRule
|
||||
{
|
||||
EnableRateLimiting = true
|
||||
},
|
||||
QoSOptions = new FileQoSOptions
|
||||
{
|
||||
ExceptionsAllowedBeforeBreaking = 1,
|
||||
TimeoutValue = 1
|
||||
},
|
||||
AuthenticationOptions = new FileAuthenticationOptions()
|
||||
{
|
||||
AuthenticationProviderKey = "Test"
|
||||
},
|
||||
RouteClaimsRequirement = new Dictionary<string, string>()
|
||||
{
|
||||
{"",""}
|
||||
},
|
||||
FileCacheOptions = new FileCacheOptions
|
||||
{
|
||||
TtlSeconds = 1
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new ReRouteOptionsBuilder()
|
||||
.WithIsAuthenticated(true)
|
||||
.WithIsAuthorised(true)
|
||||
.WithIsCached(true)
|
||||
.WithIsQos(true)
|
||||
.WithRateLimiting(true)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowing(reRoute))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(FileReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(ReRouteOptions expected)
|
||||
{
|
||||
_result.IsAuthenticated.ShouldBe(expected.IsAuthenticated);
|
||||
_result.IsAuthorised.ShouldBe(expected.IsAuthorised);
|
||||
_result.IsQos.ShouldBe(expected.IsQos);
|
||||
_result.IsCached.ShouldBe(expected.IsCached);
|
||||
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,92 +1,92 @@
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class RequestIdKeyCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private string _result;
|
||||
private RequestIdKeyCreator _creator;
|
||||
|
||||
public RequestIdKeyCreatorTests()
|
||||
{
|
||||
_creator = new RequestIdKeyCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_global_configuration()
|
||||
{
|
||||
var reRoute = new FileReRoute();
|
||||
var globalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_re_route_specific()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
var globalConfig = new FileGlobalConfiguration();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_re_route_over_global_specific()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
var globalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RequestIdKey = "test"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration globalConfig)
|
||||
{
|
||||
_fileGlobalConfig = globalConfig;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute, _fileGlobalConfig);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class RequestIdKeyCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private FileGlobalConfiguration _fileGlobalConfig;
|
||||
private string _result;
|
||||
private RequestIdKeyCreator _creator;
|
||||
|
||||
public RequestIdKeyCreatorTests()
|
||||
{
|
||||
_creator = new RequestIdKeyCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_global_configuration()
|
||||
{
|
||||
var reRoute = new FileReRoute();
|
||||
var globalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_re_route_specific()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
var globalConfig = new FileGlobalConfiguration();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_re_route_over_global_specific()
|
||||
{
|
||||
var reRoute = new FileReRoute
|
||||
{
|
||||
RequestIdKey = "cheese"
|
||||
};
|
||||
var globalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
RequestIdKey = "test"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_fileReRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration globalConfig)
|
||||
{
|
||||
_fileGlobalConfig = globalConfig;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_fileReRoute, _fileGlobalConfig);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,70 +1,70 @@
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ServiceProviderCreatorTests
|
||||
{
|
||||
private ServiceProviderConfigurationCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private FileGlobalConfiguration _globalConfig;
|
||||
private ServiceProviderConfiguration _result;
|
||||
|
||||
public ServiceProviderCreatorTests()
|
||||
{
|
||||
_creator = new ServiceProviderConfigurationCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_provider_config()
|
||||
{
|
||||
var reRoute = new FileReRoute();
|
||||
|
||||
var globalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
Port = 1234
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new ServiceProviderConfigurationBuilder()
|
||||
.WithServiceDiscoveryProviderHost("127.0.0.1")
|
||||
.WithServiceDiscoveryProviderPort(1234)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheConfigIs(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_reRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
||||
{
|
||||
_globalConfig = fileGlobalConfig;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_globalConfig);
|
||||
}
|
||||
|
||||
private void ThenTheConfigIs(ServiceProviderConfiguration expected)
|
||||
{
|
||||
_result.ServiceProviderHost.ShouldBe(expected.ServiceProviderHost);
|
||||
_result.ServiceProviderPort.ShouldBe(expected.ServiceProviderPort);
|
||||
}
|
||||
}
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class ServiceProviderCreatorTests
|
||||
{
|
||||
private ServiceProviderConfigurationCreator _creator;
|
||||
private FileReRoute _reRoute;
|
||||
private FileGlobalConfiguration _globalConfig;
|
||||
private ServiceProviderConfiguration _result;
|
||||
|
||||
public ServiceProviderCreatorTests()
|
||||
{
|
||||
_creator = new ServiceProviderConfigurationCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_service_provider_config()
|
||||
{
|
||||
var reRoute = new FileReRoute();
|
||||
|
||||
var globalConfig = new FileGlobalConfiguration
|
||||
{
|
||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
Port = 1234
|
||||
}
|
||||
};
|
||||
|
||||
var expected = new ServiceProviderConfigurationBuilder()
|
||||
.WithServiceDiscoveryProviderHost("127.0.0.1")
|
||||
.WithServiceDiscoveryProviderPort(1234)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||
.When(x => x.WhenICreate())
|
||||
.Then(x => x.ThenTheConfigIs(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_reRoute = fileReRoute;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
||||
{
|
||||
_globalConfig = fileGlobalConfig;
|
||||
}
|
||||
|
||||
private void WhenICreate()
|
||||
{
|
||||
_result = _creator.Create(_globalConfig);
|
||||
}
|
||||
|
||||
private void ThenTheConfigIs(ServiceProviderConfiguration expected)
|
||||
{
|
||||
_result.ServiceProviderHost.ShouldBe(expected.ServiceProviderHost);
|
||||
_result.ServiceProviderPort.ShouldBe(expected.ServiceProviderPort);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,184 +1,184 @@
|
||||
using System;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class UpstreamTemplatePatternCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private UpstreamTemplatePatternCreator _creator;
|
||||
private UpstreamPathTemplate _result;
|
||||
|
||||
public UpstreamTemplatePatternCreatorTests()
|
||||
{
|
||||
_creator = new UpstreamTemplatePatternCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||
ReRouteIsCaseSensitive = false
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/[0-9a-zA-Z].*$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_match_forward_slash_or_no_forward_slash_if_template_end_with_forward_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/",
|
||||
ReRouteIsCaseSensitive = false
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/[0-9a-zA-Z].*$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*/variants/[0-9a-zA-Z].*$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*/variants/[0-9a-zA-Z].*(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_to_end_of_string()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_to_end_of_string_when_slash_and_placeholder()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{url}"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_starts_with_placeholder_then_has_another_later()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{productId}/products/variants/{variantId}/",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/[0-9a-zA-Z].*/products/variants/[0-9a-zA-Z].*(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_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);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
public class UpstreamTemplatePatternCreatorTests
|
||||
{
|
||||
private FileReRoute _fileReRoute;
|
||||
private UpstreamTemplatePatternCreator _creator;
|
||||
private UpstreamPathTemplate _result;
|
||||
|
||||
public UpstreamTemplatePatternCreatorTests()
|
||||
{
|
||||
_creator = new UpstreamTemplatePatternCreator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||
ReRouteIsCaseSensitive = false
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/[0-9a-zA-Z].*$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_match_forward_slash_or_no_forward_slash_if_template_end_with_forward_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/",
|
||||
ReRouteIsCaseSensitive = false
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/PRODUCTS/{productId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/[0-9a-zA-Z].*$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*/variants/[0-9a-zA-Z].*$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*/variants/[0-9a-zA-Z].*(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_to_end_of_string()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_matches_to_end_of_string_when_slash_and_placeholder()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{url}"
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
|
||||
.And(x => ThenThePriorityIs(0))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_create_template_pattern_that_starts_with_placeholder_then_has_another_later()
|
||||
{
|
||||
var fileReRoute = new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/{productId}/products/variants/{variantId}/",
|
||||
ReRouteIsCaseSensitive = true
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||
.When(x => x.WhenICreateTheTemplatePattern())
|
||||
.Then(x => x.ThenTheFollowingIsReturned("^/[0-9a-zA-Z].*/products/variants/[0-9a-zA-Z].*(/|)$"))
|
||||
.And(x => ThenThePriorityIs(1))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
||||
{
|
||||
_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,195 +1,195 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Raft;
|
||||
using Rafty.Concensus;
|
||||
using Newtonsoft.Json;
|
||||
using Rafty.FiniteStateMachine;
|
||||
using Ocelot.Configuration;
|
||||
|
||||
namespace Ocelot.UnitTests.Controllers
|
||||
{
|
||||
public class FileConfigurationControllerTests
|
||||
{
|
||||
private FileConfigurationController _controller;
|
||||
private Mock<IFileConfigurationProvider> _configGetter;
|
||||
private Mock<IFileConfigurationSetter> _configSetter;
|
||||
private IActionResult _result;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private Mock<IServiceProvider> _provider;
|
||||
private Mock<INode> _node;
|
||||
|
||||
public FileConfigurationControllerTests()
|
||||
{
|
||||
_provider = new Mock<IServiceProvider>();
|
||||
_configGetter = new Mock<IFileConfigurationProvider>();
|
||||
_configSetter = new Mock<IFileConfigurationSetter>();
|
||||
_controller = new FileConfigurationController(_configGetter.Object, _configSetter.Object, _provider.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_file_configuration()
|
||||
{
|
||||
var expected = new Responses.OkResponse<FileConfiguration>(new FileConfiguration());
|
||||
|
||||
this.Given(x => x.GivenTheGetConfigurationReturns(expected))
|
||||
.When(x => x.WhenIGetTheFileConfiguration())
|
||||
.Then(x => x.TheTheGetFileConfigurationIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_cannot_get_config()
|
||||
{
|
||||
var expected = new Responses.ErrorResponse<FileConfiguration>(It.IsAny<Error>());
|
||||
|
||||
this.Given(x => x.GivenTheGetConfigurationReturns(expected))
|
||||
.When(x => x.WhenIGetTheFileConfiguration())
|
||||
.Then(x => x.TheTheGetFileConfigurationIsCalledCorrectly())
|
||||
.And(x => x.ThenTheResponseIs<BadRequestObjectResult>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_post_file_configuration()
|
||||
{
|
||||
var expected = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFileConfiguration(expected))
|
||||
.And(x => GivenTheConfigSetterReturns(new OkResponse()))
|
||||
.When(x => WhenIPostTheFileConfiguration())
|
||||
.Then(x => x.ThenTheConfigrationSetterIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_post_file_configuration_using_raft_node()
|
||||
{
|
||||
var expected = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFileConfiguration(expected))
|
||||
.And(x => GivenARaftNodeIsRegistered())
|
||||
.And(x => GivenTheNodeReturnsOK())
|
||||
.And(x => GivenTheConfigSetterReturns(new OkResponse()))
|
||||
.When(x => WhenIPostTheFileConfiguration())
|
||||
.Then(x => x.ThenTheNodeIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_cannot_set_config_using_raft_node()
|
||||
{
|
||||
var expected = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFileConfiguration(expected))
|
||||
.And(x => GivenARaftNodeIsRegistered())
|
||||
.And(x => GivenTheNodeReturnsError())
|
||||
.When(x => WhenIPostTheFileConfiguration())
|
||||
.Then(x => ThenTheResponseIs<BadRequestObjectResult>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_cannot_set_config()
|
||||
{
|
||||
var expected = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFileConfiguration(expected))
|
||||
.And(x => GivenTheConfigSetterReturns(new ErrorResponse(new FakeError())))
|
||||
.When(x => WhenIPostTheFileConfiguration())
|
||||
.Then(x => x.ThenTheConfigrationSetterIsCalledCorrectly())
|
||||
.And(x => ThenTheResponseIs<BadRequestObjectResult>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
private void ThenTheNodeIsCalledCorrectly()
|
||||
{
|
||||
_node.Verify(x => x.Accept(It.IsAny<UpdateFileConfiguration>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenARaftNodeIsRegistered()
|
||||
{
|
||||
_node = new Mock<INode>();
|
||||
_provider
|
||||
.Setup(x => x.GetService(typeof(INode)))
|
||||
.Returns(_node.Object);
|
||||
}
|
||||
|
||||
private void GivenTheNodeReturnsOK()
|
||||
{
|
||||
_node
|
||||
.Setup(x => x.Accept(It.IsAny<UpdateFileConfiguration>()))
|
||||
.Returns(new Rafty.Concensus.OkResponse<UpdateFileConfiguration>(new UpdateFileConfiguration(new FileConfiguration())));
|
||||
}
|
||||
|
||||
private void GivenTheNodeReturnsError()
|
||||
{
|
||||
_node
|
||||
.Setup(x => x.Accept(It.IsAny<UpdateFileConfiguration>()))
|
||||
.Returns(new Rafty.Concensus.ErrorResponse<UpdateFileConfiguration>("error", new UpdateFileConfiguration(new FileConfiguration())));
|
||||
}
|
||||
|
||||
private void GivenTheConfigSetterReturns(Response response)
|
||||
{
|
||||
_configSetter
|
||||
.Setup(x => x.Set(It.IsAny<FileConfiguration>()))
|
||||
.ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void ThenTheConfigrationSetterIsCalledCorrectly()
|
||||
{
|
||||
_configSetter
|
||||
.Verify(x => x.Set(_fileConfiguration), Times.Once);
|
||||
}
|
||||
|
||||
private void WhenIPostTheFileConfiguration()
|
||||
{
|
||||
_result = _controller.Post(_fileConfiguration).Result;
|
||||
}
|
||||
|
||||
private void GivenTheFileConfiguration(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void ThenTheResponseIs<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void GivenTheGetConfigurationReturns(Ocelot.Responses.Response<FileConfiguration> fileConfiguration)
|
||||
{
|
||||
_configGetter
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(fileConfiguration);
|
||||
}
|
||||
|
||||
private void WhenIGetTheFileConfiguration()
|
||||
{
|
||||
_result = _controller.Get().Result;
|
||||
}
|
||||
|
||||
private void TheTheGetFileConfigurationIsCalledCorrectly()
|
||||
{
|
||||
_configGetter
|
||||
.Verify(x => x.Get(), Times.Once);
|
||||
}
|
||||
|
||||
class FakeError : Error
|
||||
{
|
||||
public FakeError() : base(string.Empty, OcelotErrorCode.CannotAddDataError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Raft;
|
||||
using Rafty.Concensus;
|
||||
using Newtonsoft.Json;
|
||||
using Rafty.FiniteStateMachine;
|
||||
using Ocelot.Configuration;
|
||||
|
||||
namespace Ocelot.UnitTests.Controllers
|
||||
{
|
||||
public class FileConfigurationControllerTests
|
||||
{
|
||||
private FileConfigurationController _controller;
|
||||
private Mock<IFileConfigurationProvider> _configGetter;
|
||||
private Mock<IFileConfigurationSetter> _configSetter;
|
||||
private IActionResult _result;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private Mock<IServiceProvider> _provider;
|
||||
private Mock<INode> _node;
|
||||
|
||||
public FileConfigurationControllerTests()
|
||||
{
|
||||
_provider = new Mock<IServiceProvider>();
|
||||
_configGetter = new Mock<IFileConfigurationProvider>();
|
||||
_configSetter = new Mock<IFileConfigurationSetter>();
|
||||
_controller = new FileConfigurationController(_configGetter.Object, _configSetter.Object, _provider.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_file_configuration()
|
||||
{
|
||||
var expected = new Responses.OkResponse<FileConfiguration>(new FileConfiguration());
|
||||
|
||||
this.Given(x => x.GivenTheGetConfigurationReturns(expected))
|
||||
.When(x => x.WhenIGetTheFileConfiguration())
|
||||
.Then(x => x.TheTheGetFileConfigurationIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_cannot_get_config()
|
||||
{
|
||||
var expected = new Responses.ErrorResponse<FileConfiguration>(It.IsAny<Error>());
|
||||
|
||||
this.Given(x => x.GivenTheGetConfigurationReturns(expected))
|
||||
.When(x => x.WhenIGetTheFileConfiguration())
|
||||
.Then(x => x.TheTheGetFileConfigurationIsCalledCorrectly())
|
||||
.And(x => x.ThenTheResponseIs<BadRequestObjectResult>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_post_file_configuration()
|
||||
{
|
||||
var expected = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFileConfiguration(expected))
|
||||
.And(x => GivenTheConfigSetterReturns(new OkResponse()))
|
||||
.When(x => WhenIPostTheFileConfiguration())
|
||||
.Then(x => x.ThenTheConfigrationSetterIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_post_file_configuration_using_raft_node()
|
||||
{
|
||||
var expected = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFileConfiguration(expected))
|
||||
.And(x => GivenARaftNodeIsRegistered())
|
||||
.And(x => GivenTheNodeReturnsOK())
|
||||
.And(x => GivenTheConfigSetterReturns(new OkResponse()))
|
||||
.When(x => WhenIPostTheFileConfiguration())
|
||||
.Then(x => x.ThenTheNodeIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_cannot_set_config_using_raft_node()
|
||||
{
|
||||
var expected = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFileConfiguration(expected))
|
||||
.And(x => GivenARaftNodeIsRegistered())
|
||||
.And(x => GivenTheNodeReturnsError())
|
||||
.When(x => WhenIPostTheFileConfiguration())
|
||||
.Then(x => ThenTheResponseIs<BadRequestObjectResult>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_cannot_set_config()
|
||||
{
|
||||
var expected = new FileConfiguration();
|
||||
|
||||
this.Given(x => GivenTheFileConfiguration(expected))
|
||||
.And(x => GivenTheConfigSetterReturns(new ErrorResponse(new FakeError())))
|
||||
.When(x => WhenIPostTheFileConfiguration())
|
||||
.Then(x => x.ThenTheConfigrationSetterIsCalledCorrectly())
|
||||
.And(x => ThenTheResponseIs<BadRequestObjectResult>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
private void ThenTheNodeIsCalledCorrectly()
|
||||
{
|
||||
_node.Verify(x => x.Accept(It.IsAny<UpdateFileConfiguration>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenARaftNodeIsRegistered()
|
||||
{
|
||||
_node = new Mock<INode>();
|
||||
_provider
|
||||
.Setup(x => x.GetService(typeof(INode)))
|
||||
.Returns(_node.Object);
|
||||
}
|
||||
|
||||
private void GivenTheNodeReturnsOK()
|
||||
{
|
||||
_node
|
||||
.Setup(x => x.Accept(It.IsAny<UpdateFileConfiguration>()))
|
||||
.Returns(new Rafty.Concensus.OkResponse<UpdateFileConfiguration>(new UpdateFileConfiguration(new FileConfiguration())));
|
||||
}
|
||||
|
||||
private void GivenTheNodeReturnsError()
|
||||
{
|
||||
_node
|
||||
.Setup(x => x.Accept(It.IsAny<UpdateFileConfiguration>()))
|
||||
.Returns(new Rafty.Concensus.ErrorResponse<UpdateFileConfiguration>("error", new UpdateFileConfiguration(new FileConfiguration())));
|
||||
}
|
||||
|
||||
private void GivenTheConfigSetterReturns(Response response)
|
||||
{
|
||||
_configSetter
|
||||
.Setup(x => x.Set(It.IsAny<FileConfiguration>()))
|
||||
.ReturnsAsync(response);
|
||||
}
|
||||
|
||||
private void ThenTheConfigrationSetterIsCalledCorrectly()
|
||||
{
|
||||
_configSetter
|
||||
.Verify(x => x.Set(_fileConfiguration), Times.Once);
|
||||
}
|
||||
|
||||
private void WhenIPostTheFileConfiguration()
|
||||
{
|
||||
_result = _controller.Post(_fileConfiguration).Result;
|
||||
}
|
||||
|
||||
private void GivenTheFileConfiguration(FileConfiguration fileConfiguration)
|
||||
{
|
||||
_fileConfiguration = fileConfiguration;
|
||||
}
|
||||
|
||||
private void ThenTheResponseIs<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void GivenTheGetConfigurationReturns(Ocelot.Responses.Response<FileConfiguration> fileConfiguration)
|
||||
{
|
||||
_configGetter
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(fileConfiguration);
|
||||
}
|
||||
|
||||
private void WhenIGetTheFileConfiguration()
|
||||
{
|
||||
_result = _controller.Get().Result;
|
||||
}
|
||||
|
||||
private void TheTheGetFileConfigurationIsCalledCorrectly()
|
||||
{
|
||||
_configGetter
|
||||
.Verify(x => x.Get(), Times.Once);
|
||||
}
|
||||
|
||||
class FakeError : Error
|
||||
{
|
||||
public FakeError() : base(string.Empty, OcelotErrorCode.CannotAddDataError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,45 @@
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Ocelot.Cache;
|
||||
using System;
|
||||
using Moq;
|
||||
using System.Net.Http;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Ocelot.UnitTests.Controllers
|
||||
{
|
||||
public class OutputCacheControllerTests
|
||||
{
|
||||
private OutputCacheController _controller;
|
||||
private Mock<IOcelotCache<CachedResponse>> _cache;
|
||||
private IActionResult _result;
|
||||
|
||||
public OutputCacheControllerTests()
|
||||
{
|
||||
_cache = new Mock<IOcelotCache<CachedResponse>>();
|
||||
_controller = new OutputCacheController(_cache.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_delete_key()
|
||||
{
|
||||
this.When(_ => WhenIDeleteTheKey("a"))
|
||||
.Then(_ => ThenTheKeyIsDeleted("a"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheKeyIsDeleted(string key)
|
||||
{
|
||||
_result.ShouldBeOfType<NoContentResult>();
|
||||
_cache
|
||||
.Verify(x => x.ClearRegion(key), Times.Once);
|
||||
}
|
||||
|
||||
private void WhenIDeleteTheKey(string key)
|
||||
{
|
||||
_result = _controller.Delete(key);
|
||||
}
|
||||
}
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Ocelot.Cache;
|
||||
using System;
|
||||
using Moq;
|
||||
using System.Net.Http;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Ocelot.UnitTests.Controllers
|
||||
{
|
||||
public class OutputCacheControllerTests
|
||||
{
|
||||
private OutputCacheController _controller;
|
||||
private Mock<IOcelotCache<CachedResponse>> _cache;
|
||||
private IActionResult _result;
|
||||
|
||||
public OutputCacheControllerTests()
|
||||
{
|
||||
_cache = new Mock<IOcelotCache<CachedResponse>>();
|
||||
_controller = new OutputCacheController(_cache.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_delete_key()
|
||||
{
|
||||
this.When(_ => WhenIDeleteTheKey("a"))
|
||||
.Then(_ => ThenTheKeyIsDeleted("a"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheKeyIsDeleted(string key)
|
||||
{
|
||||
_result.ShouldBeOfType<NoContentResult>();
|
||||
_cache
|
||||
.Verify(x => x.ClearRegion(key), Times.Once);
|
||||
}
|
||||
|
||||
private void WhenIDeleteTheKey(string key)
|
||||
{
|
||||
_result = _controller.Delete(key);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,225 +1,225 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using CacheManager.Core;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Internal;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Logging;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DependencyInjection
|
||||
{
|
||||
public class OcelotBuilderTests
|
||||
{
|
||||
private IServiceCollection _services;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private IConfiguration _configRoot;
|
||||
private IOcelotBuilder _ocelotBuilder;
|
||||
private int _maxRetries;
|
||||
|
||||
public OcelotBuilderTests()
|
||||
{
|
||||
IWebHostBuilder builder = new WebHostBuilder();
|
||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||
_services = new ServiceCollection();
|
||||
_services.AddSingleton(builder);
|
||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
||||
_services.AddSingleton<IConfiguration>(_configRoot);
|
||||
_maxRetries = 100;
|
||||
}
|
||||
private Exception _ex;
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_services()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServices())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ocelot_builder()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServices())
|
||||
.Then(x => ThenAnOcelotBuilderIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_cache_manager()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenISetUpCacheManager())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.And(x => OnlyOneVersionOfEachCacheIsRegistered())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_consul()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenISetUpConsul())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_rafty()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenISetUpRafty())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.Then(x => ThenTheCorrectAdminPathIsRegitered())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_logger_factory()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenIValidateScopes())
|
||||
.When(x => WhenIAccessLoggerFactory())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_without_passing_in_config()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServicesWithoutConfig())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheCorrectAdminPathIsRegitered()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var path = _serviceProvider.GetService<IAdministrationPath>();
|
||||
path.Path.ShouldBe("/administration");
|
||||
}
|
||||
|
||||
private void OnlyOneVersionOfEachCacheIsRegistered()
|
||||
{
|
||||
var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
|
||||
var outputCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<CachedResponse>));
|
||||
var thing = (CacheManager.Core.ICacheManager<CachedResponse>)outputCacheManager.ImplementationInstance;
|
||||
thing.Configuration.MaxRetries.ShouldBe(_maxRetries);
|
||||
|
||||
var ocelotConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<IOcelotConfiguration>));
|
||||
var ocelotConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<IOcelotConfiguration>));
|
||||
|
||||
var fileConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<FileConfiguration>));
|
||||
var fileConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<FileConfiguration>));
|
||||
}
|
||||
|
||||
private void WhenISetUpConsul()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder.AddStoreOcelotConfigurationInConsul();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenISetUpRafty()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder.AddAdministration("/administration", "secret").AddRafty();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenAnOcelotBuilderIsReturned()
|
||||
{
|
||||
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
|
||||
}
|
||||
|
||||
private void WhenISetUpOcelotServices()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder = _services.AddOcelot(_configRoot);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenISetUpOcelotServicesWithoutConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder = _services.AddOcelot();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenISetUpCacheManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder.AddCacheManager(x => {
|
||||
x.WithMaxRetries(_maxRetries);
|
||||
x.WithDictionaryHandle();
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenIAccessLoggerFactory()
|
||||
{
|
||||
try
|
||||
{
|
||||
var logger = _serviceProvider.GetService<IFileConfigurationSetter>();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenIValidateScopes()
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenAnExceptionIsntThrown()
|
||||
{
|
||||
_ex.ShouldBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using CacheManager.Core;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Internal;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.File;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Logging;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DependencyInjection
|
||||
{
|
||||
public class OcelotBuilderTests
|
||||
{
|
||||
private IServiceCollection _services;
|
||||
private IServiceProvider _serviceProvider;
|
||||
private IConfiguration _configRoot;
|
||||
private IOcelotBuilder _ocelotBuilder;
|
||||
private int _maxRetries;
|
||||
|
||||
public OcelotBuilderTests()
|
||||
{
|
||||
IWebHostBuilder builder = new WebHostBuilder();
|
||||
_configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||
_services = new ServiceCollection();
|
||||
_services.AddSingleton(builder);
|
||||
_services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
|
||||
_services.AddSingleton<IConfiguration>(_configRoot);
|
||||
_maxRetries = 100;
|
||||
}
|
||||
private Exception _ex;
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_services()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServices())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ocelot_builder()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServices())
|
||||
.Then(x => ThenAnOcelotBuilderIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_cache_manager()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenISetUpCacheManager())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.And(x => OnlyOneVersionOfEachCacheIsRegistered())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_consul()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenISetUpConsul())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_rafty()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenISetUpRafty())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.Then(x => ThenTheCorrectAdminPathIsRegitered())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_logger_factory()
|
||||
{
|
||||
this.Given(x => WhenISetUpOcelotServices())
|
||||
.When(x => WhenIValidateScopes())
|
||||
.When(x => WhenIAccessLoggerFactory())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_without_passing_in_config()
|
||||
{
|
||||
this.When(x => WhenISetUpOcelotServicesWithoutConfig())
|
||||
.Then(x => ThenAnExceptionIsntThrown())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheCorrectAdminPathIsRegitered()
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider();
|
||||
var path = _serviceProvider.GetService<IAdministrationPath>();
|
||||
path.Path.ShouldBe("/administration");
|
||||
}
|
||||
|
||||
private void OnlyOneVersionOfEachCacheIsRegistered()
|
||||
{
|
||||
var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
|
||||
var outputCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<CachedResponse>));
|
||||
var thing = (CacheManager.Core.ICacheManager<CachedResponse>)outputCacheManager.ImplementationInstance;
|
||||
thing.Configuration.MaxRetries.ShouldBe(_maxRetries);
|
||||
|
||||
var ocelotConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<IOcelotConfiguration>));
|
||||
var ocelotConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<IOcelotConfiguration>));
|
||||
|
||||
var fileConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<FileConfiguration>));
|
||||
var fileConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<FileConfiguration>));
|
||||
}
|
||||
|
||||
private void WhenISetUpConsul()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder.AddStoreOcelotConfigurationInConsul();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenISetUpRafty()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder.AddAdministration("/administration", "secret").AddRafty();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenAnOcelotBuilderIsReturned()
|
||||
{
|
||||
_ocelotBuilder.ShouldBeOfType<OcelotBuilder>();
|
||||
}
|
||||
|
||||
private void WhenISetUpOcelotServices()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder = _services.AddOcelot(_configRoot);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenISetUpOcelotServicesWithoutConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder = _services.AddOcelot();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenISetUpCacheManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
_ocelotBuilder.AddCacheManager(x => {
|
||||
x.WithMaxRetries(_maxRetries);
|
||||
x.WithDictionaryHandle();
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenIAccessLoggerFactory()
|
||||
{
|
||||
try
|
||||
{
|
||||
var logger = _serviceProvider.GetService<IFileConfigurationSetter>();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenIValidateScopes()
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceProvider = _services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_ex = e;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenAnExceptionIsntThrown()
|
||||
{
|
||||
_ex.ShouldBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,91 +1,91 @@
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DownstreamRouteFinderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IDownstreamRouteFinder> _downstreamRouteFinder;
|
||||
private readonly Mock<IOcelotConfigurationProvider> _provider;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private IOcelotConfiguration _config;
|
||||
|
||||
public DownstreamRouteFinderMiddlewareTests()
|
||||
{
|
||||
_provider = new Mock<IOcelotConfigurationProvider>();
|
||||
_downstreamRouteFinder = new Mock<IDownstreamRouteFinder>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "");
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteFinderReturns(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => GivenTheFollowingConfig(config))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingConfig(IOcelotConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
_provider
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(new OkResponse<IOcelotConfiguration>(_config));
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_downstreamRouteFinder.Object);
|
||||
services.AddSingleton(_provider.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDownstreamRouteFinderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
_downstreamRouteFinder
|
||||
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IOcelotConfiguration>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void ThenTheScopedDataRepositoryIsCalledCorrectly()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("DownstreamRoute", _downstreamRoute.Data), Times.Once());
|
||||
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("ServiceProviderConfiguration", _config.ServiceProviderConfiguration), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class DownstreamRouteFinderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IDownstreamRouteFinder> _downstreamRouteFinder;
|
||||
private readonly Mock<IOcelotConfigurationProvider> _provider;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private IOcelotConfiguration _config;
|
||||
|
||||
public DownstreamRouteFinderMiddlewareTests()
|
||||
{
|
||||
_provider = new Mock<IOcelotConfigurationProvider>();
|
||||
_downstreamRouteFinder = new Mock<IDownstreamRouteFinder>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "");
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteFinderReturns(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.And(x => GivenTheFollowingConfig(config))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheFollowingConfig(IOcelotConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
_provider
|
||||
.Setup(x => x.Get())
|
||||
.ReturnsAsync(new OkResponse<IOcelotConfiguration>(_config));
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_downstreamRouteFinder.Object);
|
||||
services.AddSingleton(_provider.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDownstreamRouteFinderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
_downstreamRouteFinder
|
||||
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IOcelotConfiguration>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void ThenTheScopedDataRepositoryIsCalledCorrectly()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("DownstreamRoute", _downstreamRoute.Data), Times.Once());
|
||||
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("ServiceProviderConfiguration", _config.ServiceProviderConfiguration), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,452 +1,452 @@
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
{
|
||||
public class DownstreamRouteFinderTests
|
||||
{
|
||||
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
|
||||
private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher;
|
||||
private readonly Mock<IPlaceholderNameAndValueFinder> _finder;
|
||||
private string _upstreamUrlPath;
|
||||
private Response<DownstreamRoute> _result;
|
||||
private List<ReRoute> _reRoutesConfig;
|
||||
private OcelotConfiguration _config;
|
||||
private Response<UrlMatch> _match;
|
||||
private string _upstreamHttpMethod;
|
||||
|
||||
public DownstreamRouteFinderTests()
|
||||
{
|
||||
_mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>();
|
||||
_finder = new Mock<IPlaceholderNameAndValueFinder>();
|
||||
_downstreamRouteFinder = new Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder(_mockMatcher.Object, _finder.Object);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_return_highest_priority_when_first()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(x => x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.Build(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_highest_priority_when_lowest()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(x => x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
|
||||
.Build(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_route()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/"))
|
||||
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(
|
||||
new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
)))
|
||||
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_not_append_slash_to_upstream_url_path()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher"))
|
||||
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(
|
||||
new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
)))
|
||||
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_route_if_upstream_path_and_upstream_template_are_the_same()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
)))
|
||||
.And(x => x.ThenTheUrlMatcherIsNotCalled())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_correct_route_for_http_verb()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_route()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("dontMatchPath/"))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("somPath")
|
||||
.WithUpstreamPathTemplate("somePath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
|
||||
.Build(),
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(false))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenAnErrorResponseIsReturned())
|
||||
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_correct_route_for_http_verb_setting_multiple_upstream_http_method()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_correct_route_for_http_verb_setting_all_upstream_http_method()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string>())
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_route_for_http_verb_not_setting_in_upstream_http_method()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenAnErrorResponseIsReturned())
|
||||
.And(x => x.ThenTheUrlMatcherIsNotCalled())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheTemplateVariableAndNameFinderReturns(Response<List<PlaceholderNameAndValue>> response)
|
||||
{
|
||||
_finder
|
||||
.Setup(x => x.Find(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.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].UpstreamPathTemplate.Value), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheUrlMatcherIsCalledCorrectly(string expectedUpstreamUrlPath)
|
||||
{
|
||||
_mockMatcher
|
||||
.Verify(x => x.Match(expectedUpstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheUrlMatcherIsNotCalled()
|
||||
{
|
||||
_mockMatcher
|
||||
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Never);
|
||||
}
|
||||
|
||||
private void GivenTheUrlMatcherReturns(Response<UrlMatch> match)
|
||||
{
|
||||
_match = match;
|
||||
_mockMatcher
|
||||
.Setup(x => x.Match(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(_match);
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath, ServiceProviderConfiguration serviceProviderConfig)
|
||||
{
|
||||
_reRoutesConfig = reRoutesConfig;
|
||||
_config = new OcelotConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "");
|
||||
}
|
||||
|
||||
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
|
||||
{
|
||||
_upstreamUrlPath = upstreamUrlPath;
|
||||
}
|
||||
|
||||
private void WhenICallTheFinder()
|
||||
{
|
||||
_result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod, _config);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(DownstreamRoute expected)
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamPathTemplate.Value);
|
||||
_result.Data.ReRoute.UpstreamTemplatePattern.Priority.ShouldBe(expected.ReRoute.UpstreamTemplatePattern.Priority);
|
||||
|
||||
for (int i = 0; i < _result.Data.TemplatePlaceholderNameAndValues.Count; i++)
|
||||
{
|
||||
_result.Data.TemplatePlaceholderNameAndValues[i].Name.ShouldBe(expected.TemplatePlaceholderNameAndValues[i].Name);
|
||||
_result.Data.TemplatePlaceholderNameAndValues[i].Value.ShouldBe(expected.TemplatePlaceholderNameAndValues[i].Value);
|
||||
}
|
||||
|
||||
_result.IsError.ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Creator;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
{
|
||||
public class DownstreamRouteFinderTests
|
||||
{
|
||||
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
|
||||
private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher;
|
||||
private readonly Mock<IPlaceholderNameAndValueFinder> _finder;
|
||||
private string _upstreamUrlPath;
|
||||
private Response<DownstreamRoute> _result;
|
||||
private List<ReRoute> _reRoutesConfig;
|
||||
private OcelotConfiguration _config;
|
||||
private Response<UrlMatch> _match;
|
||||
private string _upstreamHttpMethod;
|
||||
|
||||
public DownstreamRouteFinderTests()
|
||||
{
|
||||
_mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>();
|
||||
_finder = new Mock<IPlaceholderNameAndValueFinder>();
|
||||
_downstreamRouteFinder = new Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder(_mockMatcher.Object, _finder.Object);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_return_highest_priority_when_first()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(x => x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.Build(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_highest_priority_when_lowest()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(x => x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
|
||||
.Build(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_route()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/"))
|
||||
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(
|
||||
new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
)))
|
||||
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_not_append_slash_to_upstream_url_path()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher"))
|
||||
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(
|
||||
new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
)))
|
||||
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_route_if_upstream_path_and_upstream_template_are_the_same()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
|
||||
.Build()
|
||||
)))
|
||||
.And(x => x.ThenTheUrlMatcherIsNotCalled())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_correct_route_for_http_verb()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_route()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("dontMatchPath/"))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("somPath")
|
||||
.WithUpstreamPathTemplate("somePath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
|
||||
.Build(),
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(false))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenAnErrorResponseIsReturned())
|
||||
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_correct_route_for_http_verb_setting_multiple_upstream_http_method()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_correct_route_for_http_verb_setting_all_upstream_http_method()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string>())
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Post" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_route_for_http_verb_not_setting_in_upstream_http_method()
|
||||
{
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
|
||||
.And(
|
||||
x =>
|
||||
x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
|
||||
.Build()
|
||||
}, string.Empty, serviceProviderConfig
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenAnErrorResponseIsReturned())
|
||||
.And(x => x.ThenTheUrlMatcherIsNotCalled())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheTemplateVariableAndNameFinderReturns(Response<List<PlaceholderNameAndValue>> response)
|
||||
{
|
||||
_finder
|
||||
.Setup(x => x.Find(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.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].UpstreamPathTemplate.Value), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheUrlMatcherIsCalledCorrectly(string expectedUpstreamUrlPath)
|
||||
{
|
||||
_mockMatcher
|
||||
.Verify(x => x.Match(expectedUpstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheUrlMatcherIsNotCalled()
|
||||
{
|
||||
_mockMatcher
|
||||
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Never);
|
||||
}
|
||||
|
||||
private void GivenTheUrlMatcherReturns(Response<UrlMatch> match)
|
||||
{
|
||||
_match = match;
|
||||
_mockMatcher
|
||||
.Setup(x => x.Match(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(_match);
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath, ServiceProviderConfiguration serviceProviderConfig)
|
||||
{
|
||||
_reRoutesConfig = reRoutesConfig;
|
||||
_config = new OcelotConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "");
|
||||
}
|
||||
|
||||
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
|
||||
{
|
||||
_upstreamUrlPath = upstreamUrlPath;
|
||||
}
|
||||
|
||||
private void WhenICallTheFinder()
|
||||
{
|
||||
_result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod, _config);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(DownstreamRoute expected)
|
||||
{
|
||||
_result.Data.ReRoute.DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamPathTemplate.Value);
|
||||
_result.Data.ReRoute.UpstreamTemplatePattern.Priority.ShouldBe(expected.ReRoute.UpstreamTemplatePattern.Priority);
|
||||
|
||||
for (int i = 0; i < _result.Data.TemplatePlaceholderNameAndValues.Count; i++)
|
||||
{
|
||||
_result.Data.TemplatePlaceholderNameAndValues[i].Name.ShouldBe(expected.TemplatePlaceholderNameAndValues[i].Name);
|
||||
_result.Data.TemplatePlaceholderNameAndValues[i].Value.ShouldBe(expected.TemplatePlaceholderNameAndValues[i].Value);
|
||||
}
|
||||
|
||||
_result.IsError.ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,218 +1,218 @@
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.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_not_match_slash_becaue_we_need_to_match_something_after_it()
|
||||
{
|
||||
const string RegExForwardSlashAndOnePlaceHolder = "^/[0-9a-zA-Z].*";
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(RegExForwardSlashAndOnePlaceHolder))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.And(x => x.ThenTheResultIsFalse())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_forward_slash_only_regex()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/working/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.And(x => x.ThenTheResultIsFalse())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_issue_134()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/vacancy/1/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/.*/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.And(x => x.ThenTheResultIsFalse())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_forward_slash_only_regex()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.And(x => x.ThenTheResultIsTrue())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
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/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.Then(x => x.ThenTheResultIsTrue())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
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/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.Then(x => x.ThenTheResultIsFalse())
|
||||
.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();
|
||||
}
|
||||
}
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.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_not_match_slash_becaue_we_need_to_match_something_after_it()
|
||||
{
|
||||
const string RegExForwardSlashAndOnePlaceHolder = "^/[0-9a-zA-Z].*";
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(RegExForwardSlashAndOnePlaceHolder))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.And(x => x.ThenTheResultIsFalse())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_forward_slash_only_regex()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/working/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.And(x => x.ThenTheResultIsFalse())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_issue_134()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/api/vacancy/1/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/.*/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.And(x => x.ThenTheResultIsFalse())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_forward_slash_only_regex()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.And(x => x.ThenTheResultIsTrue())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
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/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.Then(x => x.ThenTheResultIsTrue())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
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/$"))
|
||||
.When(x => x.WhenIMatchThePaths())
|
||||
.Then(x => x.ThenTheResultIsFalse())
|
||||
.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();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,267 +1,267 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
||||
{
|
||||
public class UrlPathPlaceholderNameAndValueFinderTests
|
||||
{
|
||||
private readonly IPlaceholderNameAndValueFinder _finder;
|
||||
private string _downstreamUrlPath;
|
||||
private string _downstreamPathTemplate;
|
||||
private Response<List<PlaceholderNameAndValue>> _result;
|
||||
|
||||
public UrlPathPlaceholderNameAndValueFinderTests()
|
||||
{
|
||||
_finder = new UrlPathPlaceholderNameAndValueFinder();
|
||||
}
|
||||
|
||||
[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<PlaceholderNameAndValue>()))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_nothing_then_placeholder_no_value_is_blank()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{url}", "")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath(""))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_nothing_then_placeholder_value_is_test()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{url}", "test")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/test"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_forward_slash_then_placeholder_no_value_is_blank()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{url}", "")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_forward_slash()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_forward_slash_then_placeholder_then_another_value()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{url}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/1/products"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}/products"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_find_anything()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/products"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products/"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(new List<PlaceholderNameAndValue>()))
|
||||
.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<PlaceholderNameAndValue>()))
|
||||
.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<PlaceholderNameAndValue>()))
|
||||
.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<PlaceholderNameAndValue>()))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{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<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{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<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{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<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{categoryId}", "2"),
|
||||
new PlaceholderNameAndValue("{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<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{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();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_downstream_template_with_place_holder_to_final_url_path()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{finalUrlPath}", "product/products/categories/"),
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/categories/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/{finalUrlPath}/"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheTemplatesVariablesAre(List<PlaceholderNameAndValue> expectedResults)
|
||||
{
|
||||
foreach (var expectedResult in expectedResults)
|
||||
{
|
||||
var result = _result.Data.First(t => t.Name == expectedResult.Name);
|
||||
result.Value.ShouldBe(expectedResult.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenIHaveAUpstreamPath(string downstreamPath)
|
||||
{
|
||||
_downstreamUrlPath = downstreamPath;
|
||||
}
|
||||
|
||||
private void GivenIHaveAnUpstreamUrlTemplate(string downstreamUrlTemplate)
|
||||
{
|
||||
_downstreamPathTemplate = downstreamUrlTemplate;
|
||||
}
|
||||
|
||||
private void WhenIFindTheUrlVariableNamesAndValues()
|
||||
{
|
||||
_result = _finder.Find(_downstreamUrlPath, _downstreamPathTemplate);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
|
||||
{
|
||||
public class UrlPathPlaceholderNameAndValueFinderTests
|
||||
{
|
||||
private readonly IPlaceholderNameAndValueFinder _finder;
|
||||
private string _downstreamUrlPath;
|
||||
private string _downstreamPathTemplate;
|
||||
private Response<List<PlaceholderNameAndValue>> _result;
|
||||
|
||||
public UrlPathPlaceholderNameAndValueFinderTests()
|
||||
{
|
||||
_finder = new UrlPathPlaceholderNameAndValueFinder();
|
||||
}
|
||||
|
||||
[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<PlaceholderNameAndValue>()))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_nothing_then_placeholder_no_value_is_blank()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{url}", "")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath(""))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_nothing_then_placeholder_value_is_test()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{url}", "test")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/test"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_forward_slash_then_placeholder_no_value_is_blank()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{url}", "")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_forward_slash()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_forward_slash_then_placeholder_then_another_value()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{url}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/1/products"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}/products"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_find_anything()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("/products"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products/"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(new List<PlaceholderNameAndValue>()))
|
||||
.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<PlaceholderNameAndValue>()))
|
||||
.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<PlaceholderNameAndValue>()))
|
||||
.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<PlaceholderNameAndValue>()))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{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<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{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<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{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<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{categoryId}", "2"),
|
||||
new PlaceholderNameAndValue("{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<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{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();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_match_down_stream_url_with_downstream_template_with_place_holder_to_final_url_path()
|
||||
{
|
||||
var expectedTemplates = new List<PlaceholderNameAndValue>
|
||||
{
|
||||
new PlaceholderNameAndValue("{finalUrlPath}", "product/products/categories/"),
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/categories/"))
|
||||
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/{finalUrlPath}/"))
|
||||
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
|
||||
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheTemplatesVariablesAre(List<PlaceholderNameAndValue> expectedResults)
|
||||
{
|
||||
foreach (var expectedResult in expectedResults)
|
||||
{
|
||||
var result = _result.Data.First(t => t.Name == expectedResult.Name);
|
||||
result.Value.ShouldBe(expectedResult.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenIHaveAUpstreamPath(string downstreamPath)
|
||||
{
|
||||
_downstreamUrlPath = downstreamPath;
|
||||
}
|
||||
|
||||
private void GivenIHaveAnUpstreamUrlTemplate(string downstreamUrlTemplate)
|
||||
{
|
||||
_downstreamPathTemplate = downstreamUrlTemplate;
|
||||
}
|
||||
|
||||
private void WhenIFindTheUrlVariableNamesAndValues()
|
||||
{
|
||||
_result = _finder.Find(_downstreamUrlPath, _downstreamPathTemplate);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,103 +1,103 @@
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator;
|
||||
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
|
||||
public class DownstreamUrlCreatorMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IDownstreamPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer;
|
||||
private readonly Mock<IUrlBuilder> _urlBuilder;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private OkResponse<DownstreamPath> _downstreamPath;
|
||||
private HttpRequestMessage _downstreamRequest;
|
||||
|
||||
public DownstreamUrlCreatorMiddlewareTests()
|
||||
{
|
||||
_downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamPathPlaceholderReplacer>();
|
||||
_urlBuilder = new Mock<IUrlBuilder>();
|
||||
|
||||
_downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://my.url/abc/?q=123");
|
||||
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_scheme_and_path()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://my.url/abc?q=123"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://my.url:80/api/products/1?q=123"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_downstreamUrlTemplateVariableReplacer.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
services.AddSingleton(_urlBuilder.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDownstreamUrlCreatorMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRequestUriIs(string uri)
|
||||
{
|
||||
_downstreamRequest.RequestUri = new Uri(uri);
|
||||
}
|
||||
|
||||
private void GivenTheUrlReplacerWillReturn(string path)
|
||||
{
|
||||
_downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(path));
|
||||
_downstreamUrlTemplateVariableReplacer
|
||||
.Setup(x => x.Replace(It.IsAny<PathTemplate>(), It.IsAny<List<PlaceholderNameAndValue>>()))
|
||||
.Returns(_downstreamPath);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestUriIs(string expectedUri)
|
||||
{
|
||||
_downstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator;
|
||||
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
|
||||
public class DownstreamUrlCreatorMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IDownstreamPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer;
|
||||
private readonly Mock<IUrlBuilder> _urlBuilder;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private OkResponse<DownstreamPath> _downstreamPath;
|
||||
private HttpRequestMessage _downstreamRequest;
|
||||
|
||||
public DownstreamUrlCreatorMiddlewareTests()
|
||||
{
|
||||
_downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamPathPlaceholderReplacer>();
|
||||
_urlBuilder = new Mock<IUrlBuilder>();
|
||||
|
||||
_downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://my.url/abc/?q=123");
|
||||
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_scheme_and_path()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithDownstreamScheme("https")
|
||||
.Build())))
|
||||
.And(x => x.GivenTheDownstreamRequestUriIs("http://my.url/abc?q=123"))
|
||||
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamRequestUriIs("https://my.url:80/api/products/1?q=123"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_downstreamUrlTemplateVariableReplacer.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
services.AddSingleton(_urlBuilder.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDownstreamUrlCreatorMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRequestUriIs(string uri)
|
||||
{
|
||||
_downstreamRequest.RequestUri = new Uri(uri);
|
||||
}
|
||||
|
||||
private void GivenTheUrlReplacerWillReturn(string path)
|
||||
{
|
||||
_downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(path));
|
||||
_downstreamUrlTemplateVariableReplacer
|
||||
.Setup(x => x.Replace(It.IsAny<PathTemplate>(), It.IsAny<List<PlaceholderNameAndValue>>()))
|
||||
.Returns(_downstreamPath);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestUriIs(string expectedUri)
|
||||
{
|
||||
_downstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,122 +1,122 @@
|
||||
using System;
|
||||
using Ocelot.DownstreamUrlCreator;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
{
|
||||
public class UrlBuilderTests
|
||||
{
|
||||
private readonly IUrlBuilder _urlBuilder;
|
||||
private string _dsPath;
|
||||
private string _dsScheme;
|
||||
private string _dsHost;
|
||||
private int _dsPort;
|
||||
|
||||
private Response<DownstreamUrl> _result;
|
||||
|
||||
public UrlBuilderTests()
|
||||
{
|
||||
_urlBuilder = new UrlBuilder();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_downstream_path_is_null()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamPath(null))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamPathNullOrEmptyError>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_downstream_scheme_is_null()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamScheme(null))
|
||||
.And(x => x.GivenADownstreamPath("test"))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamSchemeNullOrEmptyError>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_downstream_host_is_null()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamScheme(null))
|
||||
.And(x => x.GivenADownstreamPath("test"))
|
||||
.And(x => x.GivenADownstreamScheme("test"))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamHostNullOrEmptyError>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_use_port_if_zero()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamPath("/api/products/1"))
|
||||
.And(x => x.GivenADownstreamScheme("http"))
|
||||
.And(x => x.GivenADownstreamHost("127.0.0.1"))
|
||||
.And(x => x.GivenADownstreamPort(0))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenTheUrlIsReturned("http://127.0.0.1/api/products/1"))
|
||||
.And(x => x.ThenTheUrlIsWellFormed())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_well_formed_uri()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamPath("/api/products/1"))
|
||||
.And(x => x.GivenADownstreamScheme("http"))
|
||||
.And(x => x.GivenADownstreamHost("127.0.0.1"))
|
||||
.And(x => x.GivenADownstreamPort(5000))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenTheUrlIsReturned("http://127.0.0.1:5000/api/products/1"))
|
||||
.And(x => x.ThenTheUrlIsWellFormed())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenThereIsAnErrorOfType<T>()
|
||||
{
|
||||
_result.Errors[0].ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void GivenADownstreamPath(string dsPath)
|
||||
{
|
||||
_dsPath = dsPath;
|
||||
}
|
||||
|
||||
private void GivenADownstreamScheme(string dsScheme)
|
||||
{
|
||||
_dsScheme = dsScheme;
|
||||
}
|
||||
|
||||
private void GivenADownstreamHost(string dsHost)
|
||||
{
|
||||
_dsHost = dsHost;
|
||||
}
|
||||
|
||||
private void GivenADownstreamPort(int dsPort)
|
||||
{
|
||||
_dsPort = dsPort;
|
||||
}
|
||||
|
||||
private void WhenIBuildTheUrl()
|
||||
{
|
||||
_result = _urlBuilder.Build(_dsPath, _dsScheme, new HostAndPort(_dsHost, _dsPort));
|
||||
}
|
||||
|
||||
private void ThenTheUrlIsReturned(string expected)
|
||||
{
|
||||
_result.Data.Value.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenTheUrlIsWellFormed()
|
||||
{
|
||||
Uri.IsWellFormedUriString(_result.Data.Value, UriKind.Absolute).ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Ocelot.DownstreamUrlCreator;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
{
|
||||
public class UrlBuilderTests
|
||||
{
|
||||
private readonly IUrlBuilder _urlBuilder;
|
||||
private string _dsPath;
|
||||
private string _dsScheme;
|
||||
private string _dsHost;
|
||||
private int _dsPort;
|
||||
|
||||
private Response<DownstreamUrl> _result;
|
||||
|
||||
public UrlBuilderTests()
|
||||
{
|
||||
_urlBuilder = new UrlBuilder();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_downstream_path_is_null()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamPath(null))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamPathNullOrEmptyError>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_downstream_scheme_is_null()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamScheme(null))
|
||||
.And(x => x.GivenADownstreamPath("test"))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamSchemeNullOrEmptyError>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_when_downstream_host_is_null()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamScheme(null))
|
||||
.And(x => x.GivenADownstreamPath("test"))
|
||||
.And(x => x.GivenADownstreamScheme("test"))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamHostNullOrEmptyError>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_use_port_if_zero()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamPath("/api/products/1"))
|
||||
.And(x => x.GivenADownstreamScheme("http"))
|
||||
.And(x => x.GivenADownstreamHost("127.0.0.1"))
|
||||
.And(x => x.GivenADownstreamPort(0))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenTheUrlIsReturned("http://127.0.0.1/api/products/1"))
|
||||
.And(x => x.ThenTheUrlIsWellFormed())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_well_formed_uri()
|
||||
{
|
||||
this.Given(x => x.GivenADownstreamPath("/api/products/1"))
|
||||
.And(x => x.GivenADownstreamScheme("http"))
|
||||
.And(x => x.GivenADownstreamHost("127.0.0.1"))
|
||||
.And(x => x.GivenADownstreamPort(5000))
|
||||
.When(x => x.WhenIBuildTheUrl())
|
||||
.Then(x => x.ThenTheUrlIsReturned("http://127.0.0.1:5000/api/products/1"))
|
||||
.And(x => x.ThenTheUrlIsWellFormed())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenThereIsAnErrorOfType<T>()
|
||||
{
|
||||
_result.Errors[0].ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void GivenADownstreamPath(string dsPath)
|
||||
{
|
||||
_dsPath = dsPath;
|
||||
}
|
||||
|
||||
private void GivenADownstreamScheme(string dsScheme)
|
||||
{
|
||||
_dsScheme = dsScheme;
|
||||
}
|
||||
|
||||
private void GivenADownstreamHost(string dsHost)
|
||||
{
|
||||
_dsHost = dsHost;
|
||||
}
|
||||
|
||||
private void GivenADownstreamPort(int dsPort)
|
||||
{
|
||||
_dsPort = dsPort;
|
||||
}
|
||||
|
||||
private void WhenIBuildTheUrl()
|
||||
{
|
||||
_result = _urlBuilder.Build(_dsPath, _dsScheme, new ServiceHostAndPort(_dsHost, _dsPort));
|
||||
}
|
||||
|
||||
private void ThenTheUrlIsReturned(string expected)
|
||||
{
|
||||
_result.Data.Value.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenTheUrlIsWellFormed()
|
||||
{
|
||||
Uri.IsWellFormedUriString(_result.Data.Value, UriKind.Absolute).ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,183 +1,183 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public class UpstreamUrlPathTemplateVariableReplacerTests
|
||||
{
|
||||
private DownstreamRoute _downstreamRoute;
|
||||
private Response<DownstreamPath> _result;
|
||||
private readonly IDownstreamPathPlaceholderReplacer _downstreamPathReplacer;
|
||||
|
||||
public UpstreamUrlPathTemplateVariableReplacerTests()
|
||||
{
|
||||
_downstreamPathReplacer = new DownstreamTemplatePathPlaceholderReplacer();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_no_template_variables()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned(""))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_no_template_variables_with_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_no_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_multiple_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api/product/products/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_template_variable_with_path_after()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/variants")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_two_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{variantId}", "12")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_three_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{variantId}", "12"),
|
||||
new PlaceholderNameAndValue("{categoryId}", "34")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereIsAUrlMatch(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = downstreamRoute;
|
||||
}
|
||||
|
||||
private void WhenIReplaceTheTemplateVariables()
|
||||
{
|
||||
_result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamUrlPathIsReturned(string expected)
|
||||
{
|
||||
_result.Data.Value.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
|
||||
{
|
||||
public class UpstreamUrlPathTemplateVariableReplacerTests
|
||||
{
|
||||
private DownstreamRoute _downstreamRoute;
|
||||
private Response<DownstreamPath> _result;
|
||||
private readonly IDownstreamPathPlaceholderReplacer _downstreamPathReplacer;
|
||||
|
||||
public UpstreamUrlPathTemplateVariableReplacerTests()
|
||||
{
|
||||
_downstreamPathReplacer = new DownstreamTemplatePathPlaceholderReplacer();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_no_template_variables()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned(""))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_no_template_variables_with_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(
|
||||
new DownstreamRoute(
|
||||
new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_no_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_multiple_slash()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("api/product/products/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_one_template_variable_with_path_after()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/variants")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_two_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{variantId}", "12")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_replace_url_three_template_variable()
|
||||
{
|
||||
var templateVariables = new List<PlaceholderNameAndValue>()
|
||||
{
|
||||
new PlaceholderNameAndValue("{productId}", "1"),
|
||||
new PlaceholderNameAndValue("{variantId}", "12"),
|
||||
new PlaceholderNameAndValue("{categoryId}", "34")
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build())))
|
||||
.When(x => x.WhenIReplaceTheTemplateVariables())
|
||||
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereIsAUrlMatch(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = downstreamRoute;
|
||||
}
|
||||
|
||||
private void WhenIReplaceTheTemplateVariables()
|
||||
{
|
||||
_result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamUrlPathIsReturned(string expected)
|
||||
{
|
||||
_result.Data.Value.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Errors
|
||||
{
|
||||
public class ErrorTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_return_message()
|
||||
{
|
||||
var error = new CannotAddDataError("message");
|
||||
var result = error.ToString();
|
||||
result.ShouldBe("message");
|
||||
}
|
||||
}
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Errors
|
||||
{
|
||||
public class ErrorTests
|
||||
{
|
||||
[Fact]
|
||||
public void should_return_message()
|
||||
{
|
||||
var error = new CannotAddDataError("message");
|
||||
var result = error.ToString();
|
||||
result.ShouldBe("message");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,144 +1,144 @@
|
||||
namespace Ocelot.UnitTests.Errors
|
||||
{
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Errors.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Rafty.Concensus;
|
||||
|
||||
public class ExceptionHandlerMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
bool _shouldThrowAnException = false;
|
||||
private Mock<IOcelotConfigurationProvider> _provider;
|
||||
|
||||
public ExceptionHandlerMiddlewareTests()
|
||||
{
|
||||
_provider = new Mock<IOcelotConfigurationProvider>();
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NoDownstreamException()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, null, null);
|
||||
|
||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenICallTheMiddleware())
|
||||
.Then(_ => ThenTheResponseIsOk())
|
||||
.And(_ => TheRequestIdIsNotSet())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void TheRequestIdIsNotSet()
|
||||
{
|
||||
ScopedRepository.Verify(x => x.Add<string>(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DownstreamException()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, null, null);
|
||||
|
||||
this.Given(_ => GivenAnExceptionWillBeThrownDownstream())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenICallTheMiddleware())
|
||||
.Then(_ => ThenTheResponseIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldSetRequestId()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, null, "requestidkey");
|
||||
|
||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenICallTheMiddlewareWithTheRequestIdKey("requestidkey", "1234"))
|
||||
.Then(_ => ThenTheResponseIsOk())
|
||||
.And(_ => TheRequestIdIsSet("RequestId", "1234"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldNotSetRequestId()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, null, null);
|
||||
|
||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenICallTheMiddlewareWithTheRequestIdKey("requestidkey", "1234"))
|
||||
.Then(_ => ThenTheResponseIsOk())
|
||||
.And(_ => TheRequestIdIsNotSet())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void TheRequestIdIsSet(string key, string value)
|
||||
{
|
||||
ScopedRepository.Verify(x => x.Add<string>(key, value), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(IOcelotConfiguration config)
|
||||
{
|
||||
var response = new Ocelot.Responses.OkResponse<IOcelotConfiguration>(config);
|
||||
_provider
|
||||
.Setup(x => x.Get()).ReturnsAsync(response);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
services.AddSingleton<IOcelotConfigurationProvider>(_provider.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseExceptionHandlerMiddleware();
|
||||
app.Run(DownstreamExceptionSimulator);
|
||||
}
|
||||
|
||||
private async Task DownstreamExceptionSimulator(HttpContext context)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
if (_shouldThrowAnException)
|
||||
{
|
||||
throw new Exception("BOOM");
|
||||
}
|
||||
|
||||
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
||||
}
|
||||
|
||||
private void GivenAnExceptionWillNotBeThrownDownstream()
|
||||
{
|
||||
_shouldThrowAnException = false;
|
||||
}
|
||||
|
||||
private void GivenAnExceptionWillBeThrownDownstream()
|
||||
{
|
||||
_shouldThrowAnException = true;
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsOk()
|
||||
{
|
||||
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsError()
|
||||
{
|
||||
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Errors
|
||||
{
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.Errors.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Rafty.Concensus;
|
||||
|
||||
public class ExceptionHandlerMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
bool _shouldThrowAnException = false;
|
||||
private Mock<IOcelotConfigurationProvider> _provider;
|
||||
|
||||
public ExceptionHandlerMiddlewareTests()
|
||||
{
|
||||
_provider = new Mock<IOcelotConfigurationProvider>();
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NoDownstreamException()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, null, null);
|
||||
|
||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenICallTheMiddleware())
|
||||
.Then(_ => ThenTheResponseIsOk())
|
||||
.And(_ => TheRequestIdIsNotSet())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void TheRequestIdIsNotSet()
|
||||
{
|
||||
ScopedRepository.Verify(x => x.Add<string>(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DownstreamException()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, null, null);
|
||||
|
||||
this.Given(_ => GivenAnExceptionWillBeThrownDownstream())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenICallTheMiddleware())
|
||||
.Then(_ => ThenTheResponseIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldSetRequestId()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, null, "requestidkey");
|
||||
|
||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenICallTheMiddlewareWithTheRequestIdKey("requestidkey", "1234"))
|
||||
.Then(_ => ThenTheResponseIsOk())
|
||||
.And(_ => TheRequestIdIsSet("RequestId", "1234"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShouldNotSetRequestId()
|
||||
{
|
||||
var config = new OcelotConfiguration(null, null, null, null);
|
||||
|
||||
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
|
||||
.And(_ => GivenTheConfigurationIs(config))
|
||||
.When(_ => WhenICallTheMiddlewareWithTheRequestIdKey("requestidkey", "1234"))
|
||||
.Then(_ => ThenTheResponseIsOk())
|
||||
.And(_ => TheRequestIdIsNotSet())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void TheRequestIdIsSet(string key, string value)
|
||||
{
|
||||
ScopedRepository.Verify(x => x.Add<string>(key, value), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(IOcelotConfiguration config)
|
||||
{
|
||||
var response = new Ocelot.Responses.OkResponse<IOcelotConfiguration>(config);
|
||||
_provider
|
||||
.Setup(x => x.Get()).ReturnsAsync(response);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
services.AddSingleton<IOcelotConfigurationProvider>(_provider.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseExceptionHandlerMiddleware();
|
||||
app.Run(DownstreamExceptionSimulator);
|
||||
}
|
||||
|
||||
private async Task DownstreamExceptionSimulator(HttpContext context)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
if (_shouldThrowAnException)
|
||||
{
|
||||
throw new Exception("BOOM");
|
||||
}
|
||||
|
||||
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
||||
}
|
||||
|
||||
private void GivenAnExceptionWillNotBeThrownDownstream()
|
||||
{
|
||||
_shouldThrowAnException = false;
|
||||
}
|
||||
|
||||
private void GivenAnExceptionWillBeThrownDownstream()
|
||||
{
|
||||
_shouldThrowAnException = true;
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsOk()
|
||||
{
|
||||
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsError()
|
||||
{
|
||||
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,151 +1,151 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Headers;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class AddHeadersToRequestTests
|
||||
{
|
||||
private readonly AddHeadersToRequest _addHeadersToRequest;
|
||||
private readonly Mock<IClaimsParser> _parser;
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private List<Claim> _claims;
|
||||
private List<ClaimToThing> _configuration;
|
||||
private Response _result;
|
||||
private Response<string> _claimValue;
|
||||
|
||||
public AddHeadersToRequestTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_addHeadersToRequest = new AddHeadersToRequest(_parser.Object);
|
||||
_downstreamRequest = new HttpRequestMessage();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_headers_to_downstreamRequest()
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenConfigurationHeaderExtractorProperties(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("header-key", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(claims))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddHeadersToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.And(x => x.ThenTheHeaderIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_existing_headers_on_request()
|
||||
{
|
||||
this.Given(
|
||||
x => x.GivenConfigurationHeaderExtractorProperties(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("header-key", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
}))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.And(x => x.GivenThatTheRequestContainsHeader("header-key", "initial"))
|
||||
.When(x => x.WhenIAddHeadersToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.And(x => x.ThenTheHeaderIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
this.Given(
|
||||
x => x.GivenConfigurationHeaderExtractorProperties(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(new List<Claim>()))
|
||||
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.When(x => x.WhenIAddHeadersToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenClaims(List<Claim> claims)
|
||||
{
|
||||
_claims = claims;
|
||||
}
|
||||
|
||||
private void GivenConfigurationHeaderExtractorProperties(List<ClaimToThing> configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
private void GivenThatTheRequestContainsHeader(string key, string value)
|
||||
{
|
||||
_downstreamRequest.Headers.Add(key, value);
|
||||
}
|
||||
|
||||
private void GivenTheClaimParserReturns(Response<string> claimValue)
|
||||
{
|
||||
_claimValue = claimValue;
|
||||
_parser
|
||||
.Setup(
|
||||
x =>
|
||||
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<int>()))
|
||||
.Returns(_claimValue);
|
||||
}
|
||||
|
||||
private void WhenIAddHeadersToTheRequest()
|
||||
{
|
||||
_result = _addHeadersToRequest.SetHeadersOnDownstreamRequest(_configuration, _claims, _downstreamRequest);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsSuccess()
|
||||
{
|
||||
_result.IsError.ShouldBe(false);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsError()
|
||||
{
|
||||
|
||||
_result.IsError.ShouldBe(true);
|
||||
}
|
||||
|
||||
private void ThenTheHeaderIsAdded()
|
||||
{
|
||||
var header = _downstreamRequest.Headers.First(x => x.Key == "header-key");
|
||||
header.Value.First().ShouldBe(_claimValue.Data);
|
||||
}
|
||||
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError()
|
||||
: base("blahh", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Headers;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class AddHeadersToRequestTests
|
||||
{
|
||||
private readonly AddHeadersToRequest _addHeadersToRequest;
|
||||
private readonly Mock<IClaimsParser> _parser;
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private List<Claim> _claims;
|
||||
private List<ClaimToThing> _configuration;
|
||||
private Response _result;
|
||||
private Response<string> _claimValue;
|
||||
|
||||
public AddHeadersToRequestTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_addHeadersToRequest = new AddHeadersToRequest(_parser.Object);
|
||||
_downstreamRequest = new HttpRequestMessage();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_headers_to_downstreamRequest()
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenConfigurationHeaderExtractorProperties(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("header-key", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(claims))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddHeadersToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.And(x => x.ThenTheHeaderIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_existing_headers_on_request()
|
||||
{
|
||||
this.Given(
|
||||
x => x.GivenConfigurationHeaderExtractorProperties(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("header-key", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
}))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.And(x => x.GivenThatTheRequestContainsHeader("header-key", "initial"))
|
||||
.When(x => x.WhenIAddHeadersToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.And(x => x.ThenTheHeaderIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
this.Given(
|
||||
x => x.GivenConfigurationHeaderExtractorProperties(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(new List<Claim>()))
|
||||
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.When(x => x.WhenIAddHeadersToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenClaims(List<Claim> claims)
|
||||
{
|
||||
_claims = claims;
|
||||
}
|
||||
|
||||
private void GivenConfigurationHeaderExtractorProperties(List<ClaimToThing> configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
private void GivenThatTheRequestContainsHeader(string key, string value)
|
||||
{
|
||||
_downstreamRequest.Headers.Add(key, value);
|
||||
}
|
||||
|
||||
private void GivenTheClaimParserReturns(Response<string> claimValue)
|
||||
{
|
||||
_claimValue = claimValue;
|
||||
_parser
|
||||
.Setup(
|
||||
x =>
|
||||
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<int>()))
|
||||
.Returns(_claimValue);
|
||||
}
|
||||
|
||||
private void WhenIAddHeadersToTheRequest()
|
||||
{
|
||||
_result = _addHeadersToRequest.SetHeadersOnDownstreamRequest(_configuration, _claims, _downstreamRequest);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsSuccess()
|
||||
{
|
||||
_result.IsError.ShouldBe(false);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsError()
|
||||
{
|
||||
|
||||
_result.IsError.ShouldBe(true);
|
||||
}
|
||||
|
||||
private void ThenTheHeaderIsAdded()
|
||||
{
|
||||
var header = _downstreamRequest.Headers.First(x => x.Key == "header-key");
|
||||
header.Value.First().ShouldBe(_claimValue.Data);
|
||||
}
|
||||
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError()
|
||||
: base("blahh", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,91 +1,91 @@
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Headers.Middleware;
|
||||
using TestStack.BDDfy;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Headers;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class HttpContextRequestHeaderReplacerTests
|
||||
{
|
||||
private HttpContext _context;
|
||||
private List<HeaderFindAndReplace> _fAndRs;
|
||||
private HttpContextRequestHeaderReplacer _replacer;
|
||||
private Response _result;
|
||||
|
||||
public HttpContextRequestHeaderReplacerTests()
|
||||
{
|
||||
_replacer = new HttpContextRequestHeaderReplacer();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_headers()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
context.Request.Headers.Add("test", "test");
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("test", "test", "chiken", 0));
|
||||
|
||||
this.Given(x => GivenTheFollowingHttpRequest(context))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeadersAreReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_replace_headers()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
context.Request.Headers.Add("test", "test");
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
|
||||
this.Given(x => GivenTheFollowingHttpRequest(context))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeadersAreNotReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheHeadersAreNotReplaced()
|
||||
{
|
||||
_result.ShouldBeOfType<OkResponse>();
|
||||
foreach (var f in _fAndRs)
|
||||
{
|
||||
_context.Request.Headers.TryGetValue(f.Key, out var values);
|
||||
values[f.Index].ShouldBe("test");
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheFollowingHttpRequest(HttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingHeaderReplacements(List<HeaderFindAndReplace> fAndRs)
|
||||
{
|
||||
_fAndRs = fAndRs;
|
||||
}
|
||||
|
||||
private void WhenICallTheReplacer()
|
||||
{
|
||||
_result = _replacer.Replace(_context, _fAndRs);
|
||||
}
|
||||
|
||||
private void ThenTheHeadersAreReplaced()
|
||||
{
|
||||
_result.ShouldBeOfType<OkResponse>();
|
||||
foreach (var f in _fAndRs)
|
||||
{
|
||||
_context.Request.Headers.TryGetValue(f.Key, out var values);
|
||||
values[f.Index].ShouldBe(f.Replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Headers.Middleware;
|
||||
using TestStack.BDDfy;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Headers;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class HttpContextRequestHeaderReplacerTests
|
||||
{
|
||||
private HttpContext _context;
|
||||
private List<HeaderFindAndReplace> _fAndRs;
|
||||
private HttpContextRequestHeaderReplacer _replacer;
|
||||
private Response _result;
|
||||
|
||||
public HttpContextRequestHeaderReplacerTests()
|
||||
{
|
||||
_replacer = new HttpContextRequestHeaderReplacer();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_headers()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
context.Request.Headers.Add("test", "test");
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("test", "test", "chiken", 0));
|
||||
|
||||
this.Given(x => GivenTheFollowingHttpRequest(context))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeadersAreReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_replace_headers()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
context.Request.Headers.Add("test", "test");
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
|
||||
this.Given(x => GivenTheFollowingHttpRequest(context))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeadersAreNotReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheHeadersAreNotReplaced()
|
||||
{
|
||||
_result.ShouldBeOfType<OkResponse>();
|
||||
foreach (var f in _fAndRs)
|
||||
{
|
||||
_context.Request.Headers.TryGetValue(f.Key, out var values);
|
||||
values[f.Index].ShouldBe("test");
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheFollowingHttpRequest(HttpContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private void GivenTheFollowingHeaderReplacements(List<HeaderFindAndReplace> fAndRs)
|
||||
{
|
||||
_fAndRs = fAndRs;
|
||||
}
|
||||
|
||||
private void WhenICallTheReplacer()
|
||||
{
|
||||
_result = _replacer.Replace(_context, _fAndRs);
|
||||
}
|
||||
|
||||
private void ThenTheHeadersAreReplaced()
|
||||
{
|
||||
_result.ShouldBeOfType<OkResponse>();
|
||||
foreach (var f in _fAndRs)
|
||||
{
|
||||
_context.Request.Headers.TryGetValue(f.Key, out var values);
|
||||
values[f.Index].ShouldBe(f.Replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,101 +1,101 @@
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Ocelot.Headers.Middleware;
|
||||
using TestStack.BDDfy;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Headers;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class HttpHeadersTransformationMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private Mock<IHttpContextRequestHeaderReplacer> _preReplacer;
|
||||
private Mock<IHttpResponseHeaderReplacer> _postReplacer;
|
||||
|
||||
public HttpHeadersTransformationMiddlewareTests()
|
||||
{
|
||||
_preReplacer = new Mock<IHttpContextRequestHeaderReplacer>();
|
||||
_postReplacer = new Mock<IHttpResponseHeaderReplacer>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_pre_and_post_header_transforms()
|
||||
{
|
||||
this.Given(x => GivenTheFollowingRequest())
|
||||
.And(x => GivenTheDownstreamRequestIs())
|
||||
.And(x => GivenTheReRouteHasPreFindAndReplaceSetUp())
|
||||
.And(x => GivenTheHttpResponseMessageIs())
|
||||
.When(x => WhenICallTheMiddleware())
|
||||
.Then(x => ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly())
|
||||
.And(x => ThenTheIHttpResponseHeaderReplacerIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRequestIs()
|
||||
{
|
||||
var request = new HttpRequestMessage();
|
||||
var response = new OkResponse<HttpRequestMessage>(request);
|
||||
ScopedRepository.Setup(x => x.Get<HttpRequestMessage>("DownstreamRequest")).Returns(response);
|
||||
}
|
||||
|
||||
private void GivenTheHttpResponseMessageIs()
|
||||
{
|
||||
var httpResponseMessage = new HttpResponseMessage();
|
||||
var response = new OkResponse<HttpResponseMessage>(httpResponseMessage);
|
||||
ScopedRepository.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage")).Returns(response);
|
||||
}
|
||||
|
||||
private void GivenTheReRouteHasPreFindAndReplaceSetUp()
|
||||
{
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
var reRoute = new ReRouteBuilder().WithUpstreamHeaderFindAndReplace(fAndRs).WithDownstreamHeaderFindAndReplace(fAndRs).Build();
|
||||
var dR = new DownstreamRoute(null, reRoute);
|
||||
var response = new OkResponse<DownstreamRoute>(dR);
|
||||
ScopedRepository.Setup(x => x.Get<DownstreamRoute>("DownstreamRoute")).Returns(response);
|
||||
}
|
||||
|
||||
private void ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly()
|
||||
{
|
||||
_preReplacer.Verify(x => x.Replace(It.IsAny<HttpContext>(), It.IsAny<List<HeaderFindAndReplace>>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheIHttpResponseHeaderReplacerIsCalledCorrectly()
|
||||
{
|
||||
_postReplacer.Verify(x => x.Replace(It.IsAny<HttpResponseMessage>(), It.IsAny<List<HeaderFindAndReplace>>(), It.IsAny<HttpRequestMessage>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingRequest()
|
||||
{
|
||||
Client.DefaultRequestHeaders.Add("test", "test");
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
services.AddSingleton(_preReplacer.Object);
|
||||
services.AddSingleton(_postReplacer.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseHttpHeadersTransformationMiddleware();
|
||||
}
|
||||
}
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Ocelot.Headers.Middleware;
|
||||
using TestStack.BDDfy;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Headers;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class HttpHeadersTransformationMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private Mock<IHttpContextRequestHeaderReplacer> _preReplacer;
|
||||
private Mock<IHttpResponseHeaderReplacer> _postReplacer;
|
||||
|
||||
public HttpHeadersTransformationMiddlewareTests()
|
||||
{
|
||||
_preReplacer = new Mock<IHttpContextRequestHeaderReplacer>();
|
||||
_postReplacer = new Mock<IHttpResponseHeaderReplacer>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_pre_and_post_header_transforms()
|
||||
{
|
||||
this.Given(x => GivenTheFollowingRequest())
|
||||
.And(x => GivenTheDownstreamRequestIs())
|
||||
.And(x => GivenTheReRouteHasPreFindAndReplaceSetUp())
|
||||
.And(x => GivenTheHttpResponseMessageIs())
|
||||
.When(x => WhenICallTheMiddleware())
|
||||
.Then(x => ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly())
|
||||
.And(x => ThenTheIHttpResponseHeaderReplacerIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRequestIs()
|
||||
{
|
||||
var request = new HttpRequestMessage();
|
||||
var response = new OkResponse<HttpRequestMessage>(request);
|
||||
ScopedRepository.Setup(x => x.Get<HttpRequestMessage>("DownstreamRequest")).Returns(response);
|
||||
}
|
||||
|
||||
private void GivenTheHttpResponseMessageIs()
|
||||
{
|
||||
var httpResponseMessage = new HttpResponseMessage();
|
||||
var response = new OkResponse<HttpResponseMessage>(httpResponseMessage);
|
||||
ScopedRepository.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage")).Returns(response);
|
||||
}
|
||||
|
||||
private void GivenTheReRouteHasPreFindAndReplaceSetUp()
|
||||
{
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
var reRoute = new ReRouteBuilder().WithUpstreamHeaderFindAndReplace(fAndRs).WithDownstreamHeaderFindAndReplace(fAndRs).Build();
|
||||
var dR = new DownstreamRoute(null, reRoute);
|
||||
var response = new OkResponse<DownstreamRoute>(dR);
|
||||
ScopedRepository.Setup(x => x.Get<DownstreamRoute>("DownstreamRoute")).Returns(response);
|
||||
}
|
||||
|
||||
private void ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly()
|
||||
{
|
||||
_preReplacer.Verify(x => x.Replace(It.IsAny<HttpContext>(), It.IsAny<List<HeaderFindAndReplace>>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheIHttpResponseHeaderReplacerIsCalledCorrectly()
|
||||
{
|
||||
_postReplacer.Verify(x => x.Replace(It.IsAny<HttpResponseMessage>(), It.IsAny<List<HeaderFindAndReplace>>(), It.IsAny<HttpRequestMessage>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheFollowingRequest()
|
||||
{
|
||||
Client.DefaultRequestHeaders.Add("test", "test");
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
services.AddSingleton(_preReplacer.Object);
|
||||
services.AddSingleton(_postReplacer.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseHttpHeadersTransformationMiddleware();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,97 +1,97 @@
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Headers;
|
||||
using Ocelot.Headers.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class HttpRequestHeadersBuilderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IAddHeadersToRequest> _addHeaders;
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public HttpRequestHeadersBuilderMiddlewareTests()
|
||||
{
|
||||
_addHeaders = new Mock<IAddHeadersToRequest>();
|
||||
|
||||
_downstreamRequest = new HttpRequestMessage();
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_add_headers_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToHeaders(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("UserId", "Subject", "", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddHeadersToDownstreamRequestReturnsOk())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAddHeadersToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_addHeaders.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseHttpRequestHeadersBuilderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheAddHeadersToDownstreamRequestReturnsOk()
|
||||
{
|
||||
_addHeaders
|
||||
.Setup(x => x.SetHeadersOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<System.Security.Claims.Claim>>(),
|
||||
It.IsAny<HttpRequestMessage>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheAddHeadersToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addHeaders
|
||||
.Verify(x => x.SetHeadersOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<System.Security.Claims.Claim>>(),
|
||||
_downstreamRequest), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Headers;
|
||||
using Ocelot.Headers.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class HttpRequestHeadersBuilderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IAddHeadersToRequest> _addHeaders;
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public HttpRequestHeadersBuilderMiddlewareTests()
|
||||
{
|
||||
_addHeaders = new Mock<IAddHeadersToRequest>();
|
||||
|
||||
_downstreamRequest = new HttpRequestMessage();
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_add_headers_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToHeaders(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("UserId", "Subject", "", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddHeadersToDownstreamRequestReturnsOk())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAddHeadersToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_addHeaders.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseHttpRequestHeadersBuilderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheAddHeadersToDownstreamRequestReturnsOk()
|
||||
{
|
||||
_addHeaders
|
||||
.Setup(x => x.SetHeadersOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<System.Security.Claims.Claim>>(),
|
||||
It.IsAny<HttpRequestMessage>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheAddHeadersToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addHeaders
|
||||
.Verify(x => x.SetHeadersOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<System.Security.Claims.Claim>>(),
|
||||
_downstreamRequest), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,235 +1,235 @@
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using System.Net.Http;
|
||||
using Ocelot.Headers;
|
||||
using Ocelot.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Responses;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class HttpResponseHeaderReplacerTests
|
||||
{
|
||||
private HttpResponseMessage _response;
|
||||
private HttpResponseHeaderReplacer _replacer;
|
||||
private List<HeaderFindAndReplace> _headerFindAndReplaces;
|
||||
private Response _result;
|
||||
private HttpRequestMessage _request;
|
||||
|
||||
public HttpResponseHeaderReplacerTests()
|
||||
{
|
||||
_replacer = new HttpResponseHeaderReplacer();
|
||||
}
|
||||
[Fact]
|
||||
public void should_replace_headers()
|
||||
{
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("test", "test");
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("test", "test", "chiken", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeadersAreReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_replace_headers()
|
||||
{
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("test", "test");
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeadersAreNotReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_with_ocelot_base_url()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com/";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_with_ocelot_base_url_with_port()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com/";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:123/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com:123/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_with_ocelot_base_url_and_path()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com/test/product";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com/test/product"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_with_ocelot_base_url_with_path_and_port()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com/test/product";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:123/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com:123/test/product"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_and_port_with_ocelot_base_url()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com:123/test/product";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com/test/product"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_and_port_with_ocelot_base_url_and_port()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com:123/test/product";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:321/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com:321/test/product"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheRequestIs(HttpRequestMessage request)
|
||||
{
|
||||
_request = request;
|
||||
}
|
||||
|
||||
private void ThenTheHeadersAreNotReplaced()
|
||||
{
|
||||
_result.ShouldBeOfType<OkResponse>();
|
||||
foreach (var f in _headerFindAndReplaces)
|
||||
{
|
||||
_response.Headers.TryGetValues(f.Key, out var values);
|
||||
values.ToList()[f.Index].ShouldBe("test");
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheFollowingHeaderReplacements(List<HeaderFindAndReplace> fAndRs)
|
||||
{
|
||||
_headerFindAndReplaces = fAndRs;
|
||||
}
|
||||
|
||||
private void GivenTheHttpResponse(HttpResponseMessage response)
|
||||
{
|
||||
_response = response;
|
||||
}
|
||||
|
||||
private void WhenICallTheReplacer()
|
||||
{
|
||||
_result = _replacer.Replace(_response, _headerFindAndReplaces, _request);
|
||||
}
|
||||
|
||||
private void ThenTheHeaderShouldBe(string key, string value)
|
||||
{
|
||||
var test = _response.Headers.GetValues(key);
|
||||
test.First().ShouldBe(value);
|
||||
}
|
||||
|
||||
private void ThenTheHeadersAreReplaced()
|
||||
{
|
||||
_result.ShouldBeOfType<OkResponse>();
|
||||
foreach (var f in _headerFindAndReplaces)
|
||||
{
|
||||
_response.Headers.TryGetValues(f.Key, out var values);
|
||||
values.ToList()[f.Index].ShouldBe(f.Replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using System.Net.Http;
|
||||
using Ocelot.Headers;
|
||||
using Ocelot.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Responses;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class HttpResponseHeaderReplacerTests
|
||||
{
|
||||
private HttpResponseMessage _response;
|
||||
private HttpResponseHeaderReplacer _replacer;
|
||||
private List<HeaderFindAndReplace> _headerFindAndReplaces;
|
||||
private Response _result;
|
||||
private HttpRequestMessage _request;
|
||||
|
||||
public HttpResponseHeaderReplacerTests()
|
||||
{
|
||||
_replacer = new HttpResponseHeaderReplacer();
|
||||
}
|
||||
[Fact]
|
||||
public void should_replace_headers()
|
||||
{
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("test", "test");
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("test", "test", "chiken", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeadersAreReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_replace_headers()
|
||||
{
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("test", "test");
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeadersAreNotReplaced())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_with_ocelot_base_url()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com/";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_with_ocelot_base_url_with_port()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com/";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:123/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com:123/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_with_ocelot_base_url_and_path()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com/test/product";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com/test/product"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_with_ocelot_base_url_with_path_and_port()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com/test/product";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:123/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com:123/test/product"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_and_port_with_ocelot_base_url()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com:123/test/product";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com/test/product"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_downstream_base_url_and_port_with_ocelot_base_url_and_port()
|
||||
{
|
||||
var downstreamUrl = "http://downstream.com:123/test/product";
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new System.Uri(downstreamUrl);
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
response.Headers.Add("Location", downstreamUrl);
|
||||
|
||||
var fAndRs = new List<HeaderFindAndReplace>();
|
||||
fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:321/", 0));
|
||||
|
||||
this.Given(x => GivenTheHttpResponse(response))
|
||||
.And(x => GivenTheRequestIs(request))
|
||||
.And(x => GivenTheFollowingHeaderReplacements(fAndRs))
|
||||
.When(x => WhenICallTheReplacer())
|
||||
.Then(x => ThenTheHeaderShouldBe("Location", "http://ocelot.com:321/test/product"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheRequestIs(HttpRequestMessage request)
|
||||
{
|
||||
_request = request;
|
||||
}
|
||||
|
||||
private void ThenTheHeadersAreNotReplaced()
|
||||
{
|
||||
_result.ShouldBeOfType<OkResponse>();
|
||||
foreach (var f in _headerFindAndReplaces)
|
||||
{
|
||||
_response.Headers.TryGetValues(f.Key, out var values);
|
||||
values.ToList()[f.Index].ShouldBe("test");
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheFollowingHeaderReplacements(List<HeaderFindAndReplace> fAndRs)
|
||||
{
|
||||
_headerFindAndReplaces = fAndRs;
|
||||
}
|
||||
|
||||
private void GivenTheHttpResponse(HttpResponseMessage response)
|
||||
{
|
||||
_response = response;
|
||||
}
|
||||
|
||||
private void WhenICallTheReplacer()
|
||||
{
|
||||
_result = _replacer.Replace(_response, _headerFindAndReplaces, _request);
|
||||
}
|
||||
|
||||
private void ThenTheHeaderShouldBe(string key, string value)
|
||||
{
|
||||
var test = _response.Headers.GetValues(key);
|
||||
test.First().ShouldBe(value);
|
||||
}
|
||||
|
||||
private void ThenTheHeadersAreReplaced()
|
||||
{
|
||||
_result.ShouldBeOfType<OkResponse>();
|
||||
foreach (var f in _headerFindAndReplaces)
|
||||
{
|
||||
_response.Headers.TryGetValues(f.Key, out var values);
|
||||
values.ToList()[f.Index].ShouldBe(f.Replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,52 +1,52 @@
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class RemoveHeadersTests
|
||||
{
|
||||
private HttpResponseHeaders _headers;
|
||||
private readonly Ocelot.Headers.RemoveOutputHeaders _removeOutputHeaders;
|
||||
private Response _result;
|
||||
|
||||
public RemoveHeadersTests()
|
||||
{
|
||||
_removeOutputHeaders = new Ocelot.Headers.RemoveOutputHeaders();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_remove_header()
|
||||
{
|
||||
var httpResponse = new HttpResponseMessage()
|
||||
{
|
||||
Headers = {{ "Transfer-Encoding", "chunked"}}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAHttpContext(httpResponse.Headers))
|
||||
.When(x => x.WhenIRemoveTheHeaders())
|
||||
.Then(x => x.TheHeaderIsNoLongerInTheContext())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAHttpContext(HttpResponseHeaders headers)
|
||||
{
|
||||
_headers = headers;
|
||||
}
|
||||
|
||||
private void WhenIRemoveTheHeaders()
|
||||
{
|
||||
_result = _removeOutputHeaders.Remove(_headers);
|
||||
}
|
||||
|
||||
private void TheHeaderIsNoLongerInTheContext()
|
||||
{
|
||||
_result.IsError.ShouldBeFalse();
|
||||
_headers.ShouldNotContain(x => x.Key == "Transfer-Encoding");
|
||||
_headers.ShouldNotContain(x => x.Key == "transfer-encoding");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Headers
|
||||
{
|
||||
public class RemoveHeadersTests
|
||||
{
|
||||
private HttpResponseHeaders _headers;
|
||||
private readonly Ocelot.Headers.RemoveOutputHeaders _removeOutputHeaders;
|
||||
private Response _result;
|
||||
|
||||
public RemoveHeadersTests()
|
||||
{
|
||||
_removeOutputHeaders = new Ocelot.Headers.RemoveOutputHeaders();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_remove_header()
|
||||
{
|
||||
var httpResponse = new HttpResponseMessage()
|
||||
{
|
||||
Headers = {{ "Transfer-Encoding", "chunked"}}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAHttpContext(httpResponse.Headers))
|
||||
.When(x => x.WhenIRemoveTheHeaders())
|
||||
.Then(x => x.TheHeaderIsNoLongerInTheContext())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAHttpContext(HttpResponseHeaders headers)
|
||||
{
|
||||
_headers = headers;
|
||||
}
|
||||
|
||||
private void WhenIRemoveTheHeaders()
|
||||
{
|
||||
_result = _removeOutputHeaders.Remove(_headers);
|
||||
}
|
||||
|
||||
private void TheHeaderIsNoLongerInTheContext()
|
||||
{
|
||||
_result.IsError.ShouldBeFalse();
|
||||
_headers.ShouldNotContain(x => x.Key == "Transfer-Encoding");
|
||||
_headers.ShouldNotContain(x => x.Key == "transfer-encoding");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,124 +1,124 @@
|
||||
using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.UnitTests.Infrastructure
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ClaimParserTests
|
||||
{
|
||||
private readonly IClaimsParser _claimsParser;
|
||||
private readonly List<Claim> _claims;
|
||||
private string _key;
|
||||
private Response<string> _result;
|
||||
private string _delimiter;
|
||||
private int _index;
|
||||
|
||||
public ClaimParserTests()
|
||||
{
|
||||
_claims = new List<Claim>();
|
||||
_claimsParser = new ClaimsParser();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_parse_claims_dictionary_access_string_returning_value_to_function()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("CustomerId", "1234")))
|
||||
.And(x => x.GivenTheKeyIs("CustomerId"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new OkResponse<string>("1234")))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_response_when_cannot_find_requested_claim()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("BallsId", "1234")))
|
||||
.And(x => x.GivenTheKeyIs("CustomerId"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new CannotFindClaimError($"Cannot find claim for key: {_key}")
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_parse_claims_dictionary_access_string_using_delimiter_and_retuning_at_correct_index()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("Subject", "registered|4321")))
|
||||
.And(x => x.GivenTheDelimiterIs("|"))
|
||||
.And(x => x.GivenTheIndexIs(1))
|
||||
.And(x => x.GivenTheKeyIs("Subject"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new OkResponse<string>("4321")))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_response_if_index_too_large()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("Subject", "registered|4321")))
|
||||
.And(x => x.GivenTheDelimiterIs("|"))
|
||||
.And(x => x.GivenTheIndexIs(24))
|
||||
.And(x => x.GivenTheKeyIs("Subject"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new CannotFindClaimError($"Cannot find claim for key: {_key}, delimiter: {_delimiter}, index: {_index}")
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_response_if_index_too_small()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("Subject", "registered|4321")))
|
||||
.And(x => x.GivenTheDelimiterIs("|"))
|
||||
.And(x => x.GivenTheIndexIs(-1))
|
||||
.And(x => x.GivenTheKeyIs("Subject"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new CannotFindClaimError($"Cannot find claim for key: {_key}, delimiter: {_delimiter}, index: {_index}")
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheIndexIs(int index)
|
||||
{
|
||||
_index = index;
|
||||
}
|
||||
|
||||
private void GivenTheDelimiterIs(string delimiter)
|
||||
{
|
||||
_delimiter = delimiter;
|
||||
}
|
||||
|
||||
private void GivenAClaimOf(Claim claim)
|
||||
{
|
||||
_claims.Add(claim);
|
||||
}
|
||||
|
||||
private void GivenTheKeyIs(string key)
|
||||
{
|
||||
_key = key;
|
||||
}
|
||||
|
||||
private void WhenICallTheParser()
|
||||
{
|
||||
_result = _claimsParser.GetValue(_claims, _key, _delimiter, _index);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(Response<string> expected)
|
||||
{
|
||||
_result.Data.ShouldBe(expected.Data);
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
}
|
||||
}
|
||||
using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.UnitTests.Infrastructure
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ClaimParserTests
|
||||
{
|
||||
private readonly IClaimsParser _claimsParser;
|
||||
private readonly List<Claim> _claims;
|
||||
private string _key;
|
||||
private Response<string> _result;
|
||||
private string _delimiter;
|
||||
private int _index;
|
||||
|
||||
public ClaimParserTests()
|
||||
{
|
||||
_claims = new List<Claim>();
|
||||
_claimsParser = new ClaimsParser();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_parse_claims_dictionary_access_string_returning_value_to_function()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("CustomerId", "1234")))
|
||||
.And(x => x.GivenTheKeyIs("CustomerId"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new OkResponse<string>("1234")))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_response_when_cannot_find_requested_claim()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("BallsId", "1234")))
|
||||
.And(x => x.GivenTheKeyIs("CustomerId"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new CannotFindClaimError($"Cannot find claim for key: {_key}")
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void can_parse_claims_dictionary_access_string_using_delimiter_and_retuning_at_correct_index()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("Subject", "registered|4321")))
|
||||
.And(x => x.GivenTheDelimiterIs("|"))
|
||||
.And(x => x.GivenTheIndexIs(1))
|
||||
.And(x => x.GivenTheKeyIs("Subject"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new OkResponse<string>("4321")))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_response_if_index_too_large()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("Subject", "registered|4321")))
|
||||
.And(x => x.GivenTheDelimiterIs("|"))
|
||||
.And(x => x.GivenTheIndexIs(24))
|
||||
.And(x => x.GivenTheKeyIs("Subject"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new CannotFindClaimError($"Cannot find claim for key: {_key}, delimiter: {_delimiter}, index: {_index}")
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_response_if_index_too_small()
|
||||
{
|
||||
this.Given(x => x.GivenAClaimOf(new Claim("Subject", "registered|4321")))
|
||||
.And(x => x.GivenTheDelimiterIs("|"))
|
||||
.And(x => x.GivenTheIndexIs(-1))
|
||||
.And(x => x.GivenTheKeyIs("Subject"))
|
||||
.When(x => x.WhenICallTheParser())
|
||||
.Then(x => x.ThenTheResultIs(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new CannotFindClaimError($"Cannot find claim for key: {_key}, delimiter: {_delimiter}, index: {_index}")
|
||||
})))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheIndexIs(int index)
|
||||
{
|
||||
_index = index;
|
||||
}
|
||||
|
||||
private void GivenTheDelimiterIs(string delimiter)
|
||||
{
|
||||
_delimiter = delimiter;
|
||||
}
|
||||
|
||||
private void GivenAClaimOf(Claim claim)
|
||||
{
|
||||
_claims.Add(claim);
|
||||
}
|
||||
|
||||
private void GivenTheKeyIs(string key)
|
||||
{
|
||||
_key = key;
|
||||
}
|
||||
|
||||
private void WhenICallTheParser()
|
||||
{
|
||||
_result = _claimsParser.GetValue(_claims, _key, _delimiter, _index);
|
||||
}
|
||||
|
||||
private void ThenTheResultIs(Response<string> expected)
|
||||
{
|
||||
_result.Data.ShouldBe(expected.Data);
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,124 +1,124 @@
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Moq;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.UnitTests.Infrastructure
|
||||
{
|
||||
public class ScopesAuthoriserTests
|
||||
{
|
||||
private ScopesAuthoriser _authoriser;
|
||||
public Mock<IClaimsParser> _parser;
|
||||
private ClaimsPrincipal _principal;
|
||||
private List<string> _allowedScopes;
|
||||
private Response<bool> _result;
|
||||
|
||||
public ScopesAuthoriserTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_authoriser = new ScopesAuthoriser(_parser.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ok_if_no_allowed_scopes()
|
||||
{
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheFollowing(new List<string>()))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_return_ok_if_null_allowed_scopes()
|
||||
{
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheFollowing((List<string>)null))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_claims_parser_returns_error()
|
||||
{
|
||||
var fakeError = new FakeError();
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheParserReturns(new ErrorResponse<List<string>>(fakeError)))
|
||||
.And(_ => GivenTheFollowing(new List<string>(){"doesntmatter"}))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_scopes_and_return_ok_result()
|
||||
{
|
||||
var claimsPrincipal = new ClaimsPrincipal();
|
||||
var allowedScopes = new List<string>(){"someScope"};
|
||||
|
||||
this.Given(_ => GivenTheFollowing(claimsPrincipal))
|
||||
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(allowedScopes)))
|
||||
.And(_ => GivenTheFollowing(allowedScopes))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_scopes_and_return_error_result()
|
||||
{
|
||||
var fakeError = new FakeError();
|
||||
var claimsPrincipal = new ClaimsPrincipal();
|
||||
var allowedScopes = new List<string>(){"someScope"};
|
||||
var userScopes = new List<string>(){"anotherScope"};
|
||||
|
||||
this.Given(_ => GivenTheFollowing(claimsPrincipal))
|
||||
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(userScopes)))
|
||||
.And(_ => GivenTheFollowing(allowedScopes))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheParserReturns(Response<List<string>> response)
|
||||
{
|
||||
_parser.Setup(x => x.GetValuesByClaimType(It.IsAny<IEnumerable<Claim>>(), It.IsAny<string>())).Returns(response);
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(ClaimsPrincipal principal)
|
||||
{
|
||||
_principal = principal;
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(List<string> allowedScopes)
|
||||
{
|
||||
_allowedScopes = allowedScopes;
|
||||
}
|
||||
|
||||
private void WhenIAuthorise()
|
||||
{
|
||||
_result = _authoriser.Authorise(_principal, _allowedScopes);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(Response<bool> expected)
|
||||
{
|
||||
_result.Data.ShouldBe(expected.Data);
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
}
|
||||
|
||||
public class FakeError : Error
|
||||
{
|
||||
public FakeError() : base("fake error", OcelotErrorCode.CannotAddDataError)
|
||||
{
|
||||
}
|
||||
}
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Moq;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.UnitTests.Infrastructure
|
||||
{
|
||||
public class ScopesAuthoriserTests
|
||||
{
|
||||
private ScopesAuthoriser _authoriser;
|
||||
public Mock<IClaimsParser> _parser;
|
||||
private ClaimsPrincipal _principal;
|
||||
private List<string> _allowedScopes;
|
||||
private Response<bool> _result;
|
||||
|
||||
public ScopesAuthoriserTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_authoriser = new ScopesAuthoriser(_parser.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ok_if_no_allowed_scopes()
|
||||
{
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheFollowing(new List<string>()))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_return_ok_if_null_allowed_scopes()
|
||||
{
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheFollowing((List<string>)null))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_claims_parser_returns_error()
|
||||
{
|
||||
var fakeError = new FakeError();
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheParserReturns(new ErrorResponse<List<string>>(fakeError)))
|
||||
.And(_ => GivenTheFollowing(new List<string>(){"doesntmatter"}))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_scopes_and_return_ok_result()
|
||||
{
|
||||
var claimsPrincipal = new ClaimsPrincipal();
|
||||
var allowedScopes = new List<string>(){"someScope"};
|
||||
|
||||
this.Given(_ => GivenTheFollowing(claimsPrincipal))
|
||||
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(allowedScopes)))
|
||||
.And(_ => GivenTheFollowing(allowedScopes))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_scopes_and_return_error_result()
|
||||
{
|
||||
var fakeError = new FakeError();
|
||||
var claimsPrincipal = new ClaimsPrincipal();
|
||||
var allowedScopes = new List<string>(){"someScope"};
|
||||
var userScopes = new List<string>(){"anotherScope"};
|
||||
|
||||
this.Given(_ => GivenTheFollowing(claimsPrincipal))
|
||||
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(userScopes)))
|
||||
.And(_ => GivenTheFollowing(allowedScopes))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheParserReturns(Response<List<string>> response)
|
||||
{
|
||||
_parser.Setup(x => x.GetValuesByClaimType(It.IsAny<IEnumerable<Claim>>(), It.IsAny<string>())).Returns(response);
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(ClaimsPrincipal principal)
|
||||
{
|
||||
_principal = principal;
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(List<string> allowedScopes)
|
||||
{
|
||||
_allowedScopes = allowedScopes;
|
||||
}
|
||||
|
||||
private void WhenIAuthorise()
|
||||
{
|
||||
_result = _authoriser.Authorise(_principal, _allowedScopes);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(Response<bool> expected)
|
||||
{
|
||||
_result.Data.ShouldBe(expected.Data);
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
}
|
||||
|
||||
public class FakeError : Error
|
||||
{
|
||||
public FakeError() : base("fake error", OcelotErrorCode.CannotAddDataError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,285 +1,285 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class LeastConnectionTests
|
||||
{
|
||||
private HostAndPort _hostAndPort;
|
||||
private Response<HostAndPort> _result;
|
||||
private LeastConnection _leastConnection;
|
||||
private List<Service> _services;
|
||||
private Random _random;
|
||||
|
||||
public LeastConnectionTests()
|
||||
{
|
||||
_random = new Random();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_able_to_lease_and_release_concurrently()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
_services = availableServices;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
|
||||
var tasks = new Task[100];
|
||||
|
||||
for(var i = 0; i < tasks.Length; i++)
|
||||
{
|
||||
tasks[i] = LeaseDelayAndRelease();
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_handle_service_returning_to_available()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(availableServices), serviceName);
|
||||
|
||||
var hostAndPortOne = _leastConnection.Lease().Result;
|
||||
hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
|
||||
var hostAndPortTwo = _leastConnection.Lease().Result;
|
||||
hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.2");
|
||||
_leastConnection.Release(hostAndPortOne.Data);
|
||||
_leastConnection.Release(hostAndPortTwo.Data);
|
||||
|
||||
availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
hostAndPortOne = _leastConnection.Lease().Result;
|
||||
hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
|
||||
hostAndPortTwo = _leastConnection.Lease().Result;
|
||||
hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.1");
|
||||
_leastConnection.Release(hostAndPortOne.Data);
|
||||
_leastConnection.Release(hostAndPortTwo.Data);
|
||||
|
||||
availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
hostAndPortOne = _leastConnection.Lease().Result;
|
||||
hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
|
||||
hostAndPortTwo = _leastConnection.Lease().Result;
|
||||
hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.2");
|
||||
_leastConnection.Release(hostAndPortOne.Data);
|
||||
_leastConnection.Release(hostAndPortTwo.Data);
|
||||
|
||||
}
|
||||
|
||||
private async Task LeaseDelayAndRelease()
|
||||
{
|
||||
var hostAndPort = await _leastConnection.Lease();
|
||||
await Task.Delay(_random.Next(1, 100));
|
||||
_leastConnection.Release(hostAndPort.Data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_next_url()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var hostAndPort = new HostAndPort("localhost", 80);
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, hostAndPort, string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAHostAndPort(hostAndPort))
|
||||
.And(x => x.GivenTheLoadBalancerStarts(availableServices, serviceName))
|
||||
.When(x => x.WhenIGetTheNextHostAndPort())
|
||||
.Then(x => x.ThenTheNextHostAndPortIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_serve_from_service_with_least_connections()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new HostAndPort("127.0.0.3", 80), string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
|
||||
_services = availableServices;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
|
||||
var response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[2].HostAndPort.DownstreamHost);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_connections_per_service()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
_services = availableServices;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
|
||||
var response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_release_connection()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
_services = availableServices;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
|
||||
var response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
|
||||
//release this so 2 should have 1 connection and we should get 2 back as our next host and port
|
||||
_leastConnection.Release(availableServices[1].HostAndPort);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_services_are_null()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var hostAndPort = new HostAndPort("localhost", 80);
|
||||
this.Given(x => x.GivenAHostAndPort(hostAndPort))
|
||||
.And(x => x.GivenTheLoadBalancerStarts(null, serviceName))
|
||||
.When(x => x.WhenIGetTheNextHostAndPort())
|
||||
.Then(x => x.ThenServiceAreNullErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_services_are_empty()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var hostAndPort = new HostAndPort("localhost", 80);
|
||||
this.Given(x => x.GivenAHostAndPort(hostAndPort))
|
||||
.And(x => x.GivenTheLoadBalancerStarts(new List<Service>(), serviceName))
|
||||
.When(x => x.WhenIGetTheNextHostAndPort())
|
||||
.Then(x => x.ThenServiceAreEmptyErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenServiceAreNullErrorIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
_result.Errors[0].ShouldBeOfType<ServicesAreNullError>();
|
||||
}
|
||||
|
||||
private void ThenServiceAreEmptyErrorIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
_result.Errors[0].ShouldBeOfType<ServicesAreEmptyError>();
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerStarts(List<Service> services, string serviceName)
|
||||
{
|
||||
_services = services;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
}
|
||||
|
||||
private void WhenTheLoadBalancerStarts(List<Service> services, string serviceName)
|
||||
{
|
||||
GivenTheLoadBalancerStarts(services, serviceName);
|
||||
}
|
||||
|
||||
private void GivenAHostAndPort(HostAndPort hostAndPort)
|
||||
{
|
||||
_hostAndPort = hostAndPort;
|
||||
}
|
||||
|
||||
private void WhenIGetTheNextHostAndPort()
|
||||
{
|
||||
_result = _leastConnection.Lease().Result;
|
||||
}
|
||||
|
||||
private void ThenTheNextHostAndPortIsReturned()
|
||||
{
|
||||
_result.Data.DownstreamHost.ShouldBe(_hostAndPort.DownstreamHost);
|
||||
_result.Data.DownstreamPort.ShouldBe(_hostAndPort.DownstreamPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class LeastConnectionTests
|
||||
{
|
||||
private ServiceHostAndPort _hostAndPort;
|
||||
private Response<ServiceHostAndPort> _result;
|
||||
private LeastConnection _leastConnection;
|
||||
private List<Service> _services;
|
||||
private Random _random;
|
||||
|
||||
public LeastConnectionTests()
|
||||
{
|
||||
_random = new Random();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_be_able_to_lease_and_release_concurrently()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
_services = availableServices;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
|
||||
var tasks = new Task[100];
|
||||
|
||||
for(var i = 0; i < tasks.Length; i++)
|
||||
{
|
||||
tasks[i] = LeaseDelayAndRelease();
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_handle_service_returning_to_available()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(availableServices), serviceName);
|
||||
|
||||
var hostAndPortOne = _leastConnection.Lease().Result;
|
||||
hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
|
||||
var hostAndPortTwo = _leastConnection.Lease().Result;
|
||||
hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.2");
|
||||
_leastConnection.Release(hostAndPortOne.Data);
|
||||
_leastConnection.Release(hostAndPortTwo.Data);
|
||||
|
||||
availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
hostAndPortOne = _leastConnection.Lease().Result;
|
||||
hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
|
||||
hostAndPortTwo = _leastConnection.Lease().Result;
|
||||
hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.1");
|
||||
_leastConnection.Release(hostAndPortOne.Data);
|
||||
_leastConnection.Release(hostAndPortTwo.Data);
|
||||
|
||||
availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
hostAndPortOne = _leastConnection.Lease().Result;
|
||||
hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1");
|
||||
hostAndPortTwo = _leastConnection.Lease().Result;
|
||||
hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.2");
|
||||
_leastConnection.Release(hostAndPortOne.Data);
|
||||
_leastConnection.Release(hostAndPortTwo.Data);
|
||||
|
||||
}
|
||||
|
||||
private async Task LeaseDelayAndRelease()
|
||||
{
|
||||
var hostAndPort = await _leastConnection.Lease();
|
||||
await Task.Delay(_random.Next(1, 100));
|
||||
_leastConnection.Release(hostAndPort.Data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_next_url()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var hostAndPort = new ServiceHostAndPort("localhost", 80);
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, hostAndPort, string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAHostAndPort(hostAndPort))
|
||||
.And(x => x.GivenTheLoadBalancerStarts(availableServices, serviceName))
|
||||
.When(x => x.WhenIGetTheNextHostAndPort())
|
||||
.Then(x => x.ThenTheNextHostAndPortIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_serve_from_service_with_least_connections()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.3", 80), string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
|
||||
_services = availableServices;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
|
||||
var response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[2].HostAndPort.DownstreamHost);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_build_connections_per_service()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
_services = availableServices;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
|
||||
var response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_release_connection()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var availableServices = new List<Service>
|
||||
{
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
|
||||
new Service(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
|
||||
};
|
||||
|
||||
_services = availableServices;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
|
||||
var response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
|
||||
//release this so 2 should have 1 connection and we should get 2 back as our next host and port
|
||||
_leastConnection.Release(availableServices[1].HostAndPort);
|
||||
|
||||
response = _leastConnection.Lease().Result;
|
||||
|
||||
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_services_are_null()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var hostAndPort = new ServiceHostAndPort("localhost", 80);
|
||||
this.Given(x => x.GivenAHostAndPort(hostAndPort))
|
||||
.And(x => x.GivenTheLoadBalancerStarts(null, serviceName))
|
||||
.When(x => x.WhenIGetTheNextHostAndPort())
|
||||
.Then(x => x.ThenServiceAreNullErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_services_are_empty()
|
||||
{
|
||||
var serviceName = "products";
|
||||
|
||||
var hostAndPort = new ServiceHostAndPort("localhost", 80);
|
||||
this.Given(x => x.GivenAHostAndPort(hostAndPort))
|
||||
.And(x => x.GivenTheLoadBalancerStarts(new List<Service>(), serviceName))
|
||||
.When(x => x.WhenIGetTheNextHostAndPort())
|
||||
.Then(x => x.ThenServiceAreEmptyErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenServiceAreNullErrorIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
_result.Errors[0].ShouldBeOfType<ServicesAreNullError>();
|
||||
}
|
||||
|
||||
private void ThenServiceAreEmptyErrorIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeTrue();
|
||||
_result.Errors[0].ShouldBeOfType<ServicesAreEmptyError>();
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerStarts(List<Service> services, string serviceName)
|
||||
{
|
||||
_services = services;
|
||||
_leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName);
|
||||
}
|
||||
|
||||
private void WhenTheLoadBalancerStarts(List<Service> services, string serviceName)
|
||||
{
|
||||
GivenTheLoadBalancerStarts(services, serviceName);
|
||||
}
|
||||
|
||||
private void GivenAHostAndPort(ServiceHostAndPort hostAndPort)
|
||||
{
|
||||
_hostAndPort = hostAndPort;
|
||||
}
|
||||
|
||||
private void WhenIGetTheNextHostAndPort()
|
||||
{
|
||||
_result = _leastConnection.Lease().Result;
|
||||
}
|
||||
|
||||
private void ThenTheNextHostAndPortIsReturned()
|
||||
{
|
||||
_result.Data.DownstreamHost.ShouldBe(_hostAndPort.DownstreamHost);
|
||||
_result.Data.DownstreamPort.ShouldBe(_hostAndPort.DownstreamPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,125 +1,125 @@
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class LoadBalancerFactoryTests
|
||||
{
|
||||
private ReRoute _reRoute;
|
||||
private LoadBalancerFactory _factory;
|
||||
private ILoadBalancer _result;
|
||||
private Mock<IServiceDiscoveryProviderFactory> _serviceProviderFactory;
|
||||
private Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private ServiceProviderConfiguration _serviceProviderConfig;
|
||||
|
||||
public LoadBalancerFactoryTests()
|
||||
{
|
||||
_serviceProviderFactory = new Mock<IServiceDiscoveryProviderFactory>();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
_factory = new LoadBalancerFactory(_serviceProviderFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_load_balancer()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<NoLoadBalancer>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_round_robin_load_balancer()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithLoadBalancer("RoundRobin")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<RoundRobin>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_round_least_connection_balancer()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithLoadBalancer("LeastConnection")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<LeastConnection>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_service_provider()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithLoadBalancer("RoundRobin")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheServiceProviderIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAServiceProviderConfig(ServiceProviderConfiguration serviceProviderConfig)
|
||||
{
|
||||
_serviceProviderConfig = serviceProviderConfig;
|
||||
}
|
||||
|
||||
private void GivenTheServiceProviderFactoryReturns()
|
||||
{
|
||||
_serviceProviderFactory
|
||||
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()))
|
||||
.Returns(_serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void ThenTheServiceProviderIsCalledCorrectly()
|
||||
{
|
||||
_serviceProviderFactory
|
||||
.Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenAReRoute(ReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_result = _factory.Get(_reRoute, _serviceProviderConfig).Result;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class LoadBalancerFactoryTests
|
||||
{
|
||||
private ReRoute _reRoute;
|
||||
private LoadBalancerFactory _factory;
|
||||
private ILoadBalancer _result;
|
||||
private Mock<IServiceDiscoveryProviderFactory> _serviceProviderFactory;
|
||||
private Mock<IServiceDiscoveryProvider> _serviceProvider;
|
||||
private ServiceProviderConfiguration _serviceProviderConfig;
|
||||
|
||||
public LoadBalancerFactoryTests()
|
||||
{
|
||||
_serviceProviderFactory = new Mock<IServiceDiscoveryProviderFactory>();
|
||||
_serviceProvider = new Mock<IServiceDiscoveryProvider>();
|
||||
_factory = new LoadBalancerFactory(_serviceProviderFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_load_balancer()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<NoLoadBalancer>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_round_robin_load_balancer()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithLoadBalancer("RoundRobin")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<RoundRobin>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_round_least_connection_balancer()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithLoadBalancer("LeastConnection")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheLoadBalancerIsReturned<LeastConnection>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_service_provider()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithLoadBalancer("RoundRobin")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build()))
|
||||
.And(x => x.GivenTheServiceProviderFactoryReturns())
|
||||
.When(x => x.WhenIGetTheLoadBalancer())
|
||||
.Then(x => x.ThenTheServiceProviderIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAServiceProviderConfig(ServiceProviderConfiguration serviceProviderConfig)
|
||||
{
|
||||
_serviceProviderConfig = serviceProviderConfig;
|
||||
}
|
||||
|
||||
private void GivenTheServiceProviderFactoryReturns()
|
||||
{
|
||||
_serviceProviderFactory
|
||||
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()))
|
||||
.Returns(_serviceProvider.Object);
|
||||
}
|
||||
|
||||
private void ThenTheServiceProviderIsCalledCorrectly()
|
||||
{
|
||||
_serviceProviderFactory
|
||||
.Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenAReRoute(ReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheLoadBalancer()
|
||||
{
|
||||
_result = _factory.Get(_reRoute, _serviceProviderConfig).Result;
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIsReturned<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,165 +1,165 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class LoadBalancerHouseTests
|
||||
{
|
||||
private ReRoute _reRoute;
|
||||
private ILoadBalancer _loadBalancer;
|
||||
private readonly LoadBalancerHouse _loadBalancerHouse;
|
||||
private Response _addResult;
|
||||
private Response<ILoadBalancer> _getResult;
|
||||
private string _key;
|
||||
private Mock<ILoadBalancerFactory> _factory;
|
||||
private ServiceProviderConfiguration _serviceProviderConfig;
|
||||
|
||||
public LoadBalancerHouseTests()
|
||||
{
|
||||
_factory = new Mock<ILoadBalancerFactory>();
|
||||
_loadBalancerHouse = new LoadBalancerHouse(_factory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_store_load_balancer_on_first_request()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.Then(x => x.ThenItIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_store_load_balancer_on_second_request()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
.Then(x => x.ThenItIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_store_load_balancers_by_key()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("testtwo").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.And(x => x.GivenThereIsALoadBalancer(reRouteTwo, new FakeRoundRobinLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeLoadBalancer>())
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRouteTwo))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeRoundRobinLoadBalancer>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_exception()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().Build();
|
||||
|
||||
this.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
.Then(x => x.ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_new_load_balancer_if_reroute_load_balancer_has_changed()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
|
||||
|
||||
var reRouteTwo = new ReRouteBuilder().WithLoadBalancer("LeastConnection").WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeLoadBalancer>())
|
||||
.When(x => x.WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(reRouteTwo))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<LeastConnection>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(ReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(new LeastConnection(null, null));
|
||||
_getResult = _loadBalancerHouse.Get(_reRoute, _serviceProviderConfig).Result;
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_getResult.IsError.ShouldBeTrue();
|
||||
_getResult.Errors[0].ShouldBeOfType<UnableToFindLoadBalancerError>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIs<T>()
|
||||
{
|
||||
_getResult.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenItIsAdded()
|
||||
{
|
||||
_getResult.IsError.ShouldBe(false);
|
||||
_getResult.ShouldBeOfType<OkResponse<ILoadBalancer>>();
|
||||
_getResult.Data.ShouldBe(_loadBalancer);
|
||||
_factory.Verify(x => x.Get(_reRoute, _serviceProviderConfig), Times.Once);
|
||||
}
|
||||
|
||||
|
||||
private void GivenThereIsALoadBalancer(ReRoute reRoute, ILoadBalancer loadBalancer)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_loadBalancer = loadBalancer;
|
||||
_factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(loadBalancer);
|
||||
_getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
|
||||
}
|
||||
|
||||
private void WhenWeGetTheLoadBalancer(ReRoute reRoute)
|
||||
{
|
||||
_getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
|
||||
}
|
||||
|
||||
private void ThenItIsReturned()
|
||||
{
|
||||
_getResult.Data.ShouldBe(_loadBalancer);
|
||||
_factory.Verify(x => x.Get(_reRoute, _serviceProviderConfig), Times.Once);
|
||||
}
|
||||
|
||||
class FakeLoadBalancer : ILoadBalancer
|
||||
{
|
||||
public Task<Response<HostAndPort>> Lease()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Release(HostAndPort hostAndPort)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
class FakeRoundRobinLoadBalancer : ILoadBalancer
|
||||
{
|
||||
public Task<Response<HostAndPort>> Lease()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Release(HostAndPort hostAndPort)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class LoadBalancerHouseTests
|
||||
{
|
||||
private ReRoute _reRoute;
|
||||
private ILoadBalancer _loadBalancer;
|
||||
private readonly LoadBalancerHouse _loadBalancerHouse;
|
||||
private Response _addResult;
|
||||
private Response<ILoadBalancer> _getResult;
|
||||
private string _key;
|
||||
private Mock<ILoadBalancerFactory> _factory;
|
||||
private ServiceProviderConfiguration _serviceProviderConfig;
|
||||
|
||||
public LoadBalancerHouseTests()
|
||||
{
|
||||
_factory = new Mock<ILoadBalancerFactory>();
|
||||
_loadBalancerHouse = new LoadBalancerHouse(_factory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_store_load_balancer_on_first_request()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.Then(x => x.ThenItIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_store_load_balancer_on_second_request()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
.Then(x => x.ThenItIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_store_load_balancers_by_key()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("testtwo").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.And(x => x.GivenThereIsALoadBalancer(reRouteTwo, new FakeRoundRobinLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeLoadBalancer>())
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRouteTwo))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeRoundRobinLoadBalancer>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_exception()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().Build();
|
||||
|
||||
this.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
.Then(x => x.ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_new_load_balancer_if_reroute_load_balancer_has_changed()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
|
||||
|
||||
var reRouteTwo = new ReRouteBuilder().WithLoadBalancer("LeastConnection").WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
|
||||
.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<FakeLoadBalancer>())
|
||||
.When(x => x.WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(reRouteTwo))
|
||||
.Then(x => x.ThenTheLoadBalancerIs<LeastConnection>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(ReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(new LeastConnection(null, null));
|
||||
_getResult = _loadBalancerHouse.Get(_reRoute, _serviceProviderConfig).Result;
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_getResult.IsError.ShouldBeTrue();
|
||||
_getResult.Errors[0].ShouldBeOfType<UnableToFindLoadBalancerError>();
|
||||
}
|
||||
|
||||
private void ThenTheLoadBalancerIs<T>()
|
||||
{
|
||||
_getResult.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenItIsAdded()
|
||||
{
|
||||
_getResult.IsError.ShouldBe(false);
|
||||
_getResult.ShouldBeOfType<OkResponse<ILoadBalancer>>();
|
||||
_getResult.Data.ShouldBe(_loadBalancer);
|
||||
_factory.Verify(x => x.Get(_reRoute, _serviceProviderConfig), Times.Once);
|
||||
}
|
||||
|
||||
|
||||
private void GivenThereIsALoadBalancer(ReRoute reRoute, ILoadBalancer loadBalancer)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_loadBalancer = loadBalancer;
|
||||
_factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(loadBalancer);
|
||||
_getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
|
||||
}
|
||||
|
||||
private void WhenWeGetTheLoadBalancer(ReRoute reRoute)
|
||||
{
|
||||
_getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
|
||||
}
|
||||
|
||||
private void ThenItIsReturned()
|
||||
{
|
||||
_getResult.Data.ShouldBe(_loadBalancer);
|
||||
_factory.Verify(x => x.Get(_reRoute, _serviceProviderConfig), Times.Once);
|
||||
}
|
||||
|
||||
class FakeLoadBalancer : ILoadBalancer
|
||||
{
|
||||
public Task<Response<ServiceHostAndPort>> Lease()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Release(ServiceHostAndPort hostAndPort)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
class FakeRoundRobinLoadBalancer : ILoadBalancer
|
||||
{
|
||||
public Task<Response<ServiceHostAndPort>> Lease()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Release(ServiceHostAndPort hostAndPort)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,209 +1,209 @@
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.LoadBalancer.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class LoadBalancerMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<ILoadBalancerHouse> _loadBalancerHouse;
|
||||
private readonly Mock<ILoadBalancer> _loadBalancer;
|
||||
private HostAndPort _hostAndPort;
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
private ErrorResponse<ILoadBalancer> _getLoadBalancerHouseError;
|
||||
private ErrorResponse<HostAndPort> _getHostAndPortError;
|
||||
private HttpRequestMessage _downstreamRequest;
|
||||
private ServiceProviderConfiguration _config;
|
||||
|
||||
public LoadBalancerMiddlewareTests()
|
||||
{
|
||||
_loadBalancerHouse = new Mock<ILoadBalancerHouse>();
|
||||
_loadBalancer = new Mock<ILoadBalancer>();
|
||||
_loadBalancerHouse = new Mock<ILoadBalancerHouse>();
|
||||
_downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "");
|
||||
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
|
||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheLoadBalancerHouseReturns())
|
||||
.And(x => x.GivenTheLoadBalancerReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamUrlIsReplacedWith("http://127.0.0.1:80/abc?q=123"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_pipeline_error_if_cannot_get_load_balancer()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
|
||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheLoadBalancerHouseReturnsAnError())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_pipeline_error_if_cannot_get_least()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
|
||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheLoadBalancerHouseReturns())
|
||||
.And(x => x.GivenTheLoadBalancerReturnsAnError())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenAnErrorStatingHostAndPortCouldNotBeFoundIsSetOnPipeline())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(ServiceProviderConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<ServiceProviderConfiguration>("ServiceProviderConfiguration")).Returns(new OkResponse<ServiceProviderConfiguration>(config));
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_loadBalancerHouse.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseLoadBalancingMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamUrlIs(string downstreamUrl)
|
||||
{
|
||||
_downstreamRequest.RequestUri = new System.Uri(downstreamUrl);
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerReturnsAnError()
|
||||
{
|
||||
_getHostAndPortError = new ErrorResponse<HostAndPort>(new List<Error>() { new ServicesAreNullError($"services were null for bah") });
|
||||
_loadBalancer
|
||||
.Setup(x => x.Lease())
|
||||
.ReturnsAsync(_getHostAndPortError);
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerReturns()
|
||||
{
|
||||
_hostAndPort = new HostAndPort("127.0.0.1", 80);
|
||||
_loadBalancer
|
||||
.Setup(x => x.Lease())
|
||||
.ReturnsAsync(new OkResponse<HostAndPort>(_hostAndPort));
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerHouseReturns()
|
||||
{
|
||||
_loadBalancerHouse
|
||||
.Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
|
||||
.ReturnsAsync(new OkResponse<ILoadBalancer>(_loadBalancer.Object));
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerHouseReturnsAnError()
|
||||
{
|
||||
_getLoadBalancerHouseError = new ErrorResponse<ILoadBalancer>(new List<Ocelot.Errors.Error>()
|
||||
{
|
||||
new UnableToFindLoadBalancerError($"unabe to find load balancer for bah")
|
||||
});
|
||||
|
||||
_loadBalancerHouse
|
||||
.Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
|
||||
.ReturnsAsync(_getLoadBalancerHouseError);
|
||||
}
|
||||
|
||||
private void ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
|
||||
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareErrors", _getLoadBalancerHouseError.Errors), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenAnErrorSayingReleaseFailedIsSetOnThePipeline()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
|
||||
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareErrors", It.IsAny<List<Error>>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenAnErrorStatingHostAndPortCouldNotBeFoundIsSetOnPipeline()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
|
||||
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareErrors", _getHostAndPortError.Errors), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamUrlIsReplacedWith(string expectedUri)
|
||||
{
|
||||
_downstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Configuration.Provider;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.LoadBalancer.Middleware;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class LoadBalancerMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<ILoadBalancerHouse> _loadBalancerHouse;
|
||||
private readonly Mock<ILoadBalancer> _loadBalancer;
|
||||
private ServiceHostAndPort _hostAndPort;
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
private ErrorResponse<ILoadBalancer> _getLoadBalancerHouseError;
|
||||
private ErrorResponse<ServiceHostAndPort> _getHostAndPortError;
|
||||
private HttpRequestMessage _downstreamRequest;
|
||||
private ServiceProviderConfiguration _config;
|
||||
|
||||
public LoadBalancerMiddlewareTests()
|
||||
{
|
||||
_loadBalancerHouse = new Mock<ILoadBalancerHouse>();
|
||||
_loadBalancer = new Mock<ILoadBalancer>();
|
||||
_loadBalancerHouse = new Mock<ILoadBalancerHouse>();
|
||||
_downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "");
|
||||
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
|
||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheLoadBalancerHouseReturns())
|
||||
.And(x => x.GivenTheLoadBalancerReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheDownstreamUrlIsReplacedWith("http://127.0.0.1:80/abc?q=123"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_pipeline_error_if_cannot_get_load_balancer()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
|
||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheLoadBalancerHouseReturnsAnError())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_pipeline_error_if_cannot_get_least()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
|
||||
.And(x => GivenTheConfigurationIs(serviceProviderConfig))
|
||||
.And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheLoadBalancerHouseReturns())
|
||||
.And(x => x.GivenTheLoadBalancerReturnsAnError())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenAnErrorStatingHostAndPortCouldNotBeFoundIsSetOnPipeline())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheConfigurationIs(ServiceProviderConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<ServiceProviderConfiguration>("ServiceProviderConfiguration")).Returns(new OkResponse<ServiceProviderConfiguration>(config));
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_loadBalancerHouse.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseLoadBalancingMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamUrlIs(string downstreamUrl)
|
||||
{
|
||||
_downstreamRequest.RequestUri = new System.Uri(downstreamUrl);
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerReturnsAnError()
|
||||
{
|
||||
_getHostAndPortError = new ErrorResponse<ServiceHostAndPort>(new List<Error>() { new ServicesAreNullError($"services were null for bah") });
|
||||
_loadBalancer
|
||||
.Setup(x => x.Lease())
|
||||
.ReturnsAsync(_getHostAndPortError);
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerReturns()
|
||||
{
|
||||
_hostAndPort = new ServiceHostAndPort("127.0.0.1", 80);
|
||||
_loadBalancer
|
||||
.Setup(x => x.Lease())
|
||||
.ReturnsAsync(new OkResponse<ServiceHostAndPort>(_hostAndPort));
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerHouseReturns()
|
||||
{
|
||||
_loadBalancerHouse
|
||||
.Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
|
||||
.ReturnsAsync(new OkResponse<ILoadBalancer>(_loadBalancer.Object));
|
||||
}
|
||||
|
||||
private void GivenTheLoadBalancerHouseReturnsAnError()
|
||||
{
|
||||
_getLoadBalancerHouseError = new ErrorResponse<ILoadBalancer>(new List<Ocelot.Errors.Error>()
|
||||
{
|
||||
new UnableToFindLoadBalancerError($"unabe to find load balancer for bah")
|
||||
});
|
||||
|
||||
_loadBalancerHouse
|
||||
.Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
|
||||
.ReturnsAsync(_getLoadBalancerHouseError);
|
||||
}
|
||||
|
||||
private void ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
|
||||
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareErrors", _getLoadBalancerHouseError.Errors), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenAnErrorSayingReleaseFailedIsSetOnThePipeline()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
|
||||
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareErrors", It.IsAny<List<Error>>()), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenAnErrorStatingHostAndPortCouldNotBeFoundIsSetOnPipeline()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
|
||||
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("OcelotMiddlewareErrors", _getHostAndPortError.Errors), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamUrlIsReplacedWith(string expectedUri)
|
||||
{
|
||||
_downstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class NoLoadBalancerTests
|
||||
{
|
||||
private List<Service> _services;
|
||||
private NoLoadBalancer _loadBalancer;
|
||||
private Response<HostAndPort> _result;
|
||||
|
||||
[Fact]
|
||||
public void should_return_host_and_port()
|
||||
{
|
||||
var hostAndPort = new HostAndPort("127.0.0.1", 80);
|
||||
|
||||
var services = new List<Service>
|
||||
{
|
||||
new Service("product", hostAndPort, string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
this.Given(x => x.GivenServices(services))
|
||||
.When(x => x.WhenIGetTheNextHostAndPort())
|
||||
.Then(x => x.ThenTheHostAndPortIs(hostAndPort))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenServices(List<Service> services)
|
||||
{
|
||||
_services = services;
|
||||
}
|
||||
|
||||
private void WhenIGetTheNextHostAndPort()
|
||||
{
|
||||
_loadBalancer = new NoLoadBalancer(_services);
|
||||
_result = _loadBalancer.Lease().Result;
|
||||
}
|
||||
|
||||
private void ThenTheHostAndPortIs(HostAndPort expected)
|
||||
{
|
||||
_result.Data.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class NoLoadBalancerTests
|
||||
{
|
||||
private List<Service> _services;
|
||||
private NoLoadBalancer _loadBalancer;
|
||||
private Response<ServiceHostAndPort> _result;
|
||||
|
||||
[Fact]
|
||||
public void should_return_host_and_port()
|
||||
{
|
||||
var hostAndPort = new ServiceHostAndPort("127.0.0.1", 80);
|
||||
|
||||
var services = new List<Service>
|
||||
{
|
||||
new Service("product", hostAndPort, string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
this.Given(x => x.GivenServices(services))
|
||||
.When(x => x.WhenIGetTheNextHostAndPort())
|
||||
.Then(x => x.ThenTheHostAndPortIs(hostAndPort))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenServices(List<Service> services)
|
||||
{
|
||||
_services = services;
|
||||
}
|
||||
|
||||
private void WhenIGetTheNextHostAndPort()
|
||||
{
|
||||
_loadBalancer = new NoLoadBalancer(_services);
|
||||
_result = _loadBalancer.Lease().Result;
|
||||
}
|
||||
|
||||
private void ThenTheHostAndPortIs(ServiceHostAndPort expected)
|
||||
{
|
||||
_result.Data.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +1,69 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class RoundRobinTests
|
||||
{
|
||||
private readonly RoundRobin _roundRobin;
|
||||
private readonly List<Service> _services;
|
||||
private Response<HostAndPort> _hostAndPort;
|
||||
|
||||
public RoundRobinTests()
|
||||
{
|
||||
_services = new List<Service>
|
||||
{
|
||||
new Service("product", new HostAndPort("127.0.0.1", 5000), string.Empty, string.Empty, new string[0]),
|
||||
new Service("product", new HostAndPort("127.0.0.1", 5001), string.Empty, string.Empty, new string[0]),
|
||||
new Service("product", new HostAndPort("127.0.0.1", 5001), string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
|
||||
_roundRobin = new RoundRobin(() => Task.FromResult(_services));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_next_address()
|
||||
{
|
||||
this.Given(x => x.GivenIGetTheNextAddress())
|
||||
.Then(x => x.ThenTheNextAddressIndexIs(0))
|
||||
.Given(x => x.GivenIGetTheNextAddress())
|
||||
.Then(x => x.ThenTheNextAddressIndexIs(1))
|
||||
.Given(x => x.GivenIGetTheNextAddress())
|
||||
.Then(x => x.ThenTheNextAddressIndexIs(2))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_go_back_to_first_address_after_finished_last()
|
||||
{
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
|
||||
while (stopWatch.ElapsedMilliseconds < 1000)
|
||||
{
|
||||
var address = _roundRobin.Lease().Result;
|
||||
address.Data.ShouldBe(_services[0].HostAndPort);
|
||||
address = _roundRobin.Lease().Result;
|
||||
address.Data.ShouldBe(_services[1].HostAndPort);
|
||||
address = _roundRobin.Lease().Result;
|
||||
address.Data.ShouldBe(_services[2].HostAndPort);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenIGetTheNextAddress()
|
||||
{
|
||||
_hostAndPort = _roundRobin.Lease().Result;
|
||||
}
|
||||
|
||||
private void ThenTheNextAddressIndexIs(int index)
|
||||
{
|
||||
_hostAndPort.Data.ShouldBe(_services[index].HostAndPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ocelot.UnitTests.LoadBalancer
|
||||
{
|
||||
public class RoundRobinTests
|
||||
{
|
||||
private readonly RoundRobin _roundRobin;
|
||||
private readonly List<Service> _services;
|
||||
private Response<ServiceHostAndPort> _hostAndPort;
|
||||
|
||||
public RoundRobinTests()
|
||||
{
|
||||
_services = new List<Service>
|
||||
{
|
||||
new Service("product", new ServiceHostAndPort("127.0.0.1", 5000), string.Empty, string.Empty, new string[0]),
|
||||
new Service("product", new ServiceHostAndPort("127.0.0.1", 5001), string.Empty, string.Empty, new string[0]),
|
||||
new Service("product", new ServiceHostAndPort("127.0.0.1", 5001), string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
|
||||
_roundRobin = new RoundRobin(() => Task.FromResult(_services));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_next_address()
|
||||
{
|
||||
this.Given(x => x.GivenIGetTheNextAddress())
|
||||
.Then(x => x.ThenTheNextAddressIndexIs(0))
|
||||
.Given(x => x.GivenIGetTheNextAddress())
|
||||
.Then(x => x.ThenTheNextAddressIndexIs(1))
|
||||
.Given(x => x.GivenIGetTheNextAddress())
|
||||
.Then(x => x.ThenTheNextAddressIndexIs(2))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_go_back_to_first_address_after_finished_last()
|
||||
{
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
|
||||
while (stopWatch.ElapsedMilliseconds < 1000)
|
||||
{
|
||||
var address = _roundRobin.Lease().Result;
|
||||
address.Data.ShouldBe(_services[0].HostAndPort);
|
||||
address = _roundRobin.Lease().Result;
|
||||
address.Data.ShouldBe(_services[1].HostAndPort);
|
||||
address = _roundRobin.Lease().Result;
|
||||
address.Data.ShouldBe(_services[2].HostAndPort);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenIGetTheNextAddress()
|
||||
{
|
||||
_hostAndPort = _roundRobin.Lease().Result;
|
||||
}
|
||||
|
||||
private void ThenTheNextAddressIndexIs(int index)
|
||||
{
|
||||
_hostAndPort.Data.ShouldBe(_services[index].HostAndPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,61 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Moq;
|
||||
using Ocelot.Middleware;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Middleware
|
||||
{
|
||||
public class BaseUrlFinderTests
|
||||
{
|
||||
private readonly BaseUrlFinder _baseUrlFinder;
|
||||
private readonly Mock<IWebHostBuilder> _webHostBuilder;
|
||||
private string _result;
|
||||
|
||||
public BaseUrlFinderTests()
|
||||
{
|
||||
_webHostBuilder = new Mock<IWebHostBuilder>();
|
||||
_baseUrlFinder = new BaseUrlFinder(_webHostBuilder.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_find_base_url_based_on_webhostbuilder()
|
||||
{
|
||||
this.Given(x => GivenTheWebHostBuilderReturns("http://localhost:7000"))
|
||||
.When(x => WhenIFindTheUrl())
|
||||
.Then(x => ThenTheUrlIs("http://localhost:7000"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_default_base_url()
|
||||
{
|
||||
this.Given(x => GivenTheWebHostBuilderReturns(""))
|
||||
.When(x => WhenIFindTheUrl())
|
||||
.Then(x => ThenTheUrlIs("http://localhost:5000"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheWebHostBuilderReturns(string url)
|
||||
{
|
||||
_webHostBuilder
|
||||
.Setup(x => x.GetSetting(WebHostDefaults.ServerUrlsKey))
|
||||
.Returns(url);
|
||||
}
|
||||
|
||||
private void WhenIFindTheUrl()
|
||||
{
|
||||
_result = _baseUrlFinder.Find();
|
||||
}
|
||||
|
||||
private void ThenTheUrlIs(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Moq;
|
||||
using Ocelot.Middleware;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Middleware
|
||||
{
|
||||
public class BaseUrlFinderTests
|
||||
{
|
||||
private readonly BaseUrlFinder _baseUrlFinder;
|
||||
private readonly Mock<IWebHostBuilder> _webHostBuilder;
|
||||
private string _result;
|
||||
|
||||
public BaseUrlFinderTests()
|
||||
{
|
||||
_webHostBuilder = new Mock<IWebHostBuilder>();
|
||||
_baseUrlFinder = new BaseUrlFinder(_webHostBuilder.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_find_base_url_based_on_webhostbuilder()
|
||||
{
|
||||
this.Given(x => GivenTheWebHostBuilderReturns("http://localhost:7000"))
|
||||
.When(x => WhenIFindTheUrl())
|
||||
.Then(x => ThenTheUrlIs("http://localhost:7000"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_use_default_base_url()
|
||||
{
|
||||
this.Given(x => GivenTheWebHostBuilderReturns(""))
|
||||
.When(x => WhenIFindTheUrl())
|
||||
.Then(x => ThenTheUrlIs("http://localhost:5000"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheWebHostBuilderReturns(string url)
|
||||
{
|
||||
_webHostBuilder
|
||||
.Setup(x => x.GetSetting(WebHostDefaults.ServerUrlsKey))
|
||||
.Returns(url);
|
||||
}
|
||||
|
||||
private void WhenIFindTheUrl()
|
||||
{
|
||||
_result = _baseUrlFinder.Find();
|
||||
}
|
||||
|
||||
private void ThenTheUrlIs(string expected)
|
||||
{
|
||||
_result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,59 +1,59 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
||||
<AssemblyName>Ocelot.UnitTests</AssemblyName>
|
||||
<PackageId>Ocelot.UnitTests</PackageId>
|
||||
<OutputType>Exe</OutputType>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
|
||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Responder\HttpContextResponderTests.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="idsrv3test.pfx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.7.142" />
|
||||
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>0.0.0-dev</VersionPrefix>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
|
||||
<AssemblyName>Ocelot.UnitTests</AssemblyName>
|
||||
<PackageId>Ocelot.UnitTests</PackageId>
|
||||
<OutputType>Exe</OutputType>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
|
||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Responder\HttpContextResponderTests.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="idsrv3test.pfx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.7.142" />
|
||||
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,19 +1,19 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Ocelot.UnitTests")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("54e84f1a-e525-4443-96ec-039cbd50c263")]
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Ocelot.UnitTests")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("54e84f1a-e525-4443-96ec-039cbd50c263")]
|
||||
|
@ -1,157 +1,157 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Ocelot.QueryStrings;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Net.Http;
|
||||
using System;
|
||||
|
||||
namespace Ocelot.UnitTests.QueryStrings
|
||||
{
|
||||
public class AddQueriesToRequestTests
|
||||
{
|
||||
private readonly AddQueriesToRequest _addQueriesToRequest;
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private readonly Mock<IClaimsParser> _parser;
|
||||
private List<ClaimToThing> _configuration;
|
||||
private List<Claim> _claims;
|
||||
private Response _result;
|
||||
private Response<string> _claimValue;
|
||||
|
||||
public AddQueriesToRequestTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_addQueriesToRequest = new AddQueriesToRequest(_parser.Object);
|
||||
_downstreamRequest = new HttpRequestMessage(HttpMethod.Post, "http://my.url/abc?q=123");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_new_queries_to_downstream_request()
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("query-key", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(claims))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddQueriesToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.And(x => x.ThenTheQueryIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_existing_queries_on_downstream_request()
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("query-key", "", "", 0)
|
||||
}))
|
||||
.And(x => x.GivenClaims(claims))
|
||||
.And(x => x.GivenTheDownstreamRequestHasQueryString("query-key", "initial"))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddQueriesToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.And(x => x.ThenTheQueryIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
this.Given(
|
||||
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(new List<Claim>()))
|
||||
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.When(x => x.WhenIAddQueriesToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheQueryIsAdded()
|
||||
{
|
||||
var queries = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(_downstreamRequest.RequestUri.OriginalString);
|
||||
var query = queries.First(x => x.Key == "query-key");
|
||||
query.Value.First().ShouldBe(_claimValue.Data);
|
||||
}
|
||||
|
||||
private void GivenAClaimToThing(List<ClaimToThing> configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
private void GivenClaims(List<Claim> claims)
|
||||
{
|
||||
_claims = claims;
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRequestHasQueryString(string key, string value)
|
||||
{
|
||||
var newUri = Microsoft.AspNetCore.WebUtilities.QueryHelpers
|
||||
.AddQueryString(_downstreamRequest.RequestUri.OriginalString, key, value);
|
||||
|
||||
_downstreamRequest.RequestUri = new Uri(newUri);
|
||||
}
|
||||
|
||||
private void GivenTheClaimParserReturns(Response<string> claimValue)
|
||||
{
|
||||
_claimValue = claimValue;
|
||||
_parser
|
||||
.Setup(
|
||||
x =>
|
||||
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<int>()))
|
||||
.Returns(_claimValue);
|
||||
}
|
||||
|
||||
private void WhenIAddQueriesToTheRequest()
|
||||
{
|
||||
_result = _addQueriesToRequest.SetQueriesOnDownstreamRequest(_configuration, _claims, _downstreamRequest);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsSuccess()
|
||||
{
|
||||
_result.IsError.ShouldBe(false);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsError()
|
||||
{
|
||||
_result.IsError.ShouldBe(true);
|
||||
}
|
||||
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError()
|
||||
: base("blahh", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Ocelot.QueryStrings;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Net.Http;
|
||||
using System;
|
||||
|
||||
namespace Ocelot.UnitTests.QueryStrings
|
||||
{
|
||||
public class AddQueriesToRequestTests
|
||||
{
|
||||
private readonly AddQueriesToRequest _addQueriesToRequest;
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private readonly Mock<IClaimsParser> _parser;
|
||||
private List<ClaimToThing> _configuration;
|
||||
private List<Claim> _claims;
|
||||
private Response _result;
|
||||
private Response<string> _claimValue;
|
||||
|
||||
public AddQueriesToRequestTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_addQueriesToRequest = new AddQueriesToRequest(_parser.Object);
|
||||
_downstreamRequest = new HttpRequestMessage(HttpMethod.Post, "http://my.url/abc?q=123");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_new_queries_to_downstream_request()
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("query-key", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(claims))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddQueriesToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.And(x => x.ThenTheQueryIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_replace_existing_queries_on_downstream_request()
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim("test", "data")
|
||||
};
|
||||
|
||||
this.Given(
|
||||
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("query-key", "", "", 0)
|
||||
}))
|
||||
.And(x => x.GivenClaims(claims))
|
||||
.And(x => x.GivenTheDownstreamRequestHasQueryString("query-key", "initial"))
|
||||
.And(x => x.GivenTheClaimParserReturns(new OkResponse<string>("value")))
|
||||
.When(x => x.WhenIAddQueriesToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsSuccess())
|
||||
.And(x => x.ThenTheQueryIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error()
|
||||
{
|
||||
this.Given(
|
||||
x => x.GivenAClaimToThing(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("", "", "", 0)
|
||||
}))
|
||||
.Given(x => x.GivenClaims(new List<Claim>()))
|
||||
.And(x => x.GivenTheClaimParserReturns(new ErrorResponse<string>(new List<Error>
|
||||
{
|
||||
new AnyError()
|
||||
})))
|
||||
.When(x => x.WhenIAddQueriesToTheRequest())
|
||||
.Then(x => x.ThenTheResultIsError())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheQueryIsAdded()
|
||||
{
|
||||
var queries = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(_downstreamRequest.RequestUri.OriginalString);
|
||||
var query = queries.First(x => x.Key == "query-key");
|
||||
query.Value.First().ShouldBe(_claimValue.Data);
|
||||
}
|
||||
|
||||
private void GivenAClaimToThing(List<ClaimToThing> configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
private void GivenClaims(List<Claim> claims)
|
||||
{
|
||||
_claims = claims;
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRequestHasQueryString(string key, string value)
|
||||
{
|
||||
var newUri = Microsoft.AspNetCore.WebUtilities.QueryHelpers
|
||||
.AddQueryString(_downstreamRequest.RequestUri.OriginalString, key, value);
|
||||
|
||||
_downstreamRequest.RequestUri = new Uri(newUri);
|
||||
}
|
||||
|
||||
private void GivenTheClaimParserReturns(Response<string> claimValue)
|
||||
{
|
||||
_claimValue = claimValue;
|
||||
_parser
|
||||
.Setup(
|
||||
x =>
|
||||
x.GetValue(It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<int>()))
|
||||
.Returns(_claimValue);
|
||||
}
|
||||
|
||||
private void WhenIAddQueriesToTheRequest()
|
||||
{
|
||||
_result = _addQueriesToRequest.SetQueriesOnDownstreamRequest(_configuration, _claims, _downstreamRequest);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsSuccess()
|
||||
{
|
||||
_result.IsError.ShouldBe(false);
|
||||
}
|
||||
|
||||
private void ThenTheResultIsError()
|
||||
{
|
||||
_result.IsError.ShouldBe(true);
|
||||
}
|
||||
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError()
|
||||
: base("blahh", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,97 +1,97 @@
|
||||
namespace Ocelot.UnitTests.QueryStrings
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.QueryStrings;
|
||||
using Ocelot.QueryStrings.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public class QueryStringBuilderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IAddQueriesToRequest> _addQueries;
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public QueryStringBuilderMiddlewareTests()
|
||||
{
|
||||
_addQueries = new Mock<IAddQueriesToRequest>();
|
||||
|
||||
_downstreamRequest = new HttpRequestMessage();
|
||||
ScopedRepository.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_add_queries_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToQueries(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("UserId", "Subject", "", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddHeadersToRequestReturnsOk())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAddQueriesToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_addQueries.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseQueryStringBuilderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheAddHeadersToRequestReturnsOk()
|
||||
{
|
||||
_addQueries
|
||||
.Setup(x => x.SetQueriesOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<HttpRequestMessage>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheAddQueriesToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addQueries
|
||||
.Verify(x => x.SetQueriesOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
_downstreamRequest), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.QueryStrings
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.QueryStrings;
|
||||
using Ocelot.QueryStrings.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
public class QueryStringBuilderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IAddQueriesToRequest> _addQueries;
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
|
||||
public QueryStringBuilderMiddlewareTests()
|
||||
{
|
||||
_addQueries = new Mock<IAddQueriesToRequest>();
|
||||
|
||||
_downstreamRequest = new HttpRequestMessage();
|
||||
ScopedRepository.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_add_queries_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithClaimsToQueries(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("UserId", "Subject", "", 0)
|
||||
})
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddHeadersToRequestReturnsOk())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAddQueriesToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_addQueries.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseQueryStringBuilderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheAddHeadersToRequestReturnsOk()
|
||||
{
|
||||
_addQueries
|
||||
.Setup(x => x.SetQueriesOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
It.IsAny<HttpRequestMessage>()))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheAddQueriesToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addQueries
|
||||
.Verify(x => x.SetQueriesOnDownstreamRequest(
|
||||
It.IsAny<List<ClaimToThing>>(),
|
||||
It.IsAny<IEnumerable<Claim>>(),
|
||||
_downstreamRequest), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,45 @@
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.Raft;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Raft
|
||||
{
|
||||
public class OcelotFiniteStateMachineTests
|
||||
{
|
||||
private UpdateFileConfiguration _command;
|
||||
private OcelotFiniteStateMachine _fsm;
|
||||
private Mock<IFileConfigurationSetter> _setter;
|
||||
|
||||
public OcelotFiniteStateMachineTests()
|
||||
{
|
||||
_setter = new Mock<IFileConfigurationSetter>();
|
||||
_fsm = new OcelotFiniteStateMachine(_setter.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_handle_update_file_configuration_command()
|
||||
{
|
||||
this.Given(x => GivenACommand(new UpdateFileConfiguration(new Ocelot.Configuration.File.FileConfiguration())))
|
||||
.When(x => WhenTheCommandIsHandled())
|
||||
.Then(x => ThenTheStateIsUpdated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenACommand(UpdateFileConfiguration command)
|
||||
{
|
||||
_command = command;
|
||||
}
|
||||
|
||||
private void WhenTheCommandIsHandled()
|
||||
{
|
||||
_fsm.Handle(new Rafty.Log.LogEntry(_command, _command.GetType(), 0));
|
||||
}
|
||||
|
||||
private void ThenTheStateIsUpdated()
|
||||
{
|
||||
_setter.Verify(x => x.Set(_command.Configuration), Times.Once);
|
||||
}
|
||||
}
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Setter;
|
||||
using Ocelot.Raft;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Raft
|
||||
{
|
||||
public class OcelotFiniteStateMachineTests
|
||||
{
|
||||
private UpdateFileConfiguration _command;
|
||||
private OcelotFiniteStateMachine _fsm;
|
||||
private Mock<IFileConfigurationSetter> _setter;
|
||||
|
||||
public OcelotFiniteStateMachineTests()
|
||||
{
|
||||
_setter = new Mock<IFileConfigurationSetter>();
|
||||
_fsm = new OcelotFiniteStateMachine(_setter.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_handle_update_file_configuration_command()
|
||||
{
|
||||
this.Given(x => GivenACommand(new UpdateFileConfiguration(new Ocelot.Configuration.File.FileConfiguration())))
|
||||
.When(x => WhenTheCommandIsHandled())
|
||||
.Then(x => ThenTheStateIsUpdated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenACommand(UpdateFileConfiguration command)
|
||||
{
|
||||
_command = command;
|
||||
}
|
||||
|
||||
private void WhenTheCommandIsHandled()
|
||||
{
|
||||
_fsm.Handle(new Rafty.Log.LogEntry(_command, _command.GetType(), 0));
|
||||
}
|
||||
|
||||
private void ThenTheStateIsUpdated()
|
||||
{
|
||||
_setter.Verify(x => x.Set(_command.Configuration), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,128 +1,128 @@
|
||||
namespace Ocelot.UnitTests.RateLimit
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.RateLimit;
|
||||
using Ocelot.RateLimit.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ClientRateLimitMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
private int responseStatusCode;
|
||||
|
||||
public ClientRateLimitMiddlewareTests()
|
||||
{
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_middleware_and_ratelimiting()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
|
||||
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new Ocelot.Configuration.RateLimitRule("1s", 100, 3), 429))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
|
||||
.Then(x => x.ThenresponseStatusCodeIs200())
|
||||
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
|
||||
.Then(x => x.ThenresponseStatusCodeIs429())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_middleware_withWhitelistClient()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
|
||||
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule( "1s", 100,3),429))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.When(x => x.WhenICallTheMiddlewareWithWhiteClient())
|
||||
.Then(x => x.ThenresponseStatusCodeIs200())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddMemoryCache();
|
||||
services.AddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRateLimiting();
|
||||
app.Run(async context =>
|
||||
{
|
||||
context.Response.StatusCode = 200;
|
||||
await context.Response.WriteAsync("This is ratelimit test");
|
||||
});
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddlewareMultipleTime(int times)
|
||||
{
|
||||
var clientId = "ocelotclient1";
|
||||
|
||||
for (int i = 0; i < times; i++)
|
||||
{
|
||||
var request = new HttpRequestMessage(new HttpMethod("GET"), Url);
|
||||
request.Headers.Add("ClientId", clientId);
|
||||
|
||||
var response = Client.SendAsync(request);
|
||||
responseStatusCode = (int)response.Result.StatusCode;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddlewareWithWhiteClient()
|
||||
{
|
||||
var clientId = "ocelotclient2";
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var request = new HttpRequestMessage(new HttpMethod("GET"), Url);
|
||||
request.Headers.Add("ClientId", clientId);
|
||||
|
||||
var response = Client.SendAsync(request);
|
||||
responseStatusCode = (int)response.Result.StatusCode;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenresponseStatusCodeIs429()
|
||||
{
|
||||
responseStatusCode.ShouldBe(429);
|
||||
}
|
||||
|
||||
private void ThenresponseStatusCodeIs200()
|
||||
{
|
||||
responseStatusCode.ShouldBe(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.RateLimit
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.RateLimit;
|
||||
using Ocelot.RateLimit.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ClientRateLimitMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
private int responseStatusCode;
|
||||
|
||||
public ClientRateLimitMiddlewareTests()
|
||||
{
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_middleware_and_ratelimiting()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
|
||||
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new Ocelot.Configuration.RateLimitRule("1s", 100, 3), 429))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
|
||||
.Then(x => x.ThenresponseStatusCodeIs200())
|
||||
.When(x => x.WhenICallTheMiddlewareMultipleTime(2))
|
||||
.Then(x => x.ThenresponseStatusCodeIs429())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_middleware_withWhitelistClient()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
|
||||
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule( "1s", 100,3),429))
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.When(x => x.WhenICallTheMiddlewareWithWhiteClient())
|
||||
.Then(x => x.ThenresponseStatusCodeIs200())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddMemoryCache();
|
||||
services.AddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRateLimiting();
|
||||
app.Run(async context =>
|
||||
{
|
||||
context.Response.StatusCode = 200;
|
||||
await context.Response.WriteAsync("This is ratelimit test");
|
||||
});
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddlewareMultipleTime(int times)
|
||||
{
|
||||
var clientId = "ocelotclient1";
|
||||
|
||||
for (int i = 0; i < times; i++)
|
||||
{
|
||||
var request = new HttpRequestMessage(new HttpMethod("GET"), Url);
|
||||
request.Headers.Add("ClientId", clientId);
|
||||
|
||||
var response = Client.SendAsync(request);
|
||||
responseStatusCode = (int)response.Result.StatusCode;
|
||||
}
|
||||
}
|
||||
|
||||
private void WhenICallTheMiddlewareWithWhiteClient()
|
||||
{
|
||||
var clientId = "ocelotclient2";
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var request = new HttpRequestMessage(new HttpMethod("GET"), Url);
|
||||
request.Headers.Add("ClientId", clientId);
|
||||
|
||||
var response = Client.SendAsync(request);
|
||||
responseStatusCode = (int)response.Result.StatusCode;
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenresponseStatusCodeIs429()
|
||||
{
|
||||
responseStatusCode.ShouldBe(429);
|
||||
}
|
||||
|
||||
private void ThenresponseStatusCodeIs200()
|
||||
{
|
||||
responseStatusCode.ShouldBe(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,78 +1,78 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Repository
|
||||
{
|
||||
public class ScopedRequestDataRepositoryTests
|
||||
{
|
||||
private IRequestScopedDataRepository _requestScopedDataRepository;
|
||||
private IHttpContextAccessor _httpContextAccesor;
|
||||
private string _key;
|
||||
private object _toAdd;
|
||||
private Response<int[]> _result;
|
||||
|
||||
public ScopedRequestDataRepositoryTests()
|
||||
{
|
||||
_httpContextAccesor = new HttpContextAccessor();
|
||||
_httpContextAccesor.HttpContext = new DefaultHttpContext();
|
||||
_requestScopedDataRepository = new HttpDataRepository(_httpContextAccesor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_item()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAnItemToAdd("blahh", new [] {1,2,3,4}))
|
||||
.When(x => x.WhenIAddTheItem())
|
||||
.Then(x => x.ThenTheItemIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_item()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAnItemInTheContext("chest"))
|
||||
.When(x => x.WhenIGetTheItem())
|
||||
.Then(x => x.ThenTheItemIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheItemIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeFalse();
|
||||
_result.Data.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
private void WhenIGetTheItem()
|
||||
{
|
||||
_result = _requestScopedDataRepository.Get<int[]>(_key);
|
||||
}
|
||||
|
||||
private void GivenThereIsAnItemInTheContext(string key)
|
||||
{
|
||||
_key = key;
|
||||
var data = new[] {5435345};
|
||||
_httpContextAccesor.HttpContext.Items.Add(key, data);
|
||||
}
|
||||
|
||||
private void GivenIHaveAnItemToAdd(string key, object toAdd)
|
||||
{
|
||||
_key = key;
|
||||
_toAdd = toAdd;
|
||||
}
|
||||
|
||||
private void WhenIAddTheItem()
|
||||
{
|
||||
_requestScopedDataRepository.Add(_key, _toAdd);
|
||||
}
|
||||
|
||||
private void ThenTheItemIsAdded()
|
||||
{
|
||||
object obj;
|
||||
_httpContextAccesor.HttpContext.Items.TryGetValue(_key, out obj).ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Repository
|
||||
{
|
||||
public class ScopedRequestDataRepositoryTests
|
||||
{
|
||||
private IRequestScopedDataRepository _requestScopedDataRepository;
|
||||
private IHttpContextAccessor _httpContextAccesor;
|
||||
private string _key;
|
||||
private object _toAdd;
|
||||
private Response<int[]> _result;
|
||||
|
||||
public ScopedRequestDataRepositoryTests()
|
||||
{
|
||||
_httpContextAccesor = new HttpContextAccessor();
|
||||
_httpContextAccesor.HttpContext = new DefaultHttpContext();
|
||||
_requestScopedDataRepository = new HttpDataRepository(_httpContextAccesor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_item()
|
||||
{
|
||||
this.Given(x => x.GivenIHaveAnItemToAdd("blahh", new [] {1,2,3,4}))
|
||||
.When(x => x.WhenIAddTheItem())
|
||||
.Then(x => x.ThenTheItemIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_item()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAnItemInTheContext("chest"))
|
||||
.When(x => x.WhenIGetTheItem())
|
||||
.Then(x => x.ThenTheItemIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheItemIsReturned()
|
||||
{
|
||||
_result.IsError.ShouldBeFalse();
|
||||
_result.Data.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
private void WhenIGetTheItem()
|
||||
{
|
||||
_result = _requestScopedDataRepository.Get<int[]>(_key);
|
||||
}
|
||||
|
||||
private void GivenThereIsAnItemInTheContext(string key)
|
||||
{
|
||||
_key = key;
|
||||
var data = new[] {5435345};
|
||||
_httpContextAccesor.HttpContext.Items.Add(key, data);
|
||||
}
|
||||
|
||||
private void GivenIHaveAnItemToAdd(string key, object toAdd)
|
||||
{
|
||||
_key = key;
|
||||
_toAdd = toAdd;
|
||||
}
|
||||
|
||||
private void WhenIAddTheItem()
|
||||
{
|
||||
_requestScopedDataRepository.Add(_key, _toAdd);
|
||||
}
|
||||
|
||||
private void ThenTheItemIsAdded()
|
||||
{
|
||||
object obj;
|
||||
_httpContextAccesor.HttpContext.Items.TryGetValue(_key, out obj).ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,142 +1,142 @@
|
||||
namespace Ocelot.UnitTests.Request
|
||||
{
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Request.Mapper;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Ocelot.Responses;
|
||||
|
||||
public class DownstreamRequestInitialiserMiddlewareTests
|
||||
{
|
||||
readonly DownstreamRequestInitialiserMiddleware _middleware;
|
||||
|
||||
readonly Mock<HttpContext> _httpContext;
|
||||
|
||||
readonly Mock<HttpRequest> _httpRequest;
|
||||
|
||||
readonly Mock<RequestDelegate> _next;
|
||||
|
||||
readonly Mock<IRequestMapper> _requestMapper;
|
||||
|
||||
readonly Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
|
||||
readonly Mock<IOcelotLogger> _logger;
|
||||
|
||||
Response<HttpRequestMessage> _mappedRequest;
|
||||
|
||||
public DownstreamRequestInitialiserMiddlewareTests()
|
||||
{
|
||||
|
||||
_httpContext = new Mock<HttpContext>();
|
||||
_httpRequest = new Mock<HttpRequest>();
|
||||
_requestMapper = new Mock<IRequestMapper>();
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_next = new Mock<RequestDelegate>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory
|
||||
.Setup(lf => lf.CreateLogger<DownstreamRequestInitialiserMiddleware>())
|
||||
.Returns(_logger.Object);
|
||||
|
||||
_middleware = new DownstreamRequestInitialiserMiddleware(
|
||||
_next.Object,
|
||||
_loggerFactory.Object,
|
||||
_repo.Object,
|
||||
_requestMapper.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_valid_httpRequest()
|
||||
{
|
||||
this.Given(_ => GivenTheHttpContextContainsARequest())
|
||||
.And(_ => GivenTheMapperWillReturnAMappedRequest())
|
||||
.When(_ => WhenTheMiddlewareIsInvoked())
|
||||
.Then(_ => ThenTheContexRequestIsMappedToADownstreamRequest())
|
||||
.And(_ => ThenTheDownstreamRequestIsStored())
|
||||
.And(_ => ThenTheNextMiddlewareIsInvoked())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_mapping_failure()
|
||||
{
|
||||
this.Given(_ => GivenTheHttpContextContainsARequest())
|
||||
.And(_ => GivenTheMapperWillReturnAnError())
|
||||
.When(_ => WhenTheMiddlewareIsInvoked())
|
||||
.And(_ => ThenTheDownstreamRequestIsNotStored())
|
||||
.And(_ => ThenAPipelineErrorIsStored())
|
||||
.And(_ => ThenTheNextMiddlewareIsNotInvoked())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheHttpContextContainsARequest()
|
||||
{
|
||||
_httpContext
|
||||
.Setup(hc => hc.Request)
|
||||
.Returns(_httpRequest.Object);
|
||||
}
|
||||
|
||||
private void GivenTheMapperWillReturnAMappedRequest()
|
||||
{
|
||||
_mappedRequest = new OkResponse<HttpRequestMessage>(new HttpRequestMessage());
|
||||
|
||||
_requestMapper
|
||||
.Setup(rm => rm.Map(It.IsAny<HttpRequest>()))
|
||||
.ReturnsAsync(_mappedRequest);
|
||||
}
|
||||
|
||||
private void GivenTheMapperWillReturnAnError()
|
||||
{
|
||||
_mappedRequest = new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(new System.Exception("boooom!")));
|
||||
|
||||
_requestMapper
|
||||
.Setup(rm => rm.Map(It.IsAny<HttpRequest>()))
|
||||
.ReturnsAsync(_mappedRequest);
|
||||
}
|
||||
|
||||
private void WhenTheMiddlewareIsInvoked()
|
||||
{
|
||||
_middleware.Invoke(_httpContext.Object).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThenTheContexRequestIsMappedToADownstreamRequest()
|
||||
{
|
||||
_requestMapper.Verify(rm => rm.Map(_httpRequest.Object), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestIsStored()
|
||||
{
|
||||
_repo.Verify(r => r.Add("DownstreamRequest", _mappedRequest.Data), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestIsNotStored()
|
||||
{
|
||||
_repo.Verify(r => r.Add("DownstreamRequest", It.IsAny<HttpRequestMessage>()), Times.Never);
|
||||
}
|
||||
|
||||
private void ThenAPipelineErrorIsStored()
|
||||
{
|
||||
_repo.Verify(r => r.Add("OcelotMiddlewareError", true), Times.Once);
|
||||
_repo.Verify(r => r.Add("OcelotMiddlewareErrors", _mappedRequest.Errors), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheNextMiddlewareIsInvoked()
|
||||
{
|
||||
_next.Verify(n => n(_httpContext.Object), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheNextMiddlewareIsNotInvoked()
|
||||
{
|
||||
_next.Verify(n => n(It.IsAny<HttpContext>()), Times.Never);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Request
|
||||
{
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Request.Mapper;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Ocelot.Responses;
|
||||
|
||||
public class DownstreamRequestInitialiserMiddlewareTests
|
||||
{
|
||||
readonly DownstreamRequestInitialiserMiddleware _middleware;
|
||||
|
||||
readonly Mock<HttpContext> _httpContext;
|
||||
|
||||
readonly Mock<HttpRequest> _httpRequest;
|
||||
|
||||
readonly Mock<RequestDelegate> _next;
|
||||
|
||||
readonly Mock<IRequestMapper> _requestMapper;
|
||||
|
||||
readonly Mock<IRequestScopedDataRepository> _repo;
|
||||
|
||||
readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
|
||||
readonly Mock<IOcelotLogger> _logger;
|
||||
|
||||
Response<HttpRequestMessage> _mappedRequest;
|
||||
|
||||
public DownstreamRequestInitialiserMiddlewareTests()
|
||||
{
|
||||
|
||||
_httpContext = new Mock<HttpContext>();
|
||||
_httpRequest = new Mock<HttpRequest>();
|
||||
_requestMapper = new Mock<IRequestMapper>();
|
||||
_repo = new Mock<IRequestScopedDataRepository>();
|
||||
_next = new Mock<RequestDelegate>();
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory
|
||||
.Setup(lf => lf.CreateLogger<DownstreamRequestInitialiserMiddleware>())
|
||||
.Returns(_logger.Object);
|
||||
|
||||
_middleware = new DownstreamRequestInitialiserMiddleware(
|
||||
_next.Object,
|
||||
_loggerFactory.Object,
|
||||
_repo.Object,
|
||||
_requestMapper.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_valid_httpRequest()
|
||||
{
|
||||
this.Given(_ => GivenTheHttpContextContainsARequest())
|
||||
.And(_ => GivenTheMapperWillReturnAMappedRequest())
|
||||
.When(_ => WhenTheMiddlewareIsInvoked())
|
||||
.Then(_ => ThenTheContexRequestIsMappedToADownstreamRequest())
|
||||
.And(_ => ThenTheDownstreamRequestIsStored())
|
||||
.And(_ => ThenTheNextMiddlewareIsInvoked())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_mapping_failure()
|
||||
{
|
||||
this.Given(_ => GivenTheHttpContextContainsARequest())
|
||||
.And(_ => GivenTheMapperWillReturnAnError())
|
||||
.When(_ => WhenTheMiddlewareIsInvoked())
|
||||
.And(_ => ThenTheDownstreamRequestIsNotStored())
|
||||
.And(_ => ThenAPipelineErrorIsStored())
|
||||
.And(_ => ThenTheNextMiddlewareIsNotInvoked())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheHttpContextContainsARequest()
|
||||
{
|
||||
_httpContext
|
||||
.Setup(hc => hc.Request)
|
||||
.Returns(_httpRequest.Object);
|
||||
}
|
||||
|
||||
private void GivenTheMapperWillReturnAMappedRequest()
|
||||
{
|
||||
_mappedRequest = new OkResponse<HttpRequestMessage>(new HttpRequestMessage());
|
||||
|
||||
_requestMapper
|
||||
.Setup(rm => rm.Map(It.IsAny<HttpRequest>()))
|
||||
.ReturnsAsync(_mappedRequest);
|
||||
}
|
||||
|
||||
private void GivenTheMapperWillReturnAnError()
|
||||
{
|
||||
_mappedRequest = new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(new System.Exception("boooom!")));
|
||||
|
||||
_requestMapper
|
||||
.Setup(rm => rm.Map(It.IsAny<HttpRequest>()))
|
||||
.ReturnsAsync(_mappedRequest);
|
||||
}
|
||||
|
||||
private void WhenTheMiddlewareIsInvoked()
|
||||
{
|
||||
_middleware.Invoke(_httpContext.Object).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThenTheContexRequestIsMappedToADownstreamRequest()
|
||||
{
|
||||
_requestMapper.Verify(rm => rm.Map(_httpRequest.Object), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestIsStored()
|
||||
{
|
||||
_repo.Verify(r => r.Add("DownstreamRequest", _mappedRequest.Data), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheDownstreamRequestIsNotStored()
|
||||
{
|
||||
_repo.Verify(r => r.Add("DownstreamRequest", It.IsAny<HttpRequestMessage>()), Times.Never);
|
||||
}
|
||||
|
||||
private void ThenAPipelineErrorIsStored()
|
||||
{
|
||||
_repo.Verify(r => r.Add("OcelotMiddlewareError", true), Times.Once);
|
||||
_repo.Verify(r => r.Add("OcelotMiddlewareErrors", _mappedRequest.Errors), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheNextMiddlewareIsInvoked()
|
||||
{
|
||||
_next.Verify(n => n(_httpContext.Object), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheNextMiddlewareIsNotInvoked()
|
||||
{
|
||||
_next.Verify(n => n(It.IsAny<HttpContext>()), Times.Never);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,287 +1,287 @@
|
||||
namespace Ocelot.UnitTests.Request.Mapper
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Ocelot.Request.Mapper;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
public class RequestMapperTests
|
||||
{
|
||||
readonly HttpRequest _inputRequest;
|
||||
|
||||
readonly RequestMapper _requestMapper;
|
||||
|
||||
Response<HttpRequestMessage> _mappedRequest;
|
||||
|
||||
List<KeyValuePair<string, StringValues>> _inputHeaders = null;
|
||||
|
||||
public RequestMapperTests()
|
||||
{
|
||||
_inputRequest = new DefaultHttpRequest(new DefaultHttpContext());
|
||||
|
||||
_requestMapper = new RequestMapper();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https", "my.url:123", "/abc/DEF", "?a=1&b=2", "https://my.url:123/abc/DEF?a=1&b=2")]
|
||||
[InlineData("http", "blah.com", "/d ef", "?abc=123", "http://blah.com/d%20ef?abc=123")] // note! the input is encoded when building the input request
|
||||
[InlineData("http", "myusername:mypassword@abc.co.uk", null, null, "http://myusername:mypassword@abc.co.uk/")]
|
||||
[InlineData("http", "點看.com", null, null, "http://xn--c1yn36f.com/")]
|
||||
[InlineData("http", "xn--c1yn36f.com", null, null, "http://xn--c1yn36f.com/")]
|
||||
public void Should_map_valid_request_uri(string scheme, string host, string path, string queryString, string expectedUri)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasScheme(scheme))
|
||||
.And(_ => GivenTheInputRequestHasHost(host))
|
||||
.And(_ => GivenTheInputRequestHasPath(path))
|
||||
.And(_ => GivenTheInputRequestHasQueryString(queryString))
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasUri(expectedUri))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("ftp", "google.com", "/abc/DEF", "?a=1&b=2")]
|
||||
public void Should_error_on_unsupported_request_uri(string scheme, string host, string path, string queryString)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasScheme(scheme))
|
||||
.And(_ => GivenTheInputRequestHasHost(host))
|
||||
.And(_ => GivenTheInputRequestHasPath(path))
|
||||
.And(_ => GivenTheInputRequestHasQueryString(queryString))
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenAnErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestIsNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GET")]
|
||||
[InlineData("POST")]
|
||||
[InlineData("WHATEVER")]
|
||||
public void Should_map_method(string method)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod(method))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasMethod(method))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_all_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasHeaders())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasEachHeader())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoHeaders())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoHeaders())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_content()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContent("This is my content"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_content_type_header()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheContentTypeIs("application/json"))
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
|
||||
.And(_ => ThenTheMappedRequestHasContentSize("This is my content".Length))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheContentTypeIs(string contentType)
|
||||
{
|
||||
_inputRequest.ContentType = contentType;
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentTypeHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentType.MediaType.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentSize(long expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentLength.ShouldBe(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_content()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoContent())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasMethod(string method)
|
||||
{
|
||||
_inputRequest.Method = method;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasScheme(string scheme)
|
||||
{
|
||||
_inputRequest.Scheme = scheme;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasHost(string host)
|
||||
{
|
||||
_inputRequest.Host = new HostString(host);
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasPath(string path)
|
||||
{
|
||||
if (path != null)
|
||||
{
|
||||
_inputRequest.Path = path;
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasQueryString(string querystring)
|
||||
{
|
||||
if (querystring != null)
|
||||
{
|
||||
_inputRequest.QueryString = new QueryString(querystring);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasAValidUri()
|
||||
{
|
||||
GivenTheInputRequestHasScheme("http");
|
||||
GivenTheInputRequestHasHost("www.google.com");
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasHeaders()
|
||||
{
|
||||
_inputHeaders = new List<KeyValuePair<string, StringValues>>()
|
||||
{
|
||||
new KeyValuePair<string, StringValues>("abc", new StringValues(new string[]{"123","456" })),
|
||||
new KeyValuePair<string, StringValues>("def", new StringValues(new string[]{"789","012" })),
|
||||
};
|
||||
|
||||
foreach (var inputHeader in _inputHeaders)
|
||||
{
|
||||
_inputRequest.Headers.Add(inputHeader);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoHeaders()
|
||||
{
|
||||
_inputRequest.Headers.Clear();
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasContent(string content)
|
||||
{
|
||||
_inputRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes(content));
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoContent()
|
||||
{
|
||||
_inputRequest.Body = null;
|
||||
}
|
||||
|
||||
private void WhenMapped()
|
||||
{
|
||||
_mappedRequest = _requestMapper.Map(_inputRequest).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThenNoErrorIsReturned()
|
||||
{
|
||||
_mappedRequest.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_mappedRequest.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasUri(string expectedUri)
|
||||
{
|
||||
_mappedRequest.Data.RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasMethod(string expectedMethod)
|
||||
{
|
||||
_mappedRequest.Data.Method.ToString().ShouldBe(expectedMethod);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasEachHeader()
|
||||
{
|
||||
_mappedRequest.Data.Headers.Count().ShouldBe(_inputHeaders.Count);
|
||||
foreach(var header in _mappedRequest.Data.Headers)
|
||||
{
|
||||
var inputHeader = _inputHeaders.First(h => h.Key == header.Key);
|
||||
inputHeader.ShouldNotBeNull();
|
||||
inputHeader.Value.Count().ShouldBe(header.Value.Count());
|
||||
foreach(var inputHeaderValue in inputHeader.Value)
|
||||
{
|
||||
header.Value.Any(v => v == inputHeaderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasNoHeaders()
|
||||
{
|
||||
_mappedRequest.Data.Headers.Count().ShouldBe(0);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContent(string expectedContent)
|
||||
{
|
||||
_mappedRequest.Data.Content.ReadAsStringAsync().GetAwaiter().GetResult().ShouldBe(expectedContent);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasNoContent()
|
||||
{
|
||||
_mappedRequest.Data.Content.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestIsNull()
|
||||
{
|
||||
_mappedRequest.Data.ShouldBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Request.Mapper
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Ocelot.Request.Mapper;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
public class RequestMapperTests
|
||||
{
|
||||
readonly HttpRequest _inputRequest;
|
||||
|
||||
readonly RequestMapper _requestMapper;
|
||||
|
||||
Response<HttpRequestMessage> _mappedRequest;
|
||||
|
||||
List<KeyValuePair<string, StringValues>> _inputHeaders = null;
|
||||
|
||||
public RequestMapperTests()
|
||||
{
|
||||
_inputRequest = new DefaultHttpRequest(new DefaultHttpContext());
|
||||
|
||||
_requestMapper = new RequestMapper();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https", "my.url:123", "/abc/DEF", "?a=1&b=2", "https://my.url:123/abc/DEF?a=1&b=2")]
|
||||
[InlineData("http", "blah.com", "/d ef", "?abc=123", "http://blah.com/d%20ef?abc=123")] // note! the input is encoded when building the input request
|
||||
[InlineData("http", "myusername:mypassword@abc.co.uk", null, null, "http://myusername:mypassword@abc.co.uk/")]
|
||||
[InlineData("http", "點看.com", null, null, "http://xn--c1yn36f.com/")]
|
||||
[InlineData("http", "xn--c1yn36f.com", null, null, "http://xn--c1yn36f.com/")]
|
||||
public void Should_map_valid_request_uri(string scheme, string host, string path, string queryString, string expectedUri)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasScheme(scheme))
|
||||
.And(_ => GivenTheInputRequestHasHost(host))
|
||||
.And(_ => GivenTheInputRequestHasPath(path))
|
||||
.And(_ => GivenTheInputRequestHasQueryString(queryString))
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasUri(expectedUri))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("ftp", "google.com", "/abc/DEF", "?a=1&b=2")]
|
||||
public void Should_error_on_unsupported_request_uri(string scheme, string host, string path, string queryString)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasScheme(scheme))
|
||||
.And(_ => GivenTheInputRequestHasHost(host))
|
||||
.And(_ => GivenTheInputRequestHasPath(path))
|
||||
.And(_ => GivenTheInputRequestHasQueryString(queryString))
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenAnErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestIsNull())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("GET")]
|
||||
[InlineData("POST")]
|
||||
[InlineData("WHATEVER")]
|
||||
public void Should_map_method(string method)
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasMethod(method))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasMethod(method))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_all_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasHeaders())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasEachHeader())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_headers()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoHeaders())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoHeaders())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_content()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContent("This is my content"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_map_content_type_header()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
|
||||
.And(_ => GivenTheContentTypeIs("application/json"))
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
|
||||
.And(_ => ThenTheMappedRequestHasContentSize("This is my content".Length))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheContentTypeIs(string contentType)
|
||||
{
|
||||
_inputRequest.ContentType = contentType;
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentTypeHeader(string expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentType.MediaType.ShouldBe(expected);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContentSize(long expected)
|
||||
{
|
||||
_mappedRequest.Data.Content.Headers.ContentLength.ShouldBe(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_handle_no_content()
|
||||
{
|
||||
this.Given(_ => GivenTheInputRequestHasNoContent())
|
||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||
.When(_ => WhenMapped())
|
||||
.Then(_ => ThenNoErrorIsReturned())
|
||||
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasMethod(string method)
|
||||
{
|
||||
_inputRequest.Method = method;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasScheme(string scheme)
|
||||
{
|
||||
_inputRequest.Scheme = scheme;
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasHost(string host)
|
||||
{
|
||||
_inputRequest.Host = new HostString(host);
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasPath(string path)
|
||||
{
|
||||
if (path != null)
|
||||
{
|
||||
_inputRequest.Path = path;
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasQueryString(string querystring)
|
||||
{
|
||||
if (querystring != null)
|
||||
{
|
||||
_inputRequest.QueryString = new QueryString(querystring);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasAValidUri()
|
||||
{
|
||||
GivenTheInputRequestHasScheme("http");
|
||||
GivenTheInputRequestHasHost("www.google.com");
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasHeaders()
|
||||
{
|
||||
_inputHeaders = new List<KeyValuePair<string, StringValues>>()
|
||||
{
|
||||
new KeyValuePair<string, StringValues>("abc", new StringValues(new string[]{"123","456" })),
|
||||
new KeyValuePair<string, StringValues>("def", new StringValues(new string[]{"789","012" })),
|
||||
};
|
||||
|
||||
foreach (var inputHeader in _inputHeaders)
|
||||
{
|
||||
_inputRequest.Headers.Add(inputHeader);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoHeaders()
|
||||
{
|
||||
_inputRequest.Headers.Clear();
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasContent(string content)
|
||||
{
|
||||
_inputRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes(content));
|
||||
}
|
||||
|
||||
private void GivenTheInputRequestHasNoContent()
|
||||
{
|
||||
_inputRequest.Body = null;
|
||||
}
|
||||
|
||||
private void WhenMapped()
|
||||
{
|
||||
_mappedRequest = _requestMapper.Map(_inputRequest).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void ThenNoErrorIsReturned()
|
||||
{
|
||||
_mappedRequest.IsError.ShouldBeFalse();
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_mappedRequest.IsError.ShouldBeTrue();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasUri(string expectedUri)
|
||||
{
|
||||
_mappedRequest.Data.RequestUri.OriginalString.ShouldBe(expectedUri);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasMethod(string expectedMethod)
|
||||
{
|
||||
_mappedRequest.Data.Method.ToString().ShouldBe(expectedMethod);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasEachHeader()
|
||||
{
|
||||
_mappedRequest.Data.Headers.Count().ShouldBe(_inputHeaders.Count);
|
||||
foreach(var header in _mappedRequest.Data.Headers)
|
||||
{
|
||||
var inputHeader = _inputHeaders.First(h => h.Key == header.Key);
|
||||
inputHeader.ShouldNotBeNull();
|
||||
inputHeader.Value.Count().ShouldBe(header.Value.Count());
|
||||
foreach(var inputHeaderValue in inputHeader.Value)
|
||||
{
|
||||
header.Value.Any(v => v == inputHeaderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasNoHeaders()
|
||||
{
|
||||
_mappedRequest.Data.Headers.Count().ShouldBe(0);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasContent(string expectedContent)
|
||||
{
|
||||
_mappedRequest.Data.Content.ReadAsStringAsync().GetAwaiter().GetResult().ShouldBe(expectedContent);
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestHasNoContent()
|
||||
{
|
||||
_mappedRequest.Data.Content.ShouldBeNull();
|
||||
}
|
||||
|
||||
private void ThenTheMappedRequestIsNull()
|
||||
{
|
||||
_mappedRequest.Data.ShouldBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,182 +1,182 @@
|
||||
namespace Ocelot.UnitTests.RequestId
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.RequestId.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ReRouteRequestIdMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private string _value;
|
||||
private string _key;
|
||||
|
||||
public ReRouteRequestIdMiddlewareTests()
|
||||
{
|
||||
_downstreamRequest = new HttpRequestMessage();
|
||||
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_pass_down_request_id_from_upstream_request()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var requestId = Guid.NewGuid().ToString();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenThereIsNoGlobalRequestId())
|
||||
.And(x => x.GivenTheRequestIdIsAddedToTheRequest("LSRequestId", requestId))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheTraceIdIs(requestId))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_request_id_when_not_on_upstream_request()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenThereIsNoGlobalRequestId())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheTraceIdIsAnything())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_request_id_scoped_repo_for_logging_later()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var requestId = Guid.NewGuid().ToString();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenThereIsNoGlobalRequestId())
|
||||
.And(x => x.GivenTheRequestIdIsAddedToTheRequest("LSRequestId", requestId))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheTraceIdIs(requestId))
|
||||
.And(x => ThenTheRequestIdIsSaved())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_update_request_id_scoped_repo_for_logging_later()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var requestId = Guid.NewGuid().ToString();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenTheRequestIdWasSetGlobally())
|
||||
.And(x => x.GivenTheRequestIdIsAddedToTheRequest("LSRequestId", requestId))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheTraceIdIs(requestId))
|
||||
.And(x => ThenTheRequestIdIsUpdated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereIsNoGlobalRequestId()
|
||||
{
|
||||
ScopedRepository.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>(null));
|
||||
}
|
||||
|
||||
private void GivenTheRequestIdWasSetGlobally()
|
||||
{
|
||||
ScopedRepository.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>("alreadyset"));
|
||||
}
|
||||
|
||||
private void ThenTheRequestIdIsSaved()
|
||||
{
|
||||
ScopedRepository.Verify(x => x.Add<string>("RequestId", _value), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheRequestIdIsUpdated()
|
||||
{
|
||||
ScopedRepository.Verify(x => x.Update<string>("RequestId", _value), Times.Once);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRequestIdMiddleware();
|
||||
|
||||
app.Run(x =>
|
||||
{
|
||||
x.Response.Headers.Add("LSRequestId", x.TraceIdentifier);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheRequestIdIsAddedToTheRequest(string key, string value)
|
||||
{
|
||||
_key = key;
|
||||
_value = value;
|
||||
Client.DefaultRequestHeaders.TryAddWithoutValidation(_key, _value);
|
||||
}
|
||||
|
||||
private void ThenTheTraceIdIsAnything()
|
||||
{
|
||||
ResponseMessage.Headers.GetValues("LSRequestId").First().ShouldNotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
private void ThenTheTraceIdIs(string expected)
|
||||
{
|
||||
ResponseMessage.Headers.GetValues("LSRequestId").First().ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.RequestId
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.RequestId.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ReRouteRequestIdMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly HttpRequestMessage _downstreamRequest;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private string _value;
|
||||
private string _key;
|
||||
|
||||
public ReRouteRequestIdMiddlewareTests()
|
||||
{
|
||||
_downstreamRequest = new HttpRequestMessage();
|
||||
|
||||
ScopedRepository
|
||||
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
|
||||
.Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_pass_down_request_id_from_upstream_request()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var requestId = Guid.NewGuid().ToString();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenThereIsNoGlobalRequestId())
|
||||
.And(x => x.GivenTheRequestIdIsAddedToTheRequest("LSRequestId", requestId))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheTraceIdIs(requestId))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_request_id_when_not_on_upstream_request()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenThereIsNoGlobalRequestId())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheTraceIdIsAnything())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_add_request_id_scoped_repo_for_logging_later()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var requestId = Guid.NewGuid().ToString();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenThereIsNoGlobalRequestId())
|
||||
.And(x => x.GivenTheRequestIdIsAddedToTheRequest("LSRequestId", requestId))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheTraceIdIs(requestId))
|
||||
.And(x => ThenTheRequestIdIsSaved())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_update_request_id_scoped_repo_for_logging_later()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("any old string")
|
||||
.WithRequestIdKey("LSRequestId")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build());
|
||||
|
||||
var requestId = Guid.NewGuid().ToString();
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => GivenTheRequestIdWasSetGlobally())
|
||||
.And(x => x.GivenTheRequestIdIsAddedToTheRequest("LSRequestId", requestId))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheTraceIdIs(requestId))
|
||||
.And(x => ThenTheRequestIdIsUpdated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereIsNoGlobalRequestId()
|
||||
{
|
||||
ScopedRepository.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>(null));
|
||||
}
|
||||
|
||||
private void GivenTheRequestIdWasSetGlobally()
|
||||
{
|
||||
ScopedRepository.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>("alreadyset"));
|
||||
}
|
||||
|
||||
private void ThenTheRequestIdIsSaved()
|
||||
{
|
||||
ScopedRepository.Verify(x => x.Add<string>("RequestId", _value), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheRequestIdIsUpdated()
|
||||
{
|
||||
ScopedRepository.Verify(x => x.Update<string>("RequestId", _value), Times.Once);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRequestIdMiddleware();
|
||||
|
||||
app.Run(x =>
|
||||
{
|
||||
x.Response.Headers.Add("LSRequestId", x.TraceIdentifier);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
{
|
||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
|
||||
.Returns(_downstreamRoute);
|
||||
}
|
||||
|
||||
private void GivenTheRequestIdIsAddedToTheRequest(string key, string value)
|
||||
{
|
||||
_key = key;
|
||||
_value = value;
|
||||
Client.DefaultRequestHeaders.TryAddWithoutValidation(_key, _value);
|
||||
}
|
||||
|
||||
private void ThenTheTraceIdIsAnything()
|
||||
{
|
||||
ResponseMessage.Headers.GetValues("LSRequestId").First().ShouldNotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
private void ThenTheTraceIdIs(string expected)
|
||||
{
|
||||
ResponseMessage.Headers.GetValues("LSRequestId").First().ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,81 +1,81 @@
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Requester.Middleware;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class HttpRequesterMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IHttpRequester> _requester;
|
||||
private OkResponse<HttpResponseMessage> _response;
|
||||
private OkResponse<Ocelot.Request.Request> _request;
|
||||
|
||||
public HttpRequesterMiddlewareTests()
|
||||
{
|
||||
_requester = new Mock<IHttpRequester>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider(), false, false)))
|
||||
.And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
|
||||
.And(x => x.GivenTheScopedRepoReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheScopedRepoIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_requester.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseHttpRequesterMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheRequestIs(Ocelot.Request.Request request)
|
||||
{
|
||||
_request = new OkResponse<Ocelot.Request.Request>(request);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<Ocelot.Request.Request>(It.IsAny<string>()))
|
||||
.Returns(_request);
|
||||
}
|
||||
|
||||
private void GivenTheRequesterReturns(HttpResponseMessage response)
|
||||
{
|
||||
_response = new OkResponse<HttpResponseMessage>(response);
|
||||
_requester
|
||||
.Setup(x => x.GetResponse(It.IsAny<Ocelot.Request.Request>()))
|
||||
.ReturnsAsync(_response);
|
||||
}
|
||||
|
||||
private void GivenTheScopedRepoReturns()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Add(It.IsAny<string>(), _response.Data))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheScopedRepoIsCalledCorrectly()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("HttpResponseMessage", _response.Data), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Requester.Middleware;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class HttpRequesterMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IHttpRequester> _requester;
|
||||
private OkResponse<HttpResponseMessage> _response;
|
||||
private OkResponse<Ocelot.Request.Request> _request;
|
||||
|
||||
public HttpRequesterMiddlewareTests()
|
||||
{
|
||||
_requester = new Mock<IHttpRequester>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider(), false, false)))
|
||||
.And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
|
||||
.And(x => x.GivenTheScopedRepoReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheScopedRepoIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_requester.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseHttpRequesterMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheRequestIs(Ocelot.Request.Request request)
|
||||
{
|
||||
_request = new OkResponse<Ocelot.Request.Request>(request);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<Ocelot.Request.Request>(It.IsAny<string>()))
|
||||
.Returns(_request);
|
||||
}
|
||||
|
||||
private void GivenTheRequesterReturns(HttpResponseMessage response)
|
||||
{
|
||||
_response = new OkResponse<HttpResponseMessage>(response);
|
||||
_requester
|
||||
.Setup(x => x.GetResponse(It.IsAny<Ocelot.Request.Request>()))
|
||||
.ReturnsAsync(_response);
|
||||
}
|
||||
|
||||
private void GivenTheScopedRepoReturns()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Add(It.IsAny<string>(), _response.Data))
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheScopedRepoIsCalledCorrectly()
|
||||
{
|
||||
ScopedRepository
|
||||
.Verify(x => x.Add("HttpResponseMessage", _response.Data), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,81 +1,81 @@
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class QoSProviderFactoryTests
|
||||
{
|
||||
private readonly IQoSProviderFactory _factory;
|
||||
private ReRoute _reRoute;
|
||||
private IQoSProvider _result;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
|
||||
public QoSProviderFactoryTests()
|
||||
{
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory
|
||||
.Setup(x => x.CreateLogger<PollyQoSProvider>())
|
||||
.Returns(_logger.Object);
|
||||
_factory = new QoSProviderFactory(_loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_qos_provider()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "get" })
|
||||
.WithIsQos(false)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheQoSProvider())
|
||||
.Then(x => x.ThenTheQoSProviderIsReturned<NoQoSProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_polly_qos_provider()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.WithTimeoutValue(100)
|
||||
.WithDurationOfBreak(100)
|
||||
.WithExceptionsAllowedBeforeBreaking(100)
|
||||
.Build();
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "get" })
|
||||
.WithIsQos(true)
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheQoSProvider())
|
||||
.Then(x => x.ThenTheQoSProviderIsReturned<PollyQoSProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAReRoute(ReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheQoSProvider()
|
||||
{
|
||||
_result = _factory.Get(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheQoSProviderIsReturned<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Shouldly;
|
||||
using System.Collections.Generic;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class QoSProviderFactoryTests
|
||||
{
|
||||
private readonly IQoSProviderFactory _factory;
|
||||
private ReRoute _reRoute;
|
||||
private IQoSProvider _result;
|
||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||
private Mock<IOcelotLogger> _logger;
|
||||
|
||||
public QoSProviderFactoryTests()
|
||||
{
|
||||
_logger = new Mock<IOcelotLogger>();
|
||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
_loggerFactory
|
||||
.Setup(x => x.CreateLogger<PollyQoSProvider>())
|
||||
.Returns(_logger.Object);
|
||||
_factory = new QoSProviderFactory(_loggerFactory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_qos_provider()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "get" })
|
||||
.WithIsQos(false)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheQoSProvider())
|
||||
.Then(x => x.ThenTheQoSProviderIsReturned<NoQoSProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_polly_qos_provider()
|
||||
{
|
||||
var qosOptions = new QoSOptionsBuilder()
|
||||
.WithTimeoutValue(100)
|
||||
.WithDurationOfBreak(100)
|
||||
.WithExceptionsAllowedBeforeBreaking(100)
|
||||
.Build();
|
||||
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string> { "get" })
|
||||
.WithIsQos(true)
|
||||
.WithQosOptions(qosOptions)
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenAReRoute(reRoute))
|
||||
.When(x => x.WhenIGetTheQoSProvider())
|
||||
.Then(x => x.ThenTheQoSProviderIsReturned<PollyQoSProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenAReRoute(ReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheQoSProvider()
|
||||
{
|
||||
_result = _factory.Get(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheQoSProviderIsReturned<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,146 +1,146 @@
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.UnitTests.LoadBalancer;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class QosProviderHouseTests
|
||||
{
|
||||
private IQoSProvider _qoSProvider;
|
||||
private readonly QosProviderHouse _qosProviderHouse;
|
||||
private Response _addResult;
|
||||
private Response<IQoSProvider> _getResult;
|
||||
private ReRoute _reRoute;
|
||||
private readonly Mock<IQoSProviderFactory> _factory;
|
||||
|
||||
public QosProviderHouseTests()
|
||||
{
|
||||
_factory = new Mock<IQoSProviderFactory>();
|
||||
_qosProviderHouse = new QosProviderHouse(_factory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_store_qos_provider_on_first_request()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
.Then(x => x.ThenItIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_store_qos_provider_on_first_request()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
.Then(x => x.ThenItIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_store_qos_providers_by_key()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("testTwo").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
.And(x => x.GivenThereIsAQoSProvider(reRouteTwo, new FakePollyQoSProvider()))
|
||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
.Then(x => x.ThenTheQoSProviderIs<FakeQoSProvider>())
|
||||
.When(x => x.WhenWeGetTheQoSProvider(reRouteTwo))
|
||||
.Then(x => x.ThenTheQoSProviderIs<FakePollyQoSProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_no_qos_provider_with_key()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().Build();
|
||||
|
||||
this.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
.Then(x => x.ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_new_qos_provider_if_reroute_qos_provider_has_changed()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
|
||||
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("test").WithIsQos(true).Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
.Then(x => x.ThenTheQoSProviderIs<FakeQoSProvider>())
|
||||
.When(x => x.WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(reRouteTwo))
|
||||
.Then(x => x.ThenTheQoSProviderIs<FakePollyQoSProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(ReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_factory.Setup(x => x.Get(_reRoute)).Returns(new FakePollyQoSProvider());
|
||||
_getResult = _qosProviderHouse.Get(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_getResult.IsError.ShouldBeTrue();
|
||||
_getResult.Errors[0].ShouldBeOfType<UnableToFindQoSProviderError>();
|
||||
}
|
||||
|
||||
private void ThenTheQoSProviderIs<T>()
|
||||
{
|
||||
_getResult.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenItIsAdded()
|
||||
{
|
||||
_getResult.IsError.ShouldBe(false);
|
||||
_getResult.ShouldBeOfType<OkResponse<IQoSProvider>>();
|
||||
_factory.Verify(x => x.Get(_reRoute), Times.Once);
|
||||
_getResult.Data.ShouldBe(_qoSProvider);
|
||||
}
|
||||
|
||||
|
||||
private void GivenThereIsAQoSProvider(ReRoute reRoute, IQoSProvider qoSProvider)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_qoSProvider = qoSProvider;
|
||||
_factory.Setup(x => x.Get(_reRoute)).Returns(_qoSProvider);
|
||||
_getResult = _qosProviderHouse.Get(reRoute);
|
||||
}
|
||||
|
||||
private void WhenWeGetTheQoSProvider(ReRoute reRoute)
|
||||
{
|
||||
_getResult = _qosProviderHouse.Get(reRoute);
|
||||
}
|
||||
|
||||
private void ThenItIsReturned()
|
||||
{
|
||||
_getResult.Data.ShouldBe(_qoSProvider);
|
||||
_factory.Verify(x => x.Get(_reRoute), Times.Once);
|
||||
}
|
||||
|
||||
class FakeQoSProvider : IQoSProvider
|
||||
{
|
||||
public CircuitBreaker CircuitBreaker { get; }
|
||||
}
|
||||
|
||||
class FakePollyQoSProvider : IQoSProvider
|
||||
{
|
||||
public CircuitBreaker CircuitBreaker { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.LoadBalancer.LoadBalancers;
|
||||
using Ocelot.Requester.QoS;
|
||||
using Ocelot.Responses;
|
||||
using Ocelot.UnitTests.LoadBalancer;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Requester
|
||||
{
|
||||
public class QosProviderHouseTests
|
||||
{
|
||||
private IQoSProvider _qoSProvider;
|
||||
private readonly QosProviderHouse _qosProviderHouse;
|
||||
private Response _addResult;
|
||||
private Response<IQoSProvider> _getResult;
|
||||
private ReRoute _reRoute;
|
||||
private readonly Mock<IQoSProviderFactory> _factory;
|
||||
|
||||
public QosProviderHouseTests()
|
||||
{
|
||||
_factory = new Mock<IQoSProviderFactory>();
|
||||
_qosProviderHouse = new QosProviderHouse(_factory.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_store_qos_provider_on_first_request()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
.Then(x => x.ThenItIsAdded())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_store_qos_provider_on_first_request()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
.Then(x => x.ThenItIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_store_qos_providers_by_key()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("testTwo").Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
.And(x => x.GivenThereIsAQoSProvider(reRouteTwo, new FakePollyQoSProvider()))
|
||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
.Then(x => x.ThenTheQoSProviderIs<FakeQoSProvider>())
|
||||
.When(x => x.WhenWeGetTheQoSProvider(reRouteTwo))
|
||||
.Then(x => x.ThenTheQoSProviderIs<FakePollyQoSProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_no_qos_provider_with_key()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().Build();
|
||||
|
||||
this.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
.Then(x => x.ThenAnErrorIsReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_get_new_qos_provider_if_reroute_qos_provider_has_changed()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
|
||||
|
||||
var reRouteTwo = new ReRouteBuilder().WithReRouteKey("test").WithIsQos(true).Build();
|
||||
|
||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
||||
.Then(x => x.ThenTheQoSProviderIs<FakeQoSProvider>())
|
||||
.When(x => x.WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(reRouteTwo))
|
||||
.Then(x => x.ThenTheQoSProviderIs<FakePollyQoSProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(ReRoute reRoute)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_factory.Setup(x => x.Get(_reRoute)).Returns(new FakePollyQoSProvider());
|
||||
_getResult = _qosProviderHouse.Get(_reRoute);
|
||||
}
|
||||
|
||||
private void ThenAnErrorIsReturned()
|
||||
{
|
||||
_getResult.IsError.ShouldBeTrue();
|
||||
_getResult.Errors[0].ShouldBeOfType<UnableToFindQoSProviderError>();
|
||||
}
|
||||
|
||||
private void ThenTheQoSProviderIs<T>()
|
||||
{
|
||||
_getResult.Data.ShouldBeOfType<T>();
|
||||
}
|
||||
|
||||
private void ThenItIsAdded()
|
||||
{
|
||||
_getResult.IsError.ShouldBe(false);
|
||||
_getResult.ShouldBeOfType<OkResponse<IQoSProvider>>();
|
||||
_factory.Verify(x => x.Get(_reRoute), Times.Once);
|
||||
_getResult.Data.ShouldBe(_qoSProvider);
|
||||
}
|
||||
|
||||
|
||||
private void GivenThereIsAQoSProvider(ReRoute reRoute, IQoSProvider qoSProvider)
|
||||
{
|
||||
_reRoute = reRoute;
|
||||
_qoSProvider = qoSProvider;
|
||||
_factory.Setup(x => x.Get(_reRoute)).Returns(_qoSProvider);
|
||||
_getResult = _qosProviderHouse.Get(reRoute);
|
||||
}
|
||||
|
||||
private void WhenWeGetTheQoSProvider(ReRoute reRoute)
|
||||
{
|
||||
_getResult = _qosProviderHouse.Get(reRoute);
|
||||
}
|
||||
|
||||
private void ThenItIsReturned()
|
||||
{
|
||||
_getResult.Data.ShouldBe(_qoSProvider);
|
||||
_factory.Verify(x => x.Get(_reRoute), Times.Once);
|
||||
}
|
||||
|
||||
class FakeQoSProvider : IQoSProvider
|
||||
{
|
||||
public CircuitBreaker CircuitBreaker { get; }
|
||||
}
|
||||
|
||||
class FakePollyQoSProvider : IQoSProvider
|
||||
{
|
||||
public CircuitBreaker CircuitBreaker { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.UnitTests.Responder
|
||||
{
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError() : base("blahh", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
|
||||
public AnyError(OcelotErrorCode errorCode) : base("blah", errorCode)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.UnitTests.Responder
|
||||
{
|
||||
class AnyError : Error
|
||||
{
|
||||
public AnyError() : base("blahh", OcelotErrorCode.UnknownError)
|
||||
{
|
||||
}
|
||||
|
||||
public AnyError(OcelotErrorCode errorCode) : base("blah", errorCode)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,167 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responder;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Responder
|
||||
{
|
||||
public class ErrorsToHttpStatusCodeMapperTests
|
||||
{
|
||||
private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
|
||||
private int _result;
|
||||
private List<Error> _errors;
|
||||
|
||||
public ErrorsToHttpStatusCodeMapperTests()
|
||||
{
|
||||
_codeMapper = new ErrorsToHttpStatusCodeMapper();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(OcelotErrorCode.UnauthenticatedError)]
|
||||
public void should_return_unauthorized(OcelotErrorCode errorCode)
|
||||
{
|
||||
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(OcelotErrorCode.CannotFindClaimError)]
|
||||
[InlineData(OcelotErrorCode.ClaimValueNotAuthorisedError)]
|
||||
[InlineData(OcelotErrorCode.ScopeNotAuthorisedError)]
|
||||
[InlineData(OcelotErrorCode.UnauthorizedError)]
|
||||
[InlineData(OcelotErrorCode.UserDoesNotHaveClaimError)]
|
||||
public void should_return_forbidden(OcelotErrorCode errorCode)
|
||||
{
|
||||
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.Forbidden);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(OcelotErrorCode.RequestTimedOutError)]
|
||||
public void should_return_service_unavailable(OcelotErrorCode errorCode)
|
||||
{
|
||||
ShouldMapErrorToStatusCode(OcelotErrorCode.RequestTimedOutError, HttpStatusCode.ServiceUnavailable);
|
||||
}
|
||||
|
||||
|
||||
[Theory]
|
||||
[InlineData(OcelotErrorCode.CannotAddDataError)]
|
||||
[InlineData(OcelotErrorCode.CannotFindDataError)]
|
||||
[InlineData(OcelotErrorCode.DownstreamHostNullOrEmptyError)]
|
||||
[InlineData(OcelotErrorCode.DownstreamPathNullOrEmptyError)]
|
||||
[InlineData(OcelotErrorCode.DownstreampathTemplateAlreadyUsedError)]
|
||||
[InlineData(OcelotErrorCode.DownstreamPathTemplateContainsSchemeError)]
|
||||
[InlineData(OcelotErrorCode.DownstreamSchemeNullOrEmptyError)]
|
||||
[InlineData(OcelotErrorCode.FileValidationFailedError)]
|
||||
[InlineData(OcelotErrorCode.InstructionNotForClaimsError)]
|
||||
[InlineData(OcelotErrorCode.NoInstructionsError)]
|
||||
[InlineData(OcelotErrorCode.ParsingConfigurationHeaderError)]
|
||||
[InlineData(OcelotErrorCode.RateLimitOptionsError)]
|
||||
[InlineData(OcelotErrorCode.ServicesAreEmptyError)]
|
||||
[InlineData(OcelotErrorCode.ServicesAreNullError)]
|
||||
[InlineData(OcelotErrorCode.UnableToCompleteRequestError)]
|
||||
[InlineData(OcelotErrorCode.UnableToCreateAuthenticationHandlerError)]
|
||||
[InlineData(OcelotErrorCode.UnableToFindDownstreamRouteError)]
|
||||
[InlineData(OcelotErrorCode.UnableToFindLoadBalancerError)]
|
||||
[InlineData(OcelotErrorCode.UnableToFindServiceDiscoveryProviderError)]
|
||||
[InlineData(OcelotErrorCode.UnableToFindQoSProviderError)]
|
||||
[InlineData(OcelotErrorCode.UnableToSetConfigInConsulError)]
|
||||
[InlineData(OcelotErrorCode.UnknownError)]
|
||||
[InlineData(OcelotErrorCode.UnmappableRequestError)]
|
||||
[InlineData(OcelotErrorCode.UnsupportedAuthenticationProviderError)]
|
||||
public void should_return_not_found(OcelotErrorCode errorCode)
|
||||
{
|
||||
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthenticationErrorsHaveHighestPriority()
|
||||
{
|
||||
var errors = new List<OcelotErrorCode>
|
||||
{
|
||||
OcelotErrorCode.CannotAddDataError,
|
||||
OcelotErrorCode.CannotFindClaimError,
|
||||
OcelotErrorCode.UnauthenticatedError,
|
||||
OcelotErrorCode.RequestTimedOutError,
|
||||
};
|
||||
|
||||
ShouldMapErrorsToStatusCode(errors, HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthorisationErrorsHaveSecondHighestPriority()
|
||||
{
|
||||
var errors = new List<OcelotErrorCode>
|
||||
{
|
||||
OcelotErrorCode.CannotAddDataError,
|
||||
OcelotErrorCode.CannotFindClaimError,
|
||||
OcelotErrorCode.RequestTimedOutError
|
||||
};
|
||||
|
||||
ShouldMapErrorsToStatusCode(errors, HttpStatusCode.Forbidden);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServiceUnavailableErrorsHaveThirdHighestPriority()
|
||||
{
|
||||
var errors = new List<OcelotErrorCode>
|
||||
{
|
||||
OcelotErrorCode.CannotAddDataError,
|
||||
OcelotErrorCode.RequestTimedOutError
|
||||
};
|
||||
|
||||
ShouldMapErrorsToStatusCode(errors, HttpStatusCode.ServiceUnavailable);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void check_we_have_considered_all_errors_in_these_tests()
|
||||
{
|
||||
// If this test fails then it's because the number of error codes has changed.
|
||||
// You should make the appropriate changes to the test cases here to ensure
|
||||
// they cover all the error codes, and then modify this assertion.
|
||||
Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(32, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?");
|
||||
}
|
||||
|
||||
private void ShouldMapErrorToStatusCode(OcelotErrorCode errorCode, HttpStatusCode expectedHttpStatusCode)
|
||||
{
|
||||
ShouldMapErrorsToStatusCode(new List<OcelotErrorCode> { errorCode }, expectedHttpStatusCode);
|
||||
}
|
||||
|
||||
private void ShouldMapErrorsToStatusCode(List<OcelotErrorCode> errorCodes, HttpStatusCode expectedHttpStatusCode)
|
||||
{
|
||||
var errors = new List<Error>();
|
||||
|
||||
foreach(var errorCode in errorCodes)
|
||||
{
|
||||
errors.Add(new AnyError(errorCode));
|
||||
}
|
||||
|
||||
this.Given(x => x.GivenThereAreErrors(errors))
|
||||
.When(x => x.WhenIGetErrorStatusCode())
|
||||
.Then(x => x.ThenTheResponseIsStatusCodeIs(expectedHttpStatusCode))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereAreErrors(List<Error> errors)
|
||||
{
|
||||
_errors = errors;
|
||||
}
|
||||
|
||||
private void WhenIGetErrorStatusCode()
|
||||
{
|
||||
_result = _codeMapper.Map(_errors);
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsStatusCodeIs(int expectedCode)
|
||||
{
|
||||
_result.ShouldBe(expectedCode);
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsStatusCodeIs(HttpStatusCode expectedCode)
|
||||
{
|
||||
_result.ShouldBe((int)expectedCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Responder;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Responder
|
||||
{
|
||||
public class ErrorsToHttpStatusCodeMapperTests
|
||||
{
|
||||
private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
|
||||
private int _result;
|
||||
private List<Error> _errors;
|
||||
|
||||
public ErrorsToHttpStatusCodeMapperTests()
|
||||
{
|
||||
_codeMapper = new ErrorsToHttpStatusCodeMapper();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(OcelotErrorCode.UnauthenticatedError)]
|
||||
public void should_return_unauthorized(OcelotErrorCode errorCode)
|
||||
{
|
||||
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(OcelotErrorCode.CannotFindClaimError)]
|
||||
[InlineData(OcelotErrorCode.ClaimValueNotAuthorisedError)]
|
||||
[InlineData(OcelotErrorCode.ScopeNotAuthorisedError)]
|
||||
[InlineData(OcelotErrorCode.UnauthorizedError)]
|
||||
[InlineData(OcelotErrorCode.UserDoesNotHaveClaimError)]
|
||||
public void should_return_forbidden(OcelotErrorCode errorCode)
|
||||
{
|
||||
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.Forbidden);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(OcelotErrorCode.RequestTimedOutError)]
|
||||
public void should_return_service_unavailable(OcelotErrorCode errorCode)
|
||||
{
|
||||
ShouldMapErrorToStatusCode(OcelotErrorCode.RequestTimedOutError, HttpStatusCode.ServiceUnavailable);
|
||||
}
|
||||
|
||||
|
||||
[Theory]
|
||||
[InlineData(OcelotErrorCode.CannotAddDataError)]
|
||||
[InlineData(OcelotErrorCode.CannotFindDataError)]
|
||||
[InlineData(OcelotErrorCode.DownstreamHostNullOrEmptyError)]
|
||||
[InlineData(OcelotErrorCode.DownstreamPathNullOrEmptyError)]
|
||||
[InlineData(OcelotErrorCode.DownstreampathTemplateAlreadyUsedError)]
|
||||
[InlineData(OcelotErrorCode.DownstreamPathTemplateContainsSchemeError)]
|
||||
[InlineData(OcelotErrorCode.DownstreamSchemeNullOrEmptyError)]
|
||||
[InlineData(OcelotErrorCode.FileValidationFailedError)]
|
||||
[InlineData(OcelotErrorCode.InstructionNotForClaimsError)]
|
||||
[InlineData(OcelotErrorCode.NoInstructionsError)]
|
||||
[InlineData(OcelotErrorCode.ParsingConfigurationHeaderError)]
|
||||
[InlineData(OcelotErrorCode.RateLimitOptionsError)]
|
||||
[InlineData(OcelotErrorCode.ServicesAreEmptyError)]
|
||||
[InlineData(OcelotErrorCode.ServicesAreNullError)]
|
||||
[InlineData(OcelotErrorCode.UnableToCompleteRequestError)]
|
||||
[InlineData(OcelotErrorCode.UnableToCreateAuthenticationHandlerError)]
|
||||
[InlineData(OcelotErrorCode.UnableToFindDownstreamRouteError)]
|
||||
[InlineData(OcelotErrorCode.UnableToFindLoadBalancerError)]
|
||||
[InlineData(OcelotErrorCode.UnableToFindServiceDiscoveryProviderError)]
|
||||
[InlineData(OcelotErrorCode.UnableToFindQoSProviderError)]
|
||||
[InlineData(OcelotErrorCode.UnableToSetConfigInConsulError)]
|
||||
[InlineData(OcelotErrorCode.UnknownError)]
|
||||
[InlineData(OcelotErrorCode.UnmappableRequestError)]
|
||||
[InlineData(OcelotErrorCode.UnsupportedAuthenticationProviderError)]
|
||||
public void should_return_not_found(OcelotErrorCode errorCode)
|
||||
{
|
||||
ShouldMapErrorToStatusCode(errorCode, HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthenticationErrorsHaveHighestPriority()
|
||||
{
|
||||
var errors = new List<OcelotErrorCode>
|
||||
{
|
||||
OcelotErrorCode.CannotAddDataError,
|
||||
OcelotErrorCode.CannotFindClaimError,
|
||||
OcelotErrorCode.UnauthenticatedError,
|
||||
OcelotErrorCode.RequestTimedOutError,
|
||||
};
|
||||
|
||||
ShouldMapErrorsToStatusCode(errors, HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthorisationErrorsHaveSecondHighestPriority()
|
||||
{
|
||||
var errors = new List<OcelotErrorCode>
|
||||
{
|
||||
OcelotErrorCode.CannotAddDataError,
|
||||
OcelotErrorCode.CannotFindClaimError,
|
||||
OcelotErrorCode.RequestTimedOutError
|
||||
};
|
||||
|
||||
ShouldMapErrorsToStatusCode(errors, HttpStatusCode.Forbidden);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ServiceUnavailableErrorsHaveThirdHighestPriority()
|
||||
{
|
||||
var errors = new List<OcelotErrorCode>
|
||||
{
|
||||
OcelotErrorCode.CannotAddDataError,
|
||||
OcelotErrorCode.RequestTimedOutError
|
||||
};
|
||||
|
||||
ShouldMapErrorsToStatusCode(errors, HttpStatusCode.ServiceUnavailable);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void check_we_have_considered_all_errors_in_these_tests()
|
||||
{
|
||||
// If this test fails then it's because the number of error codes has changed.
|
||||
// You should make the appropriate changes to the test cases here to ensure
|
||||
// they cover all the error codes, and then modify this assertion.
|
||||
Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(32, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?");
|
||||
}
|
||||
|
||||
private void ShouldMapErrorToStatusCode(OcelotErrorCode errorCode, HttpStatusCode expectedHttpStatusCode)
|
||||
{
|
||||
ShouldMapErrorsToStatusCode(new List<OcelotErrorCode> { errorCode }, expectedHttpStatusCode);
|
||||
}
|
||||
|
||||
private void ShouldMapErrorsToStatusCode(List<OcelotErrorCode> errorCodes, HttpStatusCode expectedHttpStatusCode)
|
||||
{
|
||||
var errors = new List<Error>();
|
||||
|
||||
foreach(var errorCode in errorCodes)
|
||||
{
|
||||
errors.Add(new AnyError(errorCode));
|
||||
}
|
||||
|
||||
this.Given(x => x.GivenThereAreErrors(errors))
|
||||
.When(x => x.WhenIGetErrorStatusCode())
|
||||
.Then(x => x.ThenTheResponseIsStatusCodeIs(expectedHttpStatusCode))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenThereAreErrors(List<Error> errors)
|
||||
{
|
||||
_errors = errors;
|
||||
}
|
||||
|
||||
private void WhenIGetErrorStatusCode()
|
||||
{
|
||||
_result = _codeMapper.Map(_errors);
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsStatusCodeIs(int expectedCode)
|
||||
{
|
||||
_result.ShouldBe(expectedCode);
|
||||
}
|
||||
|
||||
private void ThenTheResponseIsStatusCodeIs(HttpStatusCode expectedCode)
|
||||
{
|
||||
_result.ShouldBe((int)expectedCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,72 +1,72 @@
|
||||
namespace Ocelot.UnitTests.Responder
|
||||
{
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responder;
|
||||
using Ocelot.Responder.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ResponderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IHttpResponder> _responder;
|
||||
private readonly Mock<IErrorsToHttpStatusCodeMapper> _codeMapper;
|
||||
private OkResponse<HttpResponseMessage> _response;
|
||||
|
||||
public ResponderMiddlewareTests()
|
||||
{
|
||||
_responder = new Mock<IHttpResponder>();
|
||||
_codeMapper = new Mock<IErrorsToHttpStatusCodeMapper>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_any_errors()
|
||||
{
|
||||
this.Given(x => x.GivenTheHttpResponseMessageIs(new HttpResponseMessage()))
|
||||
.And(x => x.GivenThereAreNoPipelineErrors())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenThereAreNoErrors())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_codeMapper.Object);
|
||||
services.AddSingleton(_responder.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseResponderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheHttpResponseMessageIs(HttpResponseMessage response)
|
||||
{
|
||||
_response = new OkResponse<HttpResponseMessage>(response);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<HttpResponseMessage>(It.IsAny<string>()))
|
||||
.Returns(_response);
|
||||
}
|
||||
|
||||
private void GivenThereAreNoPipelineErrors()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<bool>(It.IsAny<string>()))
|
||||
.Returns(new OkResponse<bool>(false));
|
||||
}
|
||||
|
||||
private void ThenThereAreNoErrors()
|
||||
{
|
||||
//todo a better assert?
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.Responder
|
||||
{
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responder;
|
||||
using Ocelot.Responder.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
public class ResponderMiddlewareTests : ServerHostedMiddlewareTest
|
||||
{
|
||||
private readonly Mock<IHttpResponder> _responder;
|
||||
private readonly Mock<IErrorsToHttpStatusCodeMapper> _codeMapper;
|
||||
private OkResponse<HttpResponseMessage> _response;
|
||||
|
||||
public ResponderMiddlewareTests()
|
||||
{
|
||||
_responder = new Mock<IHttpResponder>();
|
||||
_codeMapper = new Mock<IErrorsToHttpStatusCodeMapper>();
|
||||
|
||||
GivenTheTestServerIsConfigured();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_return_any_errors()
|
||||
{
|
||||
this.Given(x => x.GivenTheHttpResponseMessageIs(new HttpResponseMessage()))
|
||||
.And(x => x.GivenThereAreNoPipelineErrors())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenThereAreNoErrors())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
services.AddLogging();
|
||||
services.AddSingleton(_codeMapper.Object);
|
||||
services.AddSingleton(_responder.Object);
|
||||
services.AddSingleton(ScopedRepository.Object);
|
||||
}
|
||||
|
||||
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
app.UseResponderMiddleware();
|
||||
}
|
||||
|
||||
private void GivenTheHttpResponseMessageIs(HttpResponseMessage response)
|
||||
{
|
||||
_response = new OkResponse<HttpResponseMessage>(response);
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<HttpResponseMessage>(It.IsAny<string>()))
|
||||
.Returns(_response);
|
||||
}
|
||||
|
||||
private void GivenThereAreNoPipelineErrors()
|
||||
{
|
||||
ScopedRepository
|
||||
.Setup(x => x.Get<bool>(It.IsAny<string>()))
|
||||
.Returns(new OkResponse<bool>(false));
|
||||
}
|
||||
|
||||
private void ThenThereAreNoErrors()
|
||||
{
|
||||
//todo a better assert?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,68 +1,68 @@
|
||||
namespace Ocelot.UnitTests
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Moq;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
|
||||
public abstract class ServerHostedMiddlewareTest : IDisposable
|
||||
{
|
||||
protected TestServer Server { get; private set; }
|
||||
protected HttpClient Client { get; private set; }
|
||||
protected string Url { get; private set; }
|
||||
protected HttpResponseMessage ResponseMessage { get; private set; }
|
||||
protected Mock<IRequestScopedDataRepository> ScopedRepository { get; private set; }
|
||||
|
||||
public ServerHostedMiddlewareTest()
|
||||
{
|
||||
Url = "http://localhost:51879";
|
||||
ScopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
}
|
||||
|
||||
protected virtual void GivenTheTestServerIsConfigured()
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x => GivenTheTestServerServicesAreConfigured(x))
|
||||
.UseUrls(Url)
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.Configure(app => GivenTheTestServerPipelineIsConfigured(app));
|
||||
|
||||
Server = new TestServer(builder);
|
||||
Client = Server.CreateClient();
|
||||
}
|
||||
|
||||
protected virtual void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
// override this in your test fixture to set up service dependencies
|
||||
}
|
||||
|
||||
protected virtual void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
// override this in your test fixture to set up the test server pipeline
|
||||
}
|
||||
|
||||
protected void WhenICallTheMiddleware()
|
||||
{
|
||||
ResponseMessage = Client.GetAsync(Url).Result;
|
||||
}
|
||||
|
||||
protected void WhenICallTheMiddlewareWithTheRequestIdKey(string requestIdKey, string value)
|
||||
{
|
||||
Client.DefaultRequestHeaders.Add(requestIdKey, value);
|
||||
ResponseMessage = Client.GetAsync(Url).Result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Client.Dispose();
|
||||
Server.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Moq;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
|
||||
public abstract class ServerHostedMiddlewareTest : IDisposable
|
||||
{
|
||||
protected TestServer Server { get; private set; }
|
||||
protected HttpClient Client { get; private set; }
|
||||
protected string Url { get; private set; }
|
||||
protected HttpResponseMessage ResponseMessage { get; private set; }
|
||||
protected Mock<IRequestScopedDataRepository> ScopedRepository { get; private set; }
|
||||
|
||||
public ServerHostedMiddlewareTest()
|
||||
{
|
||||
Url = "http://localhost:51879";
|
||||
ScopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
}
|
||||
|
||||
protected virtual void GivenTheTestServerIsConfigured()
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x => GivenTheTestServerServicesAreConfigured(x))
|
||||
.UseUrls(Url)
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.Configure(app => GivenTheTestServerPipelineIsConfigured(app));
|
||||
|
||||
Server = new TestServer(builder);
|
||||
Client = Server.CreateClient();
|
||||
}
|
||||
|
||||
protected virtual void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
|
||||
{
|
||||
// override this in your test fixture to set up service dependencies
|
||||
}
|
||||
|
||||
protected virtual void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
|
||||
{
|
||||
// override this in your test fixture to set up the test server pipeline
|
||||
}
|
||||
|
||||
protected void WhenICallTheMiddleware()
|
||||
{
|
||||
ResponseMessage = Client.GetAsync(Url).Result;
|
||||
}
|
||||
|
||||
protected void WhenICallTheMiddlewareWithTheRequestIdKey(string requestIdKey, string value)
|
||||
{
|
||||
Client.DefaultRequestHeaders.Add(requestIdKey, value);
|
||||
ResponseMessage = Client.GetAsync(Url).Result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Client.Dispose();
|
||||
Server.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,52 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
public class ConfigurationServiceProviderTests
|
||||
{
|
||||
private ConfigurationServiceProvider _serviceProvider;
|
||||
private List<Service> _result;
|
||||
private List<Service> _expected;
|
||||
|
||||
[Fact]
|
||||
public void should_return_services()
|
||||
{
|
||||
var hostAndPort = new HostAndPort("127.0.0.1", 80);
|
||||
|
||||
var services = new List<Service>
|
||||
{
|
||||
new Service("product", hostAndPort, string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenServices(services))
|
||||
.When(x => x.WhenIGetTheService())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(services))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenServices(List<Service> services)
|
||||
{
|
||||
_expected = services;
|
||||
}
|
||||
|
||||
private void WhenIGetTheService()
|
||||
{
|
||||
_serviceProvider = new ConfigurationServiceProvider(_expected);
|
||||
_result = _serviceProvider.Get().Result;
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(List<Service> services)
|
||||
{
|
||||
_result[0].HostAndPort.DownstreamHost.ShouldBe(services[0].HostAndPort.DownstreamHost);
|
||||
|
||||
_result[0].HostAndPort.DownstreamPort.ShouldBe(services[0].HostAndPort.DownstreamPort);
|
||||
|
||||
_result[0].Name.ShouldBe(services[0].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
public class ConfigurationServiceProviderTests
|
||||
{
|
||||
private ConfigurationServiceProvider _serviceProvider;
|
||||
private List<Service> _result;
|
||||
private List<Service> _expected;
|
||||
|
||||
[Fact]
|
||||
public void should_return_services()
|
||||
{
|
||||
var hostAndPort = new ServiceHostAndPort("127.0.0.1", 80);
|
||||
|
||||
var services = new List<Service>
|
||||
{
|
||||
new Service("product", hostAndPort, string.Empty, string.Empty, new string[0])
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenServices(services))
|
||||
.When(x => x.WhenIGetTheService())
|
||||
.Then(x => x.ThenTheFollowingIsReturned(services))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenServices(List<Service> services)
|
||||
{
|
||||
_expected = services;
|
||||
}
|
||||
|
||||
private void WhenIGetTheService()
|
||||
{
|
||||
_serviceProvider = new ConfigurationServiceProvider(_expected);
|
||||
_result = _serviceProvider.Get().Result;
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(List<Service> services)
|
||||
{
|
||||
_result[0].HostAndPort.DownstreamHost.ShouldBe(services[0].HostAndPort.DownstreamHost);
|
||||
|
||||
_result[0].HostAndPort.DownstreamPort.ShouldBe(services[0].HostAndPort.DownstreamPort);
|
||||
|
||||
_result[0].Name.ShouldBe(services[0].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +1,107 @@
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
public class ServiceProviderFactoryTests
|
||||
{
|
||||
private ServiceProviderConfiguration _serviceConfig;
|
||||
private IServiceDiscoveryProvider _result;
|
||||
private readonly ServiceDiscoveryProviderFactory _factory;
|
||||
private ReRoute _reRoute;
|
||||
|
||||
public ServiceProviderFactoryTests()
|
||||
{
|
||||
_factory = new ServiceDiscoveryProviderFactory();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_service_provider()
|
||||
{
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new ReRouteBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_consul_service_provider()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithServiceName("product")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConsulServiceDiscoveryProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig, ReRoute reRoute)
|
||||
{
|
||||
_serviceConfig = serviceConfig;
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheServiceProvider()
|
||||
{
|
||||
_result = _factory.Get(_serviceConfig, _reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheServiceProviderIs<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.ServiceDiscovery;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
public class ServiceProviderFactoryTests
|
||||
{
|
||||
private ServiceProviderConfiguration _serviceConfig;
|
||||
private IServiceDiscoveryProvider _result;
|
||||
private readonly ServiceDiscoveryProviderFactory _factory;
|
||||
private ReRoute _reRoute;
|
||||
|
||||
public ServiceProviderFactoryTests()
|
||||
{
|
||||
_factory = new ServiceDiscoveryProviderFactory();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_no_service_provider()
|
||||
{
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
var reRoute = new ReRouteBuilder().Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_list_of_configuration_services()
|
||||
{
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
var downstreamAddresses = new List<DownstreamHostAndPort>()
|
||||
{
|
||||
new DownstreamHostAndPort("asdf.com", 80),
|
||||
new DownstreamHostAndPort("abc.com", 80)
|
||||
};
|
||||
|
||||
var reRoute = new ReRouteBuilder().WithDownstreamAddresses(downstreamAddresses).Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>())
|
||||
.Then(x => ThenTheFollowingServicesAreReturned(downstreamAddresses))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheFollowingServicesAreReturned(List<DownstreamHostAndPort> downstreamAddresses)
|
||||
{
|
||||
var result = (ConfigurationServiceProvider)_result;
|
||||
var services = result.Get().Result;
|
||||
|
||||
for (int i = 0; i < services.Count; i++)
|
||||
{
|
||||
var service = services[i];
|
||||
var downstreamAddress = downstreamAddresses[i];
|
||||
|
||||
service.HostAndPort.DownstreamHost.ShouldBe(downstreamAddress.Host);
|
||||
service.HostAndPort.DownstreamPort.ShouldBe(downstreamAddress.Port);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_consul_service_provider()
|
||||
{
|
||||
var reRoute = new ReRouteBuilder()
|
||||
.WithServiceName("product")
|
||||
.WithUseServiceDiscovery(true)
|
||||
.Build();
|
||||
|
||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||
.When(x => x.WhenIGetTheServiceProvider())
|
||||
.Then(x => x.ThenTheServiceProviderIs<ConsulServiceDiscoveryProvider>())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig, ReRoute reRoute)
|
||||
{
|
||||
_serviceConfig = serviceConfig;
|
||||
_reRoute = reRoute;
|
||||
}
|
||||
|
||||
private void WhenIGetTheServiceProvider()
|
||||
{
|
||||
_result = _factory.Get(_serviceConfig, _reRoute);
|
||||
}
|
||||
|
||||
private void ThenTheServiceProviderIs<T>()
|
||||
{
|
||||
_result.ShouldBeOfType<T>();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,138 +1,138 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
// nothing in use
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
public class ServiceRegistryTests
|
||||
{
|
||||
private Service _service;
|
||||
private List<Service> _services;
|
||||
private ServiceRegistry _serviceRegistry;
|
||||
private ServiceRepository _serviceRepository;
|
||||
|
||||
public ServiceRegistryTests()
|
||||
{
|
||||
_serviceRepository = new ServiceRepository();
|
||||
_serviceRegistry = new ServiceRegistry(_serviceRepository);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_register_service()
|
||||
{
|
||||
this.Given(x => x.GivenAServiceToRegister("product", "localhost:5000", 80))
|
||||
.When(x => x.WhenIRegisterTheService())
|
||||
.Then(x => x.ThenTheServiceIsRegistered())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_lookup_service()
|
||||
{
|
||||
this.Given(x => x.GivenAServiceIsRegistered("product", "localhost:600", 80))
|
||||
.When(x => x.WhenILookupTheService("product"))
|
||||
.Then(x => x.ThenTheServiceDetailsAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheServiceDetailsAreReturned()
|
||||
{
|
||||
_services[0].HostAndPort.DownstreamHost.ShouldBe(_service.HostAndPort.DownstreamHost);
|
||||
_services[0].HostAndPort.DownstreamPort.ShouldBe(_service.HostAndPort.DownstreamPort);
|
||||
_services[0].Name.ShouldBe(_service.Name);
|
||||
}
|
||||
|
||||
private void WhenILookupTheService(string name)
|
||||
{
|
||||
_services = _serviceRegistry.Lookup(name);
|
||||
}
|
||||
|
||||
private void GivenAServiceIsRegistered(string name, string address, int port)
|
||||
{
|
||||
_service = new Service(name, new HostAndPort(address, port), string.Empty, string.Empty, new string[0]);
|
||||
_serviceRepository.Set(_service);
|
||||
}
|
||||
|
||||
private void GivenAServiceToRegister(string name, string address, int port)
|
||||
{
|
||||
_service = new Service(name, new HostAndPort(address, port), string.Empty, string.Empty, new string[0]);
|
||||
}
|
||||
|
||||
private void WhenIRegisterTheService()
|
||||
{
|
||||
_serviceRegistry.Register(_service);
|
||||
}
|
||||
|
||||
private void ThenTheServiceIsRegistered()
|
||||
{
|
||||
var serviceNameAndAddress = _serviceRepository.Get(_service.Name);
|
||||
serviceNameAndAddress[0].HostAndPort.DownstreamHost.ShouldBe(_service.HostAndPort.DownstreamHost);
|
||||
serviceNameAndAddress[0].HostAndPort.DownstreamPort.ShouldBe(_service.HostAndPort.DownstreamPort);
|
||||
serviceNameAndAddress[0].Name.ShouldBe(_service.Name);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IServiceRegistry
|
||||
{
|
||||
void Register(Service serviceNameAndAddress);
|
||||
List<Service> Lookup(string name);
|
||||
}
|
||||
|
||||
public class ServiceRegistry : IServiceRegistry
|
||||
{
|
||||
private readonly IServiceRepository _repository;
|
||||
public ServiceRegistry(IServiceRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public void Register(Service serviceNameAndAddress)
|
||||
{
|
||||
_repository.Set(serviceNameAndAddress);
|
||||
}
|
||||
|
||||
public List<Service> Lookup(string name)
|
||||
{
|
||||
return _repository.Get(name);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IServiceRepository
|
||||
{
|
||||
List<Service> Get(string serviceName);
|
||||
void Set(Service serviceNameAndAddress);
|
||||
}
|
||||
|
||||
public class ServiceRepository : IServiceRepository
|
||||
{
|
||||
private Dictionary<string, List<Service>> _registeredServices;
|
||||
|
||||
public ServiceRepository()
|
||||
{
|
||||
_registeredServices = new Dictionary<string, List<Service>>();
|
||||
}
|
||||
|
||||
public List<Service> Get(string serviceName)
|
||||
{
|
||||
return _registeredServices[serviceName];
|
||||
}
|
||||
|
||||
public void Set(Service serviceNameAndAddress)
|
||||
{
|
||||
List<Service> services;
|
||||
if(_registeredServices.TryGetValue(serviceNameAndAddress.Name, out services))
|
||||
{
|
||||
services.Add(serviceNameAndAddress);
|
||||
_registeredServices[serviceNameAndAddress.Name] = services;
|
||||
}
|
||||
else
|
||||
{
|
||||
_registeredServices[serviceNameAndAddress.Name] = new List<Service>(){ serviceNameAndAddress };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Values;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
// nothing in use
|
||||
namespace Ocelot.UnitTests.ServiceDiscovery
|
||||
{
|
||||
public class ServiceRegistryTests
|
||||
{
|
||||
private Service _service;
|
||||
private List<Service> _services;
|
||||
private ServiceRegistry _serviceRegistry;
|
||||
private ServiceRepository _serviceRepository;
|
||||
|
||||
public ServiceRegistryTests()
|
||||
{
|
||||
_serviceRepository = new ServiceRepository();
|
||||
_serviceRegistry = new ServiceRegistry(_serviceRepository);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_register_service()
|
||||
{
|
||||
this.Given(x => x.GivenAServiceToRegister("product", "localhost:5000", 80))
|
||||
.When(x => x.WhenIRegisterTheService())
|
||||
.Then(x => x.ThenTheServiceIsRegistered())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_lookup_service()
|
||||
{
|
||||
this.Given(x => x.GivenAServiceIsRegistered("product", "localhost:600", 80))
|
||||
.When(x => x.WhenILookupTheService("product"))
|
||||
.Then(x => x.ThenTheServiceDetailsAreReturned())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void ThenTheServiceDetailsAreReturned()
|
||||
{
|
||||
_services[0].HostAndPort.DownstreamHost.ShouldBe(_service.HostAndPort.DownstreamHost);
|
||||
_services[0].HostAndPort.DownstreamPort.ShouldBe(_service.HostAndPort.DownstreamPort);
|
||||
_services[0].Name.ShouldBe(_service.Name);
|
||||
}
|
||||
|
||||
private void WhenILookupTheService(string name)
|
||||
{
|
||||
_services = _serviceRegistry.Lookup(name);
|
||||
}
|
||||
|
||||
private void GivenAServiceIsRegistered(string name, string address, int port)
|
||||
{
|
||||
_service = new Service(name, new ServiceHostAndPort(address, port), string.Empty, string.Empty, new string[0]);
|
||||
_serviceRepository.Set(_service);
|
||||
}
|
||||
|
||||
private void GivenAServiceToRegister(string name, string address, int port)
|
||||
{
|
||||
_service = new Service(name, new ServiceHostAndPort(address, port), string.Empty, string.Empty, new string[0]);
|
||||
}
|
||||
|
||||
private void WhenIRegisterTheService()
|
||||
{
|
||||
_serviceRegistry.Register(_service);
|
||||
}
|
||||
|
||||
private void ThenTheServiceIsRegistered()
|
||||
{
|
||||
var serviceNameAndAddress = _serviceRepository.Get(_service.Name);
|
||||
serviceNameAndAddress[0].HostAndPort.DownstreamHost.ShouldBe(_service.HostAndPort.DownstreamHost);
|
||||
serviceNameAndAddress[0].HostAndPort.DownstreamPort.ShouldBe(_service.HostAndPort.DownstreamPort);
|
||||
serviceNameAndAddress[0].Name.ShouldBe(_service.Name);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IServiceRegistry
|
||||
{
|
||||
void Register(Service serviceNameAndAddress);
|
||||
List<Service> Lookup(string name);
|
||||
}
|
||||
|
||||
public class ServiceRegistry : IServiceRegistry
|
||||
{
|
||||
private readonly IServiceRepository _repository;
|
||||
public ServiceRegistry(IServiceRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
|
||||
public void Register(Service serviceNameAndAddress)
|
||||
{
|
||||
_repository.Set(serviceNameAndAddress);
|
||||
}
|
||||
|
||||
public List<Service> Lookup(string name)
|
||||
{
|
||||
return _repository.Get(name);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IServiceRepository
|
||||
{
|
||||
List<Service> Get(string serviceName);
|
||||
void Set(Service serviceNameAndAddress);
|
||||
}
|
||||
|
||||
public class ServiceRepository : IServiceRepository
|
||||
{
|
||||
private Dictionary<string, List<Service>> _registeredServices;
|
||||
|
||||
public ServiceRepository()
|
||||
{
|
||||
_registeredServices = new Dictionary<string, List<Service>>();
|
||||
}
|
||||
|
||||
public List<Service> Get(string serviceName)
|
||||
{
|
||||
return _registeredServices[serviceName];
|
||||
}
|
||||
|
||||
public void Set(Service serviceNameAndAddress)
|
||||
{
|
||||
List<Service> services;
|
||||
if(_registeredServices.TryGetValue(serviceNameAndAddress.Name, out services))
|
||||
{
|
||||
services.Add(serviceNameAndAddress);
|
||||
_registeredServices[serviceNameAndAddress.Name] = services;
|
||||
}
|
||||
else
|
||||
{
|
||||
_registeredServices[serviceNameAndAddress.Name] = new List<Service>(){ serviceNameAndAddress };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +1,63 @@
|
||||
namespace Ocelot.UnitTests.TestData
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration.File;
|
||||
|
||||
public class AuthenticationConfigTestData
|
||||
{
|
||||
public static IEnumerable<object[]> GetAuthenticationData()
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
ReRouteIsCaseSensitive = true,
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "Test",
|
||||
AllowedScopes = new List<string>(),
|
||||
},
|
||||
AddHeadersToRequest =
|
||||
{
|
||||
{ "CustomerId", "Claims[CustomerId] > value" },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
ReRouteIsCaseSensitive = true,
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "Test",
|
||||
AllowedScopes = new List<string>(),
|
||||
},
|
||||
AddHeadersToRequest =
|
||||
{
|
||||
{ "CustomerId", "Claims[CustomerId] > value" },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Ocelot.UnitTests.TestData
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration.File;
|
||||
|
||||
public class AuthenticationConfigTestData
|
||||
{
|
||||
public static IEnumerable<object[]> GetAuthenticationData()
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
ReRouteIsCaseSensitive = true,
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "Test",
|
||||
AllowedScopes = new List<string>(),
|
||||
},
|
||||
AddHeadersToRequest =
|
||||
{
|
||||
{ "CustomerId", "Claims[CustomerId] > value" },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
ReRouteIsCaseSensitive = true,
|
||||
AuthenticationOptions = new FileAuthenticationOptions
|
||||
{
|
||||
AuthenticationProviderKey = "Test",
|
||||
AllowedScopes = new List<string>(),
|
||||
},
|
||||
AddHeadersToRequest =
|
||||
{
|
||||
{ "CustomerId", "Claims[CustomerId] > value" },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +1,55 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ocelot.UnitTests
|
||||
{
|
||||
public class Wait
|
||||
{
|
||||
public static Waiter WaitFor(int milliSeconds)
|
||||
{
|
||||
return new Waiter(milliSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
public class Waiter
|
||||
{
|
||||
private readonly int _milliSeconds;
|
||||
|
||||
public Waiter(int milliSeconds)
|
||||
{
|
||||
_milliSeconds = milliSeconds;
|
||||
}
|
||||
|
||||
public bool Until(Func<bool> condition)
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
var passed = false;
|
||||
while (stopwatch.ElapsedMilliseconds < _milliSeconds)
|
||||
{
|
||||
if (condition.Invoke())
|
||||
{
|
||||
passed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public bool Until<T>(Func<bool> condition)
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
var passed = false;
|
||||
while (stopwatch.ElapsedMilliseconds < _milliSeconds)
|
||||
{
|
||||
if (condition.Invoke())
|
||||
{
|
||||
passed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ocelot.UnitTests
|
||||
{
|
||||
public class Wait
|
||||
{
|
||||
public static Waiter WaitFor(int milliSeconds)
|
||||
{
|
||||
return new Waiter(milliSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
public class Waiter
|
||||
{
|
||||
private readonly int _milliSeconds;
|
||||
|
||||
public Waiter(int milliSeconds)
|
||||
{
|
||||
_milliSeconds = milliSeconds;
|
||||
}
|
||||
|
||||
public bool Until(Func<bool> condition)
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
var passed = false;
|
||||
while (stopwatch.ElapsedMilliseconds < _milliSeconds)
|
||||
{
|
||||
if (condition.Invoke())
|
||||
{
|
||||
passed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public bool Until<T>(Func<bool> condition)
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
var passed = false;
|
||||
while (stopwatch.ElapsedMilliseconds < _milliSeconds)
|
||||
{
|
||||
if (condition.Invoke())
|
||||
{
|
||||
passed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user