mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 22:10:49 +08:00 
			
		
		
		
	Merge branch 'master' into jlukawska-feature/1115-find-available-port-in-acceptance-tests
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using System;
 | 
			
		||||
using Ocelot.Configuration.ChangeTracking;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
@@ -54,6 +55,33 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_trigger_change_token_on_change()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => _steps.GivenThereIsAConfiguration(_initialConfig))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunningReloadingConfig(true))
 | 
			
		||||
                .And(x => _steps.GivenIHaveAChangeToken())
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(_anotherConfig))
 | 
			
		||||
                .And(x => _steps.GivenIWait(MillisecondsToWaitForChangeToken))
 | 
			
		||||
                .Then(x => _steps.TheChangeTokenShouldBeActive(true))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_trigger_change_token_with_no_change()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => _steps.GivenThereIsAConfiguration(_initialConfig))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunningReloadingConfig(false))
 | 
			
		||||
                .And(x => _steps.GivenIHaveAChangeToken())
 | 
			
		||||
                .And(x => _steps.GivenIWait(MillisecondsToWaitForChangeToken)) // Wait for prior activation to expire.
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(_anotherConfig))
 | 
			
		||||
                .And(x => _steps.GivenIWait(MillisecondsToWaitForChangeToken))
 | 
			
		||||
                .Then(x => _steps.TheChangeTokenShouldBeActive(false))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private const int MillisecondsToWaitForChangeToken = (int) (OcelotConfigurationChangeToken.PollingIntervalSeconds*1000) - 100;
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            _steps.Dispose();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										243
									
								
								test/Ocelot.AcceptanceTests/HttpTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								test/Ocelot.AcceptanceTests/HttpTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,243 @@
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.IO;
 | 
			
		||||
    using System.Net;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Server.Kestrel.Core;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class HttpTests : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
        private readonly ServiceHandler _serviceHandler;
 | 
			
		||||
 | 
			
		||||
        public HttpTests()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceHandler = new ServiceHandler();
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_when_using_http_one()
 | 
			
		||||
        {
 | 
			
		||||
            const int port = 53219;
 | 
			
		||||
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileReRoute
 | 
			
		||||
                    {
 | 
			
		||||
                        DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                        DownstreamScheme = "https",
 | 
			
		||||
                        UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                        UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                        {
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = port,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                        DownstreamHttpMethod = "POST",
 | 
			
		||||
                        DownstreamHttpVersion = "1.0",
 | 
			
		||||
                        DangerousAcceptAnyServerCertificateValidator = true
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http1))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_when_using_http_one_point_one()
 | 
			
		||||
        {
 | 
			
		||||
            const int port = 53279;
 | 
			
		||||
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                            DownstreamScheme = "https",
 | 
			
		||||
                            UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = port,
 | 
			
		||||
                                },
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamHttpMethod = "POST",
 | 
			
		||||
                            DownstreamHttpVersion = "1.1",
 | 
			
		||||
                            DangerousAcceptAnyServerCertificateValidator = true
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http1))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_when_using_http_two_point_zero()
 | 
			
		||||
        {
 | 
			
		||||
            const int port = 53675;
 | 
			
		||||
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileReRoute
 | 
			
		||||
                    {
 | 
			
		||||
                        DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                        DownstreamScheme = "https",
 | 
			
		||||
                        UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                        UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                        {
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = port,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                        DownstreamHttpMethod = "POST",
 | 
			
		||||
                        DownstreamHttpVersion = "2.0",
 | 
			
		||||
                        DangerousAcceptAnyServerCertificateValidator = true
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const string expected = "here is some content";
 | 
			
		||||
            var httpContent = new StringContent(expected);
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http2))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(_ => _steps.ThenTheResponseBodyShouldBe(expected))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_500_when_using_http_one_to_talk_to_server_running_http_two()
 | 
			
		||||
        {
 | 
			
		||||
            const int port = 53677;
 | 
			
		||||
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileReRoute
 | 
			
		||||
                    {
 | 
			
		||||
                        DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                        DownstreamScheme = "https",
 | 
			
		||||
                        UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                        UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                        {
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = port,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                        DownstreamHttpMethod = "POST",
 | 
			
		||||
                        DownstreamHttpVersion = "1.1",
 | 
			
		||||
                        DangerousAcceptAnyServerCertificateValidator = true
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const string expected = "here is some content";
 | 
			
		||||
            var httpContent = new StringContent(expected);
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http2))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.InternalServerError))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_when_using_http_two_to_talk_to_server_running_http_one_point_one()
 | 
			
		||||
        {
 | 
			
		||||
            const int port = 53679;
 | 
			
		||||
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileReRoute
 | 
			
		||||
                    {
 | 
			
		||||
                        DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                        DownstreamScheme = "https",
 | 
			
		||||
                        UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                        UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                        {
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = port,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                        DownstreamHttpMethod = "POST",
 | 
			
		||||
                        DownstreamHttpVersion = "2.0",
 | 
			
		||||
                        DangerousAcceptAnyServerCertificateValidator = true
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const string expected = "here is some content";
 | 
			
		||||
            var httpContent = new StringContent(expected);
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http1))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(_ => _steps.ThenTheResponseBodyShouldBe(expected))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int port, HttpProtocols protocols)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
 | 
			
		||||
            {
 | 
			
		||||
                context.Response.StatusCode = 200;
 | 
			
		||||
                var reader = new StreamReader(context.Request.Body);
 | 
			
		||||
                var body = await reader.ReadToEndAsync();
 | 
			
		||||
                await context.Response.WriteAsync(body);
 | 
			
		||||
            }, port, protocols);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceHandler.Dispose();
 | 
			
		||||
            _steps.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										158
									
								
								test/Ocelot.AcceptanceTests/MethodTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								test/Ocelot.AcceptanceTests/MethodTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.IO;
 | 
			
		||||
    using System.Net;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class MethodTests : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
        private readonly ServiceHandler _serviceHandler;
 | 
			
		||||
 | 
			
		||||
        public MethodTests()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceHandler = new ServiceHandler();
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_when_get_converted_to_post()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 53171,
 | 
			
		||||
                                },
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamHttpMethod = "POST",
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53171/", "/", "POST"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_when_get_converted_to_post_with_content()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileReRoute
 | 
			
		||||
                    {
 | 
			
		||||
                        DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                        DownstreamScheme = "http",
 | 
			
		||||
                        UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                        UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                        DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                        {
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 53271,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                        DownstreamHttpMethod = "POST",
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const string expected = "here is some content";
 | 
			
		||||
            var httpContent = new StringContent(expected);
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53271/", "/", "POST"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(_ => _steps.ThenTheResponseBodyShouldBe(expected))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_when_get_converted_to_get_with_content()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileReRoute
 | 
			
		||||
                    {
 | 
			
		||||
                        DownstreamPathTemplate = "/{url}",
 | 
			
		||||
                        DownstreamScheme = "http",
 | 
			
		||||
                        UpstreamPathTemplate = "/{url}",
 | 
			
		||||
                        UpstreamHttpMethod = new List<string> { "Post" },
 | 
			
		||||
                        DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                        {
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 53272,
 | 
			
		||||
                            },
 | 
			
		||||
                        },
 | 
			
		||||
                        DownstreamHttpMethod = "GET",
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const string expected = "here is some content";
 | 
			
		||||
            var httpContent = new StringContent(expected);
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53272/", "/", "GET"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIPostUrlOnTheApiGateway("/", httpContent))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(_ => _steps.ThenTheResponseBodyShouldBe(expected))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string expected)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
 | 
			
		||||
            {
 | 
			
		||||
                if (context.Request.Method == expected)
 | 
			
		||||
                {
 | 
			
		||||
                    context.Response.StatusCode = 200;
 | 
			
		||||
                    var reader = new StreamReader(context.Request.Body);
 | 
			
		||||
                    var body = await reader.ReadToEndAsync();
 | 
			
		||||
                    await context.Response.WriteAsync(body);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    context.Response.StatusCode = 500;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceHandler.Dispose();
 | 
			
		||||
            _steps.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,9 +6,11 @@
 | 
			
		||||
    using Microsoft.Extensions.Configuration;
 | 
			
		||||
    using Microsoft.Extensions.Logging;
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.ComponentModel;
 | 
			
		||||
    using System.IO;
 | 
			
		||||
    using System.Net;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Microsoft.AspNetCore.Server.Kestrel.Core;
 | 
			
		||||
 | 
			
		||||
    public class ServiceHandler : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
@@ -47,6 +49,31 @@
 | 
			
		||||
            _builder.Start();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, RequestDelegate del, int port, HttpProtocols protocols)
 | 
			
		||||
        {
 | 
			
		||||
            _builder = new WebHostBuilder()
 | 
			
		||||
                .UseUrls(baseUrl)
 | 
			
		||||
                .UseKestrel()
 | 
			
		||||
                .ConfigureKestrel(serverOptions =>
 | 
			
		||||
                {
 | 
			
		||||
                    serverOptions.Listen(IPAddress.Loopback, port, listenOptions =>
 | 
			
		||||
                        {
 | 
			
		||||
                            listenOptions.UseHttps("idsrv3test.pfx", "idsrv3test");
 | 
			
		||||
                            listenOptions.Protocols = protocols;
 | 
			
		||||
                        });
 | 
			
		||||
                })
 | 
			
		||||
                .UseContentRoot(Directory.GetCurrentDirectory())
 | 
			
		||||
                .UseIISIntegration()
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.UsePathBase(basePath);
 | 
			
		||||
                    app.Run(del);
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            _builder.Start();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string fileName, string password, int port, RequestDelegate del)
 | 
			
		||||
        {
 | 
			
		||||
            _builder = new WebHostBuilder()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
using Ocelot.Configuration.ChangeTracking;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    using Caching;
 | 
			
		||||
    using Configuration.Repository;
 | 
			
		||||
@@ -54,6 +56,7 @@
 | 
			
		||||
        private IWebHostBuilder _webHostBuilder;
 | 
			
		||||
        private WebHostBuilder _ocelotBuilder;
 | 
			
		||||
        private IWebHost _ocelotHost;
 | 
			
		||||
        private IOcelotConfigurationChangeTokenSource _changeToken;
 | 
			
		||||
 | 
			
		||||
        public Steps()
 | 
			
		||||
        {
 | 
			
		||||
@@ -216,6 +219,11 @@
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void GivenIHaveAChangeToken()
 | 
			
		||||
        {
 | 
			
		||||
            _changeToken = _ocelotServer.Host.Services.GetRequiredService<IOcelotConfigurationChangeTokenSource>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@@ -384,6 +392,7 @@
 | 
			
		||||
            _ocelotServer = new TestServer(_webHostBuilder);
 | 
			
		||||
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
            Thread.Sleep(1000);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void WhenIGetUrlOnTheApiGatewayWaitingForTheResponseToBeOk(string url)
 | 
			
		||||
@@ -901,6 +910,18 @@
 | 
			
		||||
            _response = _ocelotClient.GetAsync(url).Result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void WhenIGetUrlOnTheApiGateway(string url, HttpContent content)
 | 
			
		||||
        {
 | 
			
		||||
            var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url) {Content = content};
 | 
			
		||||
            _response = _ocelotClient.SendAsync(httpRequestMessage).Result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void WhenIPostUrlOnTheApiGateway(string url, HttpContent content)
 | 
			
		||||
        {
 | 
			
		||||
            var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url) { Content = content };
 | 
			
		||||
            _response = _ocelotClient.SendAsync(httpRequestMessage).Result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void WhenIGetUrlOnTheApiGateway(string url, string cookie, string value)
 | 
			
		||||
        {
 | 
			
		||||
            var request = _ocelotServer.CreateRequest(url);
 | 
			
		||||
@@ -1123,6 +1144,11 @@
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void TheChangeTokenShouldBeActive(bool itShouldBeActive)
 | 
			
		||||
        {
 | 
			
		||||
            _changeToken.ChangeToken.HasChanged.ShouldBe(itShouldBeActive);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public void GivenOcelotIsRunningWithLogger()
 | 
			
		||||
        {
 | 
			
		||||
            _webHostBuilder = new WebHostBuilder();
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ namespace Ocelot.Benchmarks
 | 
			
		||||
 | 
			
		||||
            _downstreamContext = new DownstreamContext(httpContext)
 | 
			
		||||
            {
 | 
			
		||||
                Configuration = new InternalConfiguration(new List<ReRoute>(), null, null, null, null, null, null, null)
 | 
			
		||||
                Configuration = new InternalConfiguration(new List<ReRoute>(), null, null, null, null, null, null, null, null)
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration.ChangeTracking
 | 
			
		||||
{
 | 
			
		||||
    using Ocelot.Configuration.ChangeTracking;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class OcelotConfigurationChangeTokenSourceTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IOcelotConfigurationChangeTokenSource _source;
 | 
			
		||||
 | 
			
		||||
        public OcelotConfigurationChangeTokenSourceTests()
 | 
			
		||||
        {
 | 
			
		||||
            _source = new OcelotConfigurationChangeTokenSource();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_activate_change_token()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenIActivateTheChangeTokenSource())
 | 
			
		||||
                .Then(_ => ThenTheChangeTokenShouldBeActivated())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenIActivateTheChangeTokenSource()
 | 
			
		||||
        {
 | 
			
		||||
            _source.Activate();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheChangeTokenShouldBeActivated()
 | 
			
		||||
        {
 | 
			
		||||
            _source.ChangeToken.HasChanged.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,91 @@
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration.ChangeTracking
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using Ocelot.Configuration.ChangeTracking;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
 | 
			
		||||
    public class OcelotConfigurationChangeTokenTests
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_callback_with_state()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenIHaveAChangeToken())
 | 
			
		||||
                .And(_ => AndIRegisterACallback())
 | 
			
		||||
                .Then(_ => ThenIShouldGetADisposableWrapper())
 | 
			
		||||
                .Given(_ => GivenIActivateTheToken())
 | 
			
		||||
                .Then(_ => ThenTheCallbackShouldBeCalled())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_call_callback_if_it_is_disposed()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenIHaveAChangeToken())
 | 
			
		||||
                .And(_ => AndIRegisterACallback())
 | 
			
		||||
                .Then(_ => ThenIShouldGetADisposableWrapper())
 | 
			
		||||
                .And(_ => GivenIActivateTheToken())
 | 
			
		||||
                .And(_ => AndIDisposeTheCallbackWrapper())
 | 
			
		||||
                .And(_ => GivenIActivateTheToken())
 | 
			
		||||
                .Then(_ => ThenTheCallbackShouldNotBeCalled())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private OcelotConfigurationChangeToken _changeToken;
 | 
			
		||||
        private IDisposable _callbackWrapper;
 | 
			
		||||
        private int _callbackCounter;
 | 
			
		||||
        private readonly object _callbackInitialState = new object();
 | 
			
		||||
        private object _callbackState;
 | 
			
		||||
 | 
			
		||||
        private void Callback(object state)
 | 
			
		||||
        {
 | 
			
		||||
            _callbackCounter++;
 | 
			
		||||
            _callbackState = state;
 | 
			
		||||
            _changeToken.HasChanged.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenIHaveAChangeToken()
 | 
			
		||||
        {
 | 
			
		||||
            _changeToken = new OcelotConfigurationChangeToken();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AndIRegisterACallback()
 | 
			
		||||
        {
 | 
			
		||||
            _callbackWrapper = _changeToken.RegisterChangeCallback(Callback, _callbackInitialState);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenIShouldGetADisposableWrapper()
 | 
			
		||||
        {
 | 
			
		||||
            _callbackWrapper.ShouldNotBeNull();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenIActivateTheToken()
 | 
			
		||||
        {
 | 
			
		||||
            _callbackCounter = 0;
 | 
			
		||||
            _callbackState = null;
 | 
			
		||||
            _changeToken.Activate();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheCallbackShouldBeCalled()
 | 
			
		||||
        {
 | 
			
		||||
            _callbackCounter.ShouldBe(1);
 | 
			
		||||
            _callbackState.ShouldNotBeNull();
 | 
			
		||||
            _callbackState.ShouldBeSameAs(_callbackInitialState);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheCallbackShouldNotBeCalled()
 | 
			
		||||
        {
 | 
			
		||||
            _callbackCounter.ShouldBe(0);
 | 
			
		||||
            _callbackState.ShouldBeNull();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AndIDisposeTheCallbackWrapper()
 | 
			
		||||
        {
 | 
			
		||||
            _callbackState = null;
 | 
			
		||||
            _callbackCounter = 0;
 | 
			
		||||
            _callbackWrapper.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -19,6 +19,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        private readonly Mock<IQoSOptionsCreator> _qosCreator;
 | 
			
		||||
        private readonly Mock<IHttpHandlerOptionsCreator> _hhoCreator;
 | 
			
		||||
        private readonly Mock<ILoadBalancerOptionsCreator> _lboCreator;
 | 
			
		||||
        private readonly Mock<IVersionCreator> _vCreator;
 | 
			
		||||
        private FileConfiguration _fileConfig;
 | 
			
		||||
        private List<ReRoute> _reRoutes;
 | 
			
		||||
        private ServiceProviderConfiguration _spc;
 | 
			
		||||
@@ -30,6 +31,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
 | 
			
		||||
        public ConfigurationCreatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _vCreator = new Mock<IVersionCreator>();
 | 
			
		||||
            _lboCreator = new Mock<ILoadBalancerOptionsCreator>();
 | 
			
		||||
            _hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
 | 
			
		||||
            _qosCreator = new Mock<IQoSOptionsCreator>();
 | 
			
		||||
@@ -117,7 +119,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        private void WhenICreate()
 | 
			
		||||
        {
 | 
			
		||||
            var serviceProvider = _serviceCollection.BuildServiceProvider();
 | 
			
		||||
            _creator = new ConfigurationCreator(_spcCreator.Object, _qosCreator.Object, _hhoCreator.Object, serviceProvider, _lboCreator.Object);
 | 
			
		||||
            _creator = new ConfigurationCreator(_spcCreator.Object, _qosCreator.Object, _hhoCreator.Object, serviceProvider, _lboCreator.Object, _vCreator.Object);
 | 
			
		||||
            _result = _creator.Create(_fileConfig, _reRoutes);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
    using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Newtonsoft.Json;
 | 
			
		||||
    using Ocelot.Configuration.ChangeTracking;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
    using Ocelot.Configuration.Repository;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
@@ -16,6 +17,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
    public class DiskFileConfigurationRepositoryTests : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
 | 
			
		||||
        private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource;
 | 
			
		||||
        private IFileConfigurationRepository _repo;
 | 
			
		||||
        private string _environmentSpecificPath;
 | 
			
		||||
        private string _ocelotJsonPath;
 | 
			
		||||
@@ -35,7 +37,9 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            _semaphore.Wait();
 | 
			
		||||
            _hostingEnvironment = new Mock<IWebHostEnvironment>();
 | 
			
		||||
            _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
 | 
			
		||||
            _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
 | 
			
		||||
            _changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict);
 | 
			
		||||
            _changeTokenSource.Setup(m => m.Activate());
 | 
			
		||||
            _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -70,6 +74,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                .When(_ => WhenISetTheConfiguration())
 | 
			
		||||
                .Then(_ => ThenTheConfigurationIsStoredAs(config))
 | 
			
		||||
                .And(_ => ThenTheConfigurationJsonIsIndented(config))
 | 
			
		||||
                .And(x => AndTheChangeTokenIsActivated())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -117,7 +122,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        {
 | 
			
		||||
            _environmentName = null;
 | 
			
		||||
            _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
 | 
			
		||||
            _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
 | 
			
		||||
            _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
 | 
			
		||||
@@ -210,6 +215,11 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AndTheChangeTokenIsActivated()
 | 
			
		||||
        {
 | 
			
		||||
            _changeTokenSource.Verify(m => m.Activate(), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private FileConfiguration FakeFileConfigurationForSet()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoutes = new List<FileReRoute>
 | 
			
		||||
@@ -222,11 +232,11 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                        {
 | 
			
		||||
                            Host = "123.12.12.12",
 | 
			
		||||
                            Port = 80,
 | 
			
		||||
                        }
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                    DownstreamScheme = "https",
 | 
			
		||||
                    DownstreamPathTemplate = "/asdfs/test/{test}"
 | 
			
		||||
                }
 | 
			
		||||
                    DownstreamPathTemplate = "/asdfs/test/{test}",
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var globalConfiguration = new FileGlobalConfiguration
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
@@ -14,15 +15,18 @@
 | 
			
		||||
    {
 | 
			
		||||
        private readonly DynamicsCreator _creator;
 | 
			
		||||
        private readonly Mock<IRateLimitOptionsCreator> _rloCreator;
 | 
			
		||||
        private readonly Mock<IVersionCreator> _versionCreator;
 | 
			
		||||
        private List<ReRoute> _result;
 | 
			
		||||
        private FileConfiguration _fileConfig;
 | 
			
		||||
        private RateLimitOptions _rlo1;
 | 
			
		||||
        private RateLimitOptions _rlo2;
 | 
			
		||||
        private Version _version;
 | 
			
		||||
 | 
			
		||||
        public DynamicsCreatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _versionCreator = new Mock<IVersionCreator>();
 | 
			
		||||
            _rloCreator = new Mock<IRateLimitOptionsCreator>();
 | 
			
		||||
            _creator = new DynamicsCreator(_rloCreator.Object);
 | 
			
		||||
            _creator = new DynamicsCreator(_rloCreator.Object, _versionCreator.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -50,7 +54,8 @@
 | 
			
		||||
                        RateLimitRule = new FileRateLimitRule
 | 
			
		||||
                        {
 | 
			
		||||
                            EnableRateLimiting = false
 | 
			
		||||
                        }
 | 
			
		||||
                        },
 | 
			
		||||
                        DownstreamHttpVersion = "1.1"
 | 
			
		||||
                    },
 | 
			
		||||
                    new FileDynamicReRoute
 | 
			
		||||
                    {
 | 
			
		||||
@@ -58,16 +63,19 @@
 | 
			
		||||
                        RateLimitRule = new FileRateLimitRule
 | 
			
		||||
                        {
 | 
			
		||||
                            EnableRateLimiting = true
 | 
			
		||||
                        }
 | 
			
		||||
                        },
 | 
			
		||||
                        DownstreamHttpVersion = "2.0"
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileConfig))
 | 
			
		||||
                .And(_ => GivenTheRloCreatorReturns())
 | 
			
		||||
                .And(_ => GivenTheVersionCreatorReturns())
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
                .Then(_ => ThenTheReRoutesAreReturned())
 | 
			
		||||
                .And(_ => ThenTheRloCreatorIsCalledCorrectly())
 | 
			
		||||
                .And(_ => ThenTheVersionCreatorIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -80,18 +88,32 @@
 | 
			
		||||
                _fileConfig.GlobalConfiguration), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheVersionCreatorIsCalledCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            _versionCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[0].DownstreamHttpVersion), Times.Once);
 | 
			
		||||
            _versionCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[1].DownstreamHttpVersion), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheReRoutesAreReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _result.Count.ShouldBe(2);
 | 
			
		||||
            _result[0].DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeFalse();
 | 
			
		||||
            _result[0].DownstreamReRoute[0].RateLimitOptions.ShouldBe(_rlo1);
 | 
			
		||||
            _result[0].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_version);
 | 
			
		||||
            _result[0].DownstreamReRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicReRoutes[0].ServiceName);
 | 
			
		||||
 | 
			
		||||
            _result[1].DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeTrue();
 | 
			
		||||
            _result[1].DownstreamReRoute[0].RateLimitOptions.ShouldBe(_rlo2);
 | 
			
		||||
            _result[1].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_version);
 | 
			
		||||
            _result[1].DownstreamReRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicReRoutes[1].ServiceName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheVersionCreatorReturns()
 | 
			
		||||
        {
 | 
			
		||||
            _version = new Version("1.1");
 | 
			
		||||
            _versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_version);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRloCreatorReturns()
 | 
			
		||||
        {
 | 
			
		||||
            _rlo1 = new RateLimitOptionsBuilder().Build();
 | 
			
		||||
 
 | 
			
		||||
@@ -9,11 +9,14 @@ using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Configuration.ChangeTracking;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
 | 
			
		||||
    public class FileConfigurationSetterTests
 | 
			
		||||
    {
 | 
			
		||||
        private FileConfiguration _fileConfiguration;
 | 
			
		||||
@@ -21,7 +24,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        private Mock<IInternalConfigurationRepository> _configRepo;
 | 
			
		||||
        private Mock<IInternalConfigurationCreator> _configCreator;
 | 
			
		||||
        private Response<IInternalConfiguration> _configuration;
 | 
			
		||||
        private object _result;
 | 
			
		||||
        private object _result;
 | 
			
		||||
        private Mock<IFileConfigurationRepository> _repo;
 | 
			
		||||
 | 
			
		||||
        public FileConfigurationSetterTests()
 | 
			
		||||
@@ -37,7 +40,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        {
 | 
			
		||||
            var fileConfig = new FileConfiguration();
 | 
			
		||||
            var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
 | 
			
		||||
            var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
 | 
			
		||||
            var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowingConfiguration(fileConfig))
 | 
			
		||||
                .And(x => GivenTheRepoReturns(new OkResponse()))
 | 
			
		||||
@@ -104,8 +107,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
 | 
			
		||||
        private void ThenTheConfigurationRepositoryIsCalledCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            _configRepo
 | 
			
		||||
                .Verify(x => x.AddOrReplace(_configuration.Data), Times.Once);
 | 
			
		||||
            _configRepo.Verify(x => x.AddOrReplace(_configuration.Data), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,7 @@
 | 
			
		||||
            _reRoutes = new List<ReRoute> { new ReRouteBuilder().Build() };
 | 
			
		||||
            _aggregates = new List<ReRoute> { new ReRouteBuilder().Build() };
 | 
			
		||||
            _dynamics = new List<ReRoute> { new ReRouteBuilder().Build() };
 | 
			
		||||
            _internalConfig = new InternalConfiguration(null, "", null, "", null, "", null, null);
 | 
			
		||||
            _internalConfig = new InternalConfiguration(null, "", null, "", null, "", null, null, null);
 | 
			
		||||
 | 
			
		||||
            _reRoutesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_reRoutes);
 | 
			
		||||
            _aggregatesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<ReRoute>>())).Returns(_aggregates);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,8 @@ using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Configuration.ChangeTracking;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
@@ -16,10 +18,13 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        private IInternalConfiguration _config;
 | 
			
		||||
        private Response _result;
 | 
			
		||||
        private Response<IInternalConfiguration> _getResult;
 | 
			
		||||
        private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource;
 | 
			
		||||
 | 
			
		||||
        public InMemoryConfigurationRepositoryTests()
 | 
			
		||||
        {
 | 
			
		||||
            _repo = new InMemoryInternalConfigurationRepository();
 | 
			
		||||
            _changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict);
 | 
			
		||||
            _changeTokenSource.Setup(m => m.Activate());
 | 
			
		||||
            _repo = new InMemoryInternalConfigurationRepository(_changeTokenSource.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -28,6 +33,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            this.Given(x => x.GivenTheConfigurationIs(new FakeConfig("initial", "adminath")))
 | 
			
		||||
                .When(x => x.WhenIAddOrReplaceTheConfig())
 | 
			
		||||
                .Then(x => x.ThenNoErrorsAreReturned())
 | 
			
		||||
                .And(x => AndTheChangeTokenIsActivated())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -71,6 +77,11 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            _result.IsError.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AndTheChangeTokenIsActivated()
 | 
			
		||||
        {
 | 
			
		||||
            _changeTokenSource.Verify(m => m.Activate(), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private class FakeConfig : IInternalConfiguration
 | 
			
		||||
        {
 | 
			
		||||
            private readonly string _downstreamTemplatePath;
 | 
			
		||||
@@ -109,6 +120,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            public string DownstreamScheme { get; }
 | 
			
		||||
            public QoSOptions QoSOptions { get; }
 | 
			
		||||
            public HttpHandlerOptions HttpHandlerOptions { get; }
 | 
			
		||||
            public Version DownstreamHttpVersion { get; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Cache;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
@@ -30,6 +31,7 @@
 | 
			
		||||
        private Mock<ILoadBalancerOptionsCreator> _lboCreator;
 | 
			
		||||
        private Mock<IReRouteKeyCreator> _rrkCreator;
 | 
			
		||||
        private Mock<ISecurityOptionsCreator> _soCreator;
 | 
			
		||||
        private Mock<IVersionCreator> _versionCreator;
 | 
			
		||||
        private FileConfiguration _fileConfig;
 | 
			
		||||
        private ReRouteOptions _rro;
 | 
			
		||||
        private string _requestId;
 | 
			
		||||
@@ -46,6 +48,7 @@
 | 
			
		||||
        private LoadBalancerOptions _lbo;
 | 
			
		||||
        private List<ReRoute> _result;
 | 
			
		||||
        private SecurityOptions _securityOptions;
 | 
			
		||||
        private Version _expectedVersion;
 | 
			
		||||
 | 
			
		||||
        public ReRoutesCreatorTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -63,6 +66,7 @@
 | 
			
		||||
            _lboCreator = new Mock<ILoadBalancerOptionsCreator>();
 | 
			
		||||
            _rrkCreator = new Mock<IReRouteKeyCreator>();
 | 
			
		||||
            _soCreator = new Mock<ISecurityOptionsCreator>();
 | 
			
		||||
            _versionCreator = new Mock<IVersionCreator>();
 | 
			
		||||
 | 
			
		||||
            _creator = new ReRoutesCreator(
 | 
			
		||||
                _cthCreator.Object,
 | 
			
		||||
@@ -78,7 +82,8 @@
 | 
			
		||||
                _daCreator.Object,
 | 
			
		||||
                _lboCreator.Object,
 | 
			
		||||
                _rrkCreator.Object,
 | 
			
		||||
                _soCreator.Object
 | 
			
		||||
                _soCreator.Object,
 | 
			
		||||
                _versionCreator.Object
 | 
			
		||||
                );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -155,6 +160,7 @@
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDependenciesAreSetUpCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            _expectedVersion = new Version("1.1");
 | 
			
		||||
            _rro = new ReRouteOptions(false, false, false, false, false);
 | 
			
		||||
            _requestId = "testy";
 | 
			
		||||
            _rrk = "besty";
 | 
			
		||||
@@ -182,6 +188,7 @@
 | 
			
		||||
            _hfarCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_ht);
 | 
			
		||||
            _daCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_dhp);
 | 
			
		||||
            _lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
 | 
			
		||||
            _versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_expectedVersion);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheReRoutesAreCreated()
 | 
			
		||||
@@ -209,6 +216,7 @@
 | 
			
		||||
 | 
			
		||||
        private void ThenTheReRouteIsSet(FileReRoute expected, int reRouteIndex)
 | 
			
		||||
        {
 | 
			
		||||
            _result[reRouteIndex].DownstreamReRoute[0].DownstreamHttpVersion.ShouldBe(_expectedVersion);
 | 
			
		||||
            _result[reRouteIndex].DownstreamReRoute[0].IsAuthenticated.ShouldBe(_rro.IsAuthenticated);
 | 
			
		||||
            _result[reRouteIndex].DownstreamReRoute[0].IsAuthorised.ShouldBe(_rro.IsAuthorised);
 | 
			
		||||
            _result[reRouteIndex].DownstreamReRoute[0].IsCached.ShouldBe(_rro.IsCached);
 | 
			
		||||
 
 | 
			
		||||
@@ -305,6 +305,71 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("1.0")]
 | 
			
		||||
        [InlineData("1.1")]
 | 
			
		||||
        [InlineData("2.0")]
 | 
			
		||||
        [InlineData("1,0")]
 | 
			
		||||
        [InlineData("1,1")]
 | 
			
		||||
        [InlineData("2,0")]
 | 
			
		||||
        [InlineData("1")]
 | 
			
		||||
        [InlineData("2")]
 | 
			
		||||
        [InlineData("")]
 | 
			
		||||
        [InlineData(null)]
 | 
			
		||||
        public void should_be_valid_re_route_using_downstream_http_version(string version)
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileHostAndPort
 | 
			
		||||
                    {
 | 
			
		||||
                        Host = "localhost",
 | 
			
		||||
                        Port = 5000,
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                DownstreamHttpVersion = version,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("retg1.1")]
 | 
			
		||||
        [InlineData("re2.0")]
 | 
			
		||||
        [InlineData("1,0a")]
 | 
			
		||||
        [InlineData("a1,1")]
 | 
			
		||||
        [InlineData("12,0")]
 | 
			
		||||
        [InlineData("asdf")]
 | 
			
		||||
        public void should_be_invalid_re_route_using_downstream_http_version(string version)
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileHostAndPort
 | 
			
		||||
                    {
 | 
			
		||||
                        Host = "localhost",
 | 
			
		||||
                        Port = 5000,
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                DownstreamHttpVersion = version,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("'Downstream Http Version' is not in the correct format."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenAnAuthProvider(string key)
 | 
			
		||||
        {
 | 
			
		||||
            var schemes = new List<AuthenticationScheme>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								test/Ocelot.UnitTests/Configuration/VersionCreatorTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								test/Ocelot.UnitTests/Configuration/VersionCreatorTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using Ocelot.Configuration.Creator;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class VersionCreatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly HttpVersionCreator _creator;
 | 
			
		||||
        private string _input;
 | 
			
		||||
        private Version _result;
 | 
			
		||||
 | 
			
		||||
        public VersionCreatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _creator = new HttpVersionCreator();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_create_version_based_on_input()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenTheInput("2.0"))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
                .Then(_ => ThenTheResultIs(2, 0))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_default_to_version_one_point_one()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenTheInput(""))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
                .Then(_ => ThenTheResultIs(1, 1))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheInput(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _input = input;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICreate()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _creator.Create(_input);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIs(int major, int minor)
 | 
			
		||||
        {
 | 
			
		||||
            _result.Major.ShouldBe(major);
 | 
			
		||||
            _result.Minor.ShouldBe(minor);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
@@ -44,7 +45,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_create_downstream_route()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -71,7 +72,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
 | 
			
		||||
            var reRoutes = new List<ReRoute> { reRoute };
 | 
			
		||||
 | 
			
		||||
            var configuration = new InternalConfiguration(reRoutes, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(reRoutes, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -83,7 +84,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_cache_downstream_route()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration, "/geoffisthebest/"))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -96,7 +97,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_cache_downstream_route()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration, "/geoffistheworst/"))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -110,7 +111,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        public void should_create_downstream_route_with_no_path()
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamUrlPath = "/auth/";
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -122,7 +123,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        public void should_create_downstream_route_with_only_first_segment_no_traling_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamUrlPath = "/auth";
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -134,7 +135,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        public void should_create_downstream_route_with_segments_no_traling_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamUrlPath = "/auth/test";
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -146,7 +147,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        public void should_create_downstream_route_and_remove_query_string()
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamUrlPath = "/auth/test?test=1&best=2";
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration, upstreamUrlPath))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -158,7 +159,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        public void should_create_downstream_route_for_sticky_sessions()
 | 
			
		||||
        {
 | 
			
		||||
            var loadBalancerOptions = new LoadBalancerOptionsBuilder().WithType(nameof(CookieStickySessions)).WithKey("boom").WithExpiryInMs(1).Build();
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
@@ -174,7 +175,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .WithTimeoutValue(1)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration))
 | 
			
		||||
                .And(_ => GivenTheQosCreatorReturns(qoSOptions))
 | 
			
		||||
@@ -186,7 +187,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_create_downstream_route_with_handler_options()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, "doesnt matter", null, "doesnt matter", _loadBalancerOptions, "http", _qoSOptions, _handlerOptions, new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenTheConfiguration(configuration))
 | 
			
		||||
                .When(_ => WhenICreate())
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
@@ -48,7 +49,7 @@
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_scoped_data_repository_correctly()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new InternalConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
 | 
			
		||||
            var config = new InternalConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,8 @@ using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
 | 
			
		||||
    public class DownstreamRouteFinderTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IDownstreamRouteProvider _downstreamRouteFinder;
 | 
			
		||||
@@ -739,7 +741,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath, ServiceProviderConfiguration serviceProviderConfig)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoutesConfig = reRoutesConfig;
 | 
			
		||||
            _config = new InternalConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
 | 
			
		||||
            _config = new InternalConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
@@ -140,12 +141,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
 | 
			
		||||
        private void GivenTheReRoutes(List<ReRoute> reRoutes)
 | 
			
		||||
        {
 | 
			
		||||
            _config = new InternalConfiguration(reRoutes, "", null, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
 | 
			
		||||
            _config = new InternalConfiguration(reRoutes, "", null, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheReRoutes(List<ReRoute> reRoutes, ServiceProviderConfiguration config)
 | 
			
		||||
        {
 | 
			
		||||
            _config = new InternalConfiguration(reRoutes, "", config, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
 | 
			
		||||
            _config = new InternalConfiguration(reRoutes, "", config, "", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build(), new Version("1.1"));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -382,7 +382,7 @@
 | 
			
		||||
 | 
			
		||||
        private void GivenTheServiceProviderConfigIs(ServiceProviderConfiguration config)
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null, null);
 | 
			
		||||
            _downstreamContext.Configuration = configuration;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void NoDownstreamException()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null, null, null, null, null);
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null, null, null, null, null, null);
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
 | 
			
		||||
                .And(_ => GivenTheConfigurationIs(config))
 | 
			
		||||
@@ -65,7 +65,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void DownstreamException()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null, null, null, null, null);
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null, null, null, null, null, null);
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenAnExceptionWillBeThrownDownstream())
 | 
			
		||||
                .And(_ => GivenTheConfigurationIs(config))
 | 
			
		||||
@@ -77,7 +77,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void ShouldSetRequestId()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, "requestidkey", null, null, null, null);
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, "requestidkey", null, null, null, null, null);
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
 | 
			
		||||
                .And(_ => GivenTheConfigurationIs(config))
 | 
			
		||||
@@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void ShouldSetAspDotNetRequestId()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null, null, null, null, null);
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null, null, null, null, null, null);
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
 | 
			
		||||
                .And(_ => GivenTheConfigurationIs(config))
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
        {
 | 
			
		||||
            var configRepo = new Mock<IInternalConfigurationRepository>();
 | 
			
		||||
            configRepo.Setup(x => x.Get())
 | 
			
		||||
                .Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, null, null, null, null, null, null)));
 | 
			
		||||
                .Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, null, null, null, null, null, null, null)));
 | 
			
		||||
            var services = new ServiceCollection();
 | 
			
		||||
            services.AddSingleton<IInternalConfigurationRepository>(configRepo.Object);
 | 
			
		||||
            var sp = services.BuildServiceProvider();
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
            var client = new Mock<IDiscoveryClient>();
 | 
			
		||||
            var configRepo = new Mock<IInternalConfigurationRepository>();
 | 
			
		||||
            configRepo.Setup(x => x.Get())
 | 
			
		||||
                .Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, serviceProviderConfig, null, null, null, null, null)));
 | 
			
		||||
                .Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(null, null, serviceProviderConfig, null, null, null, null, null, null)));
 | 
			
		||||
            var services = new ServiceCollection();
 | 
			
		||||
            services.AddSingleton<IInternalConfigurationRepository>(configRepo.Object);
 | 
			
		||||
            services.AddSingleton<IDiscoveryClient>(client.Object);
 | 
			
		||||
 
 | 
			
		||||
