Rename all ReRoute to Route to move closer to YARP +semver: breaking

This commit is contained in:
Tom Pallister
2020-05-23 20:50:05 +01:00
committed by GitHub
parent fe3e8bd23a
commit 3439be8927
269 changed files with 23591 additions and 23605 deletions

View File

@ -1,164 +1,164 @@
namespace Ocelot.UnitTests.Configuration
{
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using System.Net.Http;
using TestStack.BDDfy;
using Values;
using Xunit;
public class AggregatesCreatorTests
{
private readonly AggregatesCreator _creator;
private readonly Mock<IUpstreamTemplatePatternCreator> _utpCreator;
private FileConfiguration _fileConfiguration;
private List<ReRoute> _reRoutes;
private List<ReRoute> _result;
private UpstreamPathTemplate _aggregate1Utp;
private UpstreamPathTemplate _aggregate2Utp;
public AggregatesCreatorTests()
{
_utpCreator = new Mock<IUpstreamTemplatePatternCreator>();
_creator = new AggregatesCreator(_utpCreator.Object);
}
[Fact]
public void should_return_no_aggregates()
{
var fileConfig = new FileConfiguration
{
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
ReRouteKeys = new List<string>{"key1"}
}
}
};
var reRoutes = new List<ReRoute>();
this.Given(_ => GivenThe(fileConfig))
.And(_ => GivenThe(reRoutes))
.When(_ => WhenICreate())
.Then(_ => TheUtpCreatorIsNotCalled())
.And(_ => ThenTheResultIsNotNull())
.And(_ => ThenTheResultIsEmpty())
.BDDfy();
}
[Fact]
public void should_create_aggregates()
{
var fileConfig = new FileConfiguration
{
Aggregates = new List<FileAggregateReRoute>
{
new FileAggregateReRoute
{
ReRouteKeys = new List<string>{"key1", "key2"},
UpstreamHost = "hosty",
UpstreamPathTemplate = "templatey",
Aggregator = "aggregatory",
ReRouteIsCaseSensitive = true
},
new FileAggregateReRoute
{
ReRouteKeys = new List<string>{"key3", "key4"},
UpstreamHost = "hosty",
UpstreamPathTemplate = "templatey",
Aggregator = "aggregatory",
ReRouteIsCaseSensitive = true
}
}
};
var reRoutes = new List<ReRoute>
{
new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().WithKey("key1").Build()).Build(),
new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().WithKey("key2").Build()).Build(),
new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().WithKey("key3").Build()).Build(),
new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().WithKey("key4").Build()).Build()
};
this.Given(_ => GivenThe(fileConfig))
.And(_ => GivenThe(reRoutes))
.And(_ => GivenTheUtpCreatorReturns())
.When(_ => WhenICreate())
.Then(_ => ThenTheUtpCreatorIsCalledCorrectly())
.And(_ => ThenTheAggregatesAreCreated())
.BDDfy();
}
private void ThenTheAggregatesAreCreated()
{
_result.ShouldNotBeNull();
_result.Count.ShouldBe(2);
_result[0].UpstreamHttpMethod.ShouldContain(x => x == HttpMethod.Get);
_result[0].UpstreamHost.ShouldBe(_fileConfiguration.Aggregates[0].UpstreamHost);
_result[0].UpstreamTemplatePattern.ShouldBe(_aggregate1Utp);
_result[0].Aggregator.ShouldBe(_fileConfiguration.Aggregates[0].Aggregator);
_result[0].DownstreamReRoute.ShouldContain(x => x == _reRoutes[0].DownstreamReRoute[0]);
_result[0].DownstreamReRoute.ShouldContain(x => x == _reRoutes[1].DownstreamReRoute[0]);
_result[1].UpstreamHttpMethod.ShouldContain(x => x == HttpMethod.Get);
_result[1].UpstreamHost.ShouldBe(_fileConfiguration.Aggregates[1].UpstreamHost);
_result[1].UpstreamTemplatePattern.ShouldBe(_aggregate2Utp);
_result[1].Aggregator.ShouldBe(_fileConfiguration.Aggregates[1].Aggregator);
_result[1].DownstreamReRoute.ShouldContain(x => x == _reRoutes[2].DownstreamReRoute[0]);
_result[1].DownstreamReRoute.ShouldContain(x => x == _reRoutes[3].DownstreamReRoute[0]);
}
private void ThenTheUtpCreatorIsCalledCorrectly()
{
_utpCreator.Verify(x => x.Create(_fileConfiguration.Aggregates[0]), Times.Once);
_utpCreator.Verify(x => x.Create(_fileConfiguration.Aggregates[1]), Times.Once);
}
private void GivenTheUtpCreatorReturns()
{
_aggregate1Utp = new UpstreamPathTemplateBuilder().Build();
_aggregate2Utp = new UpstreamPathTemplateBuilder().Build();
_utpCreator.SetupSequence(x => x.Create(It.IsAny<IReRoute>()))
.Returns(_aggregate1Utp)
.Returns(_aggregate2Utp);
}
private void ThenTheResultIsEmpty()
{
_result.Count.ShouldBe(0);
}
private void ThenTheResultIsNotNull()
{
_result.ShouldNotBeNull();
}
private void TheUtpCreatorIsNotCalled()
{
_utpCreator.Verify(x => x.Create(It.IsAny<FileAggregateReRoute>()), Times.Never);
}
private void GivenThe(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;
}
private void GivenThe(List<ReRoute> reRoutes)
{
_reRoutes = reRoutes;
}
private void WhenICreate()
{
_result = _creator.Create(_fileConfiguration, _reRoutes);
}
}
}
namespace Ocelot.UnitTests.Configuration
{
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using System.Net.Http;
using TestStack.BDDfy;
using Values;
using Xunit;
public class AggregatesCreatorTests
{
private readonly AggregatesCreator _creator;
private readonly Mock<IUpstreamTemplatePatternCreator> _utpCreator;
private FileConfiguration _fileConfiguration;
private List<Route> _routes;
private List<Route> _result;
private UpstreamPathTemplate _aggregate1Utp;
private UpstreamPathTemplate _aggregate2Utp;
public AggregatesCreatorTests()
{
_utpCreator = new Mock<IUpstreamTemplatePatternCreator>();
_creator = new AggregatesCreator(_utpCreator.Object);
}
[Fact]
public void should_return_no_aggregates()
{
var fileConfig = new FileConfiguration
{
Aggregates = new List<FileAggregateRoute>
{
new FileAggregateRoute
{
RouteKeys = new List<string>{"key1"}
}
}
};
var routes = new List<Route>();
this.Given(_ => GivenThe(fileConfig))
.And(_ => GivenThe(routes))
.When(_ => WhenICreate())
.Then(_ => TheUtpCreatorIsNotCalled())
.And(_ => ThenTheResultIsNotNull())
.And(_ => ThenTheResultIsEmpty())
.BDDfy();
}
[Fact]
public void should_create_aggregates()
{
var fileConfig = new FileConfiguration
{
Aggregates = new List<FileAggregateRoute>
{
new FileAggregateRoute
{
RouteKeys = new List<string>{"key1", "key2"},
UpstreamHost = "hosty",
UpstreamPathTemplate = "templatey",
Aggregator = "aggregatory",
RouteIsCaseSensitive = true
},
new FileAggregateRoute
{
RouteKeys = new List<string>{"key3", "key4"},
UpstreamHost = "hosty",
UpstreamPathTemplate = "templatey",
Aggregator = "aggregatory",
RouteIsCaseSensitive = true
}
}
};
var routes = new List<Route>
{
new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().WithKey("key1").Build()).Build(),
new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().WithKey("key2").Build()).Build(),
new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().WithKey("key3").Build()).Build(),
new RouteBuilder().WithDownstreamRoute(new DownstreamRouteBuilder().WithKey("key4").Build()).Build()
};
this.Given(_ => GivenThe(fileConfig))
.And(_ => GivenThe(routes))
.And(_ => GivenTheUtpCreatorReturns())
.When(_ => WhenICreate())
.Then(_ => ThenTheUtpCreatorIsCalledCorrectly())
.And(_ => ThenTheAggregatesAreCreated())
.BDDfy();
}
private void ThenTheAggregatesAreCreated()
{
_result.ShouldNotBeNull();
_result.Count.ShouldBe(2);
_result[0].UpstreamHttpMethod.ShouldContain(x => x == HttpMethod.Get);
_result[0].UpstreamHost.ShouldBe(_fileConfiguration.Aggregates[0].UpstreamHost);
_result[0].UpstreamTemplatePattern.ShouldBe(_aggregate1Utp);
_result[0].Aggregator.ShouldBe(_fileConfiguration.Aggregates[0].Aggregator);
_result[0].DownstreamRoute.ShouldContain(x => x == _routes[0].DownstreamRoute[0]);
_result[0].DownstreamRoute.ShouldContain(x => x == _routes[1].DownstreamRoute[0]);
_result[1].UpstreamHttpMethod.ShouldContain(x => x == HttpMethod.Get);
_result[1].UpstreamHost.ShouldBe(_fileConfiguration.Aggregates[1].UpstreamHost);
_result[1].UpstreamTemplatePattern.ShouldBe(_aggregate2Utp);
_result[1].Aggregator.ShouldBe(_fileConfiguration.Aggregates[1].Aggregator);
_result[1].DownstreamRoute.ShouldContain(x => x == _routes[2].DownstreamRoute[0]);
_result[1].DownstreamRoute.ShouldContain(x => x == _routes[3].DownstreamRoute[0]);
}
private void ThenTheUtpCreatorIsCalledCorrectly()
{
_utpCreator.Verify(x => x.Create(_fileConfiguration.Aggregates[0]), Times.Once);
_utpCreator.Verify(x => x.Create(_fileConfiguration.Aggregates[1]), Times.Once);
}
private void GivenTheUtpCreatorReturns()
{
_aggregate1Utp = new UpstreamPathTemplateBuilder().Build();
_aggregate2Utp = new UpstreamPathTemplateBuilder().Build();
_utpCreator.SetupSequence(x => x.Create(It.IsAny<IRoute>()))
.Returns(_aggregate1Utp)
.Returns(_aggregate2Utp);
}
private void ThenTheResultIsEmpty()
{
_result.Count.ShouldBe(0);
}
private void ThenTheResultIsNotNull()
{
_result.ShouldNotBeNull();
}
private void TheUtpCreatorIsNotCalled()
{
_utpCreator.Verify(x => x.Create(It.IsAny<FileAggregateRoute>()), Times.Never);
}
private void GivenThe(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;
}
private void GivenThe(List<Route> routes)
{
_routes = routes;
}
private void WhenICreate()
{
_result = _creator.Create(_fileConfiguration, _routes);
}
}
}

View File

