using System.Collections.Generic; using System.Net.Http; using Microsoft.AspNetCore.Http; using Moq; using Ocelot.Infrastructure.RequestData; using Ocelot.Errors; using Ocelot.Logging; using Ocelot.Responder; using Ocelot.Responder.Middleware; using Ocelot.Responses; using TestStack.BDDfy; using Xunit; namespace Ocelot.UnitTests.Responder { public class ResponderMiddlewareTestsV2 { private readonly ResponderMiddleware _middleware; private readonly Mock _responder; private readonly Mock _scopedRepository; private readonly Mock _codeMapper; private readonly Mock _next; private readonly Mock _loggerFactory; private readonly Mock _logger; private readonly Mock _httpContext; private OkResponse _response; private int _mappedStatusCode; private List _pipelineErrors; public ResponderMiddlewareTestsV2() { _responder = new Mock(); _codeMapper = new Mock(); _next = new Mock(); _logger = new Mock(); _scopedRepository = new Mock(); _loggerFactory = new Mock(); _httpContext = new Mock(); _loggerFactory .Setup(lf => lf.CreateLogger()) .Returns(_logger.Object); _middleware = new ResponderMiddleware(_next.Object, _responder.Object, _loggerFactory.Object, _scopedRepository.Object, _codeMapper.Object); GivenTheHttpResponseMessageIs(new HttpResponseMessage()); } [Fact] public void NoPipelineErrors() { this.Given(x => x.GivenThereAreNoPipelineErrors()) .When(x => x.WhenICallTheMiddleware()) .Then(_ => ThenTheNextMiddlewareIsCalled()) .And(x => x.ThenThereAreNoErrorsOnTheHttpContext()) .BDDfy(); } [Fact] public void PipelineErrors() { this.Given(_ => GivenThereArePipelineErrors()) .And(_ => GivenTheErrorsCanBeMappedToAStatusCode()) .When(_ => WhenICallTheMiddleware()) .Then(_ => ThenTheNextMiddlewareIsCalled()) .And(x => x.ThenTheErrorsAreLogged()) .And(_ => ThenTheErrorsAreMappedToAnHttpStatus()) .And(_ => ThenAnErrorResponseIsSetOnTheHttpContext()) .BDDfy(); } private void GivenTheHttpResponseMessageIs(HttpResponseMessage response) { _response = new OkResponse(response); _scopedRepository .Setup(x => x.Get(It.IsAny())) .Returns(_response); } private void GivenThereAreNoPipelineErrors() { GivenThereArePipelineErrors(new List()); } private void GivenThereArePipelineErrors() { GivenThereArePipelineErrors(new List() { new AnyError() }); } private void GivenThereArePipelineErrors(List pipelineErrors) { _pipelineErrors = pipelineErrors; _scopedRepository .Setup(x => x.Get("OcelotMiddlewareError")) .Returns(new OkResponse(_pipelineErrors.Count != 0)); _scopedRepository .Setup(sr => sr.Get>("OcelotMiddlewareErrors")) .Returns(new OkResponse>(_pipelineErrors)); } private void GivenTheErrorsCanBeMappedToAStatusCode() { _mappedStatusCode = 500; //TODO: autofixture _codeMapper.Setup(cm => cm.Map(It.IsAny>())) .Returns(_mappedStatusCode); } private void WhenICallTheMiddleware() { _middleware.Invoke(_httpContext.Object).GetAwaiter().GetResult(); } private void ThenTheNextMiddlewareIsCalled() { _next.Verify(n => n(_httpContext.Object), Times.Once); } private void ThenTheErrorsAreMappedToAnHttpStatus() { _codeMapper.Verify(cm => cm.Map(_pipelineErrors), Times.Once); } private void ThenTheErrorsAreLogged() { _logger.Verify(l => l.LogError($"{_pipelineErrors.Count} pipeline errors found in ResponderMiddleware. Setting error response status code"), Times.Once); } private void ThenThereAreNoErrorsOnTheHttpContext() { _responder.Verify(r => r.SetErrorResponseOnContext(It.IsAny(), It.IsAny()), Times.Never); } private void ThenAnErrorResponseIsSetOnTheHttpContext() { _responder.Verify(r => r.SetErrorResponseOnContext(_httpContext.Object, _mappedStatusCode), Times.Once); } } }