@@ -139,7 +139,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        private void GivenTheConfigurationIs(ServiceProviderConfiguration config)
 | 
			
		||||
        {
 | 
			
		||||
            _config = config;
 | 
			
		||||
            var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null);
 | 
			
		||||
            var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null, null);
 | 
			
		||||
            _downstreamContext.Configuration = configuration;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Request
 | 
			
		||||
namespace Ocelot.UnitTests.Request
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Moq;
 | 
			
		||||
@@ -9,9 +7,12 @@ namespace Ocelot.UnitTests.Request
 | 
			
		||||
    using Ocelot.Request.Creator;
 | 
			
		||||
    using Ocelot.Request.Mapper;
 | 
			
		||||
    using Ocelot.Request.Middleware;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
@@ -65,6 +66,20 @@ namespace Ocelot.UnitTests.Request
 | 
			
		||||
                .Then(_ => ThenTheContexRequestIsMappedToADownstreamRequest())
 | 
			
		||||
                .And(_ => ThenTheDownstreamRequestIsStored())
 | 
			
		||||
                .And(_ => ThenTheNextMiddlewareIsInvoked())
 | 
			
		||||
                .And(_ => ThenTheDownstreamRequestMethodIs("GET"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_map_downstream_reroute_method_to_downstream_request()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenTheHttpContextContainsARequest())
 | 
			
		||||
                .And(_ => GivenTheMapperWillReturnAMappedRequest())
 | 
			
		||||
                .When(_ => WhenTheMiddlewareIsInvoked())
 | 
			
		||||
                .Then(_ => ThenTheContexRequestIsMappedToADownstreamRequest())
 | 
			
		||||
                .And(_ => ThenTheDownstreamRequestIsStored())
 | 
			
		||||
                .And(_ => ThenTheNextMiddlewareIsInvoked())
 | 
			
		||||
                .And(_ => ThenTheDownstreamRequestMethodIs("GET"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -80,6 +95,11 @@ namespace Ocelot.UnitTests.Request
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheDownstreamRequestMethodIs(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.DownstreamRequest.Method.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheHttpContextContainsARequest()
 | 
			
		||||
        {
 | 
			
		||||
            _httpContext
 | 
			
		||||
@@ -92,7 +112,7 @@ namespace Ocelot.UnitTests.Request
 | 
			
		||||
            _mappedRequest = new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "http://www.bbc.co.uk"));
 | 
			
		||||
 | 
			
		||||
            _requestMapper
 | 
			
		||||
                .Setup(rm => rm.Map(It.IsAny<HttpRequest>()))
 | 
			
		||||
                .Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamReRoute>()))
 | 
			
		||||
                .ReturnsAsync(_mappedRequest);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -101,7 +121,7 @@ namespace Ocelot.UnitTests.Request
 | 
			
		||||
            _mappedRequest = new ErrorResponse<HttpRequestMessage>(new UnmappableRequestError(new System.Exception("boooom!")));
 | 
			
		||||
 | 
			
		||||
            _requestMapper
 | 
			
		||||
                .Setup(rm => rm.Map(It.IsAny<HttpRequest>()))
 | 
			
		||||
                .Setup(rm => rm.Map(It.IsAny<HttpRequest>(), It.IsAny<DownstreamReRoute>()))
 | 
			
		||||
                .ReturnsAsync(_mappedRequest);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -112,7 +132,7 @@ namespace Ocelot.UnitTests.Request
 | 
			
		||||
 | 
			
		||||
        private void ThenTheContexRequestIsMappedToADownstreamRequest()
 | 
			
		||||
        {
 | 
			
		||||
            _requestMapper.Verify(rm => rm.Map(_httpRequest.Object), Times.Once);
 | 
			
		||||
            _requestMapper.Verify(rm => rm.Map(_httpRequest.Object, _downstreamContext.DownstreamReRoute), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheDownstreamRequestIsStored()
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,8 @@
 | 
			
		||||
    using System.Security.Cryptography;
 | 
			
		||||
    using System.Text;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
@@ -27,6 +29,8 @@
 | 
			
		||||
 | 
			
		||||
        private List<KeyValuePair<string, StringValues>> _inputHeaders = null;
 | 
			
		||||
 | 
			
		||||
        private DownstreamReRoute _downstreamReRoute;
 | 
			
		||||
 | 
			
		||||
        public RequestMapperTests()
 | 
			
		||||
        {
 | 
			
		||||
            _httpContext = new DefaultHttpContext();
 | 
			
		||||
@@ -47,6 +51,7 @@
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasHost(host))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasPath(path))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasQueryString(queryString))
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasUri(expectedUri))
 | 
			
		||||
