public void Should_throw_friendly_exception_if_handler_returns_null()
        {
            var terminator      = new InvokeHandlerTerminator();
            var messageHandler  = CreateMessageHandlerThatReturnsNull((i, m, ctx) => { }, new FakeSaga());
            var behaviorContext = CreateBehaviorContext(messageHandler);

            Assert.That(async() => await terminator.Invoke(behaviorContext, _ => Task.CompletedTask), Throws.Exception.With.Message.EqualTo("Return a Task or mark the method as async."));
        }
        public async Task Should_invoke_handler_with_current_message()
        {
            object receivedMessage = null;
            var    terminator      = new InvokeHandlerTerminator();
            var    messageHandler  = CreateMessageHandler((i, m, ctx) => receivedMessage = m, new FakeMessageHandler());
            var    behaviorContext = CreateBehaviorContext(messageHandler);

            await terminator.Invoke(behaviorContext, _ => Task.CompletedTask);

            Assert.AreSame(behaviorContext.MessageBeingHandled, receivedMessage);
        }
        public async Task Should_indicate_when_no_transaction_scope_is_present()
        {
            var terminator = new InvokeHandlerTerminator();

            var messageHandler  = CreateMessageHandler((i, m, ctx) => { }, new FakeMessageHandler());
            var behaviorContext = CreateBehaviorContext(messageHandler);

            await terminator.Invoke(behaviorContext, _ => TaskEx.CompletedTask);

            Assert.IsFalse(behaviorContext.Extensions.Get <InvokeHandlerTerminator.State>().ScopeWasPresent);
        }
        public async Task When_no_saga_should_invoke_handler()
        {
            var handlerInvoked = false;
            var terminator     = new InvokeHandlerTerminator();

            var messageHandler  = CreateMessageHandler((i, m, ctx) => handlerInvoked = true, new FakeMessageHandler());
            var behaviorContext = CreateBehaviorContext(messageHandler);

            await terminator.Invoke(behaviorContext, _ => Task.CompletedTask);

            Assert.IsTrue(handlerInvoked);
        }
        public void Should_rethrow_exception_with_additional_data()
        {
            var thrownException = new InvalidOperationException();
            var terminator      = new InvokeHandlerTerminator();
            var messageHandler  = CreateMessageHandler((i, m, ctx) => throw thrownException, new FakeMessageHandler());
            var behaviorContext = CreateBehaviorContext(messageHandler);

            var caughtException = Assert.ThrowsAsync <InvalidOperationException>(async() => await terminator.Invoke(behaviorContext, _ => Task.CompletedTask));

            Assert.AreSame(thrownException, caughtException);
            Assert.AreEqual("System.Object", caughtException.Data["Message type"]);
            Assert.AreEqual("NServiceBus.Core.Tests.Pipeline.Incoming.InvokeHandlerTerminatorTest+FakeMessageHandler", caughtException.Data["Handler type"]);
            Assert.That(DateTimeOffsetHelper.ToDateTimeOffset((string)caughtException.Data["Handler start time"]), Is.EqualTo(DateTimeOffset.UtcNow).Within(TimeSpan.FromSeconds(5)));
            Assert.That(DateTimeOffsetHelper.ToDateTimeOffset((string)caughtException.Data["Handler failure time"]), Is.EqualTo(DateTimeOffset.UtcNow).Within(TimeSpan.FromSeconds(5)));
        }
        public async Task When_saga_not_found_and_handler_is_not_saga_should_invoke_handler()
        {
            var handlerInvoked = false;
            var terminator     = new InvokeHandlerTerminator();

            var messageHandler  = CreateMessageHandler((i, m, ctx) => handlerInvoked = true, new FakeMessageHandler());
            var behaviorContext = CreateBehaviorContext(messageHandler);
            var sagaInstance    = AssociateSagaWithMessage(new FakeSaga(), behaviorContext);

            sagaInstance.MarkAsNotFound();

            await terminator.Invoke(behaviorContext, _ => Task.CompletedTask);

            Assert.IsTrue(handlerInvoked);
        }
        public async Task When_saga_found_and_handler_is_saga_should_invoke_handler()
        {
            var handlerInvoked = false;
            var terminator     = new InvokeHandlerTerminator();
            var saga           = new FakeSaga();

            var messageHandler  = CreateMessageHandler((i, m, ctx) => handlerInvoked = true, saga);
            var behaviorContext = CreateBehaviorContext(messageHandler);

            AssociateSagaWithMessage(saga, behaviorContext);

            await terminator.Invoke(behaviorContext, _ => TaskEx.CompletedTask);

            Assert.IsTrue(handlerInvoked);
        }