mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 15:50:49 +08:00 
			
		
		
		
	Rename all ReRoute to Route to move closer to YARP +semver: breaking
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,103 +1,103 @@
 | 
			
		||||
using FluentValidation.Results;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration.Validation
 | 
			
		||||
{
 | 
			
		||||
    public class FileQoSOptionsFluentValidatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private FileQoSOptionsFluentValidator _validator;
 | 
			
		||||
        private ServiceCollection _services;
 | 
			
		||||
        private ValidationResult _result;
 | 
			
		||||
        private FileQoSOptions _qosOptions;
 | 
			
		||||
 | 
			
		||||
        public FileQoSOptionsFluentValidatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _services = new ServiceCollection();
 | 
			
		||||
            var provider = _services.BuildServiceProvider();
 | 
			
		||||
            _validator = new FileQoSOptionsFluentValidator(provider);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_as_nothing_set()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenThe(new FileQoSOptions()))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_as_qos_delegate_set()
 | 
			
		||||
        {
 | 
			
		||||
            var qosOptions = new FileQoSOptions
 | 
			
		||||
            {
 | 
			
		||||
                TimeoutValue = 1,
 | 
			
		||||
                ExceptionsAllowedBeforeBreaking = 1
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(qosOptions))
 | 
			
		||||
                .And(_ => GivenAQosDelegate())
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_invalid_as_no_qos_delegate()
 | 
			
		||||
        {
 | 
			
		||||
            var qosOptions = new FileQoSOptions
 | 
			
		||||
            {
 | 
			
		||||
                TimeoutValue = 1,
 | 
			
		||||
                ExceptionsAllowedBeforeBreaking = 1
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(qosOptions))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInValid())
 | 
			
		||||
                .And(_ => ThenTheErrorIs())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorIs()
 | 
			
		||||
        {
 | 
			
		||||
            _result.Errors[0].ErrorMessage.ShouldBe("Unable to start Ocelot because either a ReRoute or GlobalConfiguration are using QoSOptions but no QosDelegatingHandlerDelegate has been registered in dependency injection container. Are you missing a package like Ocelot.Provider.Polly and services.AddPolly()?");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsInValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenAQosDelegate()
 | 
			
		||||
        {
 | 
			
		||||
            QosDelegatingHandlerDelegate fake = (a, b) =>
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            };
 | 
			
		||||
            _services.AddSingleton<QosDelegatingHandlerDelegate>(fake);
 | 
			
		||||
            var provider = _services.BuildServiceProvider();
 | 
			
		||||
            _validator = new FileQoSOptionsFluentValidator(provider);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThe(FileQoSOptions qosOptions)
 | 
			
		||||
        {
 | 
			
		||||
            _qosOptions = qosOptions;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIValidate()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _validator.Validate(_qosOptions);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
using FluentValidation.Results;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration.Validation
 | 
			
		||||
{
 | 
			
		||||
    public class FileQoSOptionsFluentValidatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private FileQoSOptionsFluentValidator _validator;
 | 
			
		||||
        private ServiceCollection _services;
 | 
			
		||||
        private ValidationResult _result;
 | 
			
		||||
        private FileQoSOptions _qosOptions;
 | 
			
		||||
 | 
			
		||||
        public FileQoSOptionsFluentValidatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _services = new ServiceCollection();
 | 
			
		||||
            var provider = _services.BuildServiceProvider();
 | 
			
		||||
            _validator = new FileQoSOptionsFluentValidator(provider);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_as_nothing_set()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenThe(new FileQoSOptions()))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_as_qos_delegate_set()
 | 
			
		||||
        {
 | 
			
		||||
            var qosOptions = new FileQoSOptions
 | 
			
		||||
            {
 | 
			
		||||
                TimeoutValue = 1,
 | 
			
		||||
                ExceptionsAllowedBeforeBreaking = 1
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(qosOptions))
 | 
			
		||||
                .And(_ => GivenAQosDelegate())
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_invalid_as_no_qos_delegate()
 | 
			
		||||
        {
 | 
			
		||||
            var qosOptions = new FileQoSOptions
 | 
			
		||||
            {
 | 
			
		||||
                TimeoutValue = 1,
 | 
			
		||||
                ExceptionsAllowedBeforeBreaking = 1
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(qosOptions))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInValid())
 | 
			
		||||
                .And(_ => ThenTheErrorIs())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorIs()
 | 
			
		||||
        {
 | 
			
		||||
            _result.Errors[0].ErrorMessage.ShouldBe("Unable to start Ocelot because either a Route or GlobalConfiguration are using QoSOptions but no QosDelegatingHandlerDelegate has been registered in dependency injection container. Are you missing a package like Ocelot.Provider.Polly and services.AddPolly()?");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsInValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenAQosDelegate()
 | 
			
		||||
        {
 | 
			
		||||
            QosDelegatingHandlerDelegate fake = (a, b) =>
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            };
 | 
			
		||||
            _services.AddSingleton<QosDelegatingHandlerDelegate>(fake);
 | 
			
		||||
            var provider = _services.BuildServiceProvider();
 | 
			
		||||
            _validator = new FileQoSOptionsFluentValidator(provider);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThe(FileQoSOptions qosOptions)
 | 
			
		||||
        {
 | 
			
		||||
            _qosOptions = qosOptions;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIValidate()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _validator.Validate(_qosOptions);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,77 +1,77 @@
 | 
			
		||||
using FluentValidation.Results;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration.Validation
 | 
			
		||||
{
 | 
			
		||||
    public class HostAndPortValidatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private HostAndPortValidator _validator;
 | 
			
		||||
        private ValidationResult _result;
 | 
			
		||||
        private FileHostAndPort _hostAndPort;
 | 
			
		||||
 | 
			
		||||
        public HostAndPortValidatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _validator = new HostAndPortValidator();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData(null)]
 | 
			
		||||
        [InlineData("")]
 | 
			
		||||
        public void should_be_invalid_because_host_empty(string host)
 | 
			
		||||
        {
 | 
			
		||||
            var fileHostAndPort = new FileHostAndPort
 | 
			
		||||
            {
 | 
			
		||||
                Host = host
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileHostAndPort))
 | 
			
		||||
               .When(_ => WhenIValidate())
 | 
			
		||||
               .Then(_ => ThenTheResultIsInValid())
 | 
			
		||||
               .And(_ => ThenTheErorrIs())
 | 
			
		||||
               .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_because_host_set()
 | 
			
		||||
        {
 | 
			
		||||
            var fileHostAndPort = new FileHostAndPort
 | 
			
		||||
            {
 | 
			
		||||
                Host = "test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileHostAndPort))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThe(FileHostAndPort hostAndPort)
 | 
			
		||||
        {
 | 
			
		||||
            _hostAndPort = hostAndPort;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIValidate()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _validator.Validate(_hostAndPort);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErorrIs()
 | 
			
		||||
        {
 | 
			
		||||
            _result.Errors[0].ErrorMessage.ShouldBe("When not using service discovery Host must be set on DownstreamHostAndPorts if you are not using ReRoute.Host or Ocelot cannot find your service!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsInValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
using FluentValidation.Results;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration.Validation
 | 
			
		||||
{
 | 
			
		||||
    public class HostAndPortValidatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private HostAndPortValidator _validator;
 | 
			
		||||
        private ValidationResult _result;
 | 
			
		||||
        private FileHostAndPort _hostAndPort;
 | 
			
		||||
 | 
			
		||||
        public HostAndPortValidatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _validator = new HostAndPortValidator();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData(null)]
 | 
			
		||||
        [InlineData("")]
 | 
			
		||||
        public void should_be_invalid_because_host_empty(string host)
 | 
			
		||||
        {
 | 
			
		||||
            var fileHostAndPort = new FileHostAndPort
 | 
			
		||||
            {
 | 
			
		||||
                Host = host
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileHostAndPort))
 | 
			
		||||
               .When(_ => WhenIValidate())
 | 
			
		||||
               .Then(_ => ThenTheResultIsInValid())
 | 
			
		||||
               .And(_ => ThenTheErorrIs())
 | 
			
		||||
               .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_because_host_set()
 | 
			
		||||
        {
 | 
			
		||||
            var fileHostAndPort = new FileHostAndPort
 | 
			
		||||
            {
 | 
			
		||||
                Host = "test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileHostAndPort))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThe(FileHostAndPort hostAndPort)
 | 
			
		||||
        {
 | 
			
		||||
            _hostAndPort = hostAndPort;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIValidate()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _validator.Validate(_hostAndPort);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErorrIs()
 | 
			
		||||
        {
 | 
			
		||||
            _result.Errors[0].ErrorMessage.ShouldBe("When not using service discovery Host must be set on DownstreamHostAndPorts if you are not using Route.Host or Ocelot cannot find your service!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsInValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,433 +1,433 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration.Validation
 | 
			
		||||
{
 | 
			
		||||
    using FluentValidation.Results;
 | 
			
		||||
    using Microsoft.AspNetCore.Authentication;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
    using Ocelot.Configuration.Validator;
 | 
			
		||||
    using Ocelot.Requester;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class ReRouteFluentValidatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ReRouteFluentValidator _validator;
 | 
			
		||||
        private readonly Mock<IAuthenticationSchemeProvider> _authProvider;
 | 
			
		||||
        private QosDelegatingHandlerDelegate _qosDelegatingHandler;
 | 
			
		||||
        private Mock<IServiceProvider> _serviceProvider;
 | 
			
		||||
        private FileReRoute _reRoute;
 | 
			
		||||
        private ValidationResult _result;
 | 
			
		||||
 | 
			
		||||
        public ReRouteFluentValidatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _authProvider = new Mock<IAuthenticationSchemeProvider>();
 | 
			
		||||
            _serviceProvider = new Mock<IServiceProvider>();
 | 
			
		||||
            // Todo - replace with mocks
 | 
			
		||||
            _validator = new ReRouteFluentValidator(_authProvider.Object, new HostAndPortValidator(), new FileQoSOptionsFluentValidator(_serviceProvider.Object));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void downstream_path_template_should_not_be_empty()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute();
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Downstream Path Template cannot be empty"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void upstream_path_template_should_not_be_empty()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Upstream Path Template cannot be empty"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void downstream_path_template_should_start_with_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Downstream Path Template test doesnt start with forward slash"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void downstream_path_template_should_not_contain_double_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "//test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Downstream Path Template //test contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("https://test")]
 | 
			
		||||
        [InlineData("http://test")]
 | 
			
		||||
        [InlineData("/test/http://")]
 | 
			
		||||
        [InlineData("/test/https://")]
 | 
			
		||||
        public void downstream_path_template_should_not_contain_scheme(string downstreamPathTemplate)
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = downstreamPathTemplate
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains($"Downstream Path Template {downstreamPathTemplate} contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void upstream_path_template_should_start_with_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Upstream Path Template test doesnt start with forward slash"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void upstream_path_template_should_not_contain_double_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "//test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Upstream Path Template //test contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("https://test")]
 | 
			
		||||
        [InlineData("http://test")]
 | 
			
		||||
        [InlineData("/test/http://")]
 | 
			
		||||
        [InlineData("/test/https://")]
 | 
			
		||||
        public void upstream_path_template_should_not_contain_scheme(string upstreamPathTemplate)
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = upstreamPathTemplate
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains($"Upstream Path Template {upstreamPathTemplate} contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_be_valid_if_enable_rate_limiting_true_and_period_is_empty()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                RateLimitOptions = new FileRateLimitRule
 | 
			
		||||
                {
 | 
			
		||||
                    EnableRateLimiting = true
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("RateLimitOptions.Period is empty"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_be_valid_if_enable_rate_limiting_true_and_period_has_value()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                RateLimitOptions = new FileRateLimitRule
 | 
			
		||||
                {
 | 
			
		||||
                    EnableRateLimiting = true,
 | 
			
		||||
                    Period = "test"
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("RateLimitOptions.Period does not contain integer then s (second), m (minute), h (hour), d (day) e.g. 1m for 1 minute period"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_be_valid_if_specified_authentication_provider_isnt_registered()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                AuthenticationOptions = new FileAuthenticationOptions
 | 
			
		||||
                {
 | 
			
		||||
                    AuthenticationProviderKey = "JwtLads"
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains($"Authentication Options AuthenticationProviderKey:JwtLads,AllowedScopes:[] is unsupported authentication provider"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_be_valid_if_not_using_service_discovery_and_no_host_and_ports()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("When not using service discovery DownstreamHostAndPorts must be set and not empty or Ocelot cannot find your service!"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_if_using_service_discovery_and_no_host_and_ports()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                ServiceName = "Lads"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_re_route_using_host_and_port_and_paths()
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileHostAndPort
 | 
			
		||||
                    {
 | 
			
		||||
                        Host = "localhost",
 | 
			
		||||
                        Port = 5000
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_if_specified_authentication_provider_is_registered()
 | 
			
		||||
        {
 | 
			
		||||
            const string key = "JwtLads";
 | 
			
		||||
 | 
			
		||||
            var fileReRoute = new FileReRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                AuthenticationOptions = new FileAuthenticationOptions
 | 
			
		||||
                {
 | 
			
		||||
                    AuthenticationProviderKey = key
 | 
			
		||||
                },
 | 
			
		||||
                DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileHostAndPort
 | 
			
		||||
                    {
 | 
			
		||||
                        Host = "localhost",
 | 
			
		||||
                        Port = 5000
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileReRoute))
 | 
			
		||||
                .And(_ => GivenAnAuthProvider(key))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .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>
 | 
			
		||||
            {
 | 
			
		||||
                new AuthenticationScheme(key, key, typeof(FakeAutheHandler))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            _authProvider
 | 
			
		||||
                .Setup(x => x.GetAllSchemesAsync())
 | 
			
		||||
                .ReturnsAsync(schemes);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThe(FileReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIValidate()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _validator.Validate(_reRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsInvalid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorsContains(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            _result.Errors.ShouldContain(x => x.ErrorMessage == expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private class FakeAutheHandler : IAuthenticationHandler
 | 
			
		||||
        {
 | 
			
		||||
            public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
 | 
			
		||||
            {
 | 
			
		||||
                throw new System.NotImplementedException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public Task<AuthenticateResult> AuthenticateAsync()
 | 
			
		||||
            {
 | 
			
		||||
                throw new System.NotImplementedException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public Task ChallengeAsync(AuthenticationProperties properties)
 | 
			
		||||
            {
 | 
			
		||||
                throw new System.NotImplementedException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public Task ForbidAsync(AuthenticationProperties properties)
 | 
			
		||||
            {
 | 
			
		||||
                throw new System.NotImplementedException();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration.Validation
 | 
			
		||||
{
 | 
			
		||||
    using FluentValidation.Results;
 | 
			
		||||
    using Microsoft.AspNetCore.Authentication;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
    using Ocelot.Configuration.Validator;
 | 
			
		||||
    using Ocelot.Requester;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class RouteFluentValidatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly RouteFluentValidator _validator;
 | 
			
		||||
        private readonly Mock<IAuthenticationSchemeProvider> _authProvider;
 | 
			
		||||
        private QosDelegatingHandlerDelegate _qosDelegatingHandler;
 | 
			
		||||
        private Mock<IServiceProvider> _serviceProvider;
 | 
			
		||||
        private FileRoute _route;
 | 
			
		||||
        private ValidationResult _result;
 | 
			
		||||
 | 
			
		||||
        public RouteFluentValidatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _authProvider = new Mock<IAuthenticationSchemeProvider>();
 | 
			
		||||
            _serviceProvider = new Mock<IServiceProvider>();
 | 
			
		||||
            // Todo - replace with mocks
 | 
			
		||||
            _validator = new RouteFluentValidator(_authProvider.Object, new HostAndPortValidator(), new FileQoSOptionsFluentValidator(_serviceProvider.Object));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void downstream_path_template_should_not_be_empty()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute();
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Downstream Path Template cannot be empty"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void upstream_path_template_should_not_be_empty()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Upstream Path Template cannot be empty"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void downstream_path_template_should_start_with_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Downstream Path Template test doesnt start with forward slash"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void downstream_path_template_should_not_contain_double_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "//test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Downstream Path Template //test contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("https://test")]
 | 
			
		||||
        [InlineData("http://test")]
 | 
			
		||||
        [InlineData("/test/http://")]
 | 
			
		||||
        [InlineData("/test/https://")]
 | 
			
		||||
        public void downstream_path_template_should_not_contain_scheme(string downstreamPathTemplate)
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = downstreamPathTemplate
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains($"Downstream Path Template {downstreamPathTemplate} contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void upstream_path_template_should_start_with_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Upstream Path Template test doesnt start with forward slash"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void upstream_path_template_should_not_contain_double_forward_slash()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "//test"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("Upstream Path Template //test contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("https://test")]
 | 
			
		||||
        [InlineData("http://test")]
 | 
			
		||||
        [InlineData("/test/http://")]
 | 
			
		||||
        [InlineData("/test/https://")]
 | 
			
		||||
        public void upstream_path_template_should_not_contain_scheme(string upstreamPathTemplate)
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = upstreamPathTemplate
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains($"Upstream Path Template {upstreamPathTemplate} contains double forward slash, Ocelot does not support this at the moment. Please raise an issue in GitHib if you need this feature."))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_be_valid_if_enable_rate_limiting_true_and_period_is_empty()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                RateLimitOptions = new FileRateLimitRule
 | 
			
		||||
                {
 | 
			
		||||
                    EnableRateLimiting = true
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("RateLimitOptions.Period is empty"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_be_valid_if_enable_rate_limiting_true_and_period_has_value()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                RateLimitOptions = new FileRateLimitRule
 | 
			
		||||
                {
 | 
			
		||||
                    EnableRateLimiting = true,
 | 
			
		||||
                    Period = "test"
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("RateLimitOptions.Period does not contain integer then s (second), m (minute), h (hour), d (day) e.g. 1m for 1 minute period"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_be_valid_if_specified_authentication_provider_isnt_registered()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                AuthenticationOptions = new FileAuthenticationOptions
 | 
			
		||||
                {
 | 
			
		||||
                    AuthenticationProviderKey = "JwtLads"
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains($"Authentication Options AuthenticationProviderKey:JwtLads,AllowedScopes:[] is unsupported authentication provider"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_be_valid_if_not_using_service_discovery_and_no_host_and_ports()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsInvalid())
 | 
			
		||||
                .And(_ => ThenTheErrorsContains("When not using service discovery DownstreamHostAndPorts must be set and not empty or Ocelot cannot find your service!"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_if_using_service_discovery_and_no_host_and_ports()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                ServiceName = "Lads"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_re_route_using_host_and_port_and_paths()
 | 
			
		||||
        {
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileHostAndPort
 | 
			
		||||
                    {
 | 
			
		||||
                        Host = "localhost",
 | 
			
		||||
                        Port = 5000
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_valid_if_specified_authentication_provider_is_registered()
 | 
			
		||||
        {
 | 
			
		||||
            const string key = "JwtLads";
 | 
			
		||||
 | 
			
		||||
            var fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                AuthenticationOptions = new FileAuthenticationOptions
 | 
			
		||||
                {
 | 
			
		||||
                    AuthenticationProviderKey = key
 | 
			
		||||
                },
 | 
			
		||||
                DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileHostAndPort
 | 
			
		||||
                    {
 | 
			
		||||
                        Host = "localhost",
 | 
			
		||||
                        Port = 5000
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .And(_ => GivenAnAuthProvider(key))
 | 
			
		||||
                .When(_ => WhenIValidate())
 | 
			
		||||
                .Then(_ => ThenTheResultIsValid())
 | 
			
		||||
                .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 fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileHostAndPort
 | 
			
		||||
                    {
 | 
			
		||||
                        Host = "localhost",
 | 
			
		||||
                        Port = 5000,
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                DownstreamHttpVersion = version,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .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 fileRoute = new FileRoute
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamPathTemplate = "/test",
 | 
			
		||||
                UpstreamPathTemplate = "/test",
 | 
			
		||||
                DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                {
 | 
			
		||||
                    new FileHostAndPort
 | 
			
		||||
                    {
 | 
			
		||||
                        Host = "localhost",
 | 
			
		||||
                        Port = 5000,
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
                DownstreamHttpVersion = version,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenThe(fileRoute))
 | 
			
		||||
                .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>
 | 
			
		||||
            {
 | 
			
		||||
                new AuthenticationScheme(key, key, typeof(FakeAutheHandler))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            _authProvider
 | 
			
		||||
                .Setup(x => x.GetAllSchemesAsync())
 | 
			
		||||
                .ReturnsAsync(schemes);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsValid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThe(FileRoute route)
 | 
			
		||||
        {
 | 
			
		||||
            _route = route;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIValidate()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _validator.Validate(_route);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResultIsInvalid()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsValid.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorsContains(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            _result.Errors.ShouldContain(x => x.ErrorMessage == expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private class FakeAutheHandler : IAuthenticationHandler
 | 
			
		||||
        {
 | 
			
		||||
            public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
 | 
			
		||||
            {
 | 
			
		||||
                throw new System.NotImplementedException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public Task<AuthenticateResult> AuthenticateAsync()
 | 
			
		||||
            {
 | 
			
		||||
                throw new System.NotImplementedException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public Task ChallengeAsync(AuthenticationProperties properties)
 | 
			
		||||
            {
 | 
			
		||||
                throw new System.NotImplementedException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public Task ForbidAsync(AuthenticationProperties properties)
 | 
			
		||||
            {
 | 
			
		||||
                throw new System.NotImplementedException();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user