@ -1,62 +1,62 @@
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class AuthenticationOptionsCreatorTests
{
private readonly AuthenticationOptionsCreator _authOptionsCreator;
private FileReRoute _fileReRoute;
private AuthenticationOptions _result;
public AuthenticationOptionsCreatorTests()
{
_authOptionsCreator = new AuthenticationOptionsCreator();
}
[Fact]
public void should_return_auth_options()
{
var fileReRoute = new FileReRoute()
{
AuthenticationOptions = new FileAuthenticationOptions
{
AuthenticationProviderKey = "Test",
AllowedScopes = new List<string> { "cheese" },
}
};
var expected = new AuthenticationOptionsBuilder()
.WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
.WithAuthenticationProviderKey("Test")
.Build();
this.Given(x => x.GivenTheFollowing(fileReRoute))
.When(x => x.WhenICreateTheAuthenticationOptions())
.Then(x => x.ThenTheFollowingConfigIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowing(FileReRoute fileReRoute)
{
_fileReRoute = fileReRoute;
}
private void WhenICreateTheAuthenticationOptions()
{
_result = _authOptionsCreator.Create(_fileReRoute);
}
private void ThenTheFollowingConfigIsReturned(AuthenticationOptions expected)
namespace Ocelot.UnitTests.Configuration
{
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class AuthenticationOptionsCreatorTests
{
private readonly AuthenticationOptionsCreator _authOptionsCreator;
private FileRoute _fileRoute;
private AuthenticationOptions _result;
public AuthenticationOptionsCreatorTests()
{
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
_result.AuthenticationProviderKey.ShouldBe(expected.AuthenticationProviderKey);
}
}
_authOptionsCreator = new AuthenticationOptionsCreator();
}
[Fact]
public void should_return_auth_options()
{
var fileRoute = new FileRoute()
{
AuthenticationOptions = new FileAuthenticationOptions
{
AuthenticationProviderKey = "Test",
AllowedScopes = new List<string> { "cheese" },
}
};
var expected = new AuthenticationOptionsBuilder()
.WithAllowedScopes(fileRoute.AuthenticationOptions?.AllowedScopes)
.WithAuthenticationProviderKey("Test")
.Build();
this.Given(x => x.GivenTheFollowing(fileRoute))
.When(x => x.WhenICreateTheAuthenticationOptions())
.Then(x => x.ThenTheFollowingConfigIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowing(FileRoute fileRoute)
{
_fileRoute = fileRoute;
}
private void WhenICreateTheAuthenticationOptions()
{
_result = _authOptionsCreator.Create(_fileRoute);
}
private void ThenTheFollowingConfigIsReturned(AuthenticationOptions expected)
{
_result.AllowedScopes.ShouldBe(expected.AllowedScopes);
_result.AuthenticationProviderKey.ShouldBe(expected.AuthenticationProviderKey);
}
}
}

View File

@ -1,126 +1,126 @@
namespace Ocelot.UnitTests.Configuration
{
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.DependencyInjection;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class ConfigurationCreatorTests
{
private ConfigurationCreator _creator;
private InternalConfiguration _result;
private readonly Mock<IServiceProviderConfigurationCreator> _spcCreator;
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;
private LoadBalancerOptions _lbo;
private QoSOptions _qoso;
private HttpHandlerOptions _hho;
private AdministrationPath _adminPath;
private readonly ServiceCollection _serviceCollection;
public ConfigurationCreatorTests()
{
_vCreator = new Mock<IVersionCreator>();
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
_qosCreator = new Mock<IQoSOptionsCreator>();
_spcCreator = new Mock<IServiceProviderConfigurationCreator>();
_serviceCollection = new ServiceCollection();
}
[Fact]
public void should_build_configuration_with_no_admin_path()
{
this.Given(_ => GivenTheDependenciesAreSetUp())
.When(_ => WhenICreate())
.Then(_ => ThenTheDepdenciesAreCalledCorrectly())
.And(_ => ThenThePropertiesAreSetCorrectly())
.And(_ => ThenTheAdminPathIsNull())
.BDDfy();
}
[Fact]
public void should_build_configuration_with_admin_path()
{
this.Given(_ => GivenTheDependenciesAreSetUp())
.And(_ => GivenTheAdminPath())
.When(_ => WhenICreate())
.Then(_ => ThenTheDepdenciesAreCalledCorrectly())
.And(_ => ThenThePropertiesAreSetCorrectly())
.And(_ => ThenTheAdminPathIsSet())
.BDDfy();
}
private void ThenTheAdminPathIsNull()
{
_result.AdministrationPath.ShouldBeNull();
}
private void ThenThePropertiesAreSetCorrectly()
{
_result.ShouldNotBeNull();
_result.ServiceProviderConfiguration.ShouldBe(_spc);
_result.LoadBalancerOptions.ShouldBe(_lbo);
_result.QoSOptions.ShouldBe(_qoso);
_result.HttpHandlerOptions.ShouldBe(_hho);
_result.ReRoutes.ShouldBe(_reRoutes);
_result.RequestId.ShouldBe(_fileConfig.GlobalConfiguration.RequestIdKey);
_result.DownstreamScheme.ShouldBe(_fileConfig.GlobalConfiguration.DownstreamScheme);
}
private void ThenTheAdminPathIsSet()
{
_result.AdministrationPath.ShouldBe("wooty");
}
private void ThenTheDepdenciesAreCalledCorrectly()
{
_spcCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration), Times.Once);
_lboCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.LoadBalancerOptions), Times.Once);
_qosCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.QoSOptions), Times.Once);
_hhoCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.HttpHandlerOptions), Times.Once);
}
private void GivenTheAdminPath()
{
_adminPath = new AdministrationPath("wooty");
_serviceCollection.AddSingleton<IAdministrationPath>(_adminPath);
}
private void GivenTheDependenciesAreSetUp()
{
_fileConfig = new FileConfiguration
{
GlobalConfiguration = new FileGlobalConfiguration()
};
_reRoutes = new List<ReRoute>();
_spc = new ServiceProviderConfiguration("", "", "", 1, "", "", 1);
_lbo = new LoadBalancerOptionsBuilder().Build();
_qoso = new QoSOptions(1, 1, 1, "");
_hho = new HttpHandlerOptionsBuilder().Build();
_spcCreator.Setup(x => x.Create(It.IsAny<FileGlobalConfiguration>())).Returns(_spc);
_lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
_qosCreator.Setup(x => x.Create(It.IsAny<FileQoSOptions>())).Returns(_qoso);
_hhoCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>())).Returns(_hho);
}
private void WhenICreate()
{
var serviceProvider = _serviceCollection.BuildServiceProvider();
_creator = new ConfigurationCreator(_spcCreator.Object, _qosCreator.Object, _hhoCreator.Object, serviceProvider, _lboCreator.Object, _vCreator.Object);
_result = _creator.Create(_fileConfig, _reRoutes);
}
}
}
namespace Ocelot.UnitTests.Configuration
{
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.DependencyInjection;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class ConfigurationCreatorTests
{
private ConfigurationCreator _creator;
private InternalConfiguration _result;
private readonly Mock<IServiceProviderConfigurationCreator> _spcCreator;
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<Route> _routes;
private ServiceProviderConfiguration _spc;
private LoadBalancerOptions _lbo;
private QoSOptions _qoso;
private HttpHandlerOptions _hho;
private AdministrationPath _adminPath;
private readonly ServiceCollection _serviceCollection;
public ConfigurationCreatorTests()
{
_vCreator = new Mock<IVersionCreator>();
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
_qosCreator = new Mock<IQoSOptionsCreator>();
_spcCreator = new Mock<IServiceProviderConfigurationCreator>();
_serviceCollection = new ServiceCollection();
}
[Fact]
public void should_build_configuration_with_no_admin_path()
{
this.Given(_ => GivenTheDependenciesAreSetUp())
.When(_ => WhenICreate())
.Then(_ => ThenTheDepdenciesAreCalledCorrectly())
.And(_ => ThenThePropertiesAreSetCorrectly())
.And(_ => ThenTheAdminPathIsNull())
.BDDfy();
}
[Fact]
public void should_build_configuration_with_admin_path()
{
this.Given(_ => GivenTheDependenciesAreSetUp())
.And(_ => GivenTheAdminPath())
.When(_ => WhenICreate())
.Then(_ => ThenTheDepdenciesAreCalledCorrectly())
.And(_ => ThenThePropertiesAreSetCorrectly())
.And(_ => ThenTheAdminPathIsSet())
.BDDfy();
}
private void ThenTheAdminPathIsNull()
{
_result.AdministrationPath.ShouldBeNull();
}
private void ThenThePropertiesAreSetCorrectly()
{
_result.ShouldNotBeNull();
_result.ServiceProviderConfiguration.ShouldBe(_spc);
_result.LoadBalancerOptions.ShouldBe(_lbo);
_result.QoSOptions.ShouldBe(_qoso);
_result.HttpHandlerOptions.ShouldBe(_hho);
_result.Routes.ShouldBe(_routes);
_result.RequestId.ShouldBe(_fileConfig.GlobalConfiguration.RequestIdKey);
_result.DownstreamScheme.ShouldBe(_fileConfig.GlobalConfiguration.DownstreamScheme);
}
private void ThenTheAdminPathIsSet()
{
_result.AdministrationPath.ShouldBe("wooty");
}
private void ThenTheDepdenciesAreCalledCorrectly()
{
_spcCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration), Times.Once);
_lboCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.LoadBalancerOptions), Times.Once);
_qosCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.QoSOptions), Times.Once);
_hhoCreator.Verify(x => x.Create(_fileConfig.GlobalConfiguration.HttpHandlerOptions), Times.Once);
}
private void GivenTheAdminPath()
{
_adminPath = new AdministrationPath("wooty");
_serviceCollection.AddSingleton<IAdministrationPath>(_adminPath);
}
private void GivenTheDependenciesAreSetUp()
{
_fileConfig = new FileConfiguration
{
GlobalConfiguration = new FileGlobalConfiguration()
};
_routes = new List<Route>();
_spc = new ServiceProviderConfiguration("", "", "", 1, "", "", 1);
_lbo = new LoadBalancerOptionsBuilder().Build();
_qoso = new QoSOptions(1, 1, 1, "");
_hho = new HttpHandlerOptionsBuilder().Build();
_spcCreator.Setup(x => x.Create(It.IsAny<FileGlobalConfiguration>())).Returns(_spc);
_lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
_qosCreator.Setup(x => x.Create(It.IsAny<FileQoSOptions>())).Returns(_qoso);
_hhoCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>())).Returns(_hho);
}
private void WhenICreate()
{
var serviceProvider = _serviceCollection.BuildServiceProvider();
_creator = new ConfigurationCreator(_spcCreator.Object, _qosCreator.Object, _hhoCreator.Object, serviceProvider, _lboCreator.Object, _vCreator.Object);
_result = _creator.Create(_fileConfig, _routes);
}
}
}

View File

@ -1,302 +1,302 @@
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;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using TestStack.BDDfy;
using Xunit;
public class DiskFileConfigurationRepositoryTests : IDisposable
{
private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource;
private IFileConfigurationRepository _repo;
private string _environmentSpecificPath;
private string _ocelotJsonPath;
private FileConfiguration _result;
private FileConfiguration _fileConfiguration;
// This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
// cant pick it up if they run in parralel..and the semaphore stops them running at the same time...sigh
// these are not really unit tests but whatever...
private string _environmentName = "DEV.DEV";
private static SemaphoreSlim _semaphore;
public DiskFileConfigurationRepositoryTests()
{
_semaphore = new SemaphoreSlim(1, 1);
_semaphore.Wait();
_hostingEnvironment = new Mock<IWebHostEnvironment>();
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict);
_changeTokenSource.Setup(m => m.Activate());
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
}
[Fact]
public void should_return_file_configuration()
{
var config = FakeFileConfigurationForGet();
this.Given(_ => GivenTheConfigurationIs(config))
.When(_ => WhenIGetTheReRoutes())
.Then(_ => ThenTheFollowingIsReturned(config))
.BDDfy();
}
[Fact]
public void should_return_file_configuration_if_environment_name_is_unavailable()
{
var config = FakeFileConfigurationForGet();
this.Given(_ => GivenTheEnvironmentNameIsUnavailable())
.And(_ => GivenTheConfigurationIs(config))
.When(_ => WhenIGetTheReRoutes())
.Then(_ => ThenTheFollowingIsReturned(config))
.BDDfy();
}
[Fact]
public void should_set_file_configuration()
{
var config = FakeFileConfigurationForSet();
this.Given(_ => GivenIHaveAConfiguration(config))
.When(_ => WhenISetTheConfiguration())
.Then(_ => ThenTheConfigurationIsStoredAs(config))
.And(_ => ThenTheConfigurationJsonIsIndented(config))
.And(x => AndTheChangeTokenIsActivated())
.BDDfy();
}
[Fact]
public void should_set_file_configuration_if_environment_name_is_unavailable()
{
var config = FakeFileConfigurationForSet();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenTheEnvironmentNameIsUnavailable())
.When(_ => WhenISetTheConfiguration())
.Then(_ => ThenTheConfigurationIsStoredAs(config))
.And(_ => ThenTheConfigurationJsonIsIndented(config))
.BDDfy();
}
[Fact]
public void should_set_environment_file_configuration_and_ocelot_file_configuration()
{
var config = FakeFileConfigurationForSet();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenTheConfigurationIs(config))
.And(_ => GivenTheUserAddedOcelotJson())
.When(_ => WhenISetTheConfiguration())
.Then(_ => ThenTheConfigurationIsStoredAs(config))
.And(_ => ThenTheConfigurationJsonIsIndented(config))
.Then(_ => ThenTheOcelotJsonIsStoredAs(config))
.BDDfy();
}
private void GivenTheUserAddedOcelotJson()
{
_ocelotJsonPath = $"{AppContext.BaseDirectory}/ocelot.json";
if (File.Exists(_ocelotJsonPath))
{
File.Delete(_ocelotJsonPath);
}
File.WriteAllText(_ocelotJsonPath, "Doesnt matter");
}
private void GivenTheEnvironmentNameIsUnavailable()
{
_environmentName = null;
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
}
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;
}
private void WhenISetTheConfiguration()
{
_repo.Set(_fileConfiguration);
_result = _repo.Get().Result.Data;
}
private void ThenTheConfigurationIsStoredAs(FileConfiguration expecteds)
{
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
for (var i = 0; i < _result.ReRoutes.Count; i++)
{
for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
{
var result = _result.ReRoutes[i].DownstreamHostAndPorts[j];
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
result.Host.ShouldBe(expected.Host);
result.Port.ShouldBe(expected.Port);
}
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
}
}
private void ThenTheOcelotJsonIsStoredAs(FileConfiguration expecteds)
{
var resultText = File.ReadAllText(_ocelotJsonPath);
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
resultText.ShouldBe(expectedText);
}
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
{
_environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
if (File.Exists(_environmentSpecificPath))
{
File.Delete(_environmentSpecificPath);
}
File.WriteAllText(_environmentSpecificPath, jsonConfiguration);
}
private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
{
var path = !string.IsNullOrEmpty(_environmentSpecificPath) ? _environmentSpecificPath : _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
var resultText = File.ReadAllText(path);
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
resultText.ShouldBe(expectedText);
}
private void WhenIGetTheReRoutes()
{
_result = _repo.Get().Result.Data;
}
private void ThenTheFollowingIsReturned(FileConfiguration expecteds)
{
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
for (var i = 0; i < _result.ReRoutes.Count; i++)
{
for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
{
var result = _result.ReRoutes[i].DownstreamHostAndPorts[j];
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
result.Host.ShouldBe(expected.Host);
result.Port.ShouldBe(expected.Port);
}
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
}
}
private void AndTheChangeTokenIsActivated()
{
_changeTokenSource.Verify(m => m.Activate(), Times.Once);
}
private FileConfiguration FakeFileConfigurationForSet()
{
var reRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "123.12.12.12",
Port = 80,
},
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/asdfs/test/{test}",
},
};
var globalConfiguration = new FileGlobalConfiguration
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
{
Scheme = "https",
Port = 198,
Host = "blah"
}
};
return new FileConfiguration
{
GlobalConfiguration = globalConfiguration,
ReRoutes = reRoutes
};
}
private FileConfiguration FakeFileConfigurationForGet()
{
var reRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 80,
}
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/test/test/{test}"
}
};
var globalConfiguration = new FileGlobalConfiguration
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
{
Scheme = "https",
Port = 198,
Host = "blah"
}
};
return new FileConfiguration
{
GlobalConfiguration = globalConfiguration,
ReRoutes = reRoutes
};
}
public void Dispose()
{
_semaphore.Release();
}
}
}
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;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using TestStack.BDDfy;
using Xunit;
public class DiskFileConfigurationRepositoryTests : IDisposable
{
private readonly Mock<IWebHostEnvironment> _hostingEnvironment;
private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource;
private IFileConfigurationRepository _repo;
private string _environmentSpecificPath;
private string _ocelotJsonPath;
private FileConfiguration _result;
private FileConfiguration _fileConfiguration;
// This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
// cant pick it up if they run in parralel..and the semaphore stops them running at the same time...sigh
// these are not really unit tests but whatever...
private string _environmentName = "DEV.DEV";
private static SemaphoreSlim _semaphore;
public DiskFileConfigurationRepositoryTests()
{
_semaphore = new SemaphoreSlim(1, 1);
_semaphore.Wait();
_hostingEnvironment = new Mock<IWebHostEnvironment>();
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict);
_changeTokenSource.Setup(m => m.Activate());
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
}
[Fact]
public void should_return_file_configuration()
{
var config = FakeFileConfigurationForGet();
this.Given(_ => GivenTheConfigurationIs(config))
.When(_ => WhenIGetTheRoutes())
.Then(_ => ThenTheFollowingIsReturned(config))
.BDDfy();
}
[Fact]
public void should_return_file_configuration_if_environment_name_is_unavailable()
{
var config = FakeFileConfigurationForGet();
this.Given(_ => GivenTheEnvironmentNameIsUnavailable())
.And(_ => GivenTheConfigurationIs(config))
.When(_ => WhenIGetTheRoutes())
.Then(_ => ThenTheFollowingIsReturned(config))
.BDDfy();
}
[Fact]
public void should_set_file_configuration()
{
var config = FakeFileConfigurationForSet();
this.Given(_ => GivenIHaveAConfiguration(config))
.When(_ => WhenISetTheConfiguration())
.Then(_ => ThenTheConfigurationIsStoredAs(config))
.And(_ => ThenTheConfigurationJsonIsIndented(config))
.And(x => AndTheChangeTokenIsActivated())
.BDDfy();
}
[Fact]
public void should_set_file_configuration_if_environment_name_is_unavailable()
{
var config = FakeFileConfigurationForSet();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenTheEnvironmentNameIsUnavailable())
.When(_ => WhenISetTheConfiguration())
.Then(_ => ThenTheConfigurationIsStoredAs(config))
.And(_ => ThenTheConfigurationJsonIsIndented(config))
.BDDfy();
}
[Fact]
public void should_set_environment_file_configuration_and_ocelot_file_configuration()
{
var config = FakeFileConfigurationForSet();
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenTheConfigurationIs(config))
.And(_ => GivenTheUserAddedOcelotJson())
.When(_ => WhenISetTheConfiguration())
.Then(_ => ThenTheConfigurationIsStoredAs(config))
.And(_ => ThenTheConfigurationJsonIsIndented(config))
.Then(_ => ThenTheOcelotJsonIsStoredAs(config))
.BDDfy();
}
private void GivenTheUserAddedOcelotJson()
{
_ocelotJsonPath = $"{AppContext.BaseDirectory}/ocelot.json";
if (File.Exists(_ocelotJsonPath))
{
File.Delete(_ocelotJsonPath);
}
File.WriteAllText(_ocelotJsonPath, "Doesnt matter");
}
private void GivenTheEnvironmentNameIsUnavailable()
{
_environmentName = null;
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object);
}
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;
}
private void WhenISetTheConfiguration()
{
_repo.Set(_fileConfiguration);
_result = _repo.Get().Result.Data;
}
private void ThenTheConfigurationIsStoredAs(FileConfiguration expecteds)
{
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
for (var i = 0; i < _result.Routes.Count; i++)
{
for (int j = 0; j < _result.Routes[i].DownstreamHostAndPorts.Count; j++)
{
var result = _result.Routes[i].DownstreamHostAndPorts[j];
var expected = expecteds.Routes[i].DownstreamHostAndPorts[j];
result.Host.ShouldBe(expected.Host);
result.Port.ShouldBe(expected.Port);
}
_result.Routes[i].DownstreamPathTemplate.ShouldBe(expecteds.Routes[i].DownstreamPathTemplate);
_result.Routes[i].DownstreamScheme.ShouldBe(expecteds.Routes[i].DownstreamScheme);
}
}
private void ThenTheOcelotJsonIsStoredAs(FileConfiguration expecteds)
{
var resultText = File.ReadAllText(_ocelotJsonPath);
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
resultText.ShouldBe(expectedText);
}
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
{
_environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
if (File.Exists(_environmentSpecificPath))
{
File.Delete(_environmentSpecificPath);
}
File.WriteAllText(_environmentSpecificPath, jsonConfiguration);
}
private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
{
var path = !string.IsNullOrEmpty(_environmentSpecificPath) ? _environmentSpecificPath : _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
var resultText = File.ReadAllText(path);
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
resultText.ShouldBe(expectedText);
}
private void WhenIGetTheRoutes()
{
_result = _repo.Get().Result.Data;
}
private void ThenTheFollowingIsReturned(FileConfiguration expecteds)
{
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Scheme.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Scheme);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
for (var i = 0; i < _result.Routes.Count; i++)
{
for (int j = 0; j < _result.Routes[i].DownstreamHostAndPorts.Count; j++)
{
var result = _result.Routes[i].DownstreamHostAndPorts[j];
var expected = expecteds.Routes[i].DownstreamHostAndPorts[j];
result.Host.ShouldBe(expected.Host);
result.Port.ShouldBe(expected.Port);
}
_result.Routes[i].DownstreamPathTemplate.ShouldBe(expecteds.Routes[i].DownstreamPathTemplate);
_result.Routes[i].DownstreamScheme.ShouldBe(expecteds.Routes[i].DownstreamScheme);
}
}
private void AndTheChangeTokenIsActivated()
{
_changeTokenSource.Verify(m => m.Activate(), Times.Once);
}
private FileConfiguration FakeFileConfigurationForSet()
{
var routes = new List<FileRoute>
{
new FileRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "123.12.12.12",
Port = 80,
},
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/asdfs/test/{test}",
},
};
var globalConfiguration = new FileGlobalConfiguration
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
{
Scheme = "https",
Port = 198,
Host = "blah"
}
};
return new FileConfiguration
{
GlobalConfiguration = globalConfiguration,
Routes = routes
};
}
private FileConfiguration FakeFileConfigurationForGet()
{
var routes = new List<FileRoute>
{
new FileRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 80,
}
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/test/test/{test}"
}
};
var globalConfiguration = new FileGlobalConfiguration
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
{
Scheme = "https",
Port = 198,
Host = "blah"
}
};
return new FileConfiguration
{
GlobalConfiguration = globalConfiguration,
Routes = routes
};
}
public void Dispose()
{
_semaphore.Release();
}
}
}

