#296 merged develop into this branch

This commit is contained in:
Tom Gardham-Pallister
2018-04-17 19:45:27 +01:00
16 changed files with 624 additions and 428 deletions

View File

@ -819,6 +819,7 @@
result.DownstreamReRoute[0].RequestIdKey.ShouldBe(expected.DownstreamReRoute[0].RequestIdKey);
result.DownstreamReRoute[0].DelegatingHandlers.ShouldBe(expected.DownstreamReRoute[0].DelegatingHandlers);
result.DownstreamReRoute[0].AddHeadersToDownstream.ShouldBe(expected.DownstreamReRoute[0].AddHeadersToDownstream);
result.DownstreamReRoute[0].AddHeadersToUpstream.ShouldBe(expected.DownstreamReRoute[0].AddHeadersToUpstream, "AddHeadersToUpstream should be set");
}
}
@ -901,7 +902,7 @@
private void GivenTheHeaderFindAndReplaceCreatorReturns()
{
_headerFindAndReplaceCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(new HeaderTransformations(new List<HeaderFindAndReplace>(), new List<HeaderFindAndReplace>(), new List<AddHeader>()));
_headerFindAndReplaceCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(new HeaderTransformations(new List<HeaderFindAndReplace>(), new List<HeaderFindAndReplace>(), new List<AddHeader>(), new List<AddHeader>()));
}
private void GivenTheFollowingIsReturned(ServiceProviderConfiguration serviceProviderConfiguration)

View File

@ -12,13 +12,17 @@ using Ocelot.Configuration.Repository;
namespace Ocelot.UnitTests.Configuration
{
public class FileConfigurationRepositoryTests
public class FileConfigurationRepositoryTests : IDisposable
{
private readonly Mock<IHostingEnvironment> _hostingEnvironment = new Mock<IHostingEnvironment>();
private IFileConfigurationRepository _repo;
private FileConfiguration _result;
private FileConfiguration _fileConfiguration;
private string _environmentName = "DEV";
// This is a bit dirty and it is dev.dev so that the configuration tests
// cant pick it up if they run in parralel..sigh these are not really unit
// tests but whatever...
private string _environmentName = "DEV.DEV";
public FileConfigurationRepositoryTests()
{
@ -221,5 +225,10 @@ namespace Ocelot.UnitTests.Configuration
ReRoutes = reRoutes
};
}
public void Dispose()
{
File.Delete($"./ocelot.{_environmentName}.json");
}
}
}

View File

