public void Submit_CallsHandlerSavesAndPublishesEvents()
        {
            var repo      = new InMemoryEventSourcedRepository();
            var handler   = new FakeCommandHandler(repo);
            var publisher = new Mock <IEventPublisher>();

            var dispatcher = new CommandDispatcher(new[] { handler }, repo, publisher.Object);

            var id = Guid.NewGuid();

            var updatedText = Guid.NewGuid().ToString();

            dispatcher.Submit(new CreateFakeAggregate {
                Id = id
            });
            dispatcher.Submit(new UpdateFakeAggregate {
                Id = id, Text = updatedText
            });

            var aggreate = repo.GetById <FakeAggregate>(id);

            Assert.AreEqual(updatedText, aggreate.Text);

            publisher.Verify(f => f.PublishEvent(It.Is <IEvent>(e => e.GetType() == typeof(FakeAggregateCreated))), Times.Once);
            publisher.Verify(f => f.PublishEvent(It.Is <IEvent>(e => e.GetType() == typeof(FakeAggregateUpdated))), Times.Once);
        }
        public async Task when_handling_the_command_with_real_CommandProcessor()
        {
            var fakeCommandHandler = new FakeCommandHandler(_ => { });

            var mock = new Mock <IServiceProvider>();

            mock.Setup(x => x.GetService(typeof(ICommandHandler <FakeCommand>))).Returns(fakeCommandHandler);

            Subject = new FakeCommandController(new CommandProcessor(new CommandTypeCollection(typeof(FakeCommand).Assembly), mock.Object))
            {
                Request       = new HttpRequestMessage(),
                Configuration = new HttpConfiguration()
            };

            async Task should_work()
            {
                var commandName = "FakeCommand";
                var json        = JObject.Parse("{}");

                var result = await Subject.Handle(commandName, json) as OkResult;

                result.Should().NotBeNull();
            }

            async Task should_handle_errors()
            {
                var commandName = "NotFoundCommand";
                var json        = JObject.Parse("{}");

                var result = await Subject.Handle(commandName, json) as BadRequestErrorMessageResult;

                await result.ShouldBeErrorAsync("The command type 'NotFoundCommand' could not be found");
            }
        }
        public void ProcessCommand_HandlerRegisteredForCommand_ShouldCallHandlerWithCommand()
        {
            // Arrange
            var fakeCommand = new FakeCommand();
            var fakeCommandHandler = new FakeCommandHandler();
            commandProcessor.RegisterCommandHandler(fakeCommandHandler);

            // Act
            commandProcessor.ProcessCommand(fakeCommand);

            // Assert
            Assert.That(fakeCommandHandler.HandleCommandLastCalledWith, Is.SameAs(fakeCommand));
        }
        public async Task when_processing_the_command()
        {
            FakeCommandTypeCollection = new Mock <ICommandTypeCollection>();
            FakeServiceProvider       = new Mock <IServiceProvider>();
            Subject = new CommandProcessor(FakeCommandTypeCollection.Object, FakeServiceProvider.Object);

            async Task should_invoke_the_correct_command_handler()
            {
                var fakeCommandHandler = new FakeCommandHandler(x => Expected = x);

                FakeServiceProvider.Setup(x => x.GetService(typeof(ICommandHandler <FakeCommand>))).Returns(fakeCommandHandler);

                var command = new FakeCommand();

                await Subject.ProcessAsync(command);

                Expected.Should().Be(command);
            }

            void should_throw_exception_if_the_command_handler_is_not_found()
            {
                var command = new Mock <ICommand>().Object;

                Subject.Awaiting(async x => await x.ProcessAsync(command)).Should()
                .Throw <CommandProcessorException>()
                .WithMessage($"The command handler for '{command}' could not be found");
            }

            void should_throw_exception_if_the_command_type_is_not_found()
            {
                var commandName = "NotFoundCommand";
                var json        = JObject.Parse("{}");

                Subject.Awaiting(async x => await x.ProcessAsync(commandName, json)).Should()
                .Throw <CommandProcessorException>()
                .WithMessage("The command type 'NotFoundCommand' could not be found");
            }

            void should_throw_exception_if_the_json_is_invalid()
            {
                var commandName = "FakeCommand";

                FakeCommandTypeCollection.Setup(x => x.GetType(commandName)).Returns(typeof(FakeCommand));

                Subject.Awaiting(async x => await x.ProcessAsync(commandName, (JObject)null)).Should()
                .Throw <CommandProcessorException>()
                .WithMessage("The json could not be converted to an object");
            }
        }
        public void Submit_CallsHandlerSavesAndPublishesEvents()
        {
            var repo = new InMemoryEventSourcedRepository();
            var handler = new FakeCommandHandler(repo);
            var publisher = new Mock<IEventPublisher>();

            var dispatcher = new CommandDispatcher(new[] { handler }, repo, publisher.Object);

            var id = Guid.NewGuid();

            var updatedText = Guid.NewGuid().ToString();

            dispatcher.Submit(new CreateFakeAggregate { Id = id });
            dispatcher.Submit(new UpdateFakeAggregate { Id = id, Text = updatedText });

            var aggreate = repo.GetById<FakeAggregate>(id);

            Assert.AreEqual(updatedText, aggreate.Text);

            publisher.Verify(f => f.PublishEvent(It.Is<IEvent>(e => e.GetType() == typeof(FakeAggregateCreated))), Times.Once);
            publisher.Verify(f => f.PublishEvent(It.Is<IEvent>(e => e.GetType() == typeof(FakeAggregateUpdated))), Times.Once);
        }