mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 21:30:50 +08:00 
			
		
		
		
	* #298 initial hacking around better aggregation * #298 bit more hacking around * #298 abstraction over httpresponsemessage * #298 tidying up * #298 docs * #298 missed this
This commit is contained in:
		@@ -1,7 +1,4 @@
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Cache
 | 
			
		||||
namespace Ocelot.UnitTests.Cache
 | 
			
		||||
{
 | 
			
		||||
    using System.Linq;
 | 
			
		||||
    using System.Net;
 | 
			
		||||
@@ -17,15 +14,17 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
 | 
			
		||||
    public class OutputCacheMiddlewareRealCacheTests
 | 
			
		||||
    {
 | 
			
		||||
        private IOcelotCache<CachedResponse> _cacheManager;
 | 
			
		||||
        private OutputCacheMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private readonly IOcelotCache<CachedResponse> _cacheManager;
 | 
			
		||||
        private readonly OutputCacheMiddleware _middleware;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private IRegionCreator _regionCreator;
 | 
			
		||||
@@ -56,14 +55,10 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
                Headers = { ContentType = new MediaTypeHeaderValue("application/json")}
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var response = new HttpResponseMessage(HttpStatusCode.OK)
 | 
			
		||||
            {
 | 
			
		||||
                Content = content,
 | 
			
		||||
            };
 | 
			
		||||
            var response = new DownstreamResponse(content, HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>());
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenResponseIsNotCached(response))
 | 
			
		||||
                .And(x => x.GivenTheDownstreamRouteIs())
 | 
			
		||||
                .And(x => x.GivenThereAreNoErrors())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheContentTypeHeaderIsCached())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
