Ocelot/test/Ocelot.UnitTests/Errors/ExceptionHandlerMiddlewareTests.cs
Tom Pallister 05481f3af3
Feature/use any id server for admin area (#232)
* initial commits around using any id servers

* add your own id server for admin area

* lots of refactoring, now instead of injecting IWebHostBuilder we just set the Ocelot base url as a configuration extension method..this means people can pass it in on the command line aswell as hardcode which is OK I guess, also can now use your own IdentityServer to authenticate admin area

* updated docs for #231

* some tests that hopefully bump up coverage
2018-02-14 18:53:18 +00:00

194 lines
6.6 KiB
C#

namespace Ocelot.UnitTests.Errors
{
using System;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Errors.Middleware;
using Ocelot.Logging;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.Provider;
using Moq;
using Ocelot.Configuration;
using Rafty.Concensus;
using Ocelot.Errors;
public class ExceptionHandlerMiddlewareTests : ServerHostedMiddlewareTest
{
bool _shouldThrowAnException = false;
private Mock<IOcelotConfigurationProvider> _provider;
public ExceptionHandlerMiddlewareTests()
{
_provider = new Mock<IOcelotConfigurationProvider>();
GivenTheTestServerIsConfigured();
}
[Fact]
public void NoDownstreamException()
{
var config = new OcelotConfiguration(null, null, null, null);
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
.And(_ => GivenTheConfigurationIs(config))
.When(_ => WhenICallTheMiddleware())
.Then(_ => ThenTheResponseIsOk())
.And(_ => TheRequestIdIsNotSet())
.BDDfy();
}
[Fact]
public void DownstreamException()
{
var config = new OcelotConfiguration(null, null, null, null);
this.Given(_ => GivenAnExceptionWillBeThrownDownstream())
.And(_ => GivenTheConfigurationIs(config))
.When(_ => WhenICallTheMiddleware())
.Then(_ => ThenTheResponseIsError())
.BDDfy();
}
[Fact]
public void ShouldSetRequestId()
{
var config = new OcelotConfiguration(null, null, null, "requestidkey");
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
.And(_ => GivenTheConfigurationIs(config))
.When(_ => WhenICallTheMiddlewareWithTheRequestIdKey("requestidkey", "1234"))
.Then(_ => ThenTheResponseIsOk())
.And(_ => TheRequestIdIsSet("RequestId", "1234"))
.BDDfy();
}
[Fact]
public void ShouldNotSetRequestId()
{
var config = new OcelotConfiguration(null, null, null, null);
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
.And(_ => GivenTheConfigurationIs(config))
.When(_ => WhenICallTheMiddlewareWithTheRequestIdKey("requestidkey", "1234"))
.Then(_ => ThenTheResponseIsOk())
.And(_ => TheRequestIdIsNotSet())
.BDDfy();
}
[Fact]
public void should_throw_exception_if_config_provider_returns_error()
{
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
.And(_ => GivenTheConfigReturnsError())
.When(_ => WhenICallTheMiddlewareWithTheRequestIdKey("requestidkey", "1234"))
.Then(_ => ThenAnExceptionIsThrown())
.BDDfy();
}
[Fact]
public void should_throw_exception_if_config_provider_throws()
{
this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
.And(_ => GivenTheConfigThrows())
.When(_ => WhenICallTheMiddlewareWithTheRequestIdKey("requestidkey", "1234"))
.Then(_ => ThenAnExceptionIsThrown())
.BDDfy();
}
private void GivenTheConfigThrows()
{
var ex = new Exception("outer", new Exception("inner"));
_provider
.Setup(x => x.Get()).ThrowsAsync(ex);
}
private void ThenAnExceptionIsThrown()
{
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
}
private void GivenTheConfigReturnsError()
{
var config = new OcelotConfiguration(null, null, null, null);
var response = new Ocelot.Responses.ErrorResponse<IOcelotConfiguration>(new FakeError());
_provider
.Setup(x => x.Get()).ReturnsAsync(response);
}
public class FakeError : Error
{
public FakeError()
: base("meh", OcelotErrorCode.CannotAddDataError)
{
}
}
private void TheRequestIdIsSet(string key, string value)
{
ScopedRepository.Verify(x => x.Add<string>(key, value), Times.Once);
}
private void GivenTheConfigurationIs(IOcelotConfiguration config)
{
var response = new Ocelot.Responses.OkResponse<IOcelotConfiguration>(config);
_provider
.Setup(x => x.Get()).ReturnsAsync(response);
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton<IOcelotConfigurationProvider>(_provider.Object);
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseExceptionHandlerMiddleware();
app.Run(DownstreamExceptionSimulator);
}
private async Task DownstreamExceptionSimulator(HttpContext context)
{
await Task.CompletedTask;
if (_shouldThrowAnException)
{
throw new Exception("BOOM");
}
context.Response.StatusCode = (int)HttpStatusCode.OK;
}
private void GivenAnExceptionWillNotBeThrownDownstream()
{
_shouldThrowAnException = false;
}
private void GivenAnExceptionWillBeThrownDownstream()
{
_shouldThrowAnException = true;
}
private void ThenTheResponseIsOk()
{
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.OK);
}
private void ThenTheResponseIsError()
{
ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
}
private void TheRequestIdIsNotSet()
{
ScopedRepository.Verify(x => x.Add<string>(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
}
}
}