public void HandleRequest_should_allow_module_after_hook_to_add_items_to_context()
        {
            // Given
            var route = new FakeRoute();

            var before = new BeforePipeline();
            before += ctx => null;

            var after = new AfterPipeline();
            after += ctx => ctx.Items.Add("RoutePostReq", new object());

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                null);

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            context.Items.ContainsKey("RoutePostReq").ShouldBeTrue();
        }
        public async Task Should_invoke_module_before_hook_followed_by_resolved_route_followed_by_module_after_hook()
        {
            // Given
            var capturedExecutionOrder = new List <string>();
            var expectedExecutionOrder = new[] { "Prehook", "RouteInvoke", "Posthook" };

            var route = new FakeRoute
            {
                Action = (parameters, token) =>
                {
                    capturedExecutionOrder.Add("RouteInvoke");
                    return(CreateResponseTask(null));
                }
            };

            var before = new BeforePipeline();

            before += (ctx) =>
            {
                capturedExecutionOrder.Add("Prehook");
                return(null);
            };

            var after = new AfterPipeline();

            after += (ctx) =>
            {
                capturedExecutionOrder.Add("Posthook");
            };

            var resolvedRoute = new ResolveResult
            {
                Route      = route,
                Parameters = DynamicDictionary.Empty,
                Before     = before,
                After      = after,
                OnError    = null
            };

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            await this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            capturedExecutionOrder.Count().ShouldEqual(3);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public void Should_invoke_route_with_provided_parameters()
        {
            // Given
            var parameters = new DynamicDictionary();
            var route = new FakeRoute(10);
            var context = new NancyContext();

            // When
            this.invoker.Invoke(route, parameters, context);

            // Then
            Assert.Same(route.ParametersUsedToInvokeAction, parameters);
        }
示例#4
0
        public void Should_return_response_when_route_returns_string()
        {
            // Given
            var parameters = new DynamicDictionary();
            var route      = new FakeRoute("Hello World");
            var context    = new NancyContext();

            // When
            var result = this.invoker.Invoke(route, parameters, context);

            // Then
            Assert.IsType <Response>(result);
        }
        public void Should_invoke_route_with_provided_parameters()
        {
            // Given
            var parameters = new DynamicDictionary();
            var route      = new FakeRoute(10);
            var context    = new NancyContext();

            // When
            this.invoker.Invoke(route, new CancellationToken(), parameters, context);

            // Then
            Assert.Same(route.ParametersUsedToInvokeAction, parameters);
        }
        public void Should_return_response_when_route_returns_status_code()
        {
            // Given
            var parameters = new DynamicDictionary();
            var route      = new FakeRoute(HttpStatusCode.OK);
            var context    = new NancyContext();

            // When
            var result = this.invoker.Invoke(route, new CancellationToken(), parameters, context).Result;

            // Then
            Assert.IsType <Response>(result);
        }
        public void Should_return_response_when_route_returns_int()
        {
            // Given
            var parameters = new DynamicDictionary();
            var route = new FakeRoute(10);
            var context = new NancyContext();

            // When
            var result = this.invoker.Invoke(route, parameters, context);

            // Then
            Assert.IsType<Response>(result);
        }
示例#8
0
        public NancyEngineFixture()
        {
            this.resolver = A.Fake <IRouteResolver>();
            this.response = new Response();
            this.route    = new FakeRoute(response);
            this.context  = new NancyContext();

            contextFactory = A.Fake <INancyContextFactory>();
            A.CallTo(() => contextFactory.Create()).Returns(context);

            A.CallTo(() => resolver.Resolve(A <NancyContext> .Ignored, A <IRouteCache> .Ignored)).Returns(new ResolveResult(route, DynamicDictionary.Empty, null, null));

            this.engine = new NancyEngine(resolver, A.Fake <IRouteCache>(), contextFactory);
        }
        public void Should_return_response_when_route_returns_action()
        {
            // Given
            Action <Stream> action     = s => { };
            var             parameters = new DynamicDictionary();
            var             route      = new FakeRoute(action);
            var             context    = new NancyContext();

            // When
            var result = this.invoker.Invoke(route, new CancellationToken(), parameters, context).Result;

            // Then
            Assert.IsType <Response>(result);
        }
        public void Should_handle_RouteExecutionEarlyExitException_gracefully()
        {
            // Given
            var response   = new Response();
            var route      = new FakeRoute((c, t) => { throw new RouteExecutionEarlyExitException(response); });
            var parameters = new DynamicDictionary();
            var context    = new NancyContext();

            // When
            var result = this.invoker.Invoke(route, new CancellationToken(), parameters, context).Result;

            // Then
            result.ShouldBeSameAs(response);
        }
        public void Should_invoke_module_before_hook_followed_by_resolved_route_followed_by_module_after_hook()
        {
            // Given
            var capturedExecutionOrder = new List<string>();
            var expectedExecutionOrder = new[] { "Prehook", "RouteInvoke", "Posthook" };

            var route = new FakeRoute
            {
                Action = (parameters, token) =>
                             {
                                 capturedExecutionOrder.Add("RouteInvoke");
                                 return CreateResponseTask(null);
                             }
            };

            var before = new BeforePipeline();
            before += (ctx) =>
                          {
                              capturedExecutionOrder.Add("Prehook");
                              return null;
                          };

            var after = new AfterPipeline();
            after += (ctx) =>
                         {
                             capturedExecutionOrder.Add("Posthook");
                         };

            var resolvedRoute = new ResolveResult
            {
                Route = route,
                Parameters = DynamicDictionary.Empty,
                Before = before,
                After = after,
                OnError = null
            };

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            capturedExecutionOrder.Count().ShouldEqual(3);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public void Should_not_invoke_resolved_route_if_module_before_hook_returns_response_but_should_invoke_module_after_hook()
        {
            // Given
            var capturedExecutionOrder = new List <string>();
            var expectedExecutionOrder = new[] { "Prehook", "Posthook" };

            var route = new FakeRoute
            {
                Action = (parameters, token) =>
                {
                    capturedExecutionOrder.Add("RouteInvoke");
                    return(null);
                }
            };

            var before = new BeforePipeline();

            before += ctx =>
            {
                capturedExecutionOrder.Add("Prehook");
                return(new Response());
            };

            var after = new AfterPipeline();

            after += ctx => capturedExecutionOrder.Add("Posthook");

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                null);

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public void Should_log_the_reason_for_early_exits()
        {
            // Given
            var response   = new Response();
            var route      = new FakeRoute((c, t) => { throw new RouteExecutionEarlyExitException(response, "Reason Testing"); });
            var parameters = new DynamicDictionary();
            var context    = new NancyContext {
                Trace = new RequestTrace(true)
            };

            // When
            var result = this.invoker.Invoke(route, new CancellationToken(), parameters, context).Result;

            // Then
            context.Trace.TraceLog.ToString().ShouldContain("Reason Testing");
        }
示例#14
0
        public NancyEngineFixture()
        {
            this.environment =
                new DefaultNancyEnvironment();

            this.environment.Tracing(
                enabled: true,
                displayErrorTraces: true);

            this.resolver          = A.Fake <IRouteResolver>();
            this.response          = new Response();
            this.route             = new FakeRoute(response);
            this.context           = new NancyContext();
            this.statusCodeHandler = A.Fake <IStatusCodeHandler>();
            this.requestDispatcher = A.Fake <IRequestDispatcher>();
            this.negotiator        = A.Fake <IResponseNegotiator>();

            A.CallTo(() => this.requestDispatcher.Dispatch(A <NancyContext> ._, A <CancellationToken> ._))
            .Returns(Task.FromResult(new Response()));

            A.CallTo(() => this.statusCodeHandler.HandlesStatusCode(A <HttpStatusCode> .Ignored, A <NancyContext> .Ignored)).Returns(false);

            contextFactory = A.Fake <INancyContextFactory>();
            A.CallTo(() => contextFactory.Create(A <Request> ._)).Returns(context);

            var resolveResult = new ResolveResult {
                Route = route, Parameters = DynamicDictionary.Empty, Before = null, After = null, OnError = null
            };

            A.CallTo(() => resolver.Resolve(A <NancyContext> .Ignored)).Returns(resolveResult);

            var applicationPipelines = new Pipelines();

            this.routeInvoker = A.Fake <IRouteInvoker>();

            A.CallTo(() => this.routeInvoker.Invoke(A <Route> ._, A <CancellationToken> ._, A <DynamicDictionary> ._, A <NancyContext> ._)).ReturnsLazily(arg =>
            {
                return(((Route)arg.Arguments[0]).Action.Invoke((DynamicDictionary)arg.Arguments[1], A <CancellationToken> ._).Result);
            });

            this.engine =
                new NancyEngine(this.requestDispatcher, this.contextFactory, new[] { this.statusCodeHandler }, A.Fake <IRequestTracing>(), new DisabledStaticContentProvider(), this.negotiator, this.environment)
            {
                RequestPipelinesFactory = ctx => applicationPipelines
            };
        }
        public void Should_invoke_response_negotiator_for_value_type_model()
        {
            // Given
            var model      = new StructModel();
            var route      = new FakeRoute(model);
            var parameters = new DynamicDictionary();
            var context    = new NancyContext
            {
                Trace = new DefaultRequestTrace()
            };

            // When
            var result = this.invoker.Invoke(route, new CancellationToken(), parameters, context).Result;

            // Then
            A.CallTo(() => this.responseNegotiator.NegotiateResponse(model, context)).MustHaveHappened();
        }
        public async Task Should_invoke_module_onerror_hook_when_module_before_hook_throws_exception()
        {
            // Given
            var capturedExecutionOrder = new List <string>();
            var expectedExecutionOrder = new[] { "Prehook", "OnErrorHook" };

            var before = new BeforePipeline();

            before += ctx =>
            {
                capturedExecutionOrder.Add("Prehook");
                throw new Exception("Prehook");
            };

            var after = new AfterPipeline();

            after += ctx => capturedExecutionOrder.Add("Posthook");

            var route = new FakeRoute((parameters, ct) =>
            {
                capturedExecutionOrder.Add("RouteInvoke");
                return(null);
            });

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                (ctx, ex) => { capturedExecutionOrder.Add("OnErrorHook"); return(new Response()); });

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            await this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
示例#17
0
        public async Task ShouldMatchRoute()
        {
            var handler = new FakeHandler();
            var route   = new FakeRoute()
            {
                Path = "/Ping"
            };
            var request = new FakeRequest()
            {
                Path = "/Ping"
            };
            var media = new FakeMedia();

            var router = new Router(new[] { route }, new[] { media });

            await router.RouteRequest(request);

            Assert.IsTrue(request.IsHandled);
            Assert.IsTrue(route.HasSent);
        }
        public async Task Should_allow_module_after_hook_to_change_response()
        {
            // Given
            var before = new BeforePipeline();

            before += ctx => null;

            var response = new Response();

            Func <NancyContext, Response> moduleAfterHookResponse = ctx => response;

            var after = new AfterPipeline();

            after += ctx =>
            {
                ctx.Response = moduleAfterHookResponse(ctx);
            };

            var route = new FakeRoute();

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                null);

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            await this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            context.Response.ShouldBeSameAs(response);
        }
        public void HandleRequest_should_allow_module_after_hook_to_add_items_to_context()
        {
            // Given
            var route = new FakeRoute();

            var resolvedRoute = new Tuple<Route, DynamicDictionary, Func<NancyContext, Response>, Action<NancyContext>>(
                route,
                DynamicDictionary.Empty,
                ctx => null,
                ctx => ctx.Items.Add("RoutePostReq", new object()));

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            context.Items.ContainsKey("RoutePostReq").ShouldBeTrue();
        }
示例#20
0
        public NancyEngineFixture()
        {
            this.resolver                 = A.Fake <IRouteResolver>();
            this.response                 = new Response();
            this.route                    = new FakeRoute(response);
            this.context                  = new NancyContext();
            this.statusCodeHandler        = A.Fake <IStatusCodeHandler>();
            this.requestDispatcher        = A.Fake <IRequestDispatcher>();
            this.diagnosticsConfiguration = new DiagnosticsConfiguration();

            A.CallTo(() => this.requestDispatcher.Dispatch(A <NancyContext> ._)).Invokes(x => this.context.Response = new Response());

            A.CallTo(() => this.statusCodeHandler.HandlesStatusCode(A <HttpStatusCode> .Ignored, A <NancyContext> .Ignored)).Returns(false);

            contextFactory = A.Fake <INancyContextFactory>();
            A.CallTo(() => contextFactory.Create(A <Request> ._)).Returns(context);

            var resolveResult = new ResolveResult {
                Route = route, Parameters = DynamicDictionary.Empty, Before = null, After = null, OnError = null
            };

            A.CallTo(() => resolver.Resolve(A <NancyContext> .Ignored)).Returns(resolveResult);

            var applicationPipelines = new Pipelines();

            this.routeInvoker = A.Fake <IRouteInvoker>();

            A.CallTo(() => this.routeInvoker.Invoke(A <Route> ._, A <DynamicDictionary> ._, A <NancyContext> ._)).ReturnsLazily(arg =>
            {
                return((Response)((Route)arg.Arguments[0]).Action.Invoke((DynamicDictionary)arg.Arguments[1]));
            });

            this.engine =
                new NancyEngine(this.requestDispatcher, this.contextFactory, new[] { this.statusCodeHandler }, A.Fake <IRequestTracing>(), this.diagnosticsConfiguration, new DisabledStaticContentProvider())
            {
                RequestPipelinesFactory = ctx => applicationPipelines
            };
        }
示例#21
0
        public void Should_not_invoke_resolved_route_if_module_before_hook_returns_response_but_should_invoke_module_after_hook()
        {
            // Given
            var capturedExecutionOrder = new List <string>();
            var expectedExecutionOrder = new[] { "Prehook", "Posthook" };

            var route = new FakeRoute
            {
                Action = parameters =>
                {
                    capturedExecutionOrder.Add("RouteInvoke");
                    return(null);
                }
            };

            var resolvedRoute = new Tuple <Route, DynamicDictionary, Func <NancyContext, Response>, Action <NancyContext> >(
                route,
                DynamicDictionary.Empty,
                ctx => {
                capturedExecutionOrder.Add("Prehook");
                return(new Response());
            },
                ctx => capturedExecutionOrder.Add("Posthook"));

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public void Should_invoke_module_before_hook_followed_by_resolved_route_followed_by_module_after_hook()
        {
            // Given
            var capturedExecutionOrder = new List <string>();
            var expectedExecutionOrder = new[] { "Prehook", "RouteInvoke", "Posthook" };

            var route = new FakeRoute
            {
                Action = parameters =>
                {
                    capturedExecutionOrder.Add("RouteInvoke");
                    return(null);
                }
            };

            var resolvedRoute = new ResolveResult
            {
                Route      = route,
                Parameters = DynamicDictionary.Empty,
                Before     = ctx => { capturedExecutionOrder.Add("Prehook"); return(null); },
                After      = ctx => capturedExecutionOrder.Add("Posthook"),
                OnError    = null
            };

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            capturedExecutionOrder.Count().ShouldEqual(3);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
示例#23
0
        public NancyEngineFixture()
        {
            this.resolver     = A.Fake <IRouteResolver>();
            this.response     = new Response();
            this.route        = new FakeRoute(response);
            this.context      = new NancyContext();
            this.errorHandler = A.Fake <IErrorHandler>();

            A.CallTo(() => errorHandler.HandlesStatusCode(A <HttpStatusCode> .Ignored, A <NancyContext> .Ignored)).Returns(false);

            contextFactory = A.Fake <INancyContextFactory>();
            A.CallTo(() => contextFactory.Create()).Returns(context);

            A.CallTo(() => resolver.Resolve(A <NancyContext> .Ignored)).Returns(new ResolveResult(route, DynamicDictionary.Empty, null, null));

            var applicationPipelines = new Pipelines();

            this.engine =
                new NancyEngine(resolver, contextFactory, new[] { this.errorHandler }, A.Fake <IRequestTracing>())
            {
                RequestPipelinesFactory = ctx => applicationPipelines
            };
        }
        public void Should_invoke_module_onerror_hook_when_route_invoker_throws_exception()
        {
            // Given
            var capturedExecutionOrder = new List <string>();
            var expectedExecutionOrder = new[] { "RouteInvoke", "OnErrorHook" };

            var route = new FakeRoute
            {
                Action = parameters =>
                {
                    capturedExecutionOrder.Add("RouteInvoke");
                    throw new Exception("RouteInvoke");
                }
            };

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                ctx => null,
                ctx => capturedExecutionOrder.Add("Posthook"),
                (ctx, ex) => { capturedExecutionOrder.Add("OnErrorHook"); return(new Response()); });

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public void HandleRequest_should_allow_module_after_hook_to_add_items_to_context()
        {
            // Given
            var route = new FakeRoute();

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                ctx => null,
                ctx => ctx.Items.Add("RoutePostReq", new object()));

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            context.Items.ContainsKey("RoutePostReq").ShouldBeTrue();
        }
        public void Should_return_response_from_module_before_hook_when_not_null()
        {
            // Given
            var expectedResponse = new Response();
            Func <NancyContext, Response> moduleBeforeHookResponse = ctx => expectedResponse;

            var before = new BeforePipeline();

            before += moduleBeforeHookResponse;

            var after = new AfterPipeline();

            after += ctx => { };

            var route = new FakeRoute();

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                null);

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            // When
            this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            context.Response.ShouldBeSameAs(expectedResponse);
        }
        public async Task Should_not_rethrow_exception_when_onerror_hook_returns_response()
        {
            // Given
            var route = new FakeRoute
            {
                Action = (parameters, ct) => TaskHelpers.GetFaultedTask <dynamic>(new Exception())
            };

            var before = new BeforePipeline();

            before += ctx => null;

            var after = new AfterPipeline();

            after += ctx => { };

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                (ctx, ex) => new Response());

            A.CallTo(() => this.routeResolver.Resolve(A <NancyContext> .Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext {
                Request = new Request("GET", "/", "http")
            };

            //When
            var exception = await RecordAsync.Exception(async() => await this.requestDispatcher.Dispatch(context, new CancellationToken()));

            // Then
            exception.ShouldBeNull();
        }
        public void Should_allow_module_after_hook_to_change_response()
        {
            // Given
            var moduleAfterHookResponse = new Response();

            var route = new FakeRoute();

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                ctx => null,
                ctx => ctx.Response = moduleAfterHookResponse,
                null);

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            context.Response.ShouldBeSameAs(moduleAfterHookResponse);
        }
        public void should_preserve_stacktrace_when_rethrowing_the_excption()
        {
            // Given
            var route = new FakeRoute
            {
                Action = o => BrokenMethod()
            };

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                ctx => null,
                ctx => { },
                (ctx, ex) => { return null; });

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            var exception = Assert.Throws<Exception>(() => this.requestDispatcher.Dispatch(context));

            exception.StackTrace.ShouldContain("BrokenMethod");
        }
        public void Should_return_response_from_module_before_hook_when_not_null()
        {
            // Given
            var moduleBeforeHookResponse = new Response();

            var route = new FakeRoute();

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                ctx => moduleBeforeHookResponse,
                ctx => { },
                null);

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            context.Response.ShouldBeSameAs(moduleBeforeHookResponse);
        }
        public void Should_rethrow_exception_when_onerror_hook_does_return_response()
        {
            // Given
            var route = new FakeRoute
            {
                Action = parameters => { throw new Exception(); }
            };

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                ctx => null,
                ctx => { },
                (ctx, ex) => { return null; });

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            //When

            // Then
            Assert.Throws<Exception>(() => this.requestDispatcher.Dispatch(context));
        }
        public void Should_not_invoke_resolved_route_if_module_before_hook_returns_response_but_should_invoke_module_after_hook()
        {
            // Given
            var capturedExecutionOrder = new List<string>();
            var expectedExecutionOrder = new[] { "Prehook", "Posthook" };

            var route = new FakeRoute
            {
                Action = parameters =>
                {
                    capturedExecutionOrder.Add("RouteInvoke");
                    return null;
                }
            };

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                ctx =>
                {
                    capturedExecutionOrder.Add("Prehook");
                    return new Response();
                },
                ctx => capturedExecutionOrder.Add("Posthook"),
                null);

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public void Should_invoke_module_onerror_hook_when_route_invoker_throws_exception()
        {
            // Given
            var capturedExecutionOrder = new List<string>();
            var expectedExecutionOrder = new[] { "RouteInvoke", "OnErrorHook" };

            var route = new FakeRoute
            {
                Action = parameters =>
                {
                    capturedExecutionOrder.Add("RouteInvoke");
                    throw new Exception("RouteInvoke");
                }
            };

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                ctx => null,
                ctx => capturedExecutionOrder.Add("Posthook"),
                (ctx, ex) => { capturedExecutionOrder.Add("OnErrorHook"); return new Response(); });

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context);

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public void Should_return_response_from_module_before_hook_when_not_null()
        {
            // Given
            var expectedResponse = new Response();
            Func<NancyContext, Response> moduleBeforeHookResponse = ctx => expectedResponse;

            var before = new BeforePipeline();
            before += moduleBeforeHookResponse;

            var after = new AfterPipeline();
            after += ctx => { };

            var route = new FakeRoute();

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                null);

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            context.Response.ShouldBeSameAs(expectedResponse);
        }
        public void Should_allow_module_after_hook_to_change_response()
        {
            // Given
            var before = new BeforePipeline();
            before += ctx => null;

            var response = new Response();

            Func<NancyContext, Response> moduleAfterHookResponse = ctx => response;

            var after = new AfterPipeline();
            after += ctx =>
            {
                ctx.Response = moduleAfterHookResponse(ctx);
            };

            var route = new FakeRoute();

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                null);

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            context.Response.ShouldBeSameAs(response);
        }
        public void Should_not_rethrow_exception_when_onerror_hook_returns_response()
        {
            // Given
            var route = new FakeRoute
            {
                Action = (parameters,ct) => TaskHelpers.GetFaultedTask<dynamic>(new Exception())
            };

            var before = new BeforePipeline();
            before += ctx => null;

            var after = new AfterPipeline();
            after += ctx => { };

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                (ctx, ex) => new Response());

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            //When

            // Then
            Assert.DoesNotThrow(() => this.requestDispatcher.Dispatch(context, new CancellationToken()));
        }
        public void Should_invoke_module_onerror_hook_when_module_after_hook_throws_exception()
        {
            // Given
            var capturedExecutionOrder = new List<string>();
            var expectedExecutionOrder = new[] { "Posthook", "OnErrorHook" };

            var route = new FakeRoute
            {
                Action = (parameters, ct) => CreateResponseTask(null)
            };

            var before = new BeforePipeline();
            before += ctx => null;

            var after = new AfterPipeline();
            after += ctx =>
                         {
                             capturedExecutionOrder.Add("Posthook");
                             throw new Exception("Posthook");
                         };

            var resolvedRoute = new ResolveResult(
                route,
                DynamicDictionary.Empty,
                before,
                after,
                (ctx, ex) => { capturedExecutionOrder.Add("OnErrorHook"); return new Response(); });

            A.CallTo(() => this.routeResolver.Resolve(A<NancyContext>.Ignored)).Returns(resolvedRoute);

            var context =
                new NancyContext { Request = new Request("GET", "/", "http") };

            // When
            this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public void Should_set_the_context_resolved_route_from_resolve_result()
        {
            // Given
            const string expectedPath = "/the/path";

            var context =
                new NancyContext
                {
                    Request = new FakeRequest("GET", expectedPath)
                };

            var expectedRoute = new FakeRoute();

            var resolveResult = new ResolveResult(
               expectedRoute,
               new DynamicDictionary(),
               null,
               null,
               null);

            A.CallTo(() => this.routeResolver.Resolve(context)).Returns(resolveResult);

            // When
            this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            context.ResolvedRoute.ShouldBeSameAs(expectedRoute);
        }