View File

@ -1,121 +1,121 @@
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class DownstreamAddressesCreatorTests
{
public DownstreamAddressesCreator _creator;
private FileReRoute _reRoute;
private List<DownstreamHostAndPort> _result;
public DownstreamAddressesCreatorTests()
{
_creator = new DownstreamAddressesCreator();
}
[Fact]
public void should_do_nothing()
{
var reRoute = new FileReRoute
{
};
var expected = new List<DownstreamHostAndPort>
{
};
this.Given(x => GivenTheFollowingReRoute(reRoute))
.When(x => WhenICreate())
.Then(x => TheThenFollowingIsReturned(expected))
.BDDfy();
}
[Fact]
public void should_create_downstream_addresses_from_old_downstream_path_and_port()
{
var reRoute = new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test",
Port = 80
}
},
};
var expected = new List<DownstreamHostAndPort>
{
new DownstreamHostAndPort("test", 80),
};
this.Given(x => GivenTheFollowingReRoute(reRoute))
.When(x => WhenICreate())
.Then(x => TheThenFollowingIsReturned(expected))
.BDDfy();
}
[Fact]
public void should_create_downstream_addresses_from_downstream_host_and_ports()
{
var reRoute = new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test",
Port = 80
},
new FileHostAndPort
{
Host = "west",
Port = 443
}
}
};
var expected = new List<DownstreamHostAndPort>
{
new DownstreamHostAndPort("test", 80),
new DownstreamHostAndPort("west", 443)
namespace Ocelot.UnitTests.Configuration
{
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class DownstreamAddressesCreatorTests
{
public DownstreamAddressesCreator _creator;
private FileRoute _route;
private List<DownstreamHostAndPort> _result;
public DownstreamAddressesCreatorTests()
{
_creator = new DownstreamAddressesCreator();
}
[Fact]
public void should_do_nothing()
{
var route = new FileRoute
{
};
this.Given(x => GivenTheFollowingReRoute(reRoute))
.When(x => WhenICreate())
.Then(x => TheThenFollowingIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowingReRoute(FileReRoute reRoute)
{
_reRoute = reRoute;
}
private void WhenICreate()
{
_result = _creator.Create(_reRoute);
}
private void TheThenFollowingIsReturned(List<DownstreamHostAndPort> expecteds)
{
_result.Count.ShouldBe(expecteds.Count);
for (int i = 0; i < _result.Count; i++)
{
var result = _result[i];
var expected = expecteds[i];
result.Host.ShouldBe(expected.Host);
result.Port.ShouldBe(expected.Port);
}
}
}
var expected = new List<DownstreamHostAndPort>
{
};
this.Given(x => GivenTheFollowingRoute(route))
.When(x => WhenICreate())
.Then(x => TheThenFollowingIsReturned(expected))
.BDDfy();
}
[Fact]
public void should_create_downstream_addresses_from_old_downstream_path_and_port()
{
var route = new FileRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test",
Port = 80
}
},
};
var expected = new List<DownstreamHostAndPort>
{
new DownstreamHostAndPort("test", 80),
};
this.Given(x => GivenTheFollowingRoute(route))
.When(x => WhenICreate())
.Then(x => TheThenFollowingIsReturned(expected))
.BDDfy();
}
[Fact]
public void should_create_downstream_addresses_from_downstream_host_and_ports()
{
var route = new FileRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test",
Port = 80
},
new FileHostAndPort
{
Host = "west",
Port = 443
}
}
};
var expected = new List<DownstreamHostAndPort>
{
new DownstreamHostAndPort("test", 80),
new DownstreamHostAndPort("west", 443)
};
this.Given(x => GivenTheFollowingRoute(route))
.When(x => WhenICreate())
.Then(x => TheThenFollowingIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowingRoute(FileRoute route)
{
_route = route;
}
private void WhenICreate()
{
_result = _creator.Create(_route);
}
private void TheThenFollowingIsReturned(List<DownstreamHostAndPort> expecteds)
{
_result.Count.ShouldBe(expecteds.Count);
for (int i = 0; i < _result.Count; i++)
{
var result = _result[i];
var expected = expecteds[i];
result.Host.ShouldBe(expected.Host);
result.Port.ShouldBe(expected.Port);
}
}
}
}

View File

@ -1,148 +1,148 @@
namespace Ocelot.UnitTests.Configuration
{
using System;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class DynamicsCreatorTests
{
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, _versionCreator.Object);
}
[Fact]
public void should_return_nothing()
{
var fileConfig = new FileConfiguration();
this.Given(_ => GivenThe(fileConfig))
.When(_ => WhenICreate())
.Then(_ => ThenNothingIsReturned())
.And(_ => ThenTheRloCreatorIsNotCalled())
.BDDfy();
}
[Fact]
public void should_return_re_routes()
{
var fileConfig = new FileConfiguration
{
DynamicReRoutes = new List<FileDynamicReRoute>
{
new FileDynamicReRoute
{
ServiceName = "1",
RateLimitRule = new FileRateLimitRule
{
EnableRateLimiting = false
},
DownstreamHttpVersion = "1.1"
},
new FileDynamicReRoute
{
ServiceName = "2",
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();
}
private void ThenTheRloCreatorIsCalledCorrectly()
{
_rloCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[0].RateLimitRule,
_fileConfig.GlobalConfiguration), Times.Once);
_rloCreator.Verify(x => x.Create(_fileConfig.DynamicReRoutes[1].RateLimitRule,
_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();
_rlo2 = new RateLimitOptionsBuilder().WithEnableRateLimiting(true).Build();
_rloCreator
.SetupSequence(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()))
.Returns(_rlo1)
.Returns(_rlo2);
}
private void ThenTheRloCreatorIsNotCalled()
{
_rloCreator.Verify(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()), Times.Never);
}
private void ThenNothingIsReturned()
{
_result.Count.ShouldBe(0);
}
private void WhenICreate()
{
_result = _creator.Create(_fileConfig);
}
private void GivenThe(FileConfiguration fileConfig)
{
_fileConfig = fileConfig;
}
}
}
namespace Ocelot.UnitTests.Configuration
{
using System;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class DynamicsCreatorTests
{
private readonly DynamicsCreator _creator;
private readonly Mock<IRateLimitOptionsCreator> _rloCreator;
private readonly Mock<IVersionCreator> _versionCreator;
private List<Route> _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, _versionCreator.Object);
}
[Fact]
public void should_return_nothing()
{
var fileConfig = new FileConfiguration();
this.Given(_ => GivenThe(fileConfig))
.When(_ => WhenICreate())
.Then(_ => ThenNothingIsReturned())
.And(_ => ThenTheRloCreatorIsNotCalled())
.BDDfy();
}
[Fact]
public void should_return_re_routes()
{
var fileConfig = new FileConfiguration
{
DynamicRoutes = new List<FileDynamicRoute>
{
new FileDynamicRoute
{
ServiceName = "1",
RateLimitRule = new FileRateLimitRule
{
EnableRateLimiting = false
},
DownstreamHttpVersion = "1.1"
},
new FileDynamicRoute
{
ServiceName = "2",
RateLimitRule = new FileRateLimitRule
{
EnableRateLimiting = true
},
DownstreamHttpVersion = "2.0"
}
}
};
this.Given(_ => GivenThe(fileConfig))
.And(_ => GivenTheRloCreatorReturns())
.And(_ => GivenTheVersionCreatorReturns())
.When(_ => WhenICreate())
.Then(_ => ThenTheRoutesAreReturned())
.And(_ => ThenTheRloCreatorIsCalledCorrectly())
.And(_ => ThenTheVersionCreatorIsCalledCorrectly())
.BDDfy();
}
private void ThenTheRloCreatorIsCalledCorrectly()
{
_rloCreator.Verify(x => x.Create(_fileConfig.DynamicRoutes[0].RateLimitRule,
_fileConfig.GlobalConfiguration), Times.Once);
_rloCreator.Verify(x => x.Create(_fileConfig.DynamicRoutes[1].RateLimitRule,
_fileConfig.GlobalConfiguration), Times.Once);
}
private void ThenTheVersionCreatorIsCalledCorrectly()
{
_versionCreator.Verify(x => x.Create(_fileConfig.DynamicRoutes[0].DownstreamHttpVersion), Times.Once);
_versionCreator.Verify(x => x.Create(_fileConfig.DynamicRoutes[1].DownstreamHttpVersion), Times.Once);
}
private void ThenTheRoutesAreReturned()
{
_result.Count.ShouldBe(2);
_result[0].DownstreamRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeFalse();
_result[0].DownstreamRoute[0].RateLimitOptions.ShouldBe(_rlo1);
_result[0].DownstreamRoute[0].DownstreamHttpVersion.ShouldBe(_version);
_result[0].DownstreamRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicRoutes[0].ServiceName);
_result[1].DownstreamRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeTrue();
_result[1].DownstreamRoute[0].RateLimitOptions.ShouldBe(_rlo2);
_result[1].DownstreamRoute[0].DownstreamHttpVersion.ShouldBe(_version);
_result[1].DownstreamRoute[0].ServiceName.ShouldBe(_fileConfig.DynamicRoutes[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();
_rlo2 = new RateLimitOptionsBuilder().WithEnableRateLimiting(true).Build();
_rloCreator
.SetupSequence(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()))
.Returns(_rlo1)
.Returns(_rlo2);
}
private void ThenTheRloCreatorIsNotCalled()
{
_rloCreator.Verify(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()), Times.Never);
}
private void ThenNothingIsReturned()
{
_result.Count.ShouldBe(0);
}
private void WhenICreate()
{
_result = _creator.Create(_fileConfig);
}
private void GivenThe(FileConfiguration fileConfig)
{
_fileConfig = fileConfig;
}
}
}

View File