@ -149,7 +149,6 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
.BDDfy();
}
[Fact]
public void should_add_trace_id_header()
{
@ -166,7 +165,45 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => GivenTheReRoute(reRoute))
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
.When(x => WhenICreate())
.Then(x => ThenTheFollowingAddHeaderIsReturned(expected))
.Then(x => ThenTheFollowingAddHeaderToDownstreamIsReturned(expected))
.BDDfy();
}
[Fact]
public void should_add_downstream_header_as_is_when_no_replacement_is_given()
{
var reRoute = new FileReRoute
{
DownstreamHeaderTransform = new Dictionary<string, string>
{
{"X-Custom-Header", "Value"},
}
};
var expected = new AddHeader("X-Custom-Header", "Value");
this.Given(x => GivenTheReRoute(reRoute))
.And(x => WhenICreate())
.Then(x => x.ThenTheFollowingAddHeaderToDownstreamIsReturned(expected))
.BDDfy();
}
[Fact]
public void should_add_upstream_header_as_is_when_no_replacement_is_given()
{
var reRoute = new FileReRoute
{
UpstreamHeaderTransform = new Dictionary<string, string>
{
{"X-Custom-Header", "Value"},
}
};
var expected = new AddHeader("X-Custom-Header", "Value");
this.Given(x => GivenTheReRoute(reRoute))
.And(x => WhenICreate())
.Then(x => x.ThenTheFollowingAddHeaderToUpstreamIsReturned(expected))
.BDDfy();
}
@ -180,11 +217,17 @@ namespace Ocelot.UnitTests.Configuration
_placeholders.Setup(x => x.Get(It.IsAny<string>())).Returns(new ErrorResponse<string>(new AnyError()));
}
private void ThenTheFollowingAddHeaderIsReturned(AddHeader addHeader)
private void ThenTheFollowingAddHeaderToDownstreamIsReturned(AddHeader addHeader)
{
_result.AddHeadersToDownstream[0].Key.ShouldBe(addHeader.Key);
_result.AddHeadersToDownstream[0].Value.ShouldBe(addHeader.Value);
}
private void ThenTheFollowingAddHeaderToUpstreamIsReturned(AddHeader addHeader)
{
_result.AddHeadersToUpstream[0].Key.ShouldBe(addHeader.Key);
_result.AddHeadersToUpstream[0].Value.ShouldBe(addHeader.Value);
}
private void ThenTheFollowingDownstreamIsReturned(List<HeaderFindAndReplace> downstream)
{

View File

@ -6,6 +6,7 @@ using Xunit;
namespace Ocelot.UnitTests.DependencyInjection
{
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
@ -17,7 +18,7 @@ namespace Ocelot.UnitTests.DependencyInjection
private string _result;
private IConfigurationRoot _configRoot;
private FileConfiguration _globalConfig;
private FileConfiguration _reRoute;
private FileConfiguration _reRouteA;
private FileConfiguration _reRouteB;
private FileConfiguration _aggregate;
@ -64,7 +65,7 @@ namespace Ocelot.UnitTests.DependencyInjection
}
};
_reRoute = new FileConfiguration
_reRouteA = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
@ -160,17 +161,10 @@ namespace Ocelot.UnitTests.DependencyInjection
}
};
var globalJson = JsonConvert.SerializeObject(_globalConfig);
File.WriteAllText("ocelot.global.json", globalJson);
var reRouteJson = JsonConvert.SerializeObject(_reRoute);
File.WriteAllText("ocelot.reRoutes.json", reRouteJson);
var reRouteJsonB = JsonConvert.SerializeObject(_reRouteB);
File.WriteAllText("ocelot.reRoutesB.json", reRouteJsonB);
var aggregates = JsonConvert.SerializeObject(_aggregate);
File.WriteAllText("ocelot.aggregates.json", aggregates);
File.WriteAllText("ocelot.global.json", JsonConvert.SerializeObject(_globalConfig));
File.WriteAllText("ocelot.reRoutesA.json", JsonConvert.SerializeObject(_reRouteA));
File.WriteAllText("ocelot.reRoutesB.json", JsonConvert.SerializeObject(_reRouteB));
File.WriteAllText("ocelot.aggregates.json", JsonConvert.SerializeObject(_aggregate));
}
private void WhenIAddOcelotConfiguration()
@ -195,21 +189,21 @@ namespace Ocelot.UnitTests.DependencyInjection
fc.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Port);
fc.GlobalConfiguration.ServiceDiscoveryProvider.Type.ShouldBe(_globalConfig.GlobalConfiguration.ServiceDiscoveryProvider.Type);
fc.ReRoutes.Count.ShouldBe(_reRoute.ReRoutes.Count + _reRouteB.ReRoutes.Count);
fc.ReRoutes.Count.ShouldBe(_reRouteA.ReRoutes.Count + _reRouteB.ReRoutes.Count);
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRoute.ReRoutes[0].DownstreamPathTemplate);
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteA.ReRoutes[0].DownstreamPathTemplate);
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteB.ReRoutes[0].DownstreamPathTemplate);
fc.ReRoutes.ShouldContain(x => x.DownstreamPathTemplate == _reRouteB.ReRoutes[1].DownstreamPathTemplate);
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRoute.ReRoutes[0].DownstreamScheme);
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteA.ReRoutes[0].DownstreamScheme);
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteB.ReRoutes[0].DownstreamScheme);
fc.ReRoutes.ShouldContain(x => x.DownstreamScheme == _reRouteB.ReRoutes[1].DownstreamScheme);
fc.ReRoutes.ShouldContain(x => x.Key == _reRoute.ReRoutes[0].Key);
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteA.ReRoutes[0].Key);
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteB.ReRoutes[0].Key);
fc.ReRoutes.ShouldContain(x => x.Key == _reRouteB.ReRoutes[1].Key);
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRoute.ReRoutes[0].UpstreamHost);
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteA.ReRoutes[0].UpstreamHost);
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteB.ReRoutes[0].UpstreamHost);
fc.ReRoutes.ShouldContain(x => x.UpstreamHost == _reRouteB.ReRoutes[1].UpstreamHost);

View File

@ -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;
using Ocelot.Request.Middleware;
namespace Ocelot.UnitTests.Headers
{
public class AddHeadersToRequestTests
{
private readonly AddHeadersToRequest _addHeadersToRequest;
private readonly Mock<IClaimsParser> _parser;
private readonly DownstreamRequest _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 DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com"));
}
[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;
using Ocelot.Request.Middleware;
namespace Ocelot.UnitTests.Headers
{
public class AddHeadersToRequestClaimToThingTests
{
private readonly AddHeadersToRequest _addHeadersToRequest;
private readonly Mock<IClaimsParser> _parser;
private readonly DownstreamRequest _downstreamRequest;
private List<Claim> _claims;
private List<ClaimToThing> _configuration;
private Response _result;
private Response<string> _claimValue;
public AddHeadersToRequestClaimToThingTests()
{
_parser = new Mock<IClaimsParser>();
_addHeadersToRequest = new AddHeadersToRequest(_parser.Object);
_downstreamRequest = new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "http://test.com"));
}
[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)
{
}
}
}
}

View File

