public async Task HandleAsync_WhenUserWithdrawSucceededIntegrationEventIsValid_ShouldBeCompletedTask()
        {
            // Arrange
            TestMock.UserService.Setup(userService => userService.SendEmailAsync(It.IsAny <UserId>(), It.IsAny <string>(), It.IsAny <object>()))
            .Returns(Task.CompletedTask)
            .Verifiable();

            var handler = new UserWithdrawSucceededIntegrationEventHandler(TestMock.UserService.Object, TestMock.SendgridOptions.Object);

            var integrationEvent = new UserWithdrawSucceededIntegrationEvent
            {
                Transaction = new TransactionDto
                {
                    Currency = new CurrencyDto
                    {
                        Type   = EnumCurrencyType.Money,
                        Amount = Money.Fifty.Amount
                    },
                    Description = "test",
                    Id          = new TransactionId(),
                    Status      = EnumTransactionStatus.Succeeded,
                    Timestamp   = DateTime.UtcNow.ToTimestamp(),
                    Type        = EnumTransactionType.Withdraw
                },
                UserId = new UserId()
            };

            // Act
            await handler.HandleAsync(integrationEvent);

            // Assert
            TestMock.UserService.Verify(userService => userService.SendEmailAsync(It.IsAny <UserId>(), It.IsAny <string>(), It.IsAny <object>()), Times.Once);
        }
        public async Task HandleAsync_WhenUserWithdrawSucceededIntegrationEventIsValid_ShouldBeCompletedTask()
        {
            // Arrange
            var userId  = new UserId();
            var account = new Account(userId, new List <ITransaction>());

            var mockLogger = new MockLogger <UserWithdrawSucceededIntegrationEventHandler>();

            TestMock.AccountService.Setup(accountRepository => accountRepository.AccountExistsAsync(It.IsAny <UserId>())).ReturnsAsync(true).Verifiable();

            TestMock.AccountService.Setup(accountRepository => accountRepository.FindAccountAsync(It.IsAny <UserId>())).ReturnsAsync(account).Verifiable();

            TestMock.AccountService
            .Setup(
                accountService => accountService.MarkAccountTransactionAsSucceededAsync(
                    It.IsAny <IAccount>(),
                    It.IsAny <TransactionId>(),
                    It.IsAny <CancellationToken>()))
            .ReturnsAsync(new DomainValidationResult <ITransaction>())
            .Verifiable();

            var handler = new UserWithdrawSucceededIntegrationEventHandler(TestMock.AccountService.Object, mockLogger.Object);

            var integrationEvent = new UserWithdrawSucceededIntegrationEvent
            {
                UserId      = userId,
                Transaction = new TransactionDto
                {
                    Id          = new TransactionId(),
                    Description = "test",
                    Status      = EnumTransactionStatus.Succeeded,
                    Currency    = new CurrencyDto
                    {
                        Type   = EnumCurrencyType.Money,
                        Amount = Money.Fifty.Amount
                    },
                    Timestamp = Timestamp.FromDateTime(DateTime.UtcNow),
                    Type      = EnumTransactionType.Withdraw
                }
            };

            // Act
            await handler.HandleAsync(integrationEvent);

            // Assert
            TestMock.AccountService.Verify(accountRepository => accountRepository.AccountExistsAsync(It.IsAny <UserId>()), Times.Once);
            TestMock.AccountService.Verify(accountRepository => accountRepository.FindAccountAsync(It.IsAny <UserId>()), Times.Once);

            TestMock.AccountService.Verify(
                accountService =>
                accountService.MarkAccountTransactionAsSucceededAsync(It.IsAny <IAccount>(), It.IsAny <TransactionId>(), It.IsAny <CancellationToken>()),
                Times.Once);

            mockLogger.Verify(Times.Once());
        }
        public static async Task PublishUserWithdrawSucceededIntegrationEventAsync(
            this IServiceBusPublisher publisher,
            UserId userId,
            TransactionDto transaction
            )
        {
            var integrationEvent = new UserWithdrawSucceededIntegrationEvent
            {
                UserId      = userId,
                Transaction = transaction
            };

            await publisher.PublishAsync(integrationEvent);
        }