@@ -81,9 +76,9 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
            header.First().ShouldBe("application/json");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenResponseIsNotCached(HttpResponseMessage message)
 | 
			
		||||
        private void GivenResponseIsNotCached(DownstreamResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.DownstreamResponse = message;
 | 
			
		||||
            _downstreamContext.DownstreamResponse = response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamRouteIs()
 | 
			
		||||
@@ -96,10 +91,5 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereAreNoErrors()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.Errors = new List<Error>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,4 @@
 | 
			
		||||
using System.Net;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Cache
 | 
			
		||||
namespace Ocelot.UnitTests.Cache
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
@@ -19,17 +15,20 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using System.Net;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
 | 
			
		||||
    public class OutputCacheMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;    
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private OutputCacheMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private readonly OcelotRequestDelegate _next;
 | 
			
		||||
        private CachedResponse _response;
 | 
			
		||||
        private IRegionCreator _regionCreator;
 | 
			
		||||
        private readonly IRegionCreator _regionCreator;
 | 
			
		||||
 | 
			
		||||
        public OutputCacheMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -46,7 +45,17 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_returned_cached_item_when_it_is_in_cache()
 | 
			
		||||
        {
 | 
			
		||||
            var cachedResponse = new CachedResponse(HttpStatusCode.OK, new Dictionary<string, IEnumerable<string>>(), "", new Dictionary<string, IEnumerable<string>>());
 | 
			
		||||
            var headers = new Dictionary<string, IEnumerable<string>>
 | 
			
		||||
            {
 | 
			
		||||
                { "test", new List<string> { "test" } }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var contentHeaders = new Dictionary<string, IEnumerable<string>>
 | 
			
		||||
            {
 | 
			
		||||
                { "content-type", new List<string> { "application/json" } }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var cachedResponse = new CachedResponse(HttpStatusCode.OK, headers, "", contentHeaders);
 | 
			
		||||
            this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
 | 
			
		||||
                .And(x => x.GivenTheDownstreamRouteIs())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
@@ -59,7 +68,6 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenResponseIsNotCached())
 | 
			
		||||
                .And(x => x.GivenTheDownstreamRouteIs())
 | 
			
		||||
                .And(x => x.GivenThereAreNoErrors())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheCacheAddIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
@@ -81,7 +89,7 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
 | 
			
		||||
        private void GivenResponseIsNotCached()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.DownstreamResponse = new HttpResponseMessage();
 | 
			
		||||
            _downstreamContext.DownstreamResponse = new DownstreamResponse(new HttpResponseMessage());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamRouteIs()
 | 
			
		||||
@@ -101,11 +109,6 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereAreNoErrors()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.Errors = new List<Error>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheCacheGetIsCalledCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            _cacheManager
 | 
			
		||||
 
 | 
			
		||||
@@ -134,7 +134,8 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                            },
 | 
			
		||||
                            Aggregator = "asdf"
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 
 | 
			
		||||
@@ -149,7 +149,6 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                .Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_add_trace_id_header()
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@ using Shouldly;
 | 
			
		||||
using IdentityServer4.AccessTokenValidation;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using static Ocelot.UnitTests.Middleware.UserDefinedResponseAggregatorTests;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.DependencyInjection
 | 
			
		||||
{
 | 
			
		||||
@@ -177,6 +179,40 @@ namespace Ocelot.UnitTests.DependencyInjection
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_add_singleton_defined_aggregators()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => WhenISetUpOcelotServices())
 | 
			
		||||
                .When(x => AddSingletonDefinedAggregator<TestDefinedAggregator>())
 | 
			
		||||
                .When(x => AddSingletonDefinedAggregator<TestDefinedAggregator>())
 | 
			
		||||
                .Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TestDefinedAggregator, TestDefinedAggregator>())
 | 
			
		||||
                .And(x => ThenTheAggregatorsAreSingleton<TestDefinedAggregator, TestDefinedAggregator>())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_add_transient_defined_aggregators()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => WhenISetUpOcelotServices())
 | 
			
		||||
                .When(x => AddTransientDefinedAggregator<TestDefinedAggregator>())
 | 
			
		||||
                .When(x => AddTransientDefinedAggregator<TestDefinedAggregator>())
 | 
			
		||||
                .Then(x => ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TestDefinedAggregator, TestDefinedAggregator>())
 | 
			
		||||
                .And(x => ThenTheAggregatorsAreTransient<TestDefinedAggregator, TestDefinedAggregator>())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddSingletonDefinedAggregator<T>()
 | 
			
		||||
            where T : class, IDefinedAggregator
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotBuilder.AddSingletonDefinedAggregator<T>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddTransientDefinedAggregator<T>()
 | 
			
		||||
            where T : class, IDefinedAggregator
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotBuilder.AddTransientDefinedAggregator<T>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheSpecificHandlersAreSingleton()
 | 
			
		||||
        {
 | 
			
		||||
            var handlers = _serviceProvider.GetServices<DelegatingHandler>().ToList();
 | 
			
		||||
@@ -258,6 +294,32 @@ namespace Ocelot.UnitTests.DependencyInjection
 | 
			
		||||
            handlers[1].ShouldBeOfType<TWo>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheProviderIsRegisteredAndReturnsSpecificAggregators<TOne, TWo>()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceProvider = _services.BuildServiceProvider();
 | 
			
		||||
            var handlers = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
 | 
			
		||||
            handlers[0].ShouldBeOfType<TOne>();
 | 
			
		||||
            handlers[1].ShouldBeOfType<TWo>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheAggregatorsAreTransient<TOne, TWo>()
 | 
			
		||||
        {
 | 
			
		||||
            var aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
 | 
			
		||||
            var first = aggregators[0];
 | 
			
		||||
            aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
 | 
			
		||||
            var second = aggregators[0];
 | 
			
		||||
            first.ShouldNotBe(second);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheAggregatorsAreSingleton<TOne, TWo>()
 | 
			
		||||
        {
 | 
			
		||||
            var aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
 | 
			
		||||
            var first = aggregators[0];
 | 
			
		||||
            aggregators = _serviceProvider.GetServices<IDefinedAggregator>().ToList();
 | 
			
		||||
            var second = aggregators[0];
 | 
			
		||||
            first.ShouldBe(second);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void OnlyOneVersionOfEachCacheIsRegistered()
 | 
			
		||||
        {
 | 
			
		||||
            var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,4 @@
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
@@ -21,17 +18,19 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.Request.Middleware;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
    public class DownstreamUrlCreatorMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IDownstreamPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer;
 | 
			
		||||
        private OkResponse<DownstreamPath> _downstreamPath;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private DownstreamUrlCreatorMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private HttpRequestMessage _request;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private readonly OcelotRequestDelegate _next;
 | 
			
		||||
        private readonly HttpRequestMessage _request;
 | 
			
		||||
 | 
			
		||||
        public DownstreamUrlCreatorMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -212,7 +211,6 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
 | 
			
		||||
        private void GivenTheDownstreamRequestUriIs(string uri)
 | 
			
		||||
        {
 | 
			
		||||
            _request.RequestUri = new Uri(uri);
 | 
			
		||||
            //todo - not sure if needed
 | 
			
		||||
            _downstreamContext.DownstreamRequest = new DownstreamRequest(_request);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,29 +1,29 @@
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Ocelot.Headers;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Configuration.Creator;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Ocelot.Configuration.Creator;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.Infrastructure;
 | 
			
		||||
using Ocelot.UnitTests.Responder;
 | 
			
		||||
using System;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Headers
 | 
			
		||||
{
 | 
			
		||||
    public class AddHeadersToResponseTests
 | 
			
		||||
    {
 | 
			
		||||
        private IAddHeadersToResponse _adder;
 | 
			
		||||
        private Mock<IPlaceholders> _placeholders;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private readonly IAddHeadersToResponse _adder;
 | 
			
		||||
        private readonly Mock<IPlaceholders> _placeholders;
 | 
			
		||||
        private DownstreamResponse _response;
 | 
			
		||||
        private List<AddHeader> _addHeaders;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _factory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private readonly Mock<IOcelotLogger> _logger;
 | 
			
		||||
 | 
			
		||||
        public AddHeadersToResponseTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -111,7 +111,7 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
 | 
			
		||||
        private void ThenTheHeaderIsNotAdded(string key)
 | 
			
		||||
        {
 | 
			
		||||
            _response.Headers.TryGetValues(key, out var values).ShouldBeFalse();
 | 
			
		||||
            _response.Headers.Any(x => x.Key == key).ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheTraceIdIs(string traceId)
 | 
			
		||||
@@ -126,8 +126,8 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
 | 
			
		||||
        private void ThenTheHeaderIsReturned(string key, string value)
 | 
			
		||||
        {
 | 
			
		||||
            var values = _response.Headers.GetValues(key);
 | 
			
		||||
            values.First().ShouldBe(value);
 | 
			
		||||
            var values = _response.Headers.First(x => x.Key == key);
 | 
			
		||||
            values.Values.First().ShouldBe(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIAdd()
 | 
			
		||||
@@ -137,7 +137,7 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
 | 
			
		||||
        private void GivenAResponseMessage()
 | 
			
		||||
        {
 | 
			
		||||
            _response = new HttpResponseMessage();
 | 
			
		||||
            _response = new DownstreamResponse(new HttpResponseMessage());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheAddHeaders(List<AddHeader> addHeaders)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +1,33 @@
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.Headers.Middleware;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Headers;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Ocelot.Authorisation.Middleware;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Headers
 | 
			
		||||
{
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Headers.Middleware;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Headers;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Ocelot.Authorisation.Middleware;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Ocelot.Request.Middleware;
 | 
			
		||||
 | 
			
		||||
    public class HttpHeadersTransformationMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private Mock<IHttpContextRequestHeaderReplacer> _preReplacer;
 | 
			
		||||
        private Mock<IHttpResponseHeaderReplacer> _postReplacer;
 | 
			
		||||
        private readonly Mock<IHttpContextRequestHeaderReplacer> _preReplacer;
 | 
			
		||||
        private readonly Mock<IHttpResponseHeaderReplacer> _postReplacer;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private HttpHeadersTransformationMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private readonly HttpHeadersTransformationMiddleware _middleware;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private Mock<IAddHeadersToResponse> _addHeaders;
 | 
			
		||||
        private readonly Mock<IAddHeadersToResponse> _addHeaders;
 | 
			
		||||
 | 
			
		||||
        public HttpHeadersTransformationMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -74,7 +74,7 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
 | 
			
		||||
        private void GivenTheHttpResponseMessageIs()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.DownstreamResponse = new HttpResponseMessage();
 | 
			
		||||
            _downstreamContext.DownstreamResponse = new DownstreamResponse(new HttpResponseMessage());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheReRouteHasPreFindAndReplaceSetUp()
 | 
			
		||||
@@ -98,7 +98,7 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
 | 
			
		||||
        private void ThenTheIHttpResponseHeaderReplacerIsCalledCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            _postReplacer.Verify(x => x.Replace(It.IsAny<HttpResponseMessage>(), It.IsAny<List<HeaderFindAndReplace>>(), It.IsAny<DownstreamRequest>()), Times.Once);
 | 
			
		||||
            _postReplacer.Verify(x => x.Replace(It.IsAny<DownstreamResponse>(), It.IsAny<List<HeaderFindAndReplace>>(), It.IsAny<DownstreamRequest>()), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFollowingRequest()
 | 
			
		||||
 
 | 
			
		||||
@@ -7,19 +7,21 @@ using Ocelot.Configuration;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Infrastructure;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
using Ocelot.Request.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Headers
 | 
			
		||||
{
 | 
			
		||||
    public class HttpResponseHeaderReplacerTests
 | 
			
		||||
    {
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private DownstreamResponse _response;
 | 
			
		||||
        private Placeholders _placeholders;
 | 
			
		||||
        private HttpResponseHeaderReplacer _replacer;
 | 
			
		||||
        private readonly HttpResponseHeaderReplacer _replacer;
 | 
			
		||||
        private List<HeaderFindAndReplace> _headerFindAndReplaces;
 | 
			
		||||
        private Response _result;
 | 
			
		||||
        private DownstreamRequest _request;
 | 
			
		||||
@@ -37,11 +39,13 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_replace_headers()
 | 
			
		||||
        {
 | 
			
		||||
            var response = new HttpResponseMessage();
 | 
			
		||||
            response.Headers.Add("test", "test");
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.Accepted,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>()
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("test", new List<string> {"test"})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
            fAndRs.Add(new HeaderFindAndReplace("test", "test", "chiken", 0));
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace> {new HeaderFindAndReplace("test", "test", "chiken", 0)};
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheHttpResponse(response))
 | 
			
		||||
                .And(x => GivenTheFollowingHeaderReplacements(fAndRs))
 | 
			
		||||
@@ -53,8 +57,11 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_replace_headers()
 | 
			
		||||
        {
 | 
			
		||||
            var response = new HttpResponseMessage();
 | 
			
		||||
            response.Headers.Add("test", "test");
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.Accepted,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>()
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("test", new List<string> {"test"})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
 | 
			
		||||
@@ -68,16 +75,21 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_replace_downstream_base_url_with_ocelot_base_url()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamUrl = "http://downstream.com/";
 | 
			
		||||
            const string downstreamUrl = "http://downstream.com/";
 | 
			
		||||
 | 
			
		||||
            var request = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
 | 
			
		||||
            request.RequestUri = new System.Uri(downstreamUrl);
 | 
			
		||||
            var request =
 | 
			
		||||
                new HttpRequestMessage(HttpMethod.Get, "http://test.com") {RequestUri = new System.Uri(downstreamUrl)};
 | 
			
		||||
 | 
			
		||||
            var response = new HttpResponseMessage();
 | 
			
		||||
            response.Headers.Add("Location", downstreamUrl);
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.Accepted,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>()
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("Location", new List<string> {downstreamUrl})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
            fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>
 | 
			
		||||
            {
 | 
			
		||||
                new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheHttpResponse(response))
 | 
			
		||||
                .And(x => GivenTheRequestIs(request))
 | 
			
		||||
@@ -90,16 +102,21 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_replace_downstream_base_url_with_ocelot_base_url_with_port()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamUrl = "http://downstream.com/";
 | 
			
		||||
            const string downstreamUrl = "http://downstream.com/";
 | 
			
		||||
 | 
			
		||||
            var request = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
 | 
			
		||||
            request.RequestUri = new System.Uri(downstreamUrl);
 | 
			
		||||
            var request =
 | 
			
		||||
                new HttpRequestMessage(HttpMethod.Get, "http://test.com") {RequestUri = new System.Uri(downstreamUrl)};
 | 
			
		||||
 | 
			
		||||
            var response = new HttpResponseMessage();
 | 
			
		||||
            response.Headers.Add("Location", downstreamUrl);
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.Accepted,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>()
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("Location", new List<string> {downstreamUrl})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
            fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:123/", 0));
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>
 | 
			
		||||
            {
 | 
			
		||||
                new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:123/", 0)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheHttpResponse(response))
 | 
			
		||||
                .And(x => GivenTheRequestIs(request))
 | 
			
		||||
@@ -112,16 +129,21 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_replace_downstream_base_url_with_ocelot_base_url_and_path()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamUrl = "http://downstream.com/test/product";
 | 
			
		||||
            const string downstreamUrl = "http://downstream.com/test/product";
 | 
			
		||||
 | 
			
		||||
            var request = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
 | 
			
		||||
            request.RequestUri = new System.Uri(downstreamUrl);
 | 
			
		||||
            var request =
 | 
			
		||||
                new HttpRequestMessage(HttpMethod.Get, "http://test.com") {RequestUri = new System.Uri(downstreamUrl)};
 | 
			
		||||
 | 
			
		||||
            var response = new HttpResponseMessage();
 | 
			
		||||
            response.Headers.Add("Location", downstreamUrl);
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.Accepted,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>()
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("Location", new List<string> {downstreamUrl})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
            fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>
 | 
			
		||||
            {
 | 
			
		||||
                new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheHttpResponse(response))
 | 
			
		||||
                .And(x => GivenTheRequestIs(request))
 | 
			
		||||
@@ -134,16 +156,21 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_replace_downstream_base_url_with_ocelot_base_url_with_path_and_port()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamUrl = "http://downstream.com/test/product";
 | 
			
		||||
            const string downstreamUrl = "http://downstream.com/test/product";
 | 
			
		||||
 | 
			
		||||
            var request = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
 | 
			
		||||
            request.RequestUri = new System.Uri(downstreamUrl);
 | 
			
		||||
            var request =
 | 
			
		||||
                new HttpRequestMessage(HttpMethod.Get, "http://test.com") {RequestUri = new System.Uri(downstreamUrl)};
 | 
			
		||||
 | 
			
		||||
            var response = new HttpResponseMessage();
 | 
			
		||||
            response.Headers.Add("Location", downstreamUrl);
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.Accepted,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>()
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("Location", new List<string> {downstreamUrl})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
            fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:123/", 0));
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>
 | 
			
		||||
            {
 | 
			
		||||
                new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:123/", 0)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheHttpResponse(response))
 | 
			
		||||
                .And(x => GivenTheRequestIs(request))
 | 
			
		||||
@@ -156,16 +183,21 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_replace_downstream_base_url_and_port_with_ocelot_base_url()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamUrl = "http://downstream.com:123/test/product";
 | 
			
		||||
            const string downstreamUrl = "http://downstream.com:123/test/product";
 | 
			
		||||
 | 
			
		||||
            var request = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
 | 
			
		||||
            request.RequestUri = new System.Uri(downstreamUrl);
 | 
			
		||||
            var request =
 | 
			
		||||
                new HttpRequestMessage(HttpMethod.Get, "http://test.com") {RequestUri = new System.Uri(downstreamUrl)};
 | 
			
		||||
 | 
			
		||||
            var response = new HttpResponseMessage();
 | 
			
		||||
            response.Headers.Add("Location", downstreamUrl);
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.Accepted,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>()
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("Location", new List<string> {downstreamUrl})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
            fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0));
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>
 | 
			
		||||
            {
 | 
			
		||||
                new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com/", 0)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheHttpResponse(response))
 | 
			
		||||
                .And(x => GivenTheRequestIs(request))
 | 
			
		||||
@@ -178,16 +210,21 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_replace_downstream_base_url_and_port_with_ocelot_base_url_and_port()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamUrl = "http://downstream.com:123/test/product";
 | 
			
		||||
            const string downstreamUrl = "http://downstream.com:123/test/product";
 | 
			
		||||
 | 
			
		||||
            var request = new HttpRequestMessage(HttpMethod.Get, "http://test.com");
 | 
			
		||||
            request.RequestUri = new System.Uri(downstreamUrl);
 | 
			
		||||
            var request =
 | 
			
		||||
                new HttpRequestMessage(HttpMethod.Get, "http://test.com") {RequestUri = new System.Uri(downstreamUrl)};
 | 
			
		||||
 | 
			
		||||
            var response = new HttpResponseMessage();
 | 
			
		||||
            response.Headers.Add("Location", downstreamUrl);
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.Accepted,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>()
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("Location", new List<string> {downstreamUrl})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
            fAndRs.Add(new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:321/", 0));
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>
 | 
			
		||||
            {
 | 
			
		||||
                new HeaderFindAndReplace("Location", "{DownstreamBaseUrl}", "http://ocelot.com:321/", 0)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheHttpResponse(response))
 | 
			
		||||
                .And(x => GivenTheRequestIs(request))
 | 
			
		||||
@@ -207,8 +244,8 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
             _result.ShouldBeOfType<OkResponse>();
 | 
			
		||||
            foreach (var f in _headerFindAndReplaces)
 | 
			
		||||
            {
 | 
			
		||||
                _response.Headers.TryGetValues(f.Key, out var values);
 | 
			
		||||
                values.ToList()[f.Index].ShouldBe("test");
 | 
			
		||||
                var values = _response.Headers.First(x => x.Key == f.Key);
 | 
			
		||||
                values.Values.ToList()[f.Index].ShouldBe("test");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -217,7 +254,7 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
            _headerFindAndReplaces = fAndRs;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheHttpResponse(HttpResponseMessage response)
 | 
			
		||||
        private void GivenTheHttpResponse(DownstreamResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            _response = response;
 | 
			
		||||
        }
 | 
			
		||||
@@ -229,17 +266,17 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
 | 
			
		||||
        private void ThenTheHeaderShouldBe(string key, string value)
 | 
			
		||||
        {
 | 
			
		||||
            var test = _response.Headers.GetValues(key);
 | 
			
		||||
            test.First().ShouldBe(value);
 | 
			
		||||
            var test = _response.Headers.First(x => x.Key == key);
 | 
			
		||||
            test.Values.First().ShouldBe(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
         private void ThenTheHeadersAreReplaced()
 | 
			
		||||
        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);
 | 
			
		||||
                var values = _response.Headers.First(x => x.Key == f.Key);
 | 
			
		||||
                values.Values.ToList()[f.Index].ShouldBe(f.Replace);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Net.Http.Headers;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
@@ -9,7 +9,7 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
{
 | 
			
		||||
    public class RemoveHeadersTests
 | 
			
		||||
    {
 | 
			
		||||
        private HttpResponseHeaders _headers;
 | 
			
		||||
        private List<Header> _headers;
 | 
			
		||||
        private readonly Ocelot.Headers.RemoveOutputHeaders _removeOutputHeaders;
 | 
			
		||||
        private Response _result;
 | 
			
		||||
 | 
			
		||||
@@ -21,18 +21,18 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_remove_header()
 | 
			
		||||
        {
 | 
			
		||||
            var httpResponse = new HttpResponseMessage()
 | 
			
		||||
            var headers = new List<Header>()
 | 
			
		||||
            {
 | 
			
		||||
                Headers = {{ "Transfer-Encoding", "chunked"}}
 | 
			
		||||
                new Header("Transfer-Encoding", new List<string> {"chunked"})
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAHttpContext(httpResponse.Headers))
 | 
			
		||||
            this.Given(x => x.GivenAHttpContext(headers))
 | 
			
		||||
                .When(x => x.WhenIRemoveTheHeaders())
 | 
			
		||||
                .Then(x => x.TheHeaderIsNoLongerInTheContext())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenAHttpContext(HttpResponseHeaders headers)
 | 
			
		||||
        private void GivenAHttpContext(List<Header> headers)
 | 
			
		||||
        {
 | 
			
		||||
            _headers = headers;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,9 @@ namespace Ocelot.UnitTests.Infrastructure
 | 
			
		||||
{
 | 
			
		||||
    public class HttpDataRepositoryTests
 | 
			
		||||
    {
 | 
			
		||||
        private HttpContext _httpContext;
 | 
			
		||||
        private readonly HttpContext _httpContext;
 | 
			
		||||
        private IHttpContextAccessor _httpContextAccessor;
 | 
			
		||||
        private HttpDataRepository _httpDataRepository;
 | 
			
		||||
        private readonly HttpDataRepository _httpDataRepository;
 | 
			
		||||
        private object _result;
 | 
			
		||||
 | 
			
		||||
        public HttpDataRepositoryTests()
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,6 @@ namespace Ocelot.UnitTests.Infrastructure
 | 
			
		||||
            result.Data.ShouldBe("http://www.bbc.co.uk/");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_downstream_base_url_when_port_is_80_or_443()
 | 
			
		||||
        {
 | 
			
		||||
@@ -80,4 +79,4 @@ namespace Ocelot.UnitTests.Infrastructure
 | 
			
		||||
            result.Data.ShouldBe(traceId);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,6 @@ namespace Ocelot.UnitTests.Logging
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_log_error()
 | 
			
		||||
        {
 | 
			
		||||
            
 | 
			
		||||
            _logger.LogError($"a message from {_a} to {_b}", _ex);
 | 
			
		||||
 | 
			
		||||
            ThenLevelIsLogged("requestId: no request id, previousRequestId: no previous request id, message: a message from tom to laura, exception: System.Exception: oh no", LogLevel.Error);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,86 @@
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using static Ocelot.UnitTests.Middleware.UserDefinedResponseAggregatorTests;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
{
 | 
			
		||||
    public class DefinedAggregatorProviderTests
 | 
			
		||||
    {
 | 
			
		||||
        private ServiceLocatorDefinedAggregatorProvider _provider;
 | 
			
		||||
        private Response<IDefinedAggregator> _aggregator;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_find_aggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithAggregator("TestDefinedAggregator")
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenDefinedAggregator())
 | 
			
		||||
                .And(_ => GivenReRoute(reRoute))
 | 
			
		||||
                .When(_ => WhenIGet())
 | 
			
		||||
                .Then(_ => ThenTheAggregatorIsReturned())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_find_aggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithAggregator("TestDefinedAggregator")
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenNoDefinedAggregator())
 | 
			
		||||
                .And(_ => GivenReRoute(reRoute))
 | 
			
		||||
                .When(_ => WhenIGet())
 | 
			
		||||
                .Then(_ => ThenAnErrorIsReturned())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenDefinedAggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var serviceCollection = new ServiceCollection();
 | 
			
		||||
            serviceCollection.AddSingleton<IDefinedAggregator, TestDefinedAggregator>();
 | 
			
		||||
            var services = serviceCollection.BuildServiceProvider();
 | 
			
		||||
            _provider = new ServiceLocatorDefinedAggregatorProvider(services);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheAggregatorIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator.Data.ShouldNotBeNull();
 | 
			
		||||
            _aggregator.Data.ShouldBeOfType<TestDefinedAggregator>();
 | 
			
		||||
            _aggregator.IsError.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenNoDefinedAggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var serviceCollection = new ServiceCollection();
 | 
			
		||||
            var services = serviceCollection.BuildServiceProvider();
 | 
			
		||||
            _provider = new ServiceLocatorDefinedAggregatorProvider(services);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenReRoute(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIGet()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator = _provider.Get(_reRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenAnErrorIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator.IsError.ShouldBeTrue();
 | 
			
		||||
            _aggregator.Errors[0].Message.ShouldBe("Could not find Aggregator: TestDefinedAggregator");
 | 
			
		||||
            _aggregator.Errors[0].ShouldBeOfType<CouldNotFindAggregatorError>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -19,13 +19,16 @@ namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
        private readonly OcelotRequestDelegate _pipeline;
 | 
			
		||||
        private int _count;
 | 
			
		||||
        private Mock<IResponseAggregator> _aggregator;
 | 
			
		||||
        private Mock<IResponseAggregatorFactory> _factory;
 | 
			
		||||
 | 
			
		||||
        public MultiplexerTests()
 | 
			
		||||
        {
 | 
			
		||||
            _factory = new Mock<IResponseAggregatorFactory>();
 | 
			
		||||
            _aggregator = new Mock<IResponseAggregator>();
 | 
			
		||||
            _context = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _pipeline = context => Task.FromResult(_count++); 
 | 
			
		||||
            _multiplexer = new Multiplexer(_aggregator.Object);
 | 
			
		||||
            _factory.Setup(x => x.Get(It.IsAny<ReRoute>())).Returns(_aggregator.Object);
 | 
			
		||||
            _multiplexer = new Multiplexer(_factory.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,6 @@ namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
        {
 | 
			
		||||
            _errors.Add(error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class FakeMiddleware : OcelotMiddleware
 | 
			
		||||
@@ -72,4 +71,4 @@ namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,64 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
{
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
 | 
			
		||||
    public class ResponseAggregatorFactoryTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly InMemoryResponseAggregatorFactory _factory;
 | 
			
		||||
        private Mock<IDefinedAggregatorProvider> _provider;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private IResponseAggregator _aggregator;
 | 
			
		||||
 | 
			
		||||
        public ResponseAggregatorFactoryTests()
 | 
			
		||||
        {
 | 
			
		||||
            _provider = new Mock<IDefinedAggregatorProvider>();
 | 
			
		||||
            _factory = new InMemoryResponseAggregatorFactory(_provider.Object);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_simple_json_aggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenReRoute(reRoute))
 | 
			
		||||
                .When(_ => WhenIGet())
 | 
			
		||||
                .Then(_ => ThenTheAggregatorIs<SimpleJsonResponseAggregator>())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_user_defined_aggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithAggregator("doesntmatter")
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenReRoute(reRoute))
 | 
			
		||||
                .When(_ => WhenIGet())
 | 
			
		||||
                .Then(_ => ThenTheAggregatorIs<UserDefinedResponseAggregator>())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenReRoute(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIGet()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator = _factory.Get(_reRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheAggregatorIs<T>()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator.ShouldBeOfType<T>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Castle.Components.DictionaryAdapter;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
@@ -29,40 +30,6 @@ namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
            _aggregator = new SimpleJsonResponseAggregator();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_map_all_downstream_to_upstream_when_not_aggregate()
 | 
			
		||||
        {
 | 
			
		||||
            var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoutes = new List<DownstreamReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                billDownstreamReRoute,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoutes(downstreamReRoutes)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Bill says hi") },
 | 
			
		||||
                DownstreamReRoute = billDownstreamReRoute,
 | 
			
		||||
                Errors = new List<Error> { new AnyError() },
 | 
			
		||||
                DownstreamRequest = new DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, new Uri("http://www.bbc.co.uk"))),
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var downstreamContexts = new List<DownstreamContext> { billDownstreamContext };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
 | 
			
		||||
                .And(x => GivenTheReRoute(reRoute))
 | 
			
		||||
                .And(x => GivenTheDownstreamContext(downstreamContexts))
 | 
			
		||||
                .When(x => WhenIAggregate())
 | 
			
		||||
                .Then(x => ThenTheContentIs("Bill says hi"))
 | 
			
		||||
                .And(x => ThenTheUpstreamContextIsMappedForNonAggregate())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_aggregate_n_responses_and_set_response_content_on_upstream_context()
 | 
			
		||||
        {
 | 
			
		||||
@@ -82,15 +49,13 @@ namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
 | 
			
		||||
            var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("Bill says hi")},
 | 
			
		||||
                DownstreamResponse = new DownstreamResponse(new StringContent("Bill says hi"), HttpStatusCode.OK, new EditableList<KeyValuePair<string, IEnumerable<string>>>()),
 | 
			
		||||
                DownstreamReRoute = billDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("George says hi")},
 | 
			
		||||
                DownstreamResponse = new DownstreamResponse(new StringContent("George says hi"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>()),
 | 
			
		||||
                DownstreamReRoute = georgeDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
@@ -126,19 +91,18 @@ namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
 | 
			
		||||
            var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Bill says hi") },
 | 
			
		||||
                DownstreamResponse = new DownstreamResponse(new StringContent("Bill says hi"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>()),
 | 
			
		||||
                DownstreamReRoute = billDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Error") },
 | 
			
		||||
                DownstreamResponse = new DownstreamResponse(new StringContent("Error"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>()),
 | 
			
		||||
                DownstreamReRoute = georgeDownstreamReRoute,
 | 
			
		||||
                Errors = new List<Error>() { new AnyError() }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            georgeDownstreamContext.Errors.Add(new AnyError());
 | 
			
		||||
 | 
			
		||||
            var downstreamContexts = new List<DownstreamContext> { billDownstreamContext, georgeDownstreamContext };
 | 
			
		||||
 | 
			
		||||
            var expected = "Error";
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,153 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.UnitTests.Responder;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
{
 | 
			
		||||
    public class UserDefinedResponseAggregatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly UserDefinedResponseAggregator _aggregator;
 | 
			
		||||
        private readonly Mock<IDefinedAggregatorProvider> _provider;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private List<DownstreamContext> _contexts;
 | 
			
		||||
        private DownstreamContext _context;
 | 
			
		||||
 | 
			
		||||
        public UserDefinedResponseAggregatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _provider = new Mock<IDefinedAggregatorProvider>();
 | 
			
		||||
            _aggregator = new UserDefinedResponseAggregator(_provider.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_aggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().Build();
 | 
			
		||||
 | 
			
		||||
            var context = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
 | 
			
		||||
            var contexts = new List<DownstreamContext>
 | 
			
		||||
            {
 | 
			
		||||
                new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
                {
 | 
			
		||||
                    DownstreamResponse = new DownstreamResponse(new StringContent("Tom"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>())
 | 
			
		||||
                },
 | 
			
		||||
                new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
                {
 | 
			
		||||
                    DownstreamResponse = new DownstreamResponse(new StringContent("Laura"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>())
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheProviderReturnsAggregator())
 | 
			
		||||
                .And(_ => GivenReRoute(reRoute))
 | 
			
		||||
                .And(_ => GivenContexts(contexts))
 | 
			
		||||
                .And(_ => GivenContext(context))
 | 
			
		||||
                .When(_ => WhenIAggregate())
 | 
			
		||||
                .Then(_ => ThenTheProviderIsCalled())
 | 
			
		||||
                .And(_ => ThenTheContentIsCorrect())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_find_aggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().Build();
 | 
			
		||||
 | 
			
		||||
            var context = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
 | 
			
		||||
            var contexts = new List<DownstreamContext>
 | 
			
		||||
            {
 | 
			
		||||
                new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
                { 
 | 
			
		||||
                    DownstreamResponse = new DownstreamResponse(new StringContent("Tom"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>())
 | 
			
		||||
                },
 | 
			
		||||
                new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
                {
 | 
			
		||||
                    DownstreamResponse = new DownstreamResponse(new StringContent("Laura"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>())
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheProviderReturnsError())
 | 
			
		||||
                .And(_ => GivenReRoute(reRoute))
 | 
			
		||||
                .And(_ => GivenContexts(contexts))
 | 
			
		||||
                .And(_ => GivenContext(context))
 | 
			
		||||
                .When(_ => WhenIAggregate())
 | 
			
		||||
                .Then(_ => ThenTheProviderIsCalled())
 | 
			
		||||
                .And(_ => ThenTheErrorIsReturned())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _context.IsError.ShouldBeTrue();
 | 
			
		||||
            _context.Errors.Count.ShouldBe(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheProviderReturnsError()
 | 
			
		||||
        {
 | 
			
		||||
            _provider.Setup(x => x.Get(It.IsAny<ReRoute>())).Returns(new ErrorResponse<IDefinedAggregator>(new AnyError()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task ThenTheContentIsCorrect()
 | 
			
		||||
        {
 | 
			
		||||
            var content = await _context.DownstreamResponse.Content.ReadAsStringAsync();
 | 
			
		||||
            content.ShouldBe("Tom, Laura");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheProviderIsCalled()
 | 
			
		||||
        {
 | 
			
		||||
            _provider.Verify(x => x.Get(_reRoute), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenContext(DownstreamContext context)
 | 
			
		||||
        {
 | 
			
		||||
            _context = context;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenContexts(List<DownstreamContext> contexts)
 | 
			
		||||
        {
 | 
			
		||||
            _contexts = contexts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task WhenIAggregate()
 | 
			
		||||
        {
 | 
			
		||||
            await _aggregator.Aggregate(_reRoute, _context, _contexts);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheProviderReturnsAggregator()
 | 
			
		||||
        {
 | 
			
		||||
            var aggregator = new TestDefinedAggregator();
 | 
			
		||||
            _provider.Setup(x => x.Get(It.IsAny<ReRoute>())).Returns(new OkResponse<IDefinedAggregator>(aggregator));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenReRoute(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public class TestDefinedAggregator : IDefinedAggregator
 | 
			
		||||
        {
 | 
			
		||||
            public async Task<DownstreamResponse> Aggregate(List<DownstreamResponse> responses)
 | 
			
		||||
            {
 | 
			
		||||
                var tom = await responses[0].Content.ReadAsStringAsync();
 | 
			
		||||
                var laura = await responses[1].Content.ReadAsStringAsync();
 | 
			
		||||
                var content = $"{tom}, {laura}";
 | 
			
		||||
                var headers = responses.SelectMany(x => x.Headers).ToList();
 | 
			
		||||
                return new DownstreamResponse(new StringContent(content), HttpStatusCode.OK, headers);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -153,8 +153,6 @@ namespace Ocelot.UnitTests.QueryStrings
 | 
			
		||||
                .AddQueryString(_downstreamRequest.ToHttpRequestMessage().RequestUri.OriginalString, key, value);
 | 
			
		||||
 | 
			
		||||
            _request.RequestUri = new Uri(newUri);
 | 
			
		||||
            //todo - might not need to instanciate
 | 
			
		||||
            _downstreamRequest = new DownstreamRequest(_request);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheClaimParserReturns(Response<string> claimValue)
 | 
			
		||||
 
 | 
			
		||||
@@ -140,25 +140,28 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
                .UseIISIntegration()
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.Run(async context =>
 | 
			
		||||
                    app.Run(context =>
 | 
			
		||||
                    {
 | 
			
		||||
                        if (_count == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.Cookies.Append("test", "0");
 | 
			
		||||
                            context.Response.StatusCode = 200;
 | 
			
		||||
                            _count++;
 | 
			
		||||
                            return;
 | 
			
		||||
                            return Task.CompletedTask;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (_count == 1)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (context.Request.Cookies.TryGetValue("test", out var cookieValue) || context.Request.Headers.TryGetValue("Set-Cookie", out var headerValue))
 | 
			
		||||
                            {
 | 
			
		||||
                                context.Response.StatusCode = 200;
 | 
			
		||||
                                return;
 | 
			
		||||
                                return Task.CompletedTask;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            context.Response.StatusCode = 500;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
@@ -200,6 +203,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
 | 
			
		||||
                .Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFactoryReturnsNothing()
 | 
			
		||||
        {
 | 
			
		||||
            var handlers = new List<Func<DelegatingHandler>>();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Requester
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
@@ -14,11 +11,16 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Linq;
 | 
			
		||||
    using Ocelot.UnitTests.Responder;
 | 
			
		||||
 | 
			
		||||
    public class HttpRequesterMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IHttpRequester> _requester;
 | 
			
		||||
        private OkResponse<HttpResponseMessage> _response;
 | 
			
		||||
        private Response<HttpResponseMessage> _response;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private readonly HttpRequesterMiddleware _middleware;
 | 
			
		||||
@@ -39,12 +41,27 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        public void should_call_services_correctly()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheRequestIs())
 | 
			
		||||
                .And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
 | 
			
		||||
                .And(x => x.GivenTheRequesterReturns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage())))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheScopedRepoIsCalledCorrectly())
 | 
			
		||||
                .Then(x => x.ThenTheDownstreamResponseIsSet())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_set_error()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheRequestIs())
 | 
			
		||||
                .And(x => x.GivenTheRequesterReturns(new ErrorResponse<HttpResponseMessage>(new AnyError())))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheErrorIsSet())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorIsSet()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.IsError.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
@@ -52,21 +69,34 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequestIs()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = new DownstreamReRouteBuilder().Build();
 | 
			
		||||
            _downstreamContext =
 | 
			
		||||
                new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
                {
 | 
			
		||||
                    DownstreamReRoute = new DownstreamReRouteBuilder().Build()
 | 
			
		||||
                };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequesterReturns(HttpResponseMessage response)
 | 
			
		||||
        private void GivenTheRequesterReturns(Response<HttpResponseMessage> response)
 | 
			
		||||
        {
 | 
			
		||||
            _response = new OkResponse<HttpResponseMessage>(response);
 | 
			
		||||
            _response = response;
 | 
			
		||||
 | 
			
		||||
            _requester
 | 
			
		||||
                .Setup(x => x.GetResponse(It.IsAny<DownstreamContext>()))
 | 
			
		||||
                .ReturnsAsync(_response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheScopedRepoIsCalledCorrectly()
 | 
			
		||||
        private void ThenTheDownstreamResponseIsSet()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.DownstreamResponse.ShouldBe(_response.Data);
 | 
			
		||||
            foreach (var httpResponseHeader in _response.Data.Headers)
 | 
			
		||||
            {
 | 
			
		||||
                if (_downstreamContext.DownstreamResponse.Headers.Any(x => x.Key == httpResponseHeader.Key))
 | 
			
		||||
                {
 | 
			
		||||
                    throw new Exception("Header in response not in downstreamresponse headers");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _downstreamContext.DownstreamResponse.Content.ShouldBe(_response.Data.Content);
 | 
			
		||||
            _downstreamContext.DownstreamResponse.StatusCode.ShouldBe(_response.Data.StatusCode);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -120,7 +120,7 @@ namespace Ocelot.UnitTests.Responder
 | 
			
		||||
            // 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(34, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?");
 | 
			
		||||
            Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(35, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ShouldMapErrorToStatusCode(OcelotErrorCode errorCode, HttpStatusCode expectedHttpStatusCode)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,11 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Headers;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
using Ocelot.Responder;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using Xunit;
 | 
			
		||||
@@ -26,9 +27,13 @@ namespace Ocelot.UnitTests.Responder
 | 
			
		||||
        public void should_remove_transfer_encoding_header()
 | 
			
		||||
        {
 | 
			
		||||
            var httpContext = new DefaultHttpContext();
 | 
			
		||||
            var httpResponseMessage = new HttpResponseMessage {Content = new StringContent("")};
 | 
			
		||||
            httpResponseMessage.Headers.Add("Transfer-Encoding", "woop");
 | 
			
		||||
            _responder.SetResponseOnHttpContext(httpContext, httpResponseMessage).GetAwaiter().GetResult();
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(""), HttpStatusCode.OK,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("Transfer-Encoding", new List<string> {"woop"})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            _responder.SetResponseOnHttpContext(httpContext, response).GetAwaiter().GetResult();
 | 
			
		||||
            var header = httpContext.Response.Headers["Transfer-Encoding"];
 | 
			
		||||
            header.ShouldBeEmpty();
 | 
			
		||||
        }
 | 
			
		||||
@@ -37,8 +42,10 @@ namespace Ocelot.UnitTests.Responder
 | 
			
		||||
        public void should_have_content_length()
 | 
			
		||||
        {
 | 
			
		||||
            var httpContext = new DefaultHttpContext();
 | 
			
		||||
            var httpResponseMessage = new HttpResponseMessage { Content = new StringContent("test") };
 | 
			
		||||
            _responder.SetResponseOnHttpContext(httpContext, httpResponseMessage).GetAwaiter().GetResult();
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent("test"), HttpStatusCode.OK,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>());
 | 
			
		||||
 | 
			
		||||
            _responder.SetResponseOnHttpContext(httpContext, response).GetAwaiter().GetResult();
 | 
			
		||||
            var header = httpContext.Response.Headers["Content-Length"];
 | 
			
		||||
            header.First().ShouldBe("4");
 | 
			
		||||
        }
 | 
			
		||||
@@ -47,9 +54,13 @@ namespace Ocelot.UnitTests.Responder
 | 
			
		||||
        public void should_add_header()
 | 
			
		||||
        {
 | 
			
		||||
            var httpContext = new DefaultHttpContext();
 | 
			
		||||
            var httpResponseMessage = new HttpResponseMessage { Content = new StringContent("test") };
 | 
			
		||||
            httpResponseMessage.Headers.Add("test", "test");
 | 
			
		||||
            _responder.SetResponseOnHttpContext(httpContext, httpResponseMessage).GetAwaiter().GetResult();
 | 
			
		||||
            var response = new DownstreamResponse(new StringContent(""), HttpStatusCode.OK,
 | 
			
		||||
                new List<KeyValuePair<string, IEnumerable<string>>>
 | 
			
		||||
                {
 | 
			
		||||
                    new KeyValuePair<string, IEnumerable<string>>("test", new List<string> {"test"})
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            _responder.SetResponseOnHttpContext(httpContext, response).GetAwaiter().GetResult();
 | 
			
		||||
            var header = httpContext.Response.Headers["test"];
 | 
			
		||||
            header.First().ShouldBe("test");
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Responder
 | 
			
		||||
{
 | 
			
		||||
@@ -40,8 +41,7 @@ namespace Ocelot.UnitTests.Responder
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_return_any_errors()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheHttpResponseMessageIs(new HttpResponseMessage()))
 | 
			
		||||
                .And(x => x.GivenThereAreNoPipelineErrors())
 | 
			
		||||
            this.Given(x => x.GivenTheHttpResponseMessageIs(new DownstreamResponse(new HttpResponseMessage())))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenThereAreNoErrors())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
@@ -50,7 +50,7 @@ namespace Ocelot.UnitTests.Responder
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_any_errors()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheHttpResponseMessageIs(new HttpResponseMessage()))
 | 
			
		||||
            this.Given(x => x.GivenTheHttpResponseMessageIs(new DownstreamResponse(new HttpResponseMessage())))
 | 
			
		||||
                .And(x => x.GivenThereArePipelineErrors(new UnableToFindDownstreamRouteError("/path", "GET")))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenThereAreNoErrors())
 | 
			
		||||
@@ -62,16 +62,11 @@ namespace Ocelot.UnitTests.Responder
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheHttpResponseMessageIs(HttpResponseMessage response)
 | 
			
		||||
        private void GivenTheHttpResponseMessageIs(DownstreamResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.DownstreamResponse = response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereAreNoPipelineErrors()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.Errors = new List<Error>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenThereAreNoErrors()
 | 
			
		||||
        {
 | 
			
		||||
            //todo a better assert?
 | 
			
		||||
@@ -79,7 +74,7 @@ namespace Ocelot.UnitTests.Responder
 | 
			
		||||
 | 
			
		||||
        private void GivenThereArePipelineErrors(Error error)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.Errors = new List<Error>(){error};
 | 
			
		||||
            _downstreamContext.Errors.Add(error);
 | 
			
		||||
        }  
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user