public async Task When_receiving_valid_message_it_should_flow_through_pipeline_normally()
        {
            TestMessage receivedMessage = null;
            Dictionary <string, string>     receivedHeaders = null;
            IValidationFailed <TestMessage> failedMessage   = null;
            var sync = new ManualResetEvent(false);

            var activator = new BuiltinHandlerActivator();

            activator
            .Handle <TestMessage>((bus, context, message) =>
            {
                // This should happen.
                receivedMessage = message;
                receivedHeaders = context.Message.Headers;
                sync.Set();
                return(Task.CompletedTask);
            })
            .Handle <IValidationFailed <TestMessage> >(failed =>
            {
                // This should not happen, but signal completion.
                failedMessage = failed;
                sync.Set();
                return(Task.CompletedTask);
            });

            using (IBus bus = CreateBus(activator, o => o.ValidateIncomingMessages(_validatorFactoryMock.Object)))
            {
                // Act
                var testMessage = new TestMessage
                {
                    ShouldPassValidation = true
                };

                await bus.Send(testMessage);

                // Assert
                sync.WaitOne(Debugger.IsAttached ? -1 : 5000);

                failedMessage.Should().BeNull();

                receivedMessage.Should().NotBeNull();
                receivedMessage.IsValidated.Should().BeTrue();
                receivedHeaders.Should()
                .ContainKey(ValidateIncomingStep.ValidatorTypeKey)
                .WhichValue.Should()
                .Be(typeof(TestMessageValidator).GetSimpleAssemblyQualifiedName());
            }

            _loggerFactory.LogEvents
            .Select(le => le.Exception)
            .Should()
            .NotContain(ex => ex is MessageCouldNotBeDispatchedToAnyHandlersException);
        }
        public async Task Given_that_failed_handler_is_not_registered_when_receiving_invalid_message_it_should_throw()
        {
            IValidationFailed <TestMessage> failedMessage = null;
            var sync = new ManualResetEvent(false);

            var activator = new BuiltinHandlerActivator();

            using (IBus bus = CreateBus(activator,
                                        o =>
            {
                o.ValidateIncomingMessages(_validatorFactoryMock.Object);
                o.OnPipelineCompletion <IValidationFailed <TestMessage> >(failed =>
                {
                    // This should happen.
                    failedMessage = failed;
                    sync.Set();
                });
            }))
            {
                // Act
                var testMessage = new TestMessage
                {
                    ShouldPassValidation = false
                };

                await bus.Send(testMessage);

                // Assert
                sync.WaitOne(Debugger.IsAttached ? -1 : 5000);

                failedMessage.Should().NotBeNull();
                failedMessage.ValidationResult.Should().NotBeNull();
                failedMessage.Headers.Should()
                .NotBeNull()
                .And.NotBeEmpty()
                .And.ContainKey(ValidateIncomingStep.ValidatorTypeKey)
                .WhichValue.Should()
                .Be(typeof(TestMessageValidator).GetSimpleAssemblyQualifiedName());
                failedMessage.Message.IsValidated.Should().BeTrue();
                failedMessage.ValidatorType.Should().Be <TestMessageValidator>();
            }

            _loggerFactory.LogEvents
            .Select(le => le.Exception)
            .Should()
            .Contain(ex => ex is MessageCouldNotBeDispatchedToAnyHandlersException);
        }
            public async Task It_should_wrap_message_in_validation_failed()
            {
                Message message = StepContext.Load <Message>();

                message.Body.Should().BeOfType <TestMessage>();

                // Act
                await _sut.ProcessAsync(StepContext, Next, ValidatorMock.Object, ValidationResult);

                // Assert
                Message newMessage = StepContext.Load <Message>();
                IValidationFailed <TestMessage> wrappedMessageBody = newMessage.Body.Should()
                                                                     .BeAssignableTo <IValidationFailed <TestMessage> >()
                                                                     .Which;

                wrappedMessageBody.Message.Should().BeSameAs(message.Body);
                wrappedMessageBody.Headers.Should().BeSameAs(message.Headers);
                wrappedMessageBody.ValidationResult.Should().BeSameAs(ValidationResult);
                wrappedMessageBody.ValidatorType.Should().Be(ValidatorMock.Object.GetType());
            }
        public async Task When_receiving_invalid_message_it_should_be_wrapped_as_invalid_message()
        {
            string      messageId       = null;
            TestMessage receivedMessage = null;
            IValidationFailed <TestMessage> failedMessage = null;
            var sync = new ManualResetEvent(false);

            var activator = new BuiltinHandlerActivator();

            activator
            .Handle <TestMessage>(message =>
            {
                // This should not happen, but signal completion.
                receivedMessage = message;
                sync.Set();
                return(Task.CompletedTask);
            })
            .Handle <IValidationFailed <TestMessage> >((bus, context, failed) =>
            {
                // This should happen.
                failedMessage = failed;
                messageId     = context.Message.GetMessageId();
                sync.Set();
                return(Task.CompletedTask);
            });

            using (IBus bus = CreateBus(activator, o => o.ValidateIncomingMessages(_validatorFactoryMock.Object)))
            {
                // Act
                var testMessage = new TestMessage
                {
                    ShouldPassValidation = false
                };

                await bus.Send(testMessage);

                // Assert
                sync.WaitOne(Debugger.IsAttached ? -1 : 5000);

                receivedMessage.Should().BeNull();

                failedMessage.Should().NotBeNull();
                failedMessage.ValidationResult.Should().NotBeNull();
                failedMessage.Headers.Should()
                .NotBeNull()
                .And.NotBeEmpty()
                .And.ContainKey(ValidateIncomingStep.ValidatorTypeKey)
                .WhichValue.Should()
                .Be(typeof(TestMessageValidator).GetSimpleAssemblyQualifiedName());
                failedMessage.Message.IsValidated.Should().BeTrue();
                failedMessage.ValidatorType.Should().Be <TestMessageValidator>();
            }

            _loggerFactory.LogEvents
            .Select(le => le.Exception)
            .Should()
            .NotContain(ex => ex is MessageCouldNotBeDispatchedToAnyHandlersException);
            _loggerFactory.LogEvents
            .Select(le => le.ToString())
            .Should()
            .ContainMatch($"Debug: Message \"{messageId}\" failed to validate.*The specified condition was not met for 'Should Pass Validation'.*");
            _loggerFactory.LogEvents
            .Select(le => le.Message)
            .Should()
            .ContainMatch("*is configured to be wrapped as *");
        }