diff --git a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs index f8e2d506..5e3f4b44 100644 --- a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs +++ b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs @@ -162,4 +162,4 @@ namespace Ocelot.Configuration.Creator return loadBalancerKey; } } -} \ No newline at end of file +} diff --git a/src/Ocelot/Configuration/File/FileAuthenticationOptions.cs b/src/Ocelot/Configuration/File/FileAuthenticationOptions.cs index 81fc9d28..2b99dc56 100644 --- a/src/Ocelot/Configuration/File/FileAuthenticationOptions.cs +++ b/src/Ocelot/Configuration/File/FileAuthenticationOptions.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Text; namespace Ocelot.Configuration.File { @@ -11,5 +12,14 @@ namespace Ocelot.Configuration.File public string AuthenticationProviderKey {get; set;} public List AllowedScopes { get; set; } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append($"{nameof(AuthenticationProviderKey)}:{AuthenticationProviderKey},{nameof(AllowedScopes)}:["); + sb.AppendJoin(',', AllowedScopes); + sb.Append("]"); + return sb.ToString(); + } } } diff --git a/src/Ocelot/Configuration/File/FileRateLimitRule.cs b/src/Ocelot/Configuration/File/FileRateLimitRule.cs index 727a9e82..5a79c3c0 100644 --- a/src/Ocelot/Configuration/File/FileRateLimitRule.cs +++ b/src/Ocelot/Configuration/File/FileRateLimitRule.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace Ocelot.Configuration.File @@ -30,5 +31,20 @@ namespace Ocelot.Configuration.File /// Maximum number of requests that a client can make in a defined period /// public long Limit { get; set; } + + public override string ToString() + { + if (!EnableRateLimiting) + { + return string.Empty; + } + var sb = new StringBuilder(); + sb.Append( + $"{nameof(Period)}:{Period},{nameof(PeriodTimespan)}:{PeriodTimespan:F},{nameof(Limit)}:{Limit},{nameof(ClientWhitelist)}:["); + + sb.AppendJoin(',', ClientWhitelist); + sb.Append(']'); + return sb.ToString(); + } } } diff --git a/src/Ocelot/Configuration/Validator/DownstreamPathTemplateAlreadyUsedError.cs b/src/Ocelot/Configuration/Validator/DownstreamPathTemplateAlreadyUsedError.cs deleted file mode 100644 index e350753c..00000000 --- a/src/Ocelot/Configuration/Validator/DownstreamPathTemplateAlreadyUsedError.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Ocelot.Errors; - -namespace Ocelot.Configuration.Validator -{ - public class DownstreamPathTemplateAlreadyUsedError : Error - { - public DownstreamPathTemplateAlreadyUsedError(string message) : base(message, OcelotErrorCode.DownstreampathTemplateAlreadyUsedError) - { - } - } -} diff --git a/src/Ocelot/Configuration/Validator/DownstreamPathTemplateContainsSchemeError.cs b/src/Ocelot/Configuration/Validator/DownstreamPathTemplateContainsSchemeError.cs deleted file mode 100644 index a3dfa309..00000000 --- a/src/Ocelot/Configuration/Validator/DownstreamPathTemplateContainsSchemeError.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Ocelot.Errors; - -namespace Ocelot.Configuration.Validator -{ - public class DownstreamPathTemplateContainsSchemeError : Error - { - public DownstreamPathTemplateContainsSchemeError(string message) - : base(message, OcelotErrorCode.DownstreamPathTemplateContainsSchemeError) - { - } - } -} diff --git a/src/Ocelot/Configuration/Validator/DownstreamPathTemplateDoesntStartWithForwardSlash.cs b/src/Ocelot/Configuration/Validator/DownstreamPathTemplateDoesntStartWithForwardSlash.cs deleted file mode 100644 index 2f09dbfb..00000000 --- a/src/Ocelot/Configuration/Validator/DownstreamPathTemplateDoesntStartWithForwardSlash.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Ocelot.Errors; - -namespace Ocelot.Configuration.Validator -{ - public class PathTemplateDoesntStartWithForwardSlash : Error - { - public PathTemplateDoesntStartWithForwardSlash(string message) - : base(message, OcelotErrorCode.PathTemplateDoesntStartWithForwardSlash) - { - } - } -} diff --git a/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs b/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs new file mode 100644 index 00000000..5cc4967b --- /dev/null +++ b/src/Ocelot/Configuration/Validator/FileConfigurationFluentValidator.cs @@ -0,0 +1,50 @@ +using FluentValidation; +using Microsoft.AspNetCore.Authentication; +using Ocelot.Configuration.File; +using Ocelot.Errors; +using Ocelot.Responses; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Ocelot.Configuration.Validator +{ + public class FileConfigurationFluentValidator : AbstractValidator, IConfigurationValidator + { + public FileConfigurationFluentValidator(IAuthenticationSchemeProvider authenticationSchemeProvider) + { + RuleFor(configuration => configuration.ReRoutes) + .SetCollectionValidator(new ReRouteFluentValidator(authenticationSchemeProvider)); + RuleForEach(configuration => configuration.ReRoutes) + .Must((config, reRoute) => IsNotDuplicateIn(reRoute, config.ReRoutes)) + .WithMessage((config, reRoute) => $"duplicate downstreampath {reRoute.UpstreamPathTemplate}"); + } + + public async Task> IsValid(FileConfiguration configuration) + { + var validateResult = await ValidateAsync(configuration); + if (validateResult.IsValid) + { + return new OkResponse(new ConfigurationValidationResult(false)); + } + var errors = validateResult.Errors.Select(failure => new FileValidationFailedError(failure.ErrorMessage)); + var result = new ConfigurationValidationResult(true, errors.Cast().ToList()); + return new OkResponse(result); + } + + private static bool IsNotDuplicateIn(FileReRoute reRoute, List routes) + { + var reRoutesWithUpstreamPathTemplate = routes.Where(r => r.UpstreamPathTemplate == reRoute.UpstreamPathTemplate).ToList(); + var hasEmptyListToAllowAllHttpVerbs = reRoutesWithUpstreamPathTemplate.Any(x => x.UpstreamHttpMethod.Count == 0); + var hasDuplicateEmptyListToAllowAllHttpVerbs = reRoutesWithUpstreamPathTemplate.Count(x => x.UpstreamHttpMethod.Count == 0) > 1; + + var hasSpecificHttpVerbs = reRoutesWithUpstreamPathTemplate.Any(x => x.UpstreamHttpMethod.Count != 0); + var hasDuplicateSpecificHttpVerbs = reRoutesWithUpstreamPathTemplate.SelectMany(x => x.UpstreamHttpMethod).GroupBy(x => x.ToLower()).SelectMany(x => x.Skip(1)).Any(); + if (hasDuplicateEmptyListToAllowAllHttpVerbs || hasDuplicateSpecificHttpVerbs || (hasEmptyListToAllowAllHttpVerbs && hasSpecificHttpVerbs)) + { + return false; + } + return true; + } + } +} diff --git a/src/Ocelot/Configuration/Validator/FileConfigurationValidator.cs b/src/Ocelot/Configuration/Validator/FileConfigurationValidator.cs deleted file mode 100644 index 7b4f6dbe..00000000 --- a/src/Ocelot/Configuration/Validator/FileConfigurationValidator.cs +++ /dev/null @@ -1,223 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authentication; -using Ocelot.Configuration.File; -using Ocelot.Errors; -using Ocelot.Responses; - -namespace Ocelot.Configuration.Validator -{ - public class FileConfigurationValidator : IConfigurationValidator - { - private readonly IAuthenticationSchemeProvider _provider; - - public FileConfigurationValidator(IAuthenticationSchemeProvider provider) - { - _provider = provider; - } - - public async Task> IsValid(FileConfiguration configuration) - { - var result = CheckForDuplicateReRoutes(configuration); - - if (result.IsError) - { - return new OkResponse(result); - } - - result = CheckDownstreamTemplatePathBeingsWithForwardSlash(configuration); - - if (result.IsError) - { - return new OkResponse(result); - } - - result = CheckUpstreamTemplatePathBeingsWithForwardSlash(configuration); - - if (result.IsError) - { - return new OkResponse(result); - } - - result = await CheckForUnsupportedAuthenticationProviders(configuration); - - if (result.IsError) - { - return new OkResponse(result); - } - - result = CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(configuration); - - if (result.IsError) - { - return new OkResponse(result); - } - result = CheckForReRoutesRateLimitOptions(configuration); - - if (result.IsError) - { - return new OkResponse(result); - } - - return new OkResponse(result); - } - - private ConfigurationValidationResult CheckDownstreamTemplatePathBeingsWithForwardSlash(FileConfiguration configuration) - { - var errors = new List(); - - foreach(var reRoute in configuration.ReRoutes) - { - if(!reRoute.DownstreamPathTemplate.StartsWith("/")) - { - errors.Add(new PathTemplateDoesntStartWithForwardSlash($"{reRoute.DownstreamPathTemplate} doesnt start with forward slash")); - } - } - - if(errors.Any()) - { - return new ConfigurationValidationResult(true, errors); - } - - return new ConfigurationValidationResult(false, errors); - } - - private ConfigurationValidationResult CheckUpstreamTemplatePathBeingsWithForwardSlash(FileConfiguration configuration) - { - var errors = new List(); - - foreach(var reRoute in configuration.ReRoutes) - { - if(!reRoute.UpstreamPathTemplate.StartsWith("/")) - { - errors.Add(new PathTemplateDoesntStartWithForwardSlash($"{reRoute.DownstreamPathTemplate} doesnt start with forward slash")); - } - } - - if(errors.Any()) - { - return new ConfigurationValidationResult(true, errors); - } - - return new ConfigurationValidationResult(false, errors); - } - - private async Task CheckForUnsupportedAuthenticationProviders(FileConfiguration configuration) - { - var errors = new List(); - - foreach (var reRoute in configuration.ReRoutes) - { - var isAuthenticated = !string.IsNullOrEmpty(reRoute.AuthenticationOptions.AuthenticationProviderKey); - - if (!isAuthenticated) - { - continue; - } - - var data = await _provider.GetAllSchemesAsync(); - var schemes = data.ToList(); - if (schemes.Any(x => x.Name == reRoute.AuthenticationOptions.AuthenticationProviderKey)) - { - continue; - } - - var error = new UnsupportedAuthenticationProviderError($"{reRoute.AuthenticationOptions.AuthenticationProviderKey} is unsupported authentication provider, upstream template is {reRoute.UpstreamPathTemplate}, upstream method is {reRoute.UpstreamHttpMethod}"); - errors.Add(error); - } - - return errors.Count > 0 - ? new ConfigurationValidationResult(true, errors) - : new ConfigurationValidationResult(false); - } - - private ConfigurationValidationResult CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(FileConfiguration configuration) - { - var errors = new List(); - - foreach(var reRoute in configuration.ReRoutes) - { - if(reRoute.DownstreamPathTemplate.Contains("https://") - || reRoute.DownstreamPathTemplate.Contains("http://")) - { - errors.Add(new DownstreamPathTemplateContainsSchemeError($"{reRoute.DownstreamPathTemplate} contains scheme")); - } - } - - if(errors.Any()) - { - return new ConfigurationValidationResult(true, errors); - } - - return new ConfigurationValidationResult(false, errors); - } - - private ConfigurationValidationResult CheckForDuplicateReRoutes(FileConfiguration configuration) - { - var duplicatedUpstreamPathTemplates = new List(); - - var distinctUpstreamPathTemplates = configuration.ReRoutes.Select(x => x.UpstreamPathTemplate).Distinct(); - - foreach (string upstreamPathTemplate in distinctUpstreamPathTemplates) - { - var reRoutesWithUpstreamPathTemplate = configuration.ReRoutes.Where(x => x.UpstreamPathTemplate == upstreamPathTemplate); - - var hasEmptyListToAllowAllHttpVerbs = reRoutesWithUpstreamPathTemplate.Where(x => x.UpstreamHttpMethod.Count() == 0).Any(); - var hasDuplicateEmptyListToAllowAllHttpVerbs = reRoutesWithUpstreamPathTemplate.Where(x => x.UpstreamHttpMethod.Count() == 0).Count() > 1; - var hasSpecificHttpVerbs = reRoutesWithUpstreamPathTemplate.Where(x => x.UpstreamHttpMethod.Count() > 0).Any(); - var hasDuplicateSpecificHttpVerbs = reRoutesWithUpstreamPathTemplate.SelectMany(x => x.UpstreamHttpMethod).GroupBy(x => x.ToLower()).SelectMany(x => x.Skip(1)).Any(); - - if (hasDuplicateEmptyListToAllowAllHttpVerbs || hasDuplicateSpecificHttpVerbs || (hasEmptyListToAllowAllHttpVerbs && hasSpecificHttpVerbs)) - { - duplicatedUpstreamPathTemplates.Add(upstreamPathTemplate); - } - } - - if (duplicatedUpstreamPathTemplates.Count() == 0) - { - return new ConfigurationValidationResult(false); - } - else - { - var errors = duplicatedUpstreamPathTemplates - .Select(d => new DownstreamPathTemplateAlreadyUsedError(string.Format("Duplicate DownstreamPath: {0}", d))) - .Cast() - .ToList(); - - return new ConfigurationValidationResult(true, errors); - } - - } - - private ConfigurationValidationResult CheckForReRoutesRateLimitOptions(FileConfiguration configuration) - { - var errors = new List(); - - foreach (var reRoute in configuration.ReRoutes) - { - if (reRoute.RateLimitOptions.EnableRateLimiting) - { - if (!IsValidPeriod(reRoute)) - { - errors.Add(new RateLimitOptionsValidationError($"{reRoute.RateLimitOptions.Period} not contains scheme")); - } - } - } - - if (errors.Any()) - { - return new ConfigurationValidationResult(true, errors); - } - - return new ConfigurationValidationResult(false, errors); - } - - private static bool IsValidPeriod(FileReRoute reRoute) - { - string period = reRoute.RateLimitOptions.Period; - - return period.Contains("s") || period.Contains("m") || period.Contains("h") || period.Contains("d"); - } - } -} diff --git a/src/Ocelot/Configuration/Validator/FileValidationFailedError.cs b/src/Ocelot/Configuration/Validator/FileValidationFailedError.cs new file mode 100644 index 00000000..02255b5a --- /dev/null +++ b/src/Ocelot/Configuration/Validator/FileValidationFailedError.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Ocelot.Errors; + +namespace Ocelot.Configuration.Validator +{ + public class FileValidationFailedError : Error + { + public FileValidationFailedError(string message) : base(message, OcelotErrorCode.FileValidationFailedError) + { + + } + } +} diff --git a/src/Ocelot/Configuration/Validator/RateLimitOptionsValidationError.cs b/src/Ocelot/Configuration/Validator/RateLimitOptionsValidationError.cs deleted file mode 100644 index e467a486..00000000 --- a/src/Ocelot/Configuration/Validator/RateLimitOptionsValidationError.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Ocelot.Errors; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Ocelot.Configuration.Validator -{ - public class RateLimitOptionsValidationError : Error - { - public RateLimitOptionsValidationError(string message) - : base(message, OcelotErrorCode.RateLimitOptionsError) - { - } - } -} diff --git a/src/Ocelot/Configuration/Validator/ReRouteFluentValidator.cs b/src/Ocelot/Configuration/Validator/ReRouteFluentValidator.cs new file mode 100644 index 00000000..915be18b --- /dev/null +++ b/src/Ocelot/Configuration/Validator/ReRouteFluentValidator.cs @@ -0,0 +1,54 @@ +using FluentValidation; +using Microsoft.AspNetCore.Authentication; +using Ocelot.Configuration.File; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Ocelot.Configuration.Validator +{ + public class ReRouteFluentValidator : AbstractValidator + { + private readonly IAuthenticationSchemeProvider _authenticationSchemeProvider; + + public ReRouteFluentValidator(IAuthenticationSchemeProvider authenticationSchemeProvider) + { + _authenticationSchemeProvider = authenticationSchemeProvider; + + RuleFor(reRoute => reRoute.DownstreamPathTemplate) + .Must(path => path.StartsWith("/")) + .WithMessage("downstream path {PropertyValue} doesnt start with forward slash"); + RuleFor(reRoute => reRoute.UpstreamPathTemplate) + .Must(path => path.StartsWith("/")) + .WithMessage("upstream path {PropertyValue} doesnt start with forward slash"); + RuleFor(reRoute => reRoute.DownstreamPathTemplate) + .Must(path => !path.Contains("https://") && !path.Contains("http://")) + .WithMessage("downstream path {PropertyValue} contains scheme"); + RuleFor(reRoute => reRoute.RateLimitOptions) + .Must(IsValidPeriod) + .WithMessage("rate limit period {PropertyValue} not contains (s,m,h,d)"); + RuleFor(reRoute => reRoute.AuthenticationOptions) + .MustAsync(IsSupportedAuthenticationProviders) + .WithMessage("{PropertyValue} is unsupported authentication provider"); + } + + private async Task IsSupportedAuthenticationProviders(FileAuthenticationOptions authenticationOptions, CancellationToken cancellationToken) + { + if (string.IsNullOrEmpty(authenticationOptions.AuthenticationProviderKey)) + { + return true; + } + var schemes = await _authenticationSchemeProvider.GetAllSchemesAsync(); + var supportedSchemes = schemes.Select(scheme => scheme.Name).ToList(); + + return supportedSchemes.Contains(authenticationOptions.AuthenticationProviderKey); + } + + private static bool IsValidPeriod(FileRateLimitRule rateLimitOptions) + { + string period = rateLimitOptions.Period; + + return !rateLimitOptions.EnableRateLimiting || period.Contains("s") || period.Contains("m") || period.Contains("h") || period.Contains("d"); + } + } +} diff --git a/src/Ocelot/Configuration/Validator/UnsupportedAuthenticationProviderError.cs b/src/Ocelot/Configuration/Validator/UnsupportedAuthenticationProviderError.cs deleted file mode 100644 index e4f441bf..00000000 --- a/src/Ocelot/Configuration/Validator/UnsupportedAuthenticationProviderError.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Ocelot.Errors; - -namespace Ocelot.Configuration.Validator -{ - public class UnsupportedAuthenticationProviderError : Error - { - public UnsupportedAuthenticationProviderError(string message) - : base(message, OcelotErrorCode.UnsupportedAuthenticationProviderError) - { - } - } -} diff --git a/src/Ocelot/DependencyInjection/OcelotBuilder.cs b/src/Ocelot/DependencyInjection/OcelotBuilder.cs index 9eb6821e..3b54303a 100644 --- a/src/Ocelot/DependencyInjection/OcelotBuilder.cs +++ b/src/Ocelot/DependencyInjection/OcelotBuilder.cs @@ -72,7 +72,7 @@ namespace Ocelot.DependencyInjection _services.Configure(configurationRoot); _services.TryAddSingleton(); _services.TryAddSingleton(); - _services.TryAddSingleton(); + _services.TryAddSingleton(); _services.TryAddSingleton(); _services.TryAddSingleton(); _services.TryAddSingleton(); diff --git a/src/Ocelot/Errors/OcelotErrorCode.cs b/src/Ocelot/Errors/OcelotErrorCode.cs index 6f85df58..3b65a3fd 100644 --- a/src/Ocelot/Errors/OcelotErrorCode.cs +++ b/src/Ocelot/Errors/OcelotErrorCode.cs @@ -32,6 +32,7 @@ UnableToSetConfigInConsulError, UnmappableRequestError, RateLimitOptionsError, - PathTemplateDoesntStartWithForwardSlash + PathTemplateDoesntStartWithForwardSlash, + FileValidationFailedError } } diff --git a/src/Ocelot/Ocelot.csproj b/src/Ocelot/Ocelot.csproj index 243953b5..ca664327 100644 --- a/src/Ocelot/Ocelot.csproj +++ b/src/Ocelot/Ocelot.csproj @@ -26,6 +26,7 @@ + diff --git a/test/Ocelot.UnitTests/Configuration/ConfigurationValidationTests.cs b/test/Ocelot.UnitTests/Configuration/ConfigurationFluentValidationTests.cs similarity index 94% rename from test/Ocelot.UnitTests/Configuration/ConfigurationValidationTests.cs rename to test/Ocelot.UnitTests/Configuration/ConfigurationFluentValidationTests.cs index 77d1e278..6a1bac80 100644 --- a/test/Ocelot.UnitTests/Configuration/ConfigurationValidationTests.cs +++ b/test/Ocelot.UnitTests/Configuration/ConfigurationFluentValidationTests.cs @@ -15,17 +15,17 @@ using Xunit; namespace Ocelot.UnitTests.Configuration { - public class ConfigurationValidationTests + public class ConfigurationFluentValidationTests { private readonly IConfigurationValidator _configurationValidator; private FileConfiguration _fileConfiguration; private Response _result; private Mock _provider; - public ConfigurationValidationTests() + public ConfigurationFluentValidationTests() { - _provider = new Mock(); - _configurationValidator = new FileConfigurationValidator(_provider.Object); + _provider = new Mock(); + _configurationValidator = new FileConfigurationFluentValidator(_provider.Object); } [Fact] @@ -44,6 +44,7 @@ namespace Ocelot.UnitTests.Configuration })) .When(x => x.WhenIValidateTheConfiguration()) .Then(x => x.ThenTheResultIsNotValid()) + .Then(x => x.ThenTheErrorIs()) .BDDfy(); } @@ -147,7 +148,6 @@ namespace Ocelot.UnitTests.Configuration })) .When(x => x.WhenIValidateTheConfiguration()) .Then(x => x.ThenTheResultIsNotValid()) - .And(x => x.ThenTheErrorIs()) .BDDfy(); } @@ -172,10 +172,10 @@ namespace Ocelot.UnitTests.Configuration })) .When(x => x.WhenIValidateTheConfiguration()) .Then(x => x.ThenTheResultIsNotValid()) - .And(x => x.ThenTheErrorIs()) .BDDfy(); } + private void GivenAConfiguration(FileConfiguration fileConfiguration) { _fileConfiguration = fileConfiguration; @@ -225,6 +225,5 @@ namespace Ocelot.UnitTests.Configuration return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name))); } } - } -} \ No newline at end of file +} diff --git a/test/Ocelot.UnitTests/Configuration/FileConfigurationCreatorTests.cs b/test/Ocelot.UnitTests/Configuration/FileConfigurationCreatorTests.cs index 975f71da..aef99941 100644 --- a/test/Ocelot.UnitTests/Configuration/FileConfigurationCreatorTests.cs +++ b/test/Ocelot.UnitTests/Configuration/FileConfigurationCreatorTests.cs @@ -503,7 +503,7 @@ namespace Ocelot.UnitTests.Configuration [Fact] public void should_return_validation_errors() { - var errors = new List {new PathTemplateDoesntStartWithForwardSlash("some message")}; + var errors = new List {new FileValidationFailedError("some message")}; this.Given(x => x.GivenTheConfigIs(new FileConfiguration())) .And(x => x.GivenTheConfigIsInvalid(errors)) diff --git a/test/Ocelot.UnitTests/Responder/ErrorsToHttpStatusCodeMapperTests.cs b/test/Ocelot.UnitTests/Responder/ErrorsToHttpStatusCodeMapperTests.cs index c1165bc4..23809fd8 100644 --- a/test/Ocelot.UnitTests/Responder/ErrorsToHttpStatusCodeMapperTests.cs +++ b/test/Ocelot.UnitTests/Responder/ErrorsToHttpStatusCodeMapperTests.cs @@ -54,6 +54,7 @@ namespace Ocelot.UnitTests.Responder [InlineData(OcelotErrorCode.DownstreampathTemplateAlreadyUsedError)] [InlineData(OcelotErrorCode.DownstreamPathTemplateContainsSchemeError)] [InlineData(OcelotErrorCode.DownstreamSchemeNullOrEmptyError)] + [InlineData(OcelotErrorCode.FileValidationFailedError)] [InlineData(OcelotErrorCode.InstructionNotForClaimsError)] [InlineData(OcelotErrorCode.NoInstructionsError)] [InlineData(OcelotErrorCode.ParsingConfigurationHeaderError)] @@ -120,7 +121,7 @@ namespace Ocelot.UnitTests.Responder // If this test fails then it's because the number of error codes has changed. // You should make the appropriate changes to the test cases here to ensure // they cover all the error codes, and then modify this assertion. - Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(31, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?"); + Enum.GetNames(typeof(OcelotErrorCode)).Length.ShouldBe(32, "Looks like the number of error codes has changed. Do you need to modify ErrorsToHttpStatusCodeMapper?"); } private void ShouldMapErrorToStatusCode(OcelotErrorCode errorCode, HttpStatusCode expectedHttpStatusCode)