@ -1,205 +1,205 @@
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Logging;
using Ocelot.Responses;
using Ocelot.UnitTests.Responder;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Threading;
using TestStack.BDDfy;
using Xunit;
using static Ocelot.Infrastructure.Wait;
namespace Ocelot.UnitTests.Configuration
{
public class FileConfigurationPollerTests : IDisposable
{
private readonly FileConfigurationPoller _poller;
private Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IFileConfigurationRepository> _repo;
private readonly FileConfiguration _fileConfig;
private Mock<IFileConfigurationPollerOptions> _config;
private readonly Mock<IInternalConfigurationRepository> _internalConfigRepo;
private readonly Mock<IInternalConfigurationCreator> _internalConfigCreator;
private IInternalConfiguration _internalConfig;
public FileConfigurationPollerTests()
{
var logger = new Mock<IOcelotLogger>();
_factory = new Mock<IOcelotLoggerFactory>();
_factory.Setup(x => x.CreateLogger<FileConfigurationPoller>()).Returns(logger.Object);
_repo = new Mock<IFileConfigurationRepository>();
_fileConfig = new FileConfiguration();
_config = new Mock<IFileConfigurationPollerOptions>();
_repo.Setup(x => x.Get()).ReturnsAsync(new OkResponse<FileConfiguration>(_fileConfig));
_config.Setup(x => x.Delay).Returns(100);
_internalConfigRepo = new Mock<IInternalConfigurationRepository>();
_internalConfigCreator = new Mock<IInternalConfigurationCreator>();
_internalConfigCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).ReturnsAsync(new OkResponse<IInternalConfiguration>(_internalConfig));
_poller = new FileConfigurationPoller(_factory.Object, _repo.Object, _config.Object, _internalConfigRepo.Object, _internalConfigCreator.Object);
}
[Fact]
public void should_start()
{
this.Given(x => GivenPollerHasStarted())
.Given(x => ThenTheSetterIsCalled(_fileConfig, 1))
.BDDfy();
}
[Fact]
public void should_call_setter_when_gets_new_config()
{
var newConfig = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test"
}
},
}
}
};
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenTheConfigIsChanged(newConfig, 0))
.Then(x => ThenTheSetterIsCalledAtLeast(newConfig, 1))
.BDDfy();
}
[Fact]
public void should_not_poll_if_already_polling()
{
var newConfig = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test"
}
},
}
}
};
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenTheConfigIsChanged(newConfig, 10))
.Then(x => ThenTheSetterIsCalled(newConfig, 1))
.BDDfy();
}
[Fact]
public void should_do_nothing_if_call_to_provider_fails()
{
var newConfig = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test"
}
},
}
}
};
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenProviderErrors())
.Then(x => ThenTheSetterIsCalled(newConfig, 0))
.BDDfy();
}
[Fact]
public void should_dispose_cleanly_without_starting()
{
this.When(x => WhenPollerIsDisposed())
.BDDfy();
}
private void GivenPollerHasStarted()
{
_poller.StartAsync(CancellationToken.None);
}
private void WhenProviderErrors()
{
_repo
.Setup(x => x.Get())
.ReturnsAsync(new ErrorResponse<FileConfiguration>(new AnyError()));
}
private void WhenTheConfigIsChanged(FileConfiguration newConfig, int delay)
{
_repo
.Setup(x => x.Get())
.Callback(() => Thread.Sleep(delay))
.ReturnsAsync(new OkResponse<FileConfiguration>(newConfig));
}
private void WhenPollerIsDisposed()
{
_poller.Dispose();
}
private void ThenTheSetterIsCalled(FileConfiguration fileConfig, int times)
{
var result = WaitFor(4000).Until(() =>
{
try
{
_internalConfigRepo.Verify(x => x.AddOrReplace(_internalConfig), Times.Exactly(times));
_internalConfigCreator.Verify(x => x.Create(fileConfig), Times.Exactly(times));
return true;
}
catch (Exception)
{
return false;
}
});
result.ShouldBeTrue();
}
private void ThenTheSetterIsCalledAtLeast(FileConfiguration fileConfig, int times)
{
var result = WaitFor(4000).Until(() =>
{
try
{
_internalConfigRepo.Verify(x => x.AddOrReplace(_internalConfig), Times.AtLeast(times));
_internalConfigCreator.Verify(x => x.Create(fileConfig), Times.AtLeast(times));
return true;
}
catch (Exception)
{
return false;
}
});
result.ShouldBeTrue();
}
public void Dispose()
{
_poller.Dispose();
}
}
}
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Logging;
using Ocelot.Responses;
using Ocelot.UnitTests.Responder;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Threading;
using TestStack.BDDfy;
using Xunit;
using static Ocelot.Infrastructure.Wait;
namespace Ocelot.UnitTests.Configuration
{
public class FileConfigurationPollerTests : IDisposable
{
private readonly FileConfigurationPoller _poller;
private Mock<IOcelotLoggerFactory> _factory;
private readonly Mock<IFileConfigurationRepository> _repo;
private readonly FileConfiguration _fileConfig;
private Mock<IFileConfigurationPollerOptions> _config;
private readonly Mock<IInternalConfigurationRepository> _internalConfigRepo;
private readonly Mock<IInternalConfigurationCreator> _internalConfigCreator;
private IInternalConfiguration _internalConfig;
public FileConfigurationPollerTests()
{
var logger = new Mock<IOcelotLogger>();
_factory = new Mock<IOcelotLoggerFactory>();
_factory.Setup(x => x.CreateLogger<FileConfigurationPoller>()).Returns(logger.Object);
_repo = new Mock<IFileConfigurationRepository>();
_fileConfig = new FileConfiguration();
_config = new Mock<IFileConfigurationPollerOptions>();
_repo.Setup(x => x.Get()).ReturnsAsync(new OkResponse<FileConfiguration>(_fileConfig));
_config.Setup(x => x.Delay).Returns(100);
_internalConfigRepo = new Mock<IInternalConfigurationRepository>();
_internalConfigCreator = new Mock<IInternalConfigurationCreator>();
_internalConfigCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).ReturnsAsync(new OkResponse<IInternalConfiguration>(_internalConfig));
_poller = new FileConfigurationPoller(_factory.Object, _repo.Object, _config.Object, _internalConfigRepo.Object, _internalConfigCreator.Object);
}
[Fact]
public void should_start()
{
this.Given(x => GivenPollerHasStarted())
.Given(x => ThenTheSetterIsCalled(_fileConfig, 1))
.BDDfy();
}
[Fact]
public void should_call_setter_when_gets_new_config()
{
var newConfig = new FileConfiguration
{
Routes = new List<FileRoute>
{
new FileRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test"
}
},
}
}
};
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenTheConfigIsChanged(newConfig, 0))
.Then(x => ThenTheSetterIsCalledAtLeast(newConfig, 1))
.BDDfy();
}
[Fact]
public void should_not_poll_if_already_polling()
{
var newConfig = new FileConfiguration
{
Routes = new List<FileRoute>
{
new FileRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test"
}
},
}
}
};
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenTheConfigIsChanged(newConfig, 10))
.Then(x => ThenTheSetterIsCalled(newConfig, 1))
.BDDfy();
}
[Fact]
public void should_do_nothing_if_call_to_provider_fails()
{
var newConfig = new FileConfiguration
{
Routes = new List<FileRoute>
{
new FileRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "test"
}
},
}
}
};
this.Given(x => GivenPollerHasStarted())
.Given(x => WhenProviderErrors())
.Then(x => ThenTheSetterIsCalled(newConfig, 0))
.BDDfy();
}
[Fact]
public void should_dispose_cleanly_without_starting()
{
this.When(x => WhenPollerIsDisposed())
.BDDfy();
}
private void GivenPollerHasStarted()
{
_poller.StartAsync(CancellationToken.None);
}
private void WhenProviderErrors()
{
_repo
.Setup(x => x.Get())
.ReturnsAsync(new ErrorResponse<FileConfiguration>(new AnyError()));
}
private void WhenTheConfigIsChanged(FileConfiguration newConfig, int delay)
{
_repo
.Setup(x => x.Get())
.Callback(() => Thread.Sleep(delay))
.ReturnsAsync(new OkResponse<FileConfiguration>(newConfig));
}
private void WhenPollerIsDisposed()
{
_poller.Dispose();
}
private void ThenTheSetterIsCalled(FileConfiguration fileConfig, int times)
{
var result = WaitFor(4000).Until(() =>
{
try
{
_internalConfigRepo.Verify(x => x.AddOrReplace(_internalConfig), Times.Exactly(times));
_internalConfigCreator.Verify(x => x.Create(fileConfig), Times.Exactly(times));
return true;
}
catch (Exception)
{
return false;
}
});
result.ShouldBeTrue();
}
private void ThenTheSetterIsCalledAtLeast(FileConfiguration fileConfig, int times)
{
var result = WaitFor(4000).Until(() =>
{
try
{
_internalConfigRepo.Verify(x => x.AddOrReplace(_internalConfig), Times.AtLeast(times));
_internalConfigCreator.Verify(x => x.Create(fileConfig), Times.AtLeast(times));
return true;
}
catch (Exception)
{
return false;
}
});
result.ShouldBeTrue();
}
public void Dispose()
{
_poller.Dispose();
}
}
}

View File

@ -40,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(), new Version("1.1"));
var config = new InternalConfiguration(new List<Route>(), 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()))

View File

@ -1,127 +1,127 @@
namespace Ocelot.UnitTests.Configuration
{
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Validator;
using Ocelot.Errors;
using Ocelot.Responses;
using Ocelot.UnitTests.Responder;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TestStack.BDDfy;
using Xunit;
public class FileInternalConfigurationCreatorTests
{
private readonly Mock<IConfigurationValidator> _validator;
private readonly Mock<IReRoutesCreator> _reRoutesCreator;
private readonly Mock<IAggregatesCreator> _aggregatesCreator;
private readonly Mock<IDynamicsCreator> _dynamicsCreator;
private readonly Mock<IConfigurationCreator> _configCreator;
private Response<IInternalConfiguration> _config;
private FileConfiguration _fileConfiguration;
private readonly FileInternalConfigurationCreator _creator;
private Response<IInternalConfiguration> _result;
private List<ReRoute> _reRoutes;
private List<ReRoute> _aggregates;
private List<ReRoute> _dynamics;
private InternalConfiguration _internalConfig;
public FileInternalConfigurationCreatorTests()
{
_validator = new Mock<IConfigurationValidator>();
_reRoutesCreator = new Mock<IReRoutesCreator>();
_aggregatesCreator = new Mock<IAggregatesCreator>();
_dynamicsCreator = new Mock<IDynamicsCreator>();
_configCreator = new Mock<IConfigurationCreator>();
_creator = new FileInternalConfigurationCreator(_validator.Object, _reRoutesCreator.Object, _aggregatesCreator.Object, _dynamicsCreator.Object, _configCreator.Object);
}
[Fact]
public void should_return_validation_error()
{
var fileConfiguration = new FileConfiguration();
this.Given(_ => GivenThe(fileConfiguration))
.And(_ => GivenTheValidationFails())
.When(_ => WhenICreate())
.Then(_ => ThenAnErrorIsReturned())
.BDDfy();
}
[Fact]
public void should_return_internal_configuration()
{
var fileConfiguration = new FileConfiguration();
this.Given(_ => GivenThe(fileConfiguration))
.And(_ => GivenTheValidationSucceeds())
.And(_ => GivenTheDependenciesAreSetUp())
.When(_ => WhenICreate())
.Then(_ => ThenTheDependenciesAreCalledCorrectly())
.BDDfy();
}
private void ThenTheDependenciesAreCalledCorrectly()
{
_reRoutesCreator.Verify(x => x.Create(_fileConfiguration), Times.Once);
_aggregatesCreator.Verify(x => x.Create(_fileConfiguration, _reRoutes), Times.Once);
_dynamicsCreator.Verify(x => x.Create(_fileConfiguration), Times.Once);
var mergedReRoutes = _reRoutes
.Union(_aggregates)
.Union(_dynamics)
.ToList();
_configCreator.Verify(x => x.Create(_fileConfiguration, It.Is<List<ReRoute>>(y => y.Count == mergedReRoutes.Count)), Times.Once);
}
private void GivenTheDependenciesAreSetUp()
{
_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, 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);
_dynamicsCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_dynamics);
_configCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<ReRoute>>())).Returns(_internalConfig);
}
private void GivenTheValidationSucceeds()
{
var ok = new ConfigurationValidationResult(false);
var response = new OkResponse<ConfigurationValidationResult>(ok);
_validator.Setup(x => x.IsValid(It.IsAny<FileConfiguration>())).ReturnsAsync(response);
}
private void ThenAnErrorIsReturned()
{
_result.IsError.ShouldBeTrue();
}
private async Task WhenICreate()
{
_result = await _creator.Create(_fileConfiguration);
}
private void GivenTheValidationFails()
{
var error = new ConfigurationValidationResult(true, new List<Error> { new AnyError() });
var response = new OkResponse<ConfigurationValidationResult>(error);
_validator.Setup(x => x.IsValid(It.IsAny<FileConfiguration>())).ReturnsAsync(response);
}
private void GivenThe(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;
}
}
}
namespace Ocelot.UnitTests.Configuration
{
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Validator;
using Ocelot.Errors;
using Ocelot.Responses;
using Ocelot.UnitTests.Responder;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TestStack.BDDfy;
using Xunit;
public class FileInternalConfigurationCreatorTests
{
private readonly Mock<IConfigurationValidator> _validator;
private readonly Mock<IRoutesCreator> _routesCreator;
private readonly Mock<IAggregatesCreator> _aggregatesCreator;
private readonly Mock<IDynamicsCreator> _dynamicsCreator;
private readonly Mock<IConfigurationCreator> _configCreator;
private Response<IInternalConfiguration> _config;
private FileConfiguration _fileConfiguration;
private readonly FileInternalConfigurationCreator _creator;
private Response<IInternalConfiguration> _result;
private List<Route> _routes;
private List<Route> _aggregates;
private List<Route> _dynamics;
private InternalConfiguration _internalConfig;
public FileInternalConfigurationCreatorTests()
{
_validator = new Mock<IConfigurationValidator>();
_routesCreator = new Mock<IRoutesCreator>();
_aggregatesCreator = new Mock<IAggregatesCreator>();
_dynamicsCreator = new Mock<IDynamicsCreator>();
_configCreator = new Mock<IConfigurationCreator>();
_creator = new FileInternalConfigurationCreator(_validator.Object, _routesCreator.Object, _aggregatesCreator.Object, _dynamicsCreator.Object, _configCreator.Object);
}
[Fact]
public void should_return_validation_error()
{
var fileConfiguration = new FileConfiguration();
this.Given(_ => GivenThe(fileConfiguration))
.And(_ => GivenTheValidationFails())
.When(_ => WhenICreate())
.Then(_ => ThenAnErrorIsReturned())
.BDDfy();
}
[Fact]
public void should_return_internal_configuration()
{
var fileConfiguration = new FileConfiguration();
this.Given(_ => GivenThe(fileConfiguration))
.And(_ => GivenTheValidationSucceeds())
.And(_ => GivenTheDependenciesAreSetUp())
.When(_ => WhenICreate())
.Then(_ => ThenTheDependenciesAreCalledCorrectly())
.BDDfy();
}
private void ThenTheDependenciesAreCalledCorrectly()
{
_routesCreator.Verify(x => x.Create(_fileConfiguration), Times.Once);
_aggregatesCreator.Verify(x => x.Create(_fileConfiguration, _routes), Times.Once);
_dynamicsCreator.Verify(x => x.Create(_fileConfiguration), Times.Once);
var mergedRoutes = _routes
.Union(_aggregates)
.Union(_dynamics)
.ToList();
_configCreator.Verify(x => x.Create(_fileConfiguration, It.Is<List<Route>>(y => y.Count == mergedRoutes.Count)), Times.Once);
}
private void GivenTheDependenciesAreSetUp()
{
_routes = new List<Route> { new RouteBuilder().Build() };
_aggregates = new List<Route> { new RouteBuilder().Build() };
_dynamics = new List<Route> { new RouteBuilder().Build() };
_internalConfig = new InternalConfiguration(null, "", null, "", null, "", null, null, null);
_routesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_routes);
_aggregatesCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<Route>>())).Returns(_aggregates);
_dynamicsCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).Returns(_dynamics);
_configCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>(), It.IsAny<List<Route>>())).Returns(_internalConfig);
}
private void GivenTheValidationSucceeds()
{
var ok = new ConfigurationValidationResult(false);
var response = new OkResponse<ConfigurationValidationResult>(ok);
_validator.Setup(x => x.IsValid(It.IsAny<FileConfiguration>())).ReturnsAsync(response);
}
private void ThenAnErrorIsReturned()
{
_result.IsError.ShouldBeTrue();
}
private async Task WhenICreate()
{
_result = await _creator.Create(_fileConfiguration);
}
private void GivenTheValidationFails()
{
var error = new ConfigurationValidationResult(true, new List<Error> { new AnyError() });
var response = new OkResponse<ConfigurationValidationResult>(error);
_validator.Setup(x => x.IsValid(It.IsAny<FileConfiguration>())).ReturnsAsync(response);
}
private void GivenThe(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;
}
}
}

View File

