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();
        }
Example #2
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>();
            this.requestDispatcher = A.Fake<IRequestDispatcher>();

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

            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, null));

            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, contextFactory, new[] { this.errorHandler }, A.Fake<IRequestTracing>())
                {
                    RequestPipelinesFactory = ctx => applicationPipelines
                };
        }
Example #3
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>._, A<CancellationToken>._)).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<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>(), this.diagnosticsConfiguration, new DisabledStaticContentProvider())
                {
                    RequestPipelinesFactory = ctx => applicationPipelines
                };
        }
Example #4
0
        private static Func<dynamic, CancellationToken, Task<dynamic>> Wrap(
            FakeRoute route,
            Func<dynamic, CancellationToken, Task<dynamic>> action)
        {
            return (parameters, token) =>
            {
                route.ParametersUsedToInvokeAction = parameters;
                route.ActionWasInvoked = true;

                var tcs = 
                    new TaskCompletionSource<dynamic>();

                try
                {
                    var result = action.Invoke(parameters, token);
                    tcs.SetResult(result.Result);
                }
                catch (Exception e)
                {
                    tcs.SetException(e);
                }

                return tcs.Task;
            };
        }
Example #5
0
        public NancyEngineFixture()
        {
            this.resolver = A.Fake<IRouteResolver>();
            this.route = new FakeRoute();

            A.CallTo(() => resolver.Resolve(A<Request>.Ignored, A<IRouteCache>.Ignored.Argument)).Returns(route);
            this.engine = new NancyEngine(resolver, A.Fake<IRouteCache>());
        }
Example #6
0
        private static Func<dynamic, CancellationToken, Task<dynamic>> Wrap(
            FakeRoute route,
            Func<dynamic, CancellationToken, Task<dynamic>> action)
        {
            return (parameters, token) =>
            {
                route.ParametersUsedToInvokeAction = parameters;
                route.ActionWasInvoked = true;

                return action.Invoke(parameters, token);
            };
        }
        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);
        }
Example #8
0
        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, parameters, context);

            // Then
            Assert.IsType<Response>(result);
        }
        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);

            // Then
            context.Trace.TraceLog.ToString().ShouldContain("Reason Testing");
        }
        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);

            // Then
            result.ShouldBeSameAs(response);
        }
Example #11
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.Argument)).Returns(new ResolveResult(route, DynamicDictionary.Empty, null, null));

            this.engine = new NancyEngine(resolver, A.Fake<IRouteCache>(), contextFactory);
        }
Example #12
0
        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, parameters, context);

            // Then
            Assert.IsType<Response>(result);
        }
        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 Task.FromResult<object>(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();
        }
Example #14
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)).Returns(false);

            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, this.errorHandler);
        }
Example #15
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>();

            this.engine =
                new NancyEngine(this.requestDispatcher, this.contextFactory, new[] { this.statusCodeHandler }, A.Fake<IRequestTracing>(), new DisabledStaticContentProvider(), this.negotiator, this.environment)
                {
                    RequestPipelinesFactory = ctx => applicationPipelines
                };
        }
Example #16
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 async Task 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) => Task.FromResult<object>(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
            await this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        public async Task 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
            await this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            context.ResolvedRoute.ShouldBeSameAs(expectedRoute);
        }
        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 async Task 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
            await this.requestDispatcher.Dispatch(context, new CancellationToken());

            // Then
            capturedExecutionOrder.Count().ShouldEqual(2);
            capturedExecutionOrder.SequenceEqual(expectedExecutionOrder).ShouldBeTrue();
        }
        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
            {
                Trace = new DefaultRequestTrace
                {
                    TraceLog = new DefaultTraceLog()
                }
            };

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

            // Then
            Assert.IsType<Response>(result);
        }
        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_rethrow_exception_when_onerror_hook_does_return_response()
        {
            // Given
            var route = new FakeRoute
            {
                Action = (parameters, ct) => { throw 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) => { 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, new CancellationToken()));
        }
        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, new CancellationToken(), parameters, context);

            // Then
            Assert.IsType<Response>(result);
        }
        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 async Task should_preserve_stacktrace_when_rethrowing_the_excption()
        {
            // Given
            var route = new FakeRoute
            {
                Action = (o, ct) => BrokenMethod()
            };

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

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

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

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

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

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

            exception.StackTrace.ShouldContain("BrokenMethod");
        }
        public void Should_invoke_response_negotiator()
        {
            // Given
            var model = new Person { FirstName = "First", LastName = "Last" };
            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();
        }