mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:55:28 +08:00 
			
		
		
		
	Remove Ocelot specific Middleware to make Ocelot more compatible with kestrel middleware and get ready for YARP
This commit is contained in:
		@@ -0,0 +1,86 @@
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Multiplexer;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using static Ocelot.UnitTests.Multiplexing.UserDefinedResponseAggregatorTests;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Multiplexing
 | 
			
		||||
{
 | 
			
		||||
    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>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,81 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Multiplexing
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Multiplexer;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class MultiplexingMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly MultiplexingMiddleware _middleware;
 | 
			
		||||
        private DownstreamRoute _downstreamRoute;
 | 
			
		||||
        private int _count;
 | 
			
		||||
        private Mock<IResponseAggregator> _aggregator;
 | 
			
		||||
        private Mock<IResponseAggregatorFactory> _factory;
 | 
			
		||||
        private HttpContext _httpContext;
 | 
			
		||||
        private RequestDelegate _next;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
 | 
			
		||||
        public MultiplexingMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _httpContext = new DefaultHttpContext();
 | 
			
		||||
            _factory = new Mock<IResponseAggregatorFactory>();
 | 
			
		||||
            _aggregator = new Mock<IResponseAggregator>();
 | 
			
		||||
            _factory.Setup(x => x.Get(It.IsAny<ReRoute>())).Returns(_aggregator.Object);
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<MultiplexingMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = context => Task.FromResult(_count++);
 | 
			
		||||
            _middleware = new MultiplexingMiddleware(_next, _loggerFactory.Object, _factory.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_multiplex()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowing(reRoute))
 | 
			
		||||
                .When(x => WhenIMultiplex())
 | 
			
		||||
                .Then(x => ThePipelineIsCalled(2))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_multiplex()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowing(reRoute))
 | 
			
		||||
                .When(x => WhenIMultiplex())
 | 
			
		||||
                .Then(x => ThePipelineIsCalled(1))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFollowing(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
 | 
			
		||||
            _httpContext.Items.UpsertDownstreamRoute(_downstreamRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIMultiplex()
 | 
			
		||||
        {
 | 
			
		||||
            _middleware.Invoke(_httpContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThePipelineIsCalled(int expected)
 | 
			
		||||
        {
 | 
			
		||||
            _count.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,65 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Multiplexing
 | 
			
		||||
{
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Multiplexer;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class ResponseAggregatorFactoryTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly InMemoryResponseAggregatorFactory _factory;
 | 
			
		||||
        private Mock<IDefinedAggregatorProvider> _provider;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private IResponseAggregator _aggregator;
 | 
			
		||||
 | 
			
		||||
        public ResponseAggregatorFactoryTests()
 | 
			
		||||
        {
 | 
			
		||||
            _provider = new Mock<IDefinedAggregatorProvider>();
 | 
			
		||||
            _aggregator = new SimpleJsonResponseAggregator();
 | 
			
		||||
            _factory = new InMemoryResponseAggregatorFactory(_provider.Object, _aggregator);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [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>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,211 @@
 | 
			
		||||
using Castle.Components.DictionaryAdapter;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Multiplexer;
 | 
			
		||||
using Ocelot.UnitTests.Responder;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Multiplexing
 | 
			
		||||
{
 | 
			
		||||
    public class SimpleJsonResponseAggregatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly SimpleJsonResponseAggregator _aggregator;
 | 
			
		||||
        private List<HttpContext> _downstreamContexts;
 | 
			
		||||
        private HttpContext _upstreamContext;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
 | 
			
		||||
        public SimpleJsonResponseAggregatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator = new SimpleJsonResponseAggregator();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_aggregate_n_responses_and_set_response_content_on_upstream_context_withConfig()
 | 
			
		||||
        {
 | 
			
		||||
            var commentsDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Comments").Build();
 | 
			
		||||
 | 
			
		||||
            var userDetailsDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("UserDetails")
 | 
			
		||||
                .WithUpstreamPathTemplate(new UpstreamPathTemplate("", 0, false, "/v1/users/{userId}"))
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoutes = new List<DownstreamReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                commentsDownstreamReRoute,
 | 
			
		||||
                userDetailsDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoutes(downstreamReRoutes)
 | 
			
		||||
                .WithAggregateReRouteConfig(new List<AggregateReRouteConfig>()
 | 
			
		||||
                {
 | 
			
		||||
                    new AggregateReRouteConfig(){ReRouteKey = "UserDetails",JsonPath = "$[*].writerId",Parameter = "userId"}
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var commentsResponseContent = @"[{""id"":1,""writerId"":1,""postId"":1,""text"":""text1""},{""id"":2,""writerId"":2,""postId"":2,""text"":""text2""},{""id"":3,""writerId"":2,""postId"":1,""text"":""text21""}]";
 | 
			
		||||
 | 
			
		||||
            var commentsDownstreamContext = new DefaultHttpContext();
 | 
			
		||||
            commentsDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent(commentsResponseContent, Encoding.UTF8, "application/json"), HttpStatusCode.OK, new EditableList<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
            commentsDownstreamContext.Items.UpsertDownstreamReRoute(commentsDownstreamReRoute);
 | 
			
		||||
 | 
			
		||||
            var userDetailsResponseContent = @"[{""id"":1,""firstName"":""abolfazl"",""lastName"":""rajabpour""},{""id"":2,""firstName"":""reza"",""lastName"":""rezaei""}]";
 | 
			
		||||
            var userDetailsDownstreamContext = new DefaultHttpContext();
 | 
			
		||||
            userDetailsDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent(userDetailsResponseContent, Encoding.UTF8, "application/json"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
            userDetailsDownstreamContext.Items.UpsertDownstreamReRoute(userDetailsDownstreamReRoute);
 | 
			
		||||
 | 
			
		||||
            var downstreamContexts = new List<HttpContext> { commentsDownstreamContext, userDetailsDownstreamContext };
 | 
			
		||||
 | 
			
		||||
            var expected = "{\"Comments\":" + commentsResponseContent + ",\"UserDetails\":" + userDetailsResponseContent + "}";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheUpstreamContext(new DefaultHttpContext()))
 | 
			
		||||
                .And(x => GivenTheReRoute(reRoute))
 | 
			
		||||
                .And(x => GivenTheDownstreamContext(downstreamContexts))
 | 
			
		||||
                .When(x => WhenIAggregate())
 | 
			
		||||
                .Then(x => ThenTheContentIs(expected))
 | 
			
		||||
                .And(x => ThenTheContentTypeIs("application/json"))
 | 
			
		||||
                .And(x => ThenTheReasonPhraseIs("cannot return from aggregate..which reason phrase would you use?"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_aggregate_n_responses_and_set_response_content_on_upstream_context()
 | 
			
		||||
        {
 | 
			
		||||
            var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoutes = new List<DownstreamReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                billDownstreamReRoute,
 | 
			
		||||
                georgeDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoutes(downstreamReRoutes)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var billDownstreamContext = new DefaultHttpContext();
 | 
			
		||||
            billDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Bill says hi"), HttpStatusCode.OK, new EditableList<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
            billDownstreamContext.Items.UpsertDownstreamReRoute(billDownstreamReRoute);
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamContext = new DefaultHttpContext();
 | 
			
		||||
            georgeDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("George says hi"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
            georgeDownstreamContext.Items.UpsertDownstreamReRoute(georgeDownstreamReRoute);
 | 
			
		||||
 | 
			
		||||
            var downstreamContexts = new List<HttpContext> { billDownstreamContext, georgeDownstreamContext };
 | 
			
		||||
 | 
			
		||||
            var expected = "{\"Bill\":Bill says hi,\"George\":George says hi}";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheUpstreamContext(new DefaultHttpContext()))
 | 
			
		||||
                .And(x => GivenTheReRoute(reRoute))
 | 
			
		||||
                .And(x => GivenTheDownstreamContext(downstreamContexts))
 | 
			
		||||
                .When(x => WhenIAggregate())
 | 
			
		||||
                .Then(x => ThenTheContentIs(expected))
 | 
			
		||||
                .And(x => ThenTheContentTypeIs("application/json"))
 | 
			
		||||
                .And(x => ThenTheReasonPhraseIs("cannot return from aggregate..which reason phrase would you use?"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error_if_any_downstreams_have_errored()
 | 
			
		||||
        {
 | 
			
		||||
            var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoutes = new List<DownstreamReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                billDownstreamReRoute,
 | 
			
		||||
                georgeDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoutes(downstreamReRoutes)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var billDownstreamContext = new DefaultHttpContext();
 | 
			
		||||
            billDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Bill says hi"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
            billDownstreamContext.Items.UpsertDownstreamReRoute(billDownstreamReRoute);
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamContext = new DefaultHttpContext();
 | 
			
		||||
            georgeDownstreamContext.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Error"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
            georgeDownstreamContext.Items.UpsertDownstreamReRoute(georgeDownstreamReRoute);
 | 
			
		||||
 | 
			
		||||
            georgeDownstreamContext.Items.SetError(new AnyError());
 | 
			
		||||
 | 
			
		||||
            var downstreamContexts = new List<HttpContext> { billDownstreamContext, georgeDownstreamContext };
 | 
			
		||||
 | 
			
		||||
            var expected = "Error";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheUpstreamContext(new DefaultHttpContext()))
 | 
			
		||||
                .And(x => GivenTheReRoute(reRoute))
 | 
			
		||||
                .And(x => GivenTheDownstreamContext(downstreamContexts))
 | 
			
		||||
                .When(x => WhenIAggregate())
 | 
			
		||||
                .Then(x => ThenTheContentIs(expected))
 | 
			
		||||
                .And(x => ThenTheErrorIsMapped())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheReasonPhraseIs(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext.Items.DownstreamResponse().ReasonPhrase.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorIsMapped()
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext.Items.Errors().ShouldBe(_downstreamContexts[1].Items.Errors());
 | 
			
		||||
            _upstreamContext.Items.DownstreamResponse().ShouldBe(_downstreamContexts[1].Items.DownstreamResponse());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheReRoute(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheUpstreamContext(HttpContext upstreamContext)
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext = upstreamContext;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamContext(List<HttpContext> downstreamContexts)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContexts = downstreamContexts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIAggregate()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator.Aggregate(_reRoute, _upstreamContext, _downstreamContexts).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheContentIs(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            var content = _upstreamContext.Items.DownstreamResponse().Content.ReadAsStringAsync()
 | 
			
		||||
                .GetAwaiter()
 | 
			
		||||
                .GetResult();
 | 
			
		||||
 | 
			
		||||
            content.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheContentTypeIs(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext.Items.DownstreamResponse().Content.Headers.ContentType.MediaType.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheUpstreamContextIsMappedForNonAggregate()
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext.Items.DownstreamRequest().ShouldBe(_downstreamContexts[0].Items.DownstreamRequest());
 | 
			
		||||
            _upstreamContext.Items.DownstreamRequest().ShouldBe(_downstreamContexts[0].Items.DownstreamRequest());
 | 
			
		||||
            _upstreamContext.Items.Errors().ShouldBe(_downstreamContexts[0].Items.Errors());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,152 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Multiplexing
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Multiplexer;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using Ocelot.UnitTests.Responder;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Linq;
 | 
			
		||||
    using System.Net;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class UserDefinedResponseAggregatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly UserDefinedResponseAggregator _aggregator;
 | 
			
		||||
        private readonly Mock<IDefinedAggregatorProvider> _provider;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private List<HttpContext> _contexts;
 | 
			
		||||
        private HttpContext _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 DefaultHttpContext();
 | 
			
		||||
 | 
			
		||||
            var contextA = new DefaultHttpContext();
 | 
			
		||||
            contextA.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Tom"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
 | 
			
		||||
            var contextB = new DefaultHttpContext();
 | 
			
		||||
            contextB.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Laura"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
 | 
			
		||||
            var contexts = new List<HttpContext>()
 | 
			
		||||
            {
 | 
			
		||||
                contextA,
 | 
			
		||||
                contextB,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            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 DefaultHttpContext();
 | 
			
		||||
 | 
			
		||||
            var contextA = new DefaultHttpContext();
 | 
			
		||||
            contextA.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Tom"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
 | 
			
		||||
            var contextB = new DefaultHttpContext();
 | 
			
		||||
            contextB.Items.UpsertDownstreamResponse(new DownstreamResponse(new StringContent("Laura"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"));
 | 
			
		||||
 | 
			
		||||
            var contexts = new List<HttpContext>()
 | 
			
		||||
            {
 | 
			
		||||
                contextA,
 | 
			
		||||
                contextB,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheProviderReturnsError())
 | 
			
		||||
                .And(_ => GivenReRoute(reRoute))
 | 
			
		||||
                .And(_ => GivenContexts(contexts))
 | 
			
		||||
                .And(_ => GivenContext(context))
 | 
			
		||||
                .When(_ => WhenIAggregate())
 | 
			
		||||
                .Then(_ => ThenTheProviderIsCalled())
 | 
			
		||||
                .And(_ => ThenTheErrorIsReturned())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _context.Items.Errors().Count.ShouldBeGreaterThan(0);
 | 
			
		||||
            _context.Items.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.Items.DownstreamResponse().Content.ReadAsStringAsync();
 | 
			
		||||
            content.ShouldBe("Tom, Laura");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheProviderIsCalled()
 | 
			
		||||
        {
 | 
			
		||||
            _provider.Verify(x => x.Get(_reRoute), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenContext(HttpContext context)
 | 
			
		||||
        {
 | 
			
		||||
            _context = context;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenContexts(List<HttpContext> 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<HttpContext> responses)
 | 
			
		||||
            {
 | 
			
		||||
                var tom = await responses[0].Items.DownstreamResponse().Content.ReadAsStringAsync();
 | 
			
		||||
                var laura = await responses[1].Items.DownstreamResponse().Content.ReadAsStringAsync();
 | 
			
		||||
                var content = $"{tom}, {laura}";
 | 
			
		||||
                var headers = responses.SelectMany(x => x.Items.DownstreamResponse().Headers).ToList();
 | 
			
		||||
                return new DownstreamResponse(new StringContent(content), HttpStatusCode.OK, headers, "some reason");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user