@ -16,7 +16,7 @@ namespace Ocelot.UnitTests.Configuration
public class HeaderFindAndReplaceCreatorTests
{
private HeaderFindAndReplaceCreator _creator;
private FileReRoute _reRoute;
private FileRoute _route;
private HeaderTransformations _result;
private Mock<IPlaceholders> _placeholders;
private Mock<IOcelotLoggerFactory> _factory;
@ -34,13 +34,13 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_create()
{
var reRoute = new FileReRoute
var route = new FileRoute
{
UpstreamHeaderTransform = new Dictionary<string, string>
{
{"Test", "Test, Chicken"},
{"Moop", "o, a"}
},
},
DownstreamHeaderTransform = new Dictionary<string, string>
{
{"Pop", "West, East"},
@ -60,7 +60,7 @@ namespace Ocelot.UnitTests.Configuration
new HeaderFindAndReplace("Bop", "e", "r", 0)
};
this.Given(x => GivenTheReRoute(reRoute))
this.Given(x => GivenTheRoute(route))
.When(x => WhenICreate())
.Then(x => ThenTheFollowingUpstreamIsReturned(upstream))
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
@ -71,19 +71,19 @@ namespace Ocelot.UnitTests.Configuration
public void should_create_with_add_headers_to_request()
{
const string key = "X-Forwarded-For";
const string value = "{RemoteIpAddress}";
const string value = "{RemoteIpAddress}";
var reRoute = new FileReRoute
var route = new FileRoute
{
UpstreamHeaderTransform = new Dictionary<string, string>
{
{key, value},
}
};
};
var expected = new AddHeader(key, value);
this.Given(x => GivenTheReRoute(reRoute))
this.Given(x => GivenTheRoute(route))
.When(x => WhenICreate())
.Then(x => ThenTheFollowingAddHeaderToUpstreamIsReturned(expected))
.BDDfy();
@ -92,8 +92,8 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_use_base_url_placeholder()
{
var reRoute = new FileReRoute
{
var route = new FileRoute
{
DownstreamHeaderTransform = new Dictionary<string, string>
{
{"Location", "http://www.bbc.co.uk/, {BaseUrl}"},
@ -105,7 +105,7 @@ namespace Ocelot.UnitTests.Configuration
new HeaderFindAndReplace("Location", "http://www.bbc.co.uk/", "http://ocelot.com/", 0),
};
this.Given(x => GivenTheReRoute(reRoute))
this.Given(x => GivenTheRoute(route))
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
.When(x => WhenICreate())
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
@ -115,7 +115,7 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_log_errors_and_not_add_headers()
{
var reRoute = new FileReRoute
var route = new FileRoute
{
DownstreamHeaderTransform = new Dictionary<string, string>
{
@ -131,7 +131,7 @@ namespace Ocelot.UnitTests.Configuration
{
};
this.Given(x => GivenTheReRoute(reRoute))
this.Given(x => GivenTheRoute(route))
.And(x => GivenTheBaseUrlErrors())
.When(x => WhenICreate())
.Then(x => ThenTheFollowingDownstreamIsReturned(expected))
@ -149,8 +149,8 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_use_base_url_partial_placeholder()
{
var reRoute = new FileReRoute
{
var route = new FileRoute
{
DownstreamHeaderTransform = new Dictionary<string, string>
{
{"Location", "http://www.bbc.co.uk/pay, {BaseUrl}pay"},
@ -162,7 +162,7 @@ namespace Ocelot.UnitTests.Configuration
new HeaderFindAndReplace("Location", "http://www.bbc.co.uk/pay", "http://ocelot.com/pay", 0),
};
this.Given(x => GivenTheReRoute(reRoute))
this.Given(x => GivenTheRoute(route))
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
.When(x => WhenICreate())
.Then(x => ThenTheFollowingDownstreamIsReturned(downstream))
@ -172,8 +172,8 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_add_trace_id_header()
{
var reRoute = new FileReRoute
{
var route = new FileRoute
{
DownstreamHeaderTransform = new Dictionary<string, string>
{
{"Trace-Id", "{TraceId}"},
@ -182,7 +182,7 @@ namespace Ocelot.UnitTests.Configuration
var expected = new AddHeader("Trace-Id", "{TraceId}");
this.Given(x => GivenTheReRoute(reRoute))
this.Given(x => GivenTheRoute(route))
.And(x => GivenTheBaseUrlIs("http://ocelot.com/"))
.When(x => WhenICreate())
.Then(x => ThenTheFollowingAddHeaderToDownstreamIsReturned(expected))
@ -192,7 +192,7 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_add_downstream_header_as_is_when_no_replacement_is_given()
{
var reRoute = new FileReRoute
var route = new FileRoute
{
DownstreamHeaderTransform = new Dictionary<string, string>
{
@ -202,7 +202,7 @@ namespace Ocelot.UnitTests.Configuration
var expected = new AddHeader("X-Custom-Header", "Value");
this.Given(x => GivenTheReRoute(reRoute))
this.Given(x => GivenTheRoute(route))
.And(x => WhenICreate())
.Then(x => x.ThenTheFollowingAddHeaderToDownstreamIsReturned(expected))
.BDDfy();
@ -211,7 +211,7 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_add_upstream_header_as_is_when_no_replacement_is_given()
{
var reRoute = new FileReRoute
var route = new FileRoute
{
UpstreamHeaderTransform = new Dictionary<string, string>
{
@ -221,7 +221,7 @@ namespace Ocelot.UnitTests.Configuration
var expected = new AddHeader("X-Custom-Header", "Value");
this.Given(x => GivenTheReRoute(reRoute))
this.Given(x => GivenTheRoute(route))
.And(x => WhenICreate())
.Then(x => x.ThenTheFollowingAddHeaderToUpstreamIsReturned(expected))
.BDDfy();
@ -241,8 +241,8 @@ namespace Ocelot.UnitTests.Configuration
{
_result.AddHeadersToDownstream[0].Key.ShouldBe(addHeader.Key);
_result.AddHeadersToDownstream[0].Value.ShouldBe(addHeader.Value);
}
}
private void ThenTheFollowingAddHeaderToUpstreamIsReturned(AddHeader addHeader)
{
_result.AddHeadersToUpstream[0].Key.ShouldBe(addHeader.Key);
@ -251,8 +251,8 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheFollowingDownstreamIsReturned(List<HeaderFindAndReplace> downstream)
{
_result.Downstream.Count.ShouldBe(downstream.Count);
_result.Downstream.Count.ShouldBe(downstream.Count);
for (int i = 0; i < _result.Downstream.Count; i++)
{
var result = _result.Downstream[i];
@ -261,23 +261,23 @@ namespace Ocelot.UnitTests.Configuration
result.Index.ShouldBe(expected.Index);
result.Key.ShouldBe(expected.Key);
result.Replace.ShouldBe(expected.Replace);
}
}
}
private void GivenTheReRoute(FileReRoute reRoute)
private void GivenTheRoute(FileRoute route)
{
_reRoute = reRoute;
_route = route;
}
private void WhenICreate()
{
_result = _creator.Create(_reRoute);
_result = _creator.Create(_route);
}
private void ThenTheFollowingUpstreamIsReturned(List<HeaderFindAndReplace> expecteds)
{
_result.Upstream.Count.ShouldBe(expecteds.Count);
_result.Upstream.Count.ShouldBe(expecteds.Count);
for (int i = 0; i < _result.Upstream.Count; i++)
{
var result = _result.Upstream[i];
@ -289,4 +289,4 @@ namespace Ocelot.UnitTests.Configuration
}
}
}
}
}

View File

@ -1,239 +1,239 @@
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
using Microsoft.AspNetCore.Http;
using Ocelot.Logging;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
public class HttpHandlerOptionsCreatorTests
{
private IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
private FileReRoute _fileReRoute;
private HttpHandlerOptions _httpHandlerOptions;
private IServiceProvider _serviceProvider;
private IServiceCollection _serviceCollection;
public HttpHandlerOptionsCreatorTests()
{
_serviceCollection = new ServiceCollection();
_serviceProvider = _serviceCollection.BuildServiceProvider();
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(_serviceProvider);
}
[Fact]
public void should_not_use_tracing_if_fake_tracer_registered()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
UseTracing = true
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_use_tracing_if_real_tracer_registered()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
UseTracing = true
}
};
var expectedOptions = new HttpHandlerOptions(false, false, true, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.And(x => GivenARealTracer())
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_useCookie_false_and_allowAutoRedirect_true_as_default()
{
var fileReRoute = new FileReRoute();
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_specified_useCookie_and_allowAutoRedirect()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
AllowAutoRedirect = false,
UseCookieContainer = false,
UseTracing = false
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_useproxy_true_as_default()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions()
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_specified_useproxy()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
UseProxy = false
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, false, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_specified_MaxConnectionsPerServer()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = 10
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, 10);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = -1
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range_when_zero()
{
var fileReRoute = new FileReRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = 0
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileReRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
private void GivenTheFollowing(FileReRoute fileReRoute)
{
_fileReRoute = fileReRoute;
}
private void WhenICreateHttpHandlerOptions()
{
_httpHandlerOptions = _httpHandlerOptionsCreator.Create(_fileReRoute.HttpHandlerOptions);
}
private void ThenTheFollowingOptionsReturned(HttpHandlerOptions expected)
{
_httpHandlerOptions.ShouldNotBeNull();
_httpHandlerOptions.AllowAutoRedirect.ShouldBe(expected.AllowAutoRedirect);
_httpHandlerOptions.UseCookieContainer.ShouldBe(expected.UseCookieContainer);
_httpHandlerOptions.UseTracing.ShouldBe(expected.UseTracing);
_httpHandlerOptions.UseProxy.ShouldBe(expected.UseProxy);
_httpHandlerOptions.MaxConnectionsPerServer.ShouldBe(expected.MaxConnectionsPerServer);
}
private void GivenARealTracer()
{
var tracer = new FakeTracer();
_serviceCollection.AddSingleton<ITracer, FakeTracer>();
_serviceProvider = _serviceCollection.BuildServiceProvider();
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(_serviceProvider);
}
private class FakeTracer : ITracer
{
public void Event(HttpContext httpContext, string @event)
{
throw new NotImplementedException();
}
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken, Action<string> addTraceIdToRepo,
Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> baseSendAsync)
{
throw new NotImplementedException();
}
}
}
}
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
using Microsoft.AspNetCore.Http;
using Ocelot.Logging;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
public class HttpHandlerOptionsCreatorTests
{
private IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
private FileRoute _fileRoute;
private HttpHandlerOptions _httpHandlerOptions;
private IServiceProvider _serviceProvider;
private IServiceCollection _serviceCollection;
public HttpHandlerOptionsCreatorTests()
{
_serviceCollection = new ServiceCollection();
_serviceProvider = _serviceCollection.BuildServiceProvider();
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(_serviceProvider);
}
[Fact]
public void should_not_use_tracing_if_fake_tracer_registered()
{
var fileRoute = new FileRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
UseTracing = true
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_use_tracing_if_real_tracer_registered()
{
var fileRoute = new FileRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
UseTracing = true
}
};
var expectedOptions = new HttpHandlerOptions(false, false, true, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileRoute))
.And(x => GivenARealTracer())
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_useCookie_false_and_allowAutoRedirect_true_as_default()
{
var fileRoute = new FileRoute();
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_specified_useCookie_and_allowAutoRedirect()
{
var fileRoute = new FileRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
AllowAutoRedirect = false,
UseCookieContainer = false,
UseTracing = false
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_useproxy_true_as_default()
{
var fileRoute = new FileRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions()
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_specified_useproxy()
{
var fileRoute = new FileRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
UseProxy = false
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, false, int.MaxValue);
this.Given(x => GivenTheFollowing(fileRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_with_specified_MaxConnectionsPerServer()
{
var fileRoute = new FileRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = 10
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, 10);
this.Given(x => GivenTheFollowing(fileRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range()
{
var fileRoute = new FileRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = -1
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
[Fact]
public void should_create_options_fixing_specified_MaxConnectionsPerServer_range_when_zero()
{
var fileRoute = new FileRoute
{
HttpHandlerOptions = new FileHttpHandlerOptions
{
MaxConnectionsPerServer = 0
}
};
var expectedOptions = new HttpHandlerOptions(false, false, false, true, int.MaxValue);
this.Given(x => GivenTheFollowing(fileRoute))
.When(x => WhenICreateHttpHandlerOptions())
.Then(x => ThenTheFollowingOptionsReturned(expectedOptions))
.BDDfy();
}
private void GivenTheFollowing(FileRoute fileRoute)
{
_fileRoute = fileRoute;
}
private void WhenICreateHttpHandlerOptions()
{
_httpHandlerOptions = _httpHandlerOptionsCreator.Create(_fileRoute.HttpHandlerOptions);
}
private void ThenTheFollowingOptionsReturned(HttpHandlerOptions expected)
{
_httpHandlerOptions.ShouldNotBeNull();
_httpHandlerOptions.AllowAutoRedirect.ShouldBe(expected.AllowAutoRedirect);
_httpHandlerOptions.UseCookieContainer.ShouldBe(expected.UseCookieContainer);
_httpHandlerOptions.UseTracing.ShouldBe(expected.UseTracing);
_httpHandlerOptions.UseProxy.ShouldBe(expected.UseProxy);
_httpHandlerOptions.MaxConnectionsPerServer.ShouldBe(expected.MaxConnectionsPerServer);
}
private void GivenARealTracer()
{
var tracer = new FakeTracer();
_serviceCollection.AddSingleton<ITracer, FakeTracer>();
_serviceProvider = _serviceCollection.BuildServiceProvider();
_httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(_serviceProvider);
}
private class FakeTracer : ITracer
{
public void Event(HttpContext httpContext, string @event)
{
throw new NotImplementedException();
}
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken, Action<string> addTraceIdToRepo,
Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> baseSendAsync)
{
throw new NotImplementedException();
}
}
}
}

View File

@ -48,7 +48,7 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheConfigurationIsReturned()
{
_getResult.Data.ReRoutes[0].DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("initial");
_getResult.Data.Routes[0].DownstreamRoute[0].DownstreamPathTemplate.Value.ShouldBe("initial");
}
private void WhenIGetTheConfiguration()
@ -92,19 +92,19 @@ namespace Ocelot.UnitTests.Configuration
AdministrationPath = administrationPath;
}
public List<ReRoute> ReRoutes
public List<Route> Routes
{
get
{
var downstreamReRoute = new DownstreamReRouteBuilder()
var downstreamRoute = new DownstreamRouteBuilder()
.WithDownstreamPathTemplate(_downstreamTemplatePath)
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
return new List<ReRoute>
return new List<Route>
{
new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute)
new RouteBuilder()
.WithDownstreamRoute(downstreamRoute)
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build()
};

View File

@ -11,22 +11,22 @@ namespace Ocelot.UnitTests.Configuration
public class QoSOptionsCreatorTests
{
private QoSOptionsCreator _creator;
private FileReRoute _fileReRoute;
private FileRoute _fileRoute;
private QoSOptions _result;
public QoSOptionsCreatorTests()
{
_creator = new QoSOptionsCreator();
}
}
[Fact]
public void should_create_qos_options()
{
var reRoute = new FileReRoute
var route = new FileRoute
{
QoSOptions = new FileQoSOptions
{
ExceptionsAllowedBeforeBreaking = 1,
ExceptionsAllowedBeforeBreaking = 1,
DurationOfBreak = 1,
TimeoutValue = 1
}
@ -37,20 +37,20 @@ namespace Ocelot.UnitTests.Configuration
.WithTimeoutValue(1)
.Build();
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
this.Given(x => x.GivenTheFollowingRoute(route))
.When(x => x.WhenICreate())
.Then(x => x.ThenTheFollowingIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
private void GivenTheFollowingRoute(FileRoute fileRoute)
{
_fileReRoute = fileReRoute;
_fileRoute = fileRoute;
}
private void WhenICreate()
{
_result = _creator.Create(_fileReRoute.QoSOptions);
_result = _creator.Create(_fileRoute.QoSOptions);
}
private void ThenTheFollowingIsReturned(QoSOptions expected)
@ -60,4 +60,4 @@ namespace Ocelot.UnitTests.Configuration
_result.TimeoutValue.ShouldBe(expected.TimeoutValue);
}
}
}
}

View File

@ -1,106 +1,106 @@
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class RateLimitOptionsCreatorTests
{
private FileReRoute _fileReRoute;
private FileGlobalConfiguration _fileGlobalConfig;
private bool _enabled;
private RateLimitOptionsCreator _creator;
private RateLimitOptions _result;
public RateLimitOptionsCreatorTests()
{
_creator = new RateLimitOptionsCreator();
}
[Fact]
public void should_create_rate_limit_options()
{
var fileReRoute = new FileReRoute
{
RateLimitOptions = new FileRateLimitRule
{
ClientWhitelist = new List<string>(),
Period = "Period",
Limit = 1,
PeriodTimespan = 1,
EnableRateLimiting = true
}
};
var fileGlobalConfig = new FileGlobalConfiguration
{
RateLimitOptions = new FileRateLimitOptions
{
ClientIdHeader = "ClientIdHeader",
DisableRateLimitHeaders = true,
QuotaExceededMessage = "QuotaExceededMessage",
RateLimitCounterPrefix = "RateLimitCounterPrefix",
HttpStatusCode = 200
}
};
var expected = new RateLimitOptionsBuilder()
.WithClientIdHeader("ClientIdHeader")
.WithClientWhiteList(() => fileReRoute.RateLimitOptions.ClientWhitelist)
.WithDisableRateLimitHeaders(true)
.WithEnableRateLimiting(true)
.WithHttpStatusCode(200)
.WithQuotaExceededMessage("QuotaExceededMessage")
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
fileReRoute.RateLimitOptions.PeriodTimespan,
fileReRoute.RateLimitOptions.Limit))
.Build();
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.And(x => x.GivenTheFollowingFileGlobalConfig(fileGlobalConfig))
.And(x => x.GivenRateLimitingIsEnabled())
.When(x => x.WhenICreate())
.Then(x => x.ThenTheFollowingIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
{
_fileReRoute = fileReRoute;
}
private void GivenTheFollowingFileGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
{
_fileGlobalConfig = fileGlobalConfig;
}
private void GivenRateLimitingIsEnabled()
{
_enabled = true;
}
private void WhenICreate()
{
_result = _creator.Create(_fileReRoute.RateLimitOptions, _fileGlobalConfig);
}
private void ThenTheFollowingIsReturned(RateLimitOptions expected)
{
_result.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
_result.ClientWhitelist.ShouldBe(expected.ClientWhitelist);
_result.DisableRateLimitHeaders.ShouldBe(expected.DisableRateLimitHeaders);
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
_result.HttpStatusCode.ShouldBe(expected.HttpStatusCode);
_result.QuotaExceededMessage.ShouldBe(expected.QuotaExceededMessage);
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
}
}
}
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class RateLimitOptionsCreatorTests
{
private FileRoute _fileRoute;
private FileGlobalConfiguration _fileGlobalConfig;
private bool _enabled;
private RateLimitOptionsCreator _creator;
private RateLimitOptions _result;
public RateLimitOptionsCreatorTests()
{
_creator = new RateLimitOptionsCreator();
}
[Fact]
public void should_create_rate_limit_options()
{
var fileRoute = new FileRoute
{
RateLimitOptions = new FileRateLimitRule
{
ClientWhitelist = new List<string>(),
Period = "Period",
Limit = 1,
PeriodTimespan = 1,
EnableRateLimiting = true
}
};
var fileGlobalConfig = new FileGlobalConfiguration
{
RateLimitOptions = new FileRateLimitOptions
{
ClientIdHeader = "ClientIdHeader",
DisableRateLimitHeaders = true,
QuotaExceededMessage = "QuotaExceededMessage",
RateLimitCounterPrefix = "RateLimitCounterPrefix",
HttpStatusCode = 200
}
};
var expected = new RateLimitOptionsBuilder()
.WithClientIdHeader("ClientIdHeader")
.WithClientWhiteList(() => fileRoute.RateLimitOptions.ClientWhitelist)
.WithDisableRateLimitHeaders(true)
.WithEnableRateLimiting(true)
.WithHttpStatusCode(200)
.WithQuotaExceededMessage("QuotaExceededMessage")
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
.WithRateLimitRule(new RateLimitRule(fileRoute.RateLimitOptions.Period,
fileRoute.RateLimitOptions.PeriodTimespan,
fileRoute.RateLimitOptions.Limit))
.Build();
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.And(x => x.GivenTheFollowingFileGlobalConfig(fileGlobalConfig))
.And(x => x.GivenRateLimitingIsEnabled())
.When(x => x.WhenICreate())
.Then(x => x.ThenTheFollowingIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowingFileRoute(FileRoute fileRoute)
{
_fileRoute = fileRoute;
}
private void GivenTheFollowingFileGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
{
_fileGlobalConfig = fileGlobalConfig;
}
private void GivenRateLimitingIsEnabled()
{
_enabled = true;
}
private void WhenICreate()
{
_result = _creator.Create(_fileRoute.RateLimitOptions, _fileGlobalConfig);
}
private void ThenTheFollowingIsReturned(RateLimitOptions expected)
{
_result.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
_result.ClientWhitelist.ShouldBe(expected.ClientWhitelist);
_result.DisableRateLimitHeaders.ShouldBe(expected.DisableRateLimitHeaders);
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
_result.HttpStatusCode.ShouldBe(expected.HttpStatusCode);
_result.QuotaExceededMessage.ShouldBe(expected.QuotaExceededMessage);
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
}
}
}

View File

@ -8,7 +8,7 @@ namespace Ocelot.UnitTests.Configuration
{
public class RequestIdKeyCreatorTests
{
private FileReRoute _fileReRoute;
private FileRoute _fileRoute;
private FileGlobalConfiguration _fileGlobalConfig;
private string _result;
private RequestIdKeyCreator _creator;
@ -21,13 +21,13 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_use_global_configuration()
{
var reRoute = new FileReRoute();
var route = new FileRoute();
var globalConfig = new FileGlobalConfiguration
{
RequestIdKey = "cheese"
};
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
this.Given(x => x.GivenTheFollowingRoute(route))
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
.When(x => x.WhenICreate())
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
@ -37,13 +37,13 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_use_re_route_specific()
{
var reRoute = new FileReRoute
var route = new FileRoute
{
RequestIdKey = "cheese"
};
var globalConfig = new FileGlobalConfiguration();
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
this.Given(x => x.GivenTheFollowingRoute(route))
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
.When(x => x.WhenICreate())
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
@ -53,25 +53,25 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_use_re_route_over_global_specific()
{
var reRoute = new FileReRoute
var route = new FileRoute
{
RequestIdKey = "cheese"
};
};
var globalConfig = new FileGlobalConfiguration
{
RequestIdKey = "test"
};
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
this.Given(x => x.GivenTheFollowingRoute(route))
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
.When(x => x.WhenICreate())
.Then(x => x.ThenTheFollowingIsReturned("cheese"))
.BDDfy();
}
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
private void GivenTheFollowingRoute(FileRoute fileRoute)
{
_fileReRoute = fileReRoute;
_fileRoute = fileRoute;
}
private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration globalConfig)
@ -81,7 +81,7 @@ namespace Ocelot.UnitTests.Configuration
private void WhenICreate()
{
_result = _creator.Create(_fileReRoute, _fileGlobalConfig);
_result = _creator.Create(_fileRoute, _fileGlobalConfig);
}
private void ThenTheFollowingIsReturned(string expected)
@ -89,4 +89,4 @@ namespace Ocelot.UnitTests.Configuration
_result.ShouldBe(expected);
}
}
}
}

View File

@ -1,84 +1,84 @@
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.LoadBalancer.LoadBalancers;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class ReRouteKeyCreatorTests
{
private ReRouteKeyCreator _creator;
private FileReRoute _reRoute;
private string _result;
public ReRouteKeyCreatorTests()
{
_creator = new ReRouteKeyCreator();
}
[Fact]
public void should_return_sticky_session_key()
{
var reRoute = new FileReRoute
{
LoadBalancerOptions = new FileLoadBalancerOptions
{
Key = "testy",
Type = nameof(CookieStickySessions)
}
};
this.Given(_ => GivenThe(reRoute))
.When(_ => WhenICreate())
.Then(_ => ThenTheResultIs($"{nameof(CookieStickySessions)}:{reRoute.LoadBalancerOptions.Key}"))
.BDDfy();
}
[Fact]
public void should_return_re_route_key()
{
var reRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/product",
UpstreamHttpMethod = new List<string> { "GET", "POST", "PUT" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 123
},
new FileHostAndPort
{
Host = "localhost",
Port = 123
}
}
};
this.Given(_ => GivenThe(reRoute))
.When(_ => WhenICreate())
.Then(_ => ThenTheResultIs($"{reRoute.UpstreamPathTemplate}|{string.Join(",", reRoute.UpstreamHttpMethod)}|{string.Join(",", reRoute.DownstreamHostAndPorts.Select(x => $"{x.Host}:{x.Port}"))}"))
.BDDfy();
}
private void GivenThe(FileReRoute reRoute)
{
_reRoute = reRoute;
}
private void WhenICreate()
{
_result = _creator.Create(_reRoute);
}
private void ThenTheResultIs(string expected)
{
_result.ShouldBe(expected);
}
}
}
namespace Ocelot.UnitTests.Configuration
{
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.LoadBalancer.LoadBalancers;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using TestStack.BDDfy;
using Xunit;
public class RouteKeyCreatorTests
{
private RouteKeyCreator _creator;
private FileRoute _route;
private string _result;
public RouteKeyCreatorTests()
{
_creator = new RouteKeyCreator();
}
[Fact]
public void should_return_sticky_session_key()
{
var route = new FileRoute
{
LoadBalancerOptions = new FileLoadBalancerOptions
{
Key = "testy",
Type = nameof(CookieStickySessions)
}
};
this.Given(_ => GivenThe(route))
.When(_ => WhenICreate())
.Then(_ => ThenTheResultIs($"{nameof(CookieStickySessions)}:{route.LoadBalancerOptions.Key}"))
.BDDfy();
}
[Fact]
public void should_return_re_route_key()
{
var route = new FileRoute
{
UpstreamPathTemplate = "/api/product",
UpstreamHttpMethod = new List<string> { "GET", "POST", "PUT" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 123
},
new FileHostAndPort
{
Host = "localhost",
Port = 123
}
}
};
this.Given(_ => GivenThe(route))
.When(_ => WhenICreate())
.Then(_ => ThenTheResultIs($"{route.UpstreamPathTemplate}|{string.Join(",", route.UpstreamHttpMethod)}|{string.Join(",", route.DownstreamHostAndPorts.Select(x => $"{x.Host}:{x.Port}"))}"))
.BDDfy();
}
private void GivenThe(FileRoute route)
{
_route = route;
}
private void WhenICreate()
{
_result = _creator.Create(_route);
}
private void ThenTheResultIs(string expected)
{
_result.ShouldBe(expected);
}
}
}

View File

@ -1,80 +1,80 @@
namespace Ocelot.UnitTests.Configuration
{
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class ReRouteOptionsCreatorTests
{
private readonly ReRouteOptionsCreator _creator;
private FileReRoute _reRoute;
private ReRouteOptions _result;
public ReRouteOptionsCreatorTests()
{
_creator = new ReRouteOptionsCreator();
}
[Fact]
public void should_create_re_route_options()
{
var reRoute = new FileReRoute
{
RateLimitOptions = new FileRateLimitRule
{
EnableRateLimiting = true
},
AuthenticationOptions = new FileAuthenticationOptions()
{
AuthenticationProviderKey = "Test"
},
RouteClaimsRequirement = new Dictionary<string, string>()
{
{"",""}
},
FileCacheOptions = new FileCacheOptions
{
TtlSeconds = 1
},
ServiceName = "west"
};
var expected = new ReRouteOptionsBuilder()
.WithIsAuthenticated(true)
.WithIsAuthorised(true)
.WithIsCached(true)
.WithRateLimiting(true)
.WithUseServiceDiscovery(true)
.Build();
this.Given(x => x.GivenTheFollowing(reRoute))
.When(x => x.WhenICreate())
.Then(x => x.ThenTheFollowingIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowing(FileReRoute reRoute)
{
_reRoute = reRoute;
}
private void WhenICreate()
{
_result = _creator.Create(_reRoute);
}
private void ThenTheFollowingIsReturned(ReRouteOptions expected)
{
_result.IsAuthenticated.ShouldBe(expected.IsAuthenticated);
_result.IsAuthorised.ShouldBe(expected.IsAuthorised);
_result.IsCached.ShouldBe(expected.IsCached);
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
_result.UseServiceDiscovery.ShouldBe(expected.UseServiceDiscovery);
}
}
}
namespace Ocelot.UnitTests.Configuration
{
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class RouteOptionsCreatorTests
{
private readonly RouteOptionsCreator _creator;
private FileRoute _route;
private RouteOptions _result;
public RouteOptionsCreatorTests()
{
_creator = new RouteOptionsCreator();
}
[Fact]
public void should_create_re_route_options()
{
var route = new FileRoute
{
RateLimitOptions = new FileRateLimitRule
{
EnableRateLimiting = true
},
AuthenticationOptions = new FileAuthenticationOptions()
{
AuthenticationProviderKey = "Test"
},
RouteClaimsRequirement = new Dictionary<string, string>()
{
{"",""}
},
FileCacheOptions = new FileCacheOptions
{
TtlSeconds = 1
},
ServiceName = "west"
};
var expected = new RouteOptionsBuilder()
.WithIsAuthenticated(true)
.WithIsAuthorised(true)
.WithIsCached(true)
.WithRateLimiting(true)
.WithUseServiceDiscovery(true)
.Build();
this.Given(x => x.GivenTheFollowing(route))
.When(x => x.WhenICreate())
.Then(x => x.ThenTheFollowingIsReturned(expected))
.BDDfy();
}
private void GivenTheFollowing(FileRoute route)
{
_route = route;
}
private void WhenICreate()
{
_result = _creator.Create(_route);
}
private void ThenTheFollowingIsReturned(RouteOptions expected)
{
_result.IsAuthenticated.ShouldBe(expected.IsAuthenticated);
_result.IsAuthorised.ShouldBe(expected.IsAuthorised);
_result.IsCached.ShouldBe(expected.IsCached);
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
_result.UseServiceDiscovery.ShouldBe(expected.UseServiceDiscovery);
}
}
}

View File

@ -1,283 +1,283 @@
namespace Ocelot.UnitTests.Configuration
{
using System;
using Moq;
using Ocelot.Cache;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Values;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using TestStack.BDDfy;
using Xunit;
public class ReRoutesCreatorTests
{
private ReRoutesCreator _creator;
private Mock<IClaimsToThingCreator> _cthCreator;
private Mock<IAuthenticationOptionsCreator> _aoCreator;
private Mock<IUpstreamTemplatePatternCreator> _utpCreator;
private Mock<IRequestIdKeyCreator> _ridkCreator;
private Mock<IQoSOptionsCreator> _qosoCreator;
private Mock<IReRouteOptionsCreator> _rroCreator;
private Mock<IRateLimitOptionsCreator> _rloCreator;
private Mock<IRegionCreator> _rCreator;
private Mock<IHttpHandlerOptionsCreator> _hhoCreator;
private Mock<IHeaderFindAndReplaceCreator> _hfarCreator;
private Mock<IDownstreamAddressesCreator> _daCreator;
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;
private string _rrk;
private UpstreamPathTemplate _upt;
private AuthenticationOptions _ao;
private List<ClaimToThing> _ctt;
private QoSOptions _qoso;
private RateLimitOptions _rlo;
private string _region;
private HttpHandlerOptions _hho;
private HeaderTransformations _ht;
private List<DownstreamHostAndPort> _dhp;
private LoadBalancerOptions _lbo;
private List<ReRoute> _result;
private SecurityOptions _securityOptions;
private Version _expectedVersion;
public ReRoutesCreatorTests()
{
_cthCreator = new Mock<IClaimsToThingCreator>();
_aoCreator = new Mock<IAuthenticationOptionsCreator>();
_utpCreator = new Mock<IUpstreamTemplatePatternCreator>();
_ridkCreator = new Mock<IRequestIdKeyCreator>();
_qosoCreator = new Mock<IQoSOptionsCreator>();
_rroCreator = new Mock<IReRouteOptionsCreator>();
_rloCreator = new Mock<IRateLimitOptionsCreator>();
_rCreator = new Mock<IRegionCreator>();
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
_hfarCreator = new Mock<IHeaderFindAndReplaceCreator>();
_daCreator = new Mock<IDownstreamAddressesCreator>();
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
_rrkCreator = new Mock<IReRouteKeyCreator>();
_soCreator = new Mock<ISecurityOptionsCreator>();
_versionCreator = new Mock<IVersionCreator>();
_creator = new ReRoutesCreator(
_cthCreator.Object,
_aoCreator.Object,
_utpCreator.Object,
_ridkCreator.Object,
_qosoCreator.Object,
_rroCreator.Object,
_rloCreator.Object,
_rCreator.Object,
_hhoCreator.Object,
_hfarCreator.Object,
_daCreator.Object,
_lboCreator.Object,
_rrkCreator.Object,
_soCreator.Object,
_versionCreator.Object
);
}
[Fact]
public void should_return_nothing()
{
var fileConfig = new FileConfiguration();
this.Given(_ => GivenThe(fileConfig))
.When(_ => WhenICreate())
.Then(_ => ThenNoReRoutesAreReturned())
.BDDfy();
}
[Fact]
public void should_return_re_routes()
{
var fileConfig = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
ServiceName = "dave",
DangerousAcceptAnyServerCertificateValidator = true,
AddClaimsToRequest = new Dictionary<string, string>
{
{ "a","b" }
},
AddHeadersToRequest = new Dictionary<string, string>
{
{ "c","d" }
},
AddQueriesToRequest = new Dictionary<string, string>
{
{ "e","f" }
},
UpstreamHttpMethod = new List<string> { "GET", "POST" }
},
new FileReRoute
{
ServiceName = "wave",
DangerousAcceptAnyServerCertificateValidator = false,
AddClaimsToRequest = new Dictionary<string, string>
{
{ "g","h" }
},
AddHeadersToRequest = new Dictionary<string, string>
{
{ "i","j" }
},
AddQueriesToRequest = new Dictionary<string, string>
{
{ "k","l" }
},
UpstreamHttpMethod = new List<string> { "PUT", "DELETE" }
}
}
};
this.Given(_ => GivenThe(fileConfig))
.And(_ => GivenTheDependenciesAreSetUpCorrectly())
.When(_ => WhenICreate())
.Then(_ => ThenTheDependenciesAreCalledCorrectly())
.And(_ => ThenTheReRoutesAreCreated())
.BDDfy();
}
private void ThenTheDependenciesAreCalledCorrectly()
{
ThenTheDepsAreCalledFor(_fileConfig.ReRoutes[0], _fileConfig.GlobalConfiguration);
ThenTheDepsAreCalledFor(_fileConfig.ReRoutes[1], _fileConfig.GlobalConfiguration);
}
private void GivenTheDependenciesAreSetUpCorrectly()
{
_expectedVersion = new Version("1.1");
_rro = new ReRouteOptions(false, false, false, false, false);
_requestId = "testy";
_rrk = "besty";
_upt = new UpstreamPathTemplateBuilder().Build();
_ao = new AuthenticationOptionsBuilder().Build();
_ctt = new List<ClaimToThing>();
_qoso = new QoSOptionsBuilder().Build();
_rlo = new RateLimitOptionsBuilder().Build();
_region = "vesty";
_hho = new HttpHandlerOptionsBuilder().Build();
_ht = new HeaderTransformations(new List<HeaderFindAndReplace>(), new List<HeaderFindAndReplace>(), new List<AddHeader>(), new List<AddHeader>());
_dhp = new List<DownstreamHostAndPort>();
_lbo = new LoadBalancerOptionsBuilder().Build();
_rroCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_rro);
_ridkCreator.Setup(x => x.Create(It.IsAny<FileReRoute>(), It.IsAny<FileGlobalConfiguration>())).Returns(_requestId);
_rrkCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_rrk);
_utpCreator.Setup(x => x.Create(It.IsAny<IReRoute>())).Returns(_upt);
_aoCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_ao);
_cthCreator.Setup(x => x.Create(It.IsAny<Dictionary<string, string>>())).Returns(_ctt);
_qosoCreator.Setup(x => x.Create(It.IsAny<FileQoSOptions>(), It.IsAny<string>(), It.IsAny<List<string>>())).Returns(_qoso);
_rloCreator.Setup(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>())).Returns(_rlo);
_rCreator.Setup(x => x.Create(It.IsAny<FileReRoute>())).Returns(_region);
_hhoCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>())).Returns(_hho);
_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()
{
_result.Count.ShouldBe(2);
ThenTheReRouteIsSet(_fileConfig.ReRoutes[0], 0);
ThenTheReRouteIsSet(_fileConfig.ReRoutes[1], 1);
}
private void ThenNoReRoutesAreReturned()
{
_result.ShouldBeEmpty();
}
private void GivenThe(FileConfiguration fileConfig)
{
_fileConfig = fileConfig;
}
private void WhenICreate()
{
_result = _creator.Create(_fileConfig);
}
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);
_result[reRouteIndex].DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBe(_rro.EnableRateLimiting);
_result[reRouteIndex].DownstreamReRoute[0].RequestIdKey.ShouldBe(_requestId);
_result[reRouteIndex].DownstreamReRoute[0].LoadBalancerKey.ShouldBe(_rrk);
_result[reRouteIndex].DownstreamReRoute[0].UpstreamPathTemplate.ShouldBe(_upt);
_result[reRouteIndex].DownstreamReRoute[0].AuthenticationOptions.ShouldBe(_ao);
_result[reRouteIndex].DownstreamReRoute[0].ClaimsToHeaders.ShouldBe(_ctt);
_result[reRouteIndex].DownstreamReRoute[0].ClaimsToQueries.ShouldBe(_ctt);
_result[reRouteIndex].DownstreamReRoute[0].ClaimsToClaims.ShouldBe(_ctt);
_result[reRouteIndex].DownstreamReRoute[0].QosOptions.ShouldBe(_qoso);
_result[reRouteIndex].DownstreamReRoute[0].RateLimitOptions.ShouldBe(_rlo);
_result[reRouteIndex].DownstreamReRoute[0].CacheOptions.Region.ShouldBe(_region);
_result[reRouteIndex].DownstreamReRoute[0].CacheOptions.TtlSeconds.ShouldBe(expected.FileCacheOptions.TtlSeconds);
_result[reRouteIndex].DownstreamReRoute[0].HttpHandlerOptions.ShouldBe(_hho);
_result[reRouteIndex].DownstreamReRoute[0].UpstreamHeadersFindAndReplace.ShouldBe(_ht.Upstream);
_result[reRouteIndex].DownstreamReRoute[0].DownstreamHeadersFindAndReplace.ShouldBe(_ht.Downstream);
_result[reRouteIndex].DownstreamReRoute[0].AddHeadersToUpstream.ShouldBe(_ht.AddHeadersToUpstream);
_result[reRouteIndex].DownstreamReRoute[0].AddHeadersToDownstream.ShouldBe(_ht.AddHeadersToDownstream);
_result[reRouteIndex].DownstreamReRoute[0].DownstreamAddresses.ShouldBe(_dhp);
_result[reRouteIndex].DownstreamReRoute[0].LoadBalancerOptions.ShouldBe(_lbo);
_result[reRouteIndex].DownstreamReRoute[0].UseServiceDiscovery.ShouldBe(_rro.UseServiceDiscovery);
_result[reRouteIndex].DownstreamReRoute[0].DangerousAcceptAnyServerCertificateValidator.ShouldBe(expected.DangerousAcceptAnyServerCertificateValidator);
_result[reRouteIndex].DownstreamReRoute[0].DelegatingHandlers.ShouldBe(expected.DelegatingHandlers);
_result[reRouteIndex].DownstreamReRoute[0].ServiceName.ShouldBe(expected.ServiceName);
_result[reRouteIndex].DownstreamReRoute[0].DownstreamScheme.ShouldBe(expected.DownstreamScheme);
_result[reRouteIndex].DownstreamReRoute[0].RouteClaimsRequirement.ShouldBe(expected.RouteClaimsRequirement);
_result[reRouteIndex].DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate);
_result[reRouteIndex].DownstreamReRoute[0].Key.ShouldBe(expected.Key);
_result[reRouteIndex].UpstreamHttpMethod
.Select(x => x.Method)
.ToList()
.ShouldContain(x => x == expected.UpstreamHttpMethod[0]);
_result[reRouteIndex].UpstreamHttpMethod
.Select(x => x.Method)
.ToList()
.ShouldContain(x => x == expected.UpstreamHttpMethod[1]);
_result[reRouteIndex].UpstreamHost.ShouldBe(expected.UpstreamHost);
_result[reRouteIndex].DownstreamReRoute.Count.ShouldBe(1);
_result[reRouteIndex].UpstreamTemplatePattern.ShouldBe(_upt);
}
private void ThenTheDepsAreCalledFor(FileReRoute fileReRoute, FileGlobalConfiguration globalConfig)
{
_rroCreator.Verify(x => x.Create(fileReRoute), Times.Once);
_ridkCreator.Verify(x => x.Create(fileReRoute, globalConfig), Times.Once);
_rrkCreator.Verify(x => x.Create(fileReRoute), Times.Once);
_utpCreator.Verify(x => x.Create(fileReRoute), Times.Exactly(2));
_aoCreator.Verify(x => x.Create(fileReRoute), Times.Once);
_cthCreator.Verify(x => x.Create(fileReRoute.AddHeadersToRequest), Times.Once);
_cthCreator.Verify(x => x.Create(fileReRoute.AddClaimsToRequest), Times.Once);
_cthCreator.Verify(x => x.Create(fileReRoute.AddQueriesToRequest), Times.Once);
_qosoCreator.Verify(x => x.Create(fileReRoute.QoSOptions, fileReRoute.UpstreamPathTemplate, fileReRoute.UpstreamHttpMethod));
_rloCreator.Verify(x => x.Create(fileReRoute.RateLimitOptions, globalConfig), Times.Once);
_rCreator.Verify(x => x.Create(fileReRoute), Times.Once);
_hhoCreator.Verify(x => x.Create(fileReRoute.HttpHandlerOptions), Times.Once);
_hfarCreator.Verify(x => x.Create(fileReRoute), Times.Once);
_daCreator.Verify(x => x.Create(fileReRoute), Times.Once);
_lboCreator.Verify(x => x.Create(fileReRoute.LoadBalancerOptions), Times.Once);
_soCreator.Verify(x => x.Create(fileReRoute.SecurityOptions), Times.Once);
}
}
}
namespace Ocelot.UnitTests.Configuration
{
using System;
using Moq;
using Ocelot.Cache;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Values;
using Shouldly;
using System.Collections.Generic;
using System.Linq;
using TestStack.BDDfy;
using Xunit;
public class RoutesCreatorTests
{
private RoutesCreator _creator;
private Mock<IClaimsToThingCreator> _cthCreator;
private Mock<IAuthenticationOptionsCreator> _aoCreator;
private Mock<IUpstreamTemplatePatternCreator> _utpCreator;
private Mock<IRequestIdKeyCreator> _ridkCreator;
private Mock<IQoSOptionsCreator> _qosoCreator;
private Mock<IRouteOptionsCreator> _rroCreator;
private Mock<IRateLimitOptionsCreator> _rloCreator;
private Mock<IRegionCreator> _rCreator;
private Mock<IHttpHandlerOptionsCreator> _hhoCreator;
private Mock<IHeaderFindAndReplaceCreator> _hfarCreator;
private Mock<IDownstreamAddressesCreator> _daCreator;
private Mock<ILoadBalancerOptionsCreator> _lboCreator;
private Mock<IRouteKeyCreator> _rrkCreator;
private Mock<ISecurityOptionsCreator> _soCreator;
private Mock<IVersionCreator> _versionCreator;
private FileConfiguration _fileConfig;
private RouteOptions _rro;
private string _requestId;
private string _rrk;
private UpstreamPathTemplate _upt;
private AuthenticationOptions _ao;
private List<ClaimToThing> _ctt;
private QoSOptions _qoso;
private RateLimitOptions _rlo;
private string _region;
private HttpHandlerOptions _hho;
private HeaderTransformations _ht;
private List<DownstreamHostAndPort> _dhp;
private LoadBalancerOptions _lbo;
private List<Route> _result;
private SecurityOptions _securityOptions;
private Version _expectedVersion;
public RoutesCreatorTests()
{
_cthCreator = new Mock<IClaimsToThingCreator>();
_aoCreator = new Mock<IAuthenticationOptionsCreator>();
_utpCreator = new Mock<IUpstreamTemplatePatternCreator>();
_ridkCreator = new Mock<IRequestIdKeyCreator>();
_qosoCreator = new Mock<IQoSOptionsCreator>();
_rroCreator = new Mock<IRouteOptionsCreator>();
_rloCreator = new Mock<IRateLimitOptionsCreator>();
_rCreator = new Mock<IRegionCreator>();
_hhoCreator = new Mock<IHttpHandlerOptionsCreator>();
_hfarCreator = new Mock<IHeaderFindAndReplaceCreator>();
_daCreator = new Mock<IDownstreamAddressesCreator>();
_lboCreator = new Mock<ILoadBalancerOptionsCreator>();
_rrkCreator = new Mock<IRouteKeyCreator>();
_soCreator = new Mock<ISecurityOptionsCreator>();
_versionCreator = new Mock<IVersionCreator>();
_creator = new RoutesCreator(
_cthCreator.Object,
_aoCreator.Object,
_utpCreator.Object,
_ridkCreator.Object,
_qosoCreator.Object,
_rroCreator.Object,
_rloCreator.Object,
_rCreator.Object,
_hhoCreator.Object,
_hfarCreator.Object,
_daCreator.Object,
_lboCreator.Object,
_rrkCreator.Object,
_soCreator.Object,
_versionCreator.Object
);
}
[Fact]
public void should_return_nothing()
{
var fileConfig = new FileConfiguration();
this.Given(_ => GivenThe(fileConfig))
.When(_ => WhenICreate())
.Then(_ => ThenNoRoutesAreReturned())
.BDDfy();
}
[Fact]
public void should_return_re_routes()
{
var fileConfig = new FileConfiguration
{
Routes = new List<FileRoute>
{
new FileRoute
{
ServiceName = "dave",
DangerousAcceptAnyServerCertificateValidator = true,
AddClaimsToRequest = new Dictionary<string, string>
{
{ "a","b" }
},
AddHeadersToRequest = new Dictionary<string, string>
{
{ "c","d" }
},
AddQueriesToRequest = new Dictionary<string, string>
{
{ "e","f" }
},
UpstreamHttpMethod = new List<string> { "GET", "POST" }
},
new FileRoute
{
ServiceName = "wave",
DangerousAcceptAnyServerCertificateValidator = false,
AddClaimsToRequest = new Dictionary<string, string>
{
{ "g","h" }
},
AddHeadersToRequest = new Dictionary<string, string>
{
{ "i","j" }
},
AddQueriesToRequest = new Dictionary<string, string>
{
{ "k","l" }
},
UpstreamHttpMethod = new List<string> { "PUT", "DELETE" }
}
}
};
this.Given(_ => GivenThe(fileConfig))
.And(_ => GivenTheDependenciesAreSetUpCorrectly())
.When(_ => WhenICreate())
.Then(_ => ThenTheDependenciesAreCalledCorrectly())
.And(_ => ThenTheRoutesAreCreated())
.BDDfy();
}
private void ThenTheDependenciesAreCalledCorrectly()
{
ThenTheDepsAreCalledFor(_fileConfig.Routes[0], _fileConfig.GlobalConfiguration);
ThenTheDepsAreCalledFor(_fileConfig.Routes[1], _fileConfig.GlobalConfiguration);
}
private void GivenTheDependenciesAreSetUpCorrectly()
{
_expectedVersion = new Version("1.1");
_rro = new RouteOptions(false, false, false, false, false);
_requestId = "testy";
_rrk = "besty";
_upt = new UpstreamPathTemplateBuilder().Build();
_ao = new AuthenticationOptionsBuilder().Build();
_ctt = new List<ClaimToThing>();
_qoso = new QoSOptionsBuilder().Build();
_rlo = new RateLimitOptionsBuilder().Build();
_region = "vesty";
_hho = new HttpHandlerOptionsBuilder().Build();
_ht = new HeaderTransformations(new List<HeaderFindAndReplace>(), new List<HeaderFindAndReplace>(), new List<AddHeader>(), new List<AddHeader>());
_dhp = new List<DownstreamHostAndPort>();
_lbo = new LoadBalancerOptionsBuilder().Build();
_rroCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_rro);
_ridkCreator.Setup(x => x.Create(It.IsAny<FileRoute>(), It.IsAny<FileGlobalConfiguration>())).Returns(_requestId);
_rrkCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_rrk);
_utpCreator.Setup(x => x.Create(It.IsAny<IRoute>())).Returns(_upt);
_aoCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_ao);
_cthCreator.Setup(x => x.Create(It.IsAny<Dictionary<string, string>>())).Returns(_ctt);
_qosoCreator.Setup(x => x.Create(It.IsAny<FileQoSOptions>(), It.IsAny<string>(), It.IsAny<List<string>>())).Returns(_qoso);
_rloCreator.Setup(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>())).Returns(_rlo);
_rCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_region);
_hhoCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>())).Returns(_hho);
_hfarCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_ht);
_daCreator.Setup(x => x.Create(It.IsAny<FileRoute>())).Returns(_dhp);
_lboCreator.Setup(x => x.Create(It.IsAny<FileLoadBalancerOptions>())).Returns(_lbo);
_versionCreator.Setup(x => x.Create(It.IsAny<string>())).Returns(_expectedVersion);
}
private void ThenTheRoutesAreCreated()
{
_result.Count.ShouldBe(2);
ThenTheRouteIsSet(_fileConfig.Routes[0], 0);
ThenTheRouteIsSet(_fileConfig.Routes[1], 1);
}
private void ThenNoRoutesAreReturned()
{
_result.ShouldBeEmpty();
}
private void GivenThe(FileConfiguration fileConfig)
{
_fileConfig = fileConfig;
}
private void WhenICreate()
{
_result = _creator.Create(_fileConfig);
}
private void ThenTheRouteIsSet(FileRoute expected, int routeIndex)
{
_result[routeIndex].DownstreamRoute[0].DownstreamHttpVersion.ShouldBe(_expectedVersion);
_result[routeIndex].DownstreamRoute[0].IsAuthenticated.ShouldBe(_rro.IsAuthenticated);
_result[routeIndex].DownstreamRoute[0].IsAuthorised.ShouldBe(_rro.IsAuthorised);
_result[routeIndex].DownstreamRoute[0].IsCached.ShouldBe(_rro.IsCached);
_result[routeIndex].DownstreamRoute[0].EnableEndpointEndpointRateLimiting.ShouldBe(_rro.EnableRateLimiting);
_result[routeIndex].DownstreamRoute[0].RequestIdKey.ShouldBe(_requestId);
_result[routeIndex].DownstreamRoute[0].LoadBalancerKey.ShouldBe(_rrk);
_result[routeIndex].DownstreamRoute[0].UpstreamPathTemplate.ShouldBe(_upt);
_result[routeIndex].DownstreamRoute[0].AuthenticationOptions.ShouldBe(_ao);
_result[routeIndex].DownstreamRoute[0].ClaimsToHeaders.ShouldBe(_ctt);
_result[routeIndex].DownstreamRoute[0].ClaimsToQueries.ShouldBe(_ctt);
_result[routeIndex].DownstreamRoute[0].ClaimsToClaims.ShouldBe(_ctt);
_result[routeIndex].DownstreamRoute[0].QosOptions.ShouldBe(_qoso);
_result[routeIndex].DownstreamRoute[0].RateLimitOptions.ShouldBe(_rlo);
_result[routeIndex].DownstreamRoute[0].CacheOptions.Region.ShouldBe(_region);
_result[routeIndex].DownstreamRoute[0].CacheOptions.TtlSeconds.ShouldBe(expected.FileCacheOptions.TtlSeconds);
_result[routeIndex].DownstreamRoute[0].HttpHandlerOptions.ShouldBe(_hho);
_result[routeIndex].DownstreamRoute[0].UpstreamHeadersFindAndReplace.ShouldBe(_ht.Upstream);
_result[routeIndex].DownstreamRoute[0].DownstreamHeadersFindAndReplace.ShouldBe(_ht.Downstream);
_result[routeIndex].DownstreamRoute[0].AddHeadersToUpstream.ShouldBe(_ht.AddHeadersToUpstream);
_result[routeIndex].DownstreamRoute[0].AddHeadersToDownstream.ShouldBe(_ht.AddHeadersToDownstream);
_result[routeIndex].DownstreamRoute[0].DownstreamAddresses.ShouldBe(_dhp);
_result[routeIndex].DownstreamRoute[0].LoadBalancerOptions.ShouldBe(_lbo);
_result[routeIndex].DownstreamRoute[0].UseServiceDiscovery.ShouldBe(_rro.UseServiceDiscovery);
_result[routeIndex].DownstreamRoute[0].DangerousAcceptAnyServerCertificateValidator.ShouldBe(expected.DangerousAcceptAnyServerCertificateValidator);
_result[routeIndex].DownstreamRoute[0].DelegatingHandlers.ShouldBe(expected.DelegatingHandlers);
_result[routeIndex].DownstreamRoute[0].ServiceName.ShouldBe(expected.ServiceName);
_result[routeIndex].DownstreamRoute[0].DownstreamScheme.ShouldBe(expected.DownstreamScheme);
_result[routeIndex].DownstreamRoute[0].RouteClaimsRequirement.ShouldBe(expected.RouteClaimsRequirement);
_result[routeIndex].DownstreamRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate);
_result[routeIndex].DownstreamRoute[0].Key.ShouldBe(expected.Key);
_result[routeIndex].UpstreamHttpMethod
.Select(x => x.Method)
.ToList()
.ShouldContain(x => x == expected.UpstreamHttpMethod[0]);
_result[routeIndex].UpstreamHttpMethod
.Select(x => x.Method)
.ToList()
.ShouldContain(x => x == expected.UpstreamHttpMethod[1]);
_result[routeIndex].UpstreamHost.ShouldBe(expected.UpstreamHost);
_result[routeIndex].DownstreamRoute.Count.ShouldBe(1);
_result[routeIndex].UpstreamTemplatePattern.ShouldBe(_upt);
}
private void ThenTheDepsAreCalledFor(FileRoute fileRoute, FileGlobalConfiguration globalConfig)
{
_rroCreator.Verify(x => x.Create(fileRoute), Times.Once);
_ridkCreator.Verify(x => x.Create(fileRoute, globalConfig), Times.Once);
_rrkCreator.Verify(x => x.Create(fileRoute), Times.Once);
_utpCreator.Verify(x => x.Create(fileRoute), Times.Exactly(2));
_aoCreator.Verify(x => x.Create(fileRoute), Times.Once);
_cthCreator.Verify(x => x.Create(fileRoute.AddHeadersToRequest), Times.Once);
_cthCreator.Verify(x => x.Create(fileRoute.AddClaimsToRequest), Times.Once);
_cthCreator.Verify(x => x.Create(fileRoute.AddQueriesToRequest), Times.Once);
_qosoCreator.Verify(x => x.Create(fileRoute.QoSOptions, fileRoute.UpstreamPathTemplate, fileRoute.UpstreamHttpMethod));
_rloCreator.Verify(x => x.Create(fileRoute.RateLimitOptions, globalConfig), Times.Once);
_rCreator.Verify(x => x.Create(fileRoute), Times.Once);
_hhoCreator.Verify(x => x.Create(fileRoute.HttpHandlerOptions), Times.Once);
_hfarCreator.Verify(x => x.Create(fileRoute), Times.Once);
_daCreator.Verify(x => x.Create(fileRoute), Times.Once);
_lboCreator.Verify(x => x.Create(fileRoute.LoadBalancerOptions), Times.Once);
_soCreator.Verify(x => x.Create(fileRoute.SecurityOptions), Times.Once);
}
}
}

