public void ProcessRequestAsync_IfExceptionIsNotHttpResponseException_DisposesRequest()
        {
            // Arrange
            using (HttpRequestMessage request = CreateRequest())
                using (SpyDisposable spy = new SpyDisposable())
                {
                    request.RegisterForDispose(spy);

                    ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(CreateException());
                    IExceptionLogger      logger        = CreateDummyLogger();
                    IExceptionHandler     handler       = CreateDummyHandler();

                    HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

                    Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>();
                    responseBaseMock.SetupGet(r => r.Cache).Returns(() => new Mock <HttpCachePolicyBase>().Object);
                    HttpResponseBase responseBase = responseBaseMock.Object;
                    HttpContextBase  contextBase  = CreateStubContextBase(responseBase);
                    contextBase.SetHttpRequestMessage(request);

                    // Act
                    Task task = product.ProcessRequestAsync(contextBase);

                    // Assert
                    Assert.NotNull(task);
                    task.WaitUntilCompleted();
                    Assert.Equal(TaskStatus.Faulted, task.Status);

                    Assert.True(spy.Disposed);
                    Assert.ThrowsObjectDisposed(() => request.Method = HttpMethod.Get,
                                                typeof(HttpRequestMessage).FullName);
                }
        }
        public void ProcessRequestAsync_WritingResponseCanceled_CancelsRequest()
        {
            // Arrange
            using (HttpRequestMessage request = CreateRequest())
            {
                ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(new HttpResponseException(HttpStatusCode.OK));
                IExceptionLogger      logger        = CreateDummyLogger();
                IExceptionHandler     handler       = CreateDummyHandler();

                HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

                Mock <HttpRequestBase> requestBase = new Mock <HttpRequestBase>(MockBehavior.Strict);
                requestBase.Setup(r => r.Abort()).Verifiable();

                Mock <HttpResponseBase> responseBase = new Mock <HttpResponseBase>(MockBehavior.Strict);
                responseBase.SetupSet(r => r.StatusCode = It.IsAny <int>()).Throws(new OperationCanceledException());

                HttpContextBase contextBase = CreateStubContextBase(requestBase.Object, responseBase.Object);
                contextBase.SetHttpRequestMessage(request);

                // Act
                Task task = product.ProcessRequestAsync(contextBase);

                // Assert
                Assert.NotNull(task);
                task.WaitUntilCompleted();
                Assert.Equal(TaskStatus.RanToCompletion, task.Status);

                requestBase.Verify(r => r.Abort(), Times.Once());
            }
        }
        public void ProcessRequestAsync_IfExceptionIsHttpResponseException_UsesExceptionResponse()
        {
            // Arrange
            HttpStatusCode expectedStatusCode = HttpStatusCode.Forbidden;

            using (HttpResponseMessage response = CreateResponse(expectedStatusCode))
                using (HttpRequestMessage request = CreateRequest())
                {
                    ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(new HttpResponseException(response));
                    IExceptionLogger      logger        = CreateDummyLogger();
                    IExceptionHandler     handler       = CreateDummyHandler();

                    HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

                    int statusCode = 0;
                    Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>();
                    responseBaseMock.SetupSet(r => r.StatusCode = It.IsAny <int>()).Callback <int>((s) => statusCode = s);
                    responseBaseMock.SetupGet(r => r.Cache).Returns(() => new Mock <HttpCachePolicyBase>().Object);
                    HttpResponseBase responseBase = responseBaseMock.Object;
                    HttpContextBase  contextBase  = CreateStubContextBase(responseBase);
                    contextBase.SetHttpRequestMessage(request);

                    // Act
                    Task task = product.ProcessRequestAsync(contextBase);

                    // Assert
                    Assert.NotNull(task);
                    task.WaitUntilCompleted();
                    Assert.Equal(TaskStatus.RanToCompletion, task.Status);

                    Assert.Equal((int)expectedStatusCode, statusCode);
                }
        }
        public void ProcessRequestAsync_IfHandlerDoesNotHandle_ReturnsTaskPropagatingException()
        {
            // Arrange
            Exception             expectedException  = CreateExceptionWithCallStack();
            string                expectedStackTrace = expectedException.StackTrace;
            ExceptionDispatchInfo exceptionInfo      = CreateExceptionInfo(expectedException);

            IExceptionLogger  logger  = CreateStubExceptionLogger();
            IExceptionHandler handler = CreateStubExceptionHandler();

            HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

            HttpResponseBase responseBase = CreateStubResponseBase();
            HttpContextBase  contextBase  = CreateStubContextBase(responseBase);

            using (HttpRequestMessage request = CreateRequest())
            {
                contextBase.SetHttpRequestMessage(request);

                // Act
                Task task = product.ProcessRequestAsync(contextBase);

                // Assert
                Assert.NotNull(task);
                task.WaitUntilCompleted();
                Assert.Equal(TaskStatus.Faulted, task.Status);
                Assert.NotNull(task.Exception); // Guard
                Exception exception = task.Exception.GetBaseException();
                Assert.Same(expectedException, exception);
                Assert.NotNull(exception.StackTrace);
                Assert.True(exception.StackTrace.StartsWith(expectedStackTrace));
            }
        }
        public async Task ProcessRequestAsync_IfExceptionIsNotHttpResponseException_DisposesRequest()
        {
            // Arrange
            using (HttpRequestMessage request = CreateRequest())
                using (SpyDisposable spy = new SpyDisposable())
                {
                    request.RegisterForDispose(spy);

                    ExceptionDispatchInfo   exceptionInfo = CreateExceptionInfo(CreateException());
                    Mock <IExceptionLogger> loggerMock    = new Mock <IExceptionLogger>(MockBehavior.Strict);
                    loggerMock
                    .Setup(l => l.LogAsync(It.IsAny <ExceptionLoggerContext>(), It.IsAny <CancellationToken>()))
                    .Returns(Task.FromResult(0));
                    Mock <IExceptionHandler> handlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict);
                    handlerMock
                    .Setup(h => h.HandleAsync(It.IsAny <ExceptionHandlerContext>(), It.IsAny <CancellationToken>()))
                    .Returns(Task.FromResult(0));

                    HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, loggerMock.Object, handlerMock.Object);

                    Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>();
                    responseBaseMock.SetupGet(r => r.Cache).Returns(() => new Mock <HttpCachePolicyBase>().Object);
                    HttpResponseBase responseBase = responseBaseMock.Object;
                    HttpContextBase  contextBase  = CreateStubContextBase(responseBase);
                    contextBase.SetHttpRequestMessage(request);

                    // Act & Assert
                    await Assert.ThrowsAsync <Exception>(() => product.ProcessRequestAsync(contextBase));

                    Assert.True(spy.Disposed);
                    Assert.ThrowsObjectDisposed(() => request.Method = HttpMethod.Get,
                                                typeof(HttpRequestMessage).FullName);
                }
        }
        public async Task ProcessRequestAsync_IfHandlerDoesNotHandle_ReturnsTaskPropagatingException()
        {
            // Arrange
            Exception             expectedException  = CreateExceptionWithCallStack();
            string                expectedStackTrace = expectedException.StackTrace;
            ExceptionDispatchInfo exceptionInfo      = CreateExceptionInfo(expectedException);

            IExceptionLogger  logger  = CreateStubExceptionLogger();
            IExceptionHandler handler = CreateStubExceptionHandler();

            HttpRouteExceptionHandler product = CreateProductUnderTest(
                exceptionInfo,
                logger,
                handler
                );

            HttpResponseBase responseBase = CreateStubResponseBase();
            HttpContextBase  contextBase  = CreateStubContextBase(responseBase);

            using (HttpRequestMessage request = CreateRequest())
            {
                contextBase.SetHttpRequestMessage(request);

                // Act & Assert
                var exception = await Assert.ThrowsAsync <Exception>(
                    () => product.ProcessRequestAsync(contextBase)
                    );

                Assert.Same(expectedException, exception);
                Assert.NotNull(exception.StackTrace);
                Assert.StartsWith(expectedStackTrace, exception.StackTrace);
            }
        }
        public async Task ProcessRequestAsync_RouteCanceled_CancelsRequest()
        {
            // Arrange
            using (HttpRequestMessage request = CreateRequest())
            {
                ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(new OperationCanceledException());
                IExceptionLogger      logger        = CreateDummyLogger();
                IExceptionHandler     handler       = CreateDummyHandler();

                HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

                Mock <HttpRequestBase> requestBase = new Mock <HttpRequestBase>(MockBehavior.Strict);
                requestBase.Setup(r => r.Abort()).Verifiable();

                Mock <HttpResponseBase> responseBase = new Mock <HttpResponseBase>(MockBehavior.Strict);

                HttpContextBase contextBase = CreateStubContextBase(requestBase.Object, responseBase.Object);
                contextBase.SetHttpRequestMessage(request);

                // Act
                await product.ProcessRequestAsync(contextBase);

                // Assert
                requestBase.Verify(r => r.Abort(), Times.Once());
            }
        }
        public async Task ProcessRequestAsync_IfExceptionIsHttpResponseException_DisposesRequestAndResponse()
        {
            // Arrange
            using (HttpResponseMessage response = CreateResponse())
                using (HttpRequestMessage request = CreateRequest())
                    using (SpyDisposable spy = new SpyDisposable())
                    {
                        request.RegisterForDispose(spy);

                        ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo(new HttpResponseException(response));
                        IExceptionLogger      logger        = CreateDummyLogger();
                        IExceptionHandler     handler       = CreateDummyHandler();

                        HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

                        Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>();
                        responseBaseMock.SetupGet(r => r.Cache).Returns(() => new Mock <HttpCachePolicyBase>().Object);
                        HttpResponseBase responseBase = responseBaseMock.Object;
                        HttpContextBase  contextBase  = CreateStubContextBase(responseBase);
                        contextBase.SetHttpRequestMessage(request);

                        // Act
                        await product.ProcessRequestAsync(contextBase);

                        // Assert
                        Assert.True(spy.Disposed);
                        Assert.ThrowsObjectDisposed(() => request.Method = HttpMethod.Get,
                                                    typeof(HttpRequestMessage).FullName);
                        Assert.ThrowsObjectDisposed(() => response.StatusCode = HttpStatusCode.OK,
                                                    typeof(HttpResponseMessage).FullName);
                    }
        }
        public async Task ProcessRequestAsync_IfExceptionIsNotHttpResponseException_CallsExceptionServices()
        {
            // Arrange
            Exception             expectedException = CreateException();
            ExceptionDispatchInfo exceptionInfo     = CreateExceptionInfo(expectedException);

            Mock <IExceptionLogger>  loggerMock  = CreateStubExceptionLoggerMock();
            IExceptionLogger         logger      = loggerMock.Object;
            Mock <IExceptionHandler> handlerMock = CreateStubExceptionHandlerMock();
            IExceptionHandler        handler     = handlerMock.Object;

            HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

            HttpResponseBase responseBase = CreateStubResponseBase();
            HttpContextBase  contextBase  = CreateStubContextBase(responseBase);

            using (HttpRequestMessage expectedRequest = new HttpRequestMessage())
            {
                contextBase.SetHttpRequestMessage(expectedRequest);

                // Act & Assert
                await Assert.ThrowsAsync <Exception>(() => product.ProcessRequestAsync(contextBase));

                Func <ExceptionContext, bool> exceptionContextMatches = (c) =>
                                                                        c != null &&
                                                                        c.Exception == expectedException &&
                                                                        c.CatchBlock == WebHostExceptionCatchBlocks.HttpWebRoute &&
                                                                        c.Request == expectedRequest;

                loggerMock.Verify(l => l.LogAsync(It.Is <ExceptionLoggerContext>(c =>
                                                                                 exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once());
                handlerMock.Verify(l => l.HandleAsync(It.Is <ExceptionHandlerContext>(c =>
                                                                                      exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once());
            }
        }
        public async Task ProcessRequestAsync_IfHandlerHandles_UsesHandlerResult()
        {
            // Arrange
            ExceptionDispatchInfo exceptionInfo = CreateExceptionInfo();

            IExceptionLogger logger = CreateStubExceptionLogger();

            HttpStatusCode           expectedStatusCode = HttpStatusCode.Ambiguous;
            Mock <IExceptionHandler> handlerMock        = new Mock <IExceptionHandler>(MockBehavior.Strict);

            handlerMock
            .Setup(
                h =>
                h.HandleAsync(
                    It.IsAny <ExceptionHandlerContext>(),
                    It.IsAny <CancellationToken>()
                    )
                )
            .Returns <ExceptionHandlerContext, CancellationToken>(
                (c, i) =>
            {
                c.Result = new StatusCodeResult(
                    expectedStatusCode,
                    new HttpRequestMessage()
                    );
                return(Task.FromResult(0));
            }
                );
            IExceptionHandler handler = handlerMock.Object;

            HttpRouteExceptionHandler product = CreateProductUnderTest(
                exceptionInfo,
                logger,
                handler
                );

            int statusCode = 0;
            Mock <HttpResponseBase> responseBaseMock = new Mock <HttpResponseBase>();

            responseBaseMock
            .SetupSet(r => r.StatusCode       = It.IsAny <int>())
            .Callback <int>((c) => statusCode = c);
            responseBaseMock
            .SetupGet(r => r.Cache)
            .Returns(() => new Mock <HttpCachePolicyBase>().Object);
            HttpResponseBase responseBase = responseBaseMock.Object;
            HttpContextBase  contextBase  = CreateStubContextBase(responseBase);

            using (HttpRequestMessage request = CreateRequest())
            {
                contextBase.SetHttpRequestMessage(request);

                // Act
                await product.ProcessRequestAsync(contextBase);

                // Assert
                Assert.Equal((int)expectedStatusCode, statusCode);
            }
        }
        public void ProcessRequestAsync_IfCopyToAsyncOnErrorResponseThrows_CallsExceptionLogger()
        {
            // Arrange
            Exception             expectedOriginalException = CreateException();
            ExceptionDispatchInfo exceptionInfo             = CreateExceptionInfo(expectedOriginalException);

            Mock <IExceptionLogger> loggerMock = CreateStubExceptionLoggerMock();
            IExceptionLogger        logger     = loggerMock.Object;

            Exception expectedErrorException = CreateException();

            using (HttpResponseMessage expectedErrorResponse = new HttpResponseMessage())
                using (HttpRequestMessage expectedRequest = new HttpRequestMessage())
                {
                    expectedErrorResponse.Content = CreateFaultingContent(expectedErrorException);

                    Mock <IExceptionHandler> handlerMock = new Mock <IExceptionHandler>(MockBehavior.Strict);
                    handlerMock
                    .Setup(h => h.HandleAsync(It.IsAny <ExceptionHandlerContext>(), It.IsAny <CancellationToken>()))
                    .Returns <ExceptionHandlerContext, CancellationToken>((c, i) =>
                    {
                        c.Result = new ResponseMessageResult(expectedErrorResponse);
                        return(Task.FromResult(0));
                    });
                    IExceptionHandler handler = handlerMock.Object;

                    HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

                    HttpResponseBase responseBase = CreateStubResponseBase(Stream.Null);
                    HttpContextBase  contextBase  = CreateStubContextBase(responseBase);
                    contextBase.SetHttpRequestMessage(expectedRequest);

                    // Act
                    Task task = product.ProcessRequestAsync(contextBase);

                    // Assert
                    Assert.NotNull(task);
                    task.WaitUntilCompleted();
                    Assert.Equal(TaskStatus.RanToCompletion, task.Status);

                    loggerMock.Verify(l => l.LogAsync(It.Is <ExceptionLoggerContext>(c =>
                                                                                     c.CanBeHandled == true &&
                                                                                     c.ExceptionContext != null &&
                                                                                     c.ExceptionContext.Exception == expectedOriginalException &&
                                                                                     c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpWebRoute &&
                                                                                     c.ExceptionContext.Request == expectedRequest),
                                                      CancellationToken.None), Times.Once());
                    loggerMock.Verify(l => l.LogAsync(It.Is <ExceptionLoggerContext>(c =>
                                                                                     c.CanBeHandled == false &&
                                                                                     c.ExceptionContext != null &&
                                                                                     c.ExceptionContext.Exception == expectedErrorException &&
                                                                                     c.ExceptionContext.CatchBlock == WebHostExceptionCatchBlocks.HttpControllerHandlerBufferError &&
                                                                                     c.ExceptionContext.Request == expectedRequest &&
                                                                                     c.ExceptionContext.Response == expectedErrorResponse),
                                                      CancellationToken.None), Times.Once());
                }
        }
        public void ExceptionInfo_IfUsingExceptionInfoConstructor_ReturnsSpecifiedInstance()
        {
            // Arrange
            ExceptionDispatchInfo     expectedExceptionInfo = CreateExceptionInfo();
            HttpRouteExceptionHandler product = CreateProductUnderTest(expectedExceptionInfo);

            // Act
            ExceptionDispatchInfo exceptionInfo = product.ExceptionInfo;

            // Assert
            Assert.Same(exceptionInfo, expectedExceptionInfo);
        }
        public void ExceptionHandler_IfUsingExceptionInfoConstructor_ReturnsExceptionServicesInstance()
        {
            // Arrange
            ExceptionDispatchInfo     exceptionInfo = CreateExceptionInfo();
            HttpRouteExceptionHandler product       = CreateProductUnderTest(exceptionInfo);

            // Act
            IExceptionHandler handler = product.ExceptionHandler;

            // Assert
            IExceptionHandler expectedHandler = ExceptionServices.GetHandler(GlobalConfiguration.Configuration);

            Assert.Same(expectedHandler, handler);
        }
        public void ExceptionHandler_ReturnsSpecifiedInstance()
        {
            // Arrange
            ExceptionDispatchInfo     exceptionInfo   = CreateExceptionInfo();
            IExceptionLogger          logger          = CreateDummyLogger();
            IExceptionHandler         expectedHandler = CreateDummyHandler();
            HttpRouteExceptionHandler product         = CreateProductUnderTest(exceptionInfo, logger, expectedHandler);

            // Act
            IExceptionHandler handler = product.ExceptionHandler;

            // Assert
            Assert.Same(expectedHandler, handler);
        }
Ejemplo n.º 15
0
        public void GetHttpHandler_ReturnsExceptionHandlerWithExceptionInfo()
        {
            // Arrange
            ExceptionDispatchInfo expectedExceptionInfo = CreateExceptionInfo();
            IRouteHandler         product        = CreateProductUnderTest(expectedExceptionInfo);
            RequestContext        requestContext = null;

            // Act
            IHttpHandler handler = product.GetHttpHandler(requestContext);

            // Assert
            HttpRouteExceptionHandler typedHandler = Assert.IsType <HttpRouteExceptionHandler>(handler);

            Assert.Same(expectedExceptionInfo, typedHandler.ExceptionInfo);
        }
        public void ProcessRequestAsync_IfExceptionIsNotHttpResponseException_CallsExceptionServices()
        {
            // Arrange
            Exception             expectedException = CreateException();
            ExceptionDispatchInfo exceptionInfo     = CreateExceptionInfo(expectedException);

            Mock <IExceptionLogger>  loggerMock  = CreateStubExceptionLoggerMock();
            IExceptionLogger         logger      = loggerMock.Object;
            Mock <IExceptionHandler> handlerMock = CreateStubExceptionHandlerMock();
            IExceptionHandler        handler     = handlerMock.Object;

            HttpRouteExceptionHandler product = CreateProductUnderTest(exceptionInfo, logger, handler);

            HttpResponseBase responseBase = CreateStubResponseBase();
            HttpContextBase  contextBase  = CreateStubContextBase(responseBase);

            using (HttpRequestMessage expectedRequest = new HttpRequestMessage())
            {
                contextBase.SetHttpRequestMessage(expectedRequest);

                // Act
                Task task = product.ProcessRequestAsync(contextBase);

                // Assert
                Assert.NotNull(task);
                task.WaitUntilCompleted();
                Assert.Equal(TaskStatus.Faulted, task.Status);

                Func <ExceptionContext, bool> exceptionContextMatches = (c) =>
                                                                        c != null &&
                                                                        c.Exception == expectedException &&
                                                                        c.CatchBlock == WebHostExceptionCatchBlocks.HttpWebRoute &&
                                                                        c.Request == expectedRequest;

                loggerMock.Verify(l => l.LogAsync(It.Is <ExceptionLoggerContext>(c =>
                                                                                 c.CanBeHandled == true && exceptionContextMatches(c.ExceptionContext)),
                                                  CancellationToken.None), Times.Once());
                handlerMock.Verify(l => l.HandleAsync(It.Is <ExceptionHandlerContext>(c =>
                                                                                      exceptionContextMatches(c.ExceptionContext)), CancellationToken.None), Times.Once());
            }
        }