public void When_create_account_command_is_triggered_with_an_empty_name_it_should_throw()
        {
            // Arrange
            var eventStore = new InMemoryEventRepositoryBuilder().Build();
            var handler = new CreateAccountCommandHandler(eventStore);

            // Act
            Action action = () => handler.Handle(new CreateAccountCommand(Guid.NewGuid(), ""));

            // Assert
            action.ShouldThrow<ArgumentException>();
        }
        public void When_create_account_command_is_triggered_it_should_raise_the_appropriate_events()
        {
            // Arrange
            var eventStore = new InMemoryEventRepositoryBuilder().Build();
            var handler = new CreateAccountCommandHandler(eventStore);

            // Act
            handler.Handle(new CreateAccountCommand(Guid.NewGuid(), "Thomas"));

            // Assert
            eventStore.Events.Should().HaveCount(1);
            eventStore.Events.OfType<AccountCreatedEvent>().Should().HaveCount(1);
        }
        public void When_account_holder_moved_command_is_triggered_but_nothing_has_changed_it_should_throw()
        {
            // Arrange
            var account = new Account(Guid.NewGuid(), "Thomas");
            account.SetDetails("Thomas", "New Address", "New Town");

            var eventStore = new InMemoryEventRepositoryBuilder().WithAggregates(account).Build();
            var handler = new AccountHolderMovedCommandHandler(eventStore);

            // Act
            Action action = () => handler.Handle(new AccountHolderMovedCommand(account.Id, "New Address", "New Town"));

            // Assert
            action.ShouldThrow<InvalidOperationException>();
        }
        public void When_close_account_command_is_triggered_on_a_closed_account_it_should_not_raise_events()
        {
            // Arrange
            var account = new Account(Guid.NewGuid(), "Thomas");
            account.Close();

            var eventStore = new InMemoryEventRepositoryBuilder().WithAggregates(account).Build();
            var handler = new CloseAccountCommandHandler(eventStore);

            // Act
            handler.Handle(new CloseAccountCommand(account.Id));

            // Assert
            eventStore.Events.OfType<AccountClosedEvent>().Should().BeEmpty();
        }
        public void When_withdrawing_money_on_a_closed_account_it_should_throw()
        {
            // Arrange
            var account = new Account(Guid.NewGuid(), "Thomas");
            account.Close();

            var eventStore = new InMemoryEventRepositoryBuilder().WithAggregates(account).Build();
            var handler = new WithdrawMoneyCommandHandler(eventStore);

            // Act
            Action action = () => handler.Handle(new WithdrawMoneyCommand(account.Id, 200));

            // Assert
            action.ShouldThrow<InvalidOperationException>();
        }
        public void When_set_account_details_command_is_triggered_but_nothing_has_changed_it_should_not_raise_events()
        {
            // Arrange
            var account = new Account(Guid.NewGuid(), "Thomas");
            account.SetDetails("New Name", "New Address", "New Town");

            var eventStore = new InMemoryEventRepositoryBuilder().WithAggregates(account).Build();
            var handler = new SetAccountDetailsCommandHandler(eventStore);

            // Act
            handler.Handle(new SetAccountDetailsCommand(account.Id, "New Name", "New Address", "New Town"));

            // Assert
            eventStore.Events.Should().BeEmpty();
        }
        public void When_depositing_money_it_should_add_it_to_the_account()
        {
            // Arrange
            var account = new Account(Guid.NewGuid(), "Thomas");
            var eventStore = new InMemoryEventRepositoryBuilder().WithAggregates(account).Build();
            var handler = new DepositMoneyCommandHandler(eventStore);

            // Act
            handler.Handle(new DepositMoneyCommand(account.Id, 200));

            // Assert
            eventStore.Events.Should().HaveCount(1);
            eventStore.Events.OfType<MoneyDepositedEvent>().Should().HaveCount(1);

            account = eventStore.GetById<Account>(account.Id);
            account.Amount.Should().Be(200);
        }
        public void When_close_account_command_is_triggered_it_should_raise_the_appropriate_events()
        {
            // Arrange
            var account = new Account(Guid.NewGuid(), "Thomas");

            var eventStore = new InMemoryEventRepositoryBuilder().WithAggregates(account).Build();
            var handler = new CloseAccountCommandHandler(eventStore);

            // Act
            handler.Handle(new CloseAccountCommand(account.Id));

            // Assert
            eventStore.Events.Should().HaveCount(1);
            eventStore.Events.OfType<AccountClosedEvent>().Should().HaveCount(1);

            account = eventStore.GetById<Account>(account.Id);
            account.IsActive.Should().BeFalse();
        }
        public void When_account_holder_moved_command_is_triggered_it_should_raise_the_appropriate_events()
        {
            // Arrange
            var account = new Account(Guid.NewGuid(), "Thomas");

            var eventStore = new InMemoryEventRepositoryBuilder().WithAggregates(account).Build();
            var handler = new AccountHolderMovedCommandHandler(eventStore);

            // Act
            handler.Handle(new AccountHolderMovedCommand(account.Id, "New Address", "New City"));

            // Assert
            eventStore.Events.Should().HaveCount(1);
            eventStore.Events.OfType<AccountHolderMovedEvent>().Should().HaveCount(1);

            account = eventStore.GetById<Account>(account.Id);
            account.Address.Should().Be("New Address");
            account.City.Should().Be("New City");
        }