View File

@ -1,68 +1,68 @@
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class SecurityOptionsCreatorTests
{
private FileReRoute _fileReRoute;
private FileGlobalConfiguration _fileGlobalConfig;
private SecurityOptions _result;
private ISecurityOptionsCreator _creator;
public SecurityOptionsCreatorTests()
{
_creator = new SecurityOptionsCreator();
}
[Fact]
public void should_create_security_config()
{
var ipAllowedList = new List<string>() { "127.0.0.1", "192.168.1.1" };
var ipBlockedList = new List<string>() { "127.0.0.1", "192.168.1.1" };
var fileReRoute = new FileReRoute
{
SecurityOptions = new FileSecurityOptions()
{
IPAllowedList = ipAllowedList,
IPBlockedList = ipBlockedList
}
};
var expected = new SecurityOptions(ipAllowedList, ipBlockedList);
this.Given(x => x.GivenThe(fileReRoute))
.When(x => x.WhenICreate())
.Then(x => x.ThenTheResultIs(expected))
.BDDfy();
}
private void GivenThe(FileReRoute reRoute)
{
_fileReRoute = reRoute;
}
private void WhenICreate()
{
_result = _creator.Create(_fileReRoute.SecurityOptions);
}
private void ThenTheResultIs(SecurityOptions expected)
{
for (int i = 0; i < expected.IPAllowedList.Count; i++)
{
_result.IPAllowedList[i].ShouldBe(expected.IPAllowedList[i]);
}
for (int i = 0; i < expected.IPBlockedList.Count; i++)
{
_result.IPBlockedList[i].ShouldBe(expected.IPBlockedList[i]);
}
}
}
}
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class SecurityOptionsCreatorTests
{
private FileRoute _fileRoute;
private FileGlobalConfiguration _fileGlobalConfig;
private SecurityOptions _result;
private ISecurityOptionsCreator _creator;
public SecurityOptionsCreatorTests()
{
_creator = new SecurityOptionsCreator();
}
[Fact]
public void should_create_security_config()
{
var ipAllowedList = new List<string>() { "127.0.0.1", "192.168.1.1" };
var ipBlockedList = new List<string>() { "127.0.0.1", "192.168.1.1" };
var fileRoute = new FileRoute
{
SecurityOptions = new FileSecurityOptions()
{
IPAllowedList = ipAllowedList,
IPBlockedList = ipBlockedList
}
};
var expected = new SecurityOptions(ipAllowedList, ipBlockedList);
this.Given(x => x.GivenThe(fileRoute))
.When(x => x.WhenICreate())
.Then(x => x.ThenTheResultIs(expected))
.BDDfy();
}
private void GivenThe(FileRoute route)
{
_fileRoute = route;
}
private void WhenICreate()
{
_result = _creator.Create(_fileRoute.SecurityOptions);
}
private void ThenTheResultIs(SecurityOptions expected)
{
for (int i = 0; i < expected.IPAllowedList.Count; i++)
{
_result.IPAllowedList[i].ShouldBe(expected.IPAllowedList[i]);
}
for (int i = 0; i < expected.IPBlockedList.Count; i++)
{
_result.IPBlockedList[i].ShouldBe(expected.IPBlockedList[i]);
}
}
}
}

