public void ShouldExecuteTheCorrectHandlers()
        {
            // Arrange
            var bus = new MessageBus.Bus(_mockConfiguration.Object);

            var message1HandlerReference = new HandlerReference
            {
                HandlerType = typeof (FakeHandler1),
                MessageType = typeof (FakeMessage1)
            };

            var handlerReferences = new List<HandlerReference>
            {
                message1HandlerReference,
                new HandlerReference
                {
                    HandlerType = typeof (FakeHandler2),
                    MessageType = typeof (FakeMessage2)
                }
            };

            _mockContainer.Setup(x => x.GetHandlerTypes()).Returns(handlerReferences);
            _mockConsumer.Setup(x => x.StartConsuming(It.Is<ConsumerEventHandler>(y => AssignEventHandler(y)), It.IsAny<string>(), It.IsAny<string>()));
            _mockContainer.Setup(x => x.GetHandlerTypes(typeof(IMessageHandler<FakeMessage1>))).Returns(new List<HandlerReference>
            {
                message1HandlerReference
            });
            var fakeHandler = new FakeHandler1();
            _mockContainer.Setup(x => x.GetInstance(typeof (FakeHandler1))).Returns(fakeHandler);

            bus.StartConsuming();

            // Act
            var message1 = new FakeMessage1(Guid.NewGuid())
            {
                Username = "******"
            };
            _fakeEventHandler(Encoding.UTF8.GetBytes(_serializer.Serialize(message1)));

            var message2 = new FakeMessage2(Guid.NewGuid())
            {
                DisplayName = "Tim Watson"
            };

            _fakeEventHandler(Encoding.UTF8.GetBytes(_serializer.Serialize(message2)));

            // Assert
            Assert.Equal(message1.CorrelationId, fakeHandler.Command.CorrelationId);
            Assert.Equal(message1.Username, fakeHandler.Command.Username);
            _mockContainer.Verify(x => x.GetInstance(typeof (FakeHandler2)), Times.Never);
        }
        public void ShouldRemoveProcessManagerDataIfProcessManagerIsComplete()
        {
            // Arrange
            var id = Guid.NewGuid();
            var message = new FakeMessage2(id)
            {
                Email = "*****@*****.**"
            };

            var data = new FakeProcessManagerData
            {
                User = "******"
            };

            var mockPersistanceData = new Mock<IPersistanceData<FakeProcessManagerData>>();
            mockPersistanceData.Setup(x => x.Data).Returns(data);
            _mockContainer.Setup(x => x.GetHandlerTypes(typeof(IMessageHandler<FakeMessage2>))).Returns(new List<HandlerReference>
            {
                new HandlerReference
                {
                    HandlerType = typeof(FakeProcessManager1),
                    MessageType = typeof(FakeMessage2)
                }
            });

            var processManager = new FakeProcessManager1
            {
                Complete = true
            };
            _mockContainer.Setup(x => x.GetInstance(typeof(FakeProcessManager1))).Returns(processManager);
            _mockProcessManagerFinder.Setup(x => x.FindData<FakeProcessManagerData>(It.IsAny<ProcessManagerPropertyMapper>(), It.Is<FakeMessage2>(m => m.CorrelationId == id))).Returns(mockPersistanceData.Object);

            _mockProcessManagerFinder.Setup(x => x.UpdateData(It.IsAny<FakePersistanceData>()));

            var processManagerProcessor = new ProcessManagerProcessor(_mockProcessManagerFinder.Object, _mockContainer.Object);

            // Act
            processManagerProcessor.ProcessMessage<FakeMessage2>(JsonConvert.SerializeObject(message), new ConsumeContext());

            // Assert
            _mockProcessManagerFinder.Verify(x => x.DeleteData(It.Is<IPersistanceData<FakeProcessManagerData>>(y => y.Data.Email == "*****@*****.**" && y.Data.User == "Tim Watson")), Times.Once);
        }
        public void ShouldNotExecuteHandlerIfProcessManagerDataIsNotFound()
        {
            // Arrange
            var id = Guid.NewGuid();
            var message = new FakeMessage2(id)
            {
                Email = "*****@*****.**"
            };

            _mockContainer.Setup(x => x.GetHandlerTypes(typeof(IMessageHandler<FakeMessage2>))).Returns(new List<HandlerReference>
            {
                new HandlerReference
                {
                    HandlerType = typeof(FakeProcessManager1),
                    MessageType = typeof(FakeMessage2)
                }
            });

            var processManager = new FakeProcessManager1();
            _mockContainer.Setup(x => x.GetInstance(typeof(FakeProcessManager1))).Returns(processManager);
            _mockProcessManagerFinder.Setup(x => x.FindData<FakeProcessManagerData>(It.IsAny<IProcessManagerPropertyMapper>(), It.Is<Message>(m => m.CorrelationId == id))).Returns((IPersistanceData<FakeProcessManagerData>) null);

            _mockProcessManagerFinder.Setup(x => x.UpdateData(It.IsAny<FakePersistanceData>()));

            var processManagerProcessor = new ProcessManagerProcessor(_mockProcessManagerFinder.Object, _mockContainer.Object);

            // Act
            processManagerProcessor.ProcessMessage<FakeMessage2>(JsonConvert.SerializeObject(message), new ConsumeContext());

            // Assert
            _mockProcessManagerFinder.Verify(x => x.UpdateData(It.IsAny<IPersistanceData<FakeProcessManagerData>>()), Times.Never);
        }
        public void ShouldRemoveProcessManagerDataIfProcessManagerIsComplete()
        {
            // Arrange
            var id = Guid.NewGuid();
            var message = new FakeMessage2(id)
            {
                Email = "*****@*****.**"
            };

            var data = new FakeProcessManagerData
            {
                User = "******"
            };

            var mockPersistanceData = new Mock<IPersistanceData<FakeProcessManagerData>>();
            mockPersistanceData.Setup(x => x.Data).Returns(data);
            _mockContainer.Setup(x => x.GetHandlerTypes(typeof(IMessageHandler<FakeMessage2>))).Returns(new List<HandlerReference>
            {
                new HandlerReference
                {
                    HandlerType = typeof(FakeProcessManager1),
                    MessageType = typeof(FakeMessage2)
                }
            });

            var processManager = new FakeProcessManager1
            {
                Complete = true
            };
            _mockContainer.Setup(x => x.GetInstance(typeof(FakeProcessManager1))).Returns(processManager);
            _mockProcessManagerFinder.Setup(x => x.FindData<FakeProcessManagerData>(id)).Returns(mockPersistanceData.Object);

            _mockProcessManagerFinder.Setup(x => x.UpdateData(It.IsAny<FakePersistanceData>()));

            _bus.StartConsuming();

            // Act
            _fakeEventHandler(Encoding.UTF8.GetBytes(_serializer.Serialize(message)));

            // Assert
            _mockProcessManagerFinder.Verify(x => x.DeleteData(It.Is<IPersistanceData<FakeProcessManagerData>>(y => y.Data.Email == "*****@*****.**" && y.Data.User == "Tim Watson")), Times.Once);
        }
        public void ShouldStartExistingProcessManagerWithConsumerContext()
        {
            // Arrange
            var id = Guid.NewGuid();
            var message = new FakeMessage2(id)
            {
                Email = "*****@*****.**"
            };

            var data = new FakeProcessManagerData
            {
                User = "******"
            };

            var mockPersistanceData = new Mock<IPersistanceData<FakeProcessManagerData>>();
            mockPersistanceData.Setup(x => x.Data).Returns(data);
            _mockContainer.Setup(x => x.GetHandlerTypes(typeof(IMessageHandler<FakeMessage2>))).Returns(new List<HandlerReference>
            {
                new HandlerReference
                {
                    HandlerType = typeof(FakeProcessManager1),
                    MessageType = typeof(FakeMessage2)
                }
            });

            var processManager = new FakeProcessManager1();
            _mockContainer.Setup(x => x.GetInstance(typeof(FakeProcessManager1))).Returns(processManager);
            _mockProcessManagerFinder.Setup(x => x.FindData<FakeProcessManagerData>(It.IsAny<ProcessManagerPropertyMapper>(), It.Is<FakeMessage2>(m => m.CorrelationId == id))).Returns(mockPersistanceData.Object);

            var processManagerProcessor = new ProcessManagerProcessor(_mockProcessManagerFinder.Object, _mockContainer.Object);

            var context = new ConsumeContext();

            // Act
            processManagerProcessor.ProcessMessage<FakeMessage2>(JsonConvert.SerializeObject(message), context);

            // Assert
            Assert.Equal(context, processManager.Context); 
        }
        public void ShouldStartProcessManagerWithExistingData()
        {
            // Arrange
            var id = Guid.NewGuid();
            var message = new FakeMessage2(id)
            {
                Email = "*****@*****.**"
            };

            var data = new FakeProcessManagerData
            {
                User = "******"
            };

            var mockPersistanceData = new Mock<IPersistanceData<FakeProcessManagerData>>();
            mockPersistanceData.Setup(x => x.Data).Returns(data);
            _mockContainer.Setup(x => x.GetHandlerTypes(typeof(IMessageHandler<FakeMessage2>))).Returns(new List<HandlerReference>
            {
                new HandlerReference
                {
                    HandlerType = typeof(FakeProcessManager1),
                    MessageType = typeof(FakeMessage2)
                }
            });

            var processManager = new FakeProcessManager1();
            _mockContainer.Setup(x => x.GetInstance(typeof(FakeProcessManager1))).Returns(processManager);
            _mockProcessManagerFinder.Setup(x => x.FindData<FakeProcessManagerData>(id)).Returns(mockPersistanceData.Object);

            _bus.StartConsuming();

            // Act
            _fakeEventHandler(Encoding.UTF8.GetBytes(_serializer.Serialize(message)));

            // Assert
            Assert.Equal("Tim Watson", processManager.Data.User); // Can only be this if Data was set on process manager
            Assert.Equal("*****@*****.**", processManager.Data.Email); // Can only be this if execute was called
        }
        public void ShouldFindExistingProcessManagerInstance()
        {
            // Arrange
            var id = Guid.NewGuid();
            var message = new FakeMessage2(id);

            _mockContainer.Setup(x => x.GetHandlerTypes(typeof(IMessageHandler<FakeMessage2>))).Returns(new List<HandlerReference>
            {
                new HandlerReference
                {
                    HandlerType = typeof(FakeProcessManager1),
                    MessageType = typeof(FakeMessage2)
                }
            });

            var processManager = new FakeProcessManager1();
            _mockContainer.Setup(x => x.GetInstance(typeof(FakeProcessManager1))).Returns(processManager);

            var data = new FakeProcessManagerData
            {
                User = "******"
            };
            var mockPersistanceData = new Mock<IPersistanceData<FakeProcessManagerData>>();
            mockPersistanceData.Setup(x => x.Data).Returns(data);
            _mockProcessManagerFinder.Setup(x => x.FindData<FakeProcessManagerData>(id)).Returns(mockPersistanceData.Object);

            _bus.StartConsuming();

            // Act
            _fakeEventHandler(Encoding.UTF8.GetBytes(_serializer.Serialize(message)));

            // Assert
            _mockContainer.Verify(x => x.GetInstance(typeof (FakeProcessManager1)), Times.Once);
            _mockProcessManagerFinder.Verify(x => x.FindData<FakeProcessManagerData>(id), Times.Once);
        }
        public void PublishRequestShouldPublishMessagesAndReturnResponses()
        {
            // Arrange
            var mockConfiguration = new Mock<IConfiguration>();
            var mockProducer = new Mock<IProducer>();
            var mockContainer = new Mock<IBusContainer>();
            var mockProessManagerFinder = new Mock<IProcessManagerFinder>();
            var mockRequestConfiguration = new Mock<IRequestConfiguration>();

            mockConfiguration.Setup(x => x.GetContainer()).Returns(mockContainer.Object);
            mockConfiguration.Setup(x => x.GetProcessManagerFinder()).Returns(mockProessManagerFinder.Object);
            mockConfiguration.Setup(x => x.GetProducer()).Returns(mockProducer.Object);
            mockConfiguration.SetupGet(x => x.TransportSettings).Returns(new TransportSettings());

            mockConfiguration.Setup(x => x.GetRequestConfiguration(It.IsAny<Guid>())).Returns(mockRequestConfiguration.Object);
            var task = new Task(() => { });

            Action<FakeMessage2> action = null;
            mockRequestConfiguration.Setup(x => x.SetHandler(It.IsAny<Action<object>>())).Returns(task).Callback<Action<FakeMessage2>>(r =>
            {
                action = r;
            });

            var message = new FakeMessage1(Guid.NewGuid())
            {
                Username = "******"
            };

            var r1 = new FakeMessage2(Guid.NewGuid());
            var r2 = new FakeMessage2(Guid.NewGuid());

            mockProducer.Setup(x => x.Publish(It.IsAny<Type>(), It.IsAny<byte[]>(), It.IsAny<Dictionary<string, string>>())).Callback(() =>
            {
                action(r1);
                action(r2);
                task.Start();
            });
            
            // Act
            var bus = new Bus(mockConfiguration.Object);
            var responses = bus.PublishRequest<FakeMessage1, FakeMessage2>(message, 1, null, 1000);
            
            // Assert
            Assert.Equal(2, responses.Count);
            Assert.True(responses.Contains(r1));
            Assert.True(responses.Contains(r2));
        }
        public void SendingRequestToMultipleEndpointsSynchronouslyShouldReturnResponses()
        {
            // Arrange
            var mockConfiguration = new Mock<IConfiguration>();
            var mockProducer = new Mock<IProducer>();
            var mockContainer = new Mock<IBusContainer>();
            var mockRequestConfiguration = new Mock<IRequestConfiguration>();

            mockConfiguration.Setup(x => x.GetContainer()).Returns(mockContainer.Object);
            mockConfiguration.Setup(x => x.GetProducer()).Returns(mockProducer.Object);
            mockConfiguration.SetupGet(x => x.TransportSettings).Returns(new TransportSettings());
            mockConfiguration.Setup(x => x.GetRequestConfiguration(It.IsAny<Guid>())).Returns(mockRequestConfiguration.Object);
            var task = new Task(() => { });

            Action<FakeMessage2> action = null;
            mockRequestConfiguration.Setup(x => x.SetHandler(It.IsAny<Action<object>>())).Returns(task).Callback<Action<FakeMessage2>>(r =>
            {
                action = r;
            });

            var message = new FakeMessage1(Guid.NewGuid())
            {
                Username = "******"
            };

            var r1 = new FakeMessage2(Guid.NewGuid());
            var r2 = new FakeMessage2(Guid.NewGuid());

            mockProducer.Setup(x => x.Send("test1", It.IsAny<Type>(), It.IsAny<byte[]>(), It.IsAny<Dictionary<string, string>>())).Callback(() =>
            {
                action(r1);
            });

            mockProducer.Setup(x => x.Send("test2", It.IsAny<Type>(), It.IsAny<byte[]>(), It.IsAny<Dictionary<string, string>>())).Callback(() =>
            {
                action(r2);
                task.Start();
            });

            // Act
            var bus = new Bus(mockConfiguration.Object);
            IList<FakeMessage2> responses = bus.SendRequest<FakeMessage1, FakeMessage2>(new List<string>{ "test1", "test2" }, message, null, 1000);

            // Assert
            Assert.Equal(2, responses.Count);
            Assert.True(responses.Contains(r1));
            Assert.True(responses.Contains(r2));
        }
        public void SendingRequestToMultipleEndpointsShouldPassResponsesToCallbackHandler()
        {
            // Arrange
            var mockConfiguration = new Mock<IConfiguration>();
            var mockProducer = new Mock<IProducer>();
            var mockContainer = new Mock<IBusContainer>();
            var mockRequestConfiguration = new Mock<IRequestConfiguration>();

            mockConfiguration.Setup(x => x.GetContainer()).Returns(mockContainer.Object);
            mockConfiguration.Setup(x => x.GetProducer()).Returns(mockProducer.Object);
            mockConfiguration.SetupGet(x => x.TransportSettings).Returns(new TransportSettings());
            mockConfiguration.Setup(x => x.GetRequestConfiguration(It.IsAny<Guid>())).Returns(mockRequestConfiguration.Object);
            var task = new Task(() => { });

            int count = 0;
            var r1 = new FakeMessage2(Guid.NewGuid());
            var r2 = new FakeMessage2(Guid.NewGuid());

            var responses = new List<FakeMessage2>();
            Action<FakeMessage2> action = message2 =>
            {
                count++;
                responses.Add(message2);
            };

            mockRequestConfiguration.Setup(x => x.SetHandler(It.IsAny<Action<object>>())).Callback<Action<object>>(a =>
            {
                a(r1);
                a(r2);
            }).Returns(task);

            var message = new FakeMessage1(Guid.NewGuid())
            {
                Username = "******"
            };

            mockProducer.Setup(x => x.Send(It.IsAny<Type>(), It.IsAny<byte[]>(), It.IsAny<Dictionary<string, string>>()));

            // Act
            var bus = new Bus(mockConfiguration.Object);
            bus.SendRequest(message, action, null);

            // Assert
            mockRequestConfiguration.Verify(x => x.SetHandler(It.IsAny<Action<object>>()), Times.Exactly(1));
            Assert.Equal(2, count);
            Assert.True(responses.Contains(r1));
            Assert.True(responses.Contains(r2));
        }