@ -0,0 +1,75 @@
using Microsoft.AspNetCore.Http;
using Moq;
using Ocelot.Configuration.Creator;
using Ocelot.Headers;
using Ocelot.Infrastructure.Claims.Parser;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Headers
{
public class AddHeadersToRequestPlainTests
{
private readonly AddHeadersToRequest _addHeadersToRequest;
private HttpContext _context;
private AddHeader _addedHeader;
public AddHeadersToRequestPlainTests()
{
_addHeadersToRequest = new AddHeadersToRequest(Mock.Of<IClaimsParser>());
}
[Fact]
public void should_add_plain_text_header_to_downstream_request()
{
this.Given(_ => GivenHttpRequestWithoutHeaders())
.When(_ => WhenAddingHeader("X-Custom-Header", "PlainValue"))
.Then(_ => ThenTheHeaderGetsTakenOverToTheRequestHeaders())
.BDDfy();
}
[Fact]
public void should_overwrite_existing_header_with_added_header()
{
this.Given(_ => GivenHttpRequestWithHeader("X-Custom-Header", "This should get overwritten"))
.When(_ => WhenAddingHeader("X-Custom-Header", "PlainValue"))
.Then(_ => ThenTheHeaderGetsTakenOverToTheRequestHeaders())
.BDDfy();
}
private void GivenHttpRequestWithoutHeaders()
{
_context = new DefaultHttpContext();
}
private void GivenHttpRequestWithHeader(string headerKey, string headerValue)
{
_context = new DefaultHttpContext
{
Request =
{
Headers =
{
{ headerKey, headerValue }
}
}
};
}
private void WhenAddingHeader(string headerKey, string headerValue)
{
_addedHeader = new AddHeader(headerKey, headerValue);
_addHeadersToRequest.SetHeadersOnDownstreamRequest(new[] { _addedHeader }, _context);
}
private void ThenTheHeaderGetsTakenOverToTheRequestHeaders()
{
var requestHeaders = _context.Request.Headers;
requestHeaders.ContainsKey(_addedHeader.Key).ShouldBeTrue($"Header {_addedHeader.Key} was expected but not there.");
var value = requestHeaders[_addedHeader.Key];
value.ShouldNotBeNull($"Value of header {_addedHeader.Key} was expected to not be null.");
value.ToString().ShouldBe(_addedHeader.Value);
}
}
}

View File

@ -27,7 +27,8 @@ namespace Ocelot.UnitTests.Headers
private readonly HttpHeadersTransformationMiddleware _middleware;
private readonly DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
private readonly Mock<IAddHeadersToResponse> _addHeaders;
private readonly Mock<IAddHeadersToResponse> _addHeadersToResponse;
private readonly Mock<IAddHeadersToRequest> _addHeadersToRequest;
public HttpHeadersTransformationMiddlewareTests()
{
@ -38,8 +39,11 @@ namespace Ocelot.UnitTests.Headers
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<AuthorisationMiddleware>()).Returns(_logger.Object);
_next = context => Task.CompletedTask;
_addHeaders = new Mock<IAddHeadersToResponse>();
_middleware = new HttpHeadersTransformationMiddleware(_next, _loggerFactory.Object, _preReplacer.Object, _postReplacer.Object, _addHeaders.Object);
_addHeadersToResponse = new Mock<IAddHeadersToResponse>();
_addHeadersToRequest = new Mock<IAddHeadersToRequest>();
_middleware = new HttpHeadersTransformationMiddleware(
_next, _loggerFactory.Object, _preReplacer.Object,
_postReplacer.Object, _addHeadersToResponse.Object, _addHeadersToRequest.Object);
}
[Fact]
@ -51,17 +55,24 @@ namespace Ocelot.UnitTests.Headers
.And(x => GivenTheHttpResponseMessageIs())
.When(x => WhenICallTheMiddleware())
.Then(x => ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly())
.Then(x => ThenAddHeadersToRequestIsCalledCorrectly())
.And(x => ThenTheIHttpResponseHeaderReplacerIsCalledCorrectly())
.And(x => ThenAddHeadersIsCalledCorrectly())
.And(x => ThenAddHeadersToResponseIsCalledCorrectly())
.BDDfy();
}
private void ThenAddHeadersIsCalledCorrectly()
private void ThenAddHeadersToResponseIsCalledCorrectly()
{
_addHeaders
_addHeadersToResponse
.Verify(x => x.Add(_downstreamContext.DownstreamReRoute.AddHeadersToDownstream, _downstreamContext.DownstreamResponse), Times.Once);
}
private void ThenAddHeadersToRequestIsCalledCorrectly()
{
_addHeadersToRequest
.Verify(x => x.SetHeadersOnDownstreamRequest(_downstreamContext.DownstreamReRoute.AddHeadersToUpstream, _downstreamContext.HttpContext), Times.Once);
}
private void WhenICallTheMiddleware()
{
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();