View File

@ -1,260 +1,260 @@
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Values;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class UpstreamTemplatePatternCreatorTests
{
private FileReRoute _fileReRoute;
private readonly UpstreamTemplatePatternCreator _creator;
private UpstreamPathTemplate _result;
public UpstreamTemplatePatternCreatorTests()
{
_creator = new UpstreamTemplatePatternCreator();
}
[Fact]
public void should_match_up_to_next_slash()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/v{apiVersion}/cards",
Priority = 0
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/v[^/]+/cards$"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_use_re_route_priority()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/orders/{catchAll}",
Priority = 0
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/orders/.+$"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_use_zero_priority()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/{catchAll}",
Priority = 1
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/PRODUCTS/{productId}",
ReRouteIsCaseSensitive = false
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_match_forward_slash_or_no_forward_slash_if_template_end_with_forward_slash()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/PRODUCTS/",
ReRouteIsCaseSensitive = false
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/PRODUCTS/{productId}",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/[^/]+(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_to_end_of_string()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/"
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_to_end_of_string_when_slash_and_placeholder()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/{url}"
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_starts_with_placeholder_then_has_another_later()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/{productId}/products/variants/{variantId}/",
ReRouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/[^/]+/products/variants/[^/]+(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_query_string()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_query_string_with_multiple_params()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}&productId={productId}"
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+&productId=.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
{
_fileReRoute = fileReRoute;
}
private void WhenICreateTheTemplatePattern()
{
_result = _creator.Create(_fileReRoute);
}
private void ThenTheFollowingIsReturned(string expected)
{
_result.Template.ShouldBe(expected);
}
private void ThenThePriorityIs(int v)
{
_result.Priority.ShouldBe(v);
}
}
}
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Values;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class UpstreamTemplatePatternCreatorTests
{
private FileRoute _fileRoute;
private readonly UpstreamTemplatePatternCreator _creator;
private UpstreamPathTemplate _result;
public UpstreamTemplatePatternCreatorTests()
{
_creator = new UpstreamTemplatePatternCreator();
}
[Fact]
public void should_match_up_to_next_slash()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/api/v{apiVersion}/cards",
Priority = 0
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/v[^/]+/cards$"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_use_re_route_priority()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/orders/{catchAll}",
Priority = 0
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/orders/.+$"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_use_zero_priority()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/{catchAll}",
Priority = 1
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/PRODUCTS/{productId}",
RouteIsCaseSensitive = false
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_match_forward_slash_or_no_forward_slash_if_template_end_with_forward_slash()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/PRODUCTS/",
RouteIsCaseSensitive = false
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_set_upstream_template_pattern_to_respect_case_sensitivity()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/PRODUCTS/{productId}",
RouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_anything_to_end_of_string()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/api/products/{productId}",
RouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_more_than_one_placeholder()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
RouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_more_than_one_placeholder_with_trailing_slash()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
RouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[^/]+/variants/[^/]+(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_to_end_of_string()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/"
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_to_end_of_string_when_slash_and_placeholder()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/{url}"
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_starts_with_placeholder_then_has_another_later()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/{productId}/products/variants/{variantId}/",
RouteIsCaseSensitive = true
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/[^/]+/products/variants/[^/]+(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_query_string()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}"
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
[Fact]
public void should_create_template_pattern_that_matches_query_string_with_multiple_params()
{
var fileRoute = new FileRoute
{
UpstreamPathTemplate = "/api/subscriptions/{subscriptionId}/updates?unitId={unitId}&productId={productId}"
};
this.Given(x => x.GivenTheFollowingFileRoute(fileRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/api/subscriptions/[^/]+/updates\\?unitId=.+&productId=.+$"))
.And(x => ThenThePriorityIs(1))
.BDDfy();
}
private void GivenTheFollowingFileRoute(FileRoute fileRoute)
{
_fileRoute = fileRoute;
}
private void WhenICreateTheTemplatePattern()
{
_result = _creator.Create(_fileRoute);
}
private void ThenTheFollowingIsReturned(string expected)
{
_result.Template.ShouldBe(expected);
}
private void ThenThePriorityIs(int v)
{
_result.Priority.ShouldBe(v);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}
}