@@ -76,18 +81,35 @@
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenTheInputRequestHasMethod(method))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasMethod(method))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("", "GET")]
 | 
			
		||||
        [InlineData(null, "GET")]
 | 
			
		||||
        [InlineData("POST", "POST")]
 | 
			
		||||
        public void Should_use_downstream_reroute_method_if_set(string input, string expected)
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenTheInputRequestHasMethod("GET"))
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRouteMethodIs(input))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasMethod(expected))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_map_all_headers()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenTheInputRequestHasHeaders())
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasMethod("GET"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasEachHeader())
 | 
			
		||||
@@ -100,6 +122,7 @@
 | 
			
		||||
            this.Given(_ => GivenTheInputRequestHasNoHeaders())
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasMethod("GET"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasNoHeaders())
 | 
			
		||||
@@ -112,6 +135,7 @@
 | 
			
		||||
            this.Given(_ => GivenTheInputRequestHasContent("This is my content"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasMethod("GET"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasContent("This is my content"))
 | 
			
		||||
@@ -124,6 +148,7 @@
 | 
			
		||||
            this.Given(_ => GivenTheInputRequestHasNullContent())
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasMethod("GET"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasNoContent())
 | 
			
		||||
@@ -136,6 +161,7 @@
 | 
			
		||||
            this.Given(_ => GivenTheInputRequestHasNoContentType())
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasMethod("GET"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasNoContent())
 | 
			
		||||
@@ -148,22 +174,13 @@
 | 
			
		||||
            this.Given(_ => GivenTheInputRequestHasNoContentLength())
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasMethod("GET"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasNoContent())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheInputRequestHasNoContentLength()
 | 
			
		||||
        {
 | 
			
		||||
            _inputRequest.ContentLength = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheInputRequestHasNoContentType()
 | 
			
		||||
        {
 | 
			
		||||
            _inputRequest.ContentType = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_map_content_headers()
 | 
			
		||||
        {
 | 
			
		||||
@@ -183,6 +200,7 @@
 | 
			
		||||
                .And(_ => GivenTheContentMD5Is(md5bytes))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasMethod("GET"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
 | 
			
		||||
@@ -204,6 +222,7 @@
 | 
			
		||||
                .And(_ => GivenTheContentTypeIs("application/json"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasMethod("POST"))
 | 
			
		||||
                .And(_ => GivenTheInputRequestHasAValidUri())
 | 
			
		||||
                .And(_ => GivenTheDownstreamReRoute())
 | 
			
		||||
                .When(_ => WhenMapped())
 | 
			
		||||
                .Then(_ => ThenNoErrorIsReturned())
 | 
			
		||||
                .And(_ => ThenTheMappedRequestHasContentTypeHeader("application/json"))
 | 
			
		||||
@@ -212,6 +231,30 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamReRouteMethodIs(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownStreamHttpMethod(input)
 | 
			
		||||
                .WithDownstreamHttpVersion(new Version("1.1")).Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamReRoute()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamHttpVersion(new Version("1.1")).Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheInputRequestHasNoContentLength()
 | 
			
		||||
        {
 | 
			
		||||
            _inputRequest.ContentLength = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheInputRequestHasNoContentType()
 | 
			
		||||
        {
 | 
			
		||||
            _inputRequest.ContentType = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private void ThenTheContentHeadersAreNotAddedToNonContentHeaders()
 | 
			
		||||
        {
 | 
			
		||||
            _mappedRequest.Data.Headers.ShouldNotContain(x => x.Key == "Content-Disposition");
 | 
			
		||||
@@ -380,7 +423,7 @@
 | 
			
		||||
 | 
			
		||||
        private async Task WhenMapped()
 | 
			
		||||
        {
 | 
			
		||||
            _mappedRequest = await _requestMapper.Map(_inputRequest);
 | 
			
		||||
            _mappedRequest = await _requestMapper.Map(_inputRequest, _downstreamReRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenNoErrorIsReturned()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user