public async Task ValidPaymentIsProcessed()
        {
            var service = BuildPaymentService();

            var response = await service.ProcessPayment(PaymentRequestBuilder.ValidPaymentRequest());

            Assert.That(response.Status, Is.EqualTo(PaymentStatus.Accepted));
            Assert.That(response.Id, Is.Not.EqualTo(Guid.Empty));
            Assert.That(response.BankTransactionId, Is.Not.EqualTo(Guid.Empty));
        }
        public async Task PaymentCanFail()
        {
            var bankService = new FakeAquiringBankService();
            var payment     = PaymentRequestBuilder.RequestToBeRejected();

            var result = await bankService.ProcessPayment(payment);

            Assert.That(result, Is.Not.Null);
            Assert.That(result.Success, Is.False);
            Assert.That(result.TransactionId, Is.Not.EqualTo(Guid.Empty));
        }
        public async Task CanProcessPayment()
        {
            var bankService = new FakeAquiringBankService();
            var payment     = PaymentRequestBuilder.ValidPaymentRequest();

            var result = await bankService.ProcessPayment(payment);

            Assert.That(result, Is.Not.Null);
            Assert.That(result.Success, Is.True);
            Assert.That(result.TransactionId, Is.Not.EqualTo(Guid.Empty));
        }
        public async Task KnownPaymentIdReturnsData()
        {
            var service = BuildPaymentService();

            var response = await service.ProcessPayment(PaymentRequestBuilder.ValidPaymentRequest());

            var payment = service.GetPaymentById(response.Id);

            Assert.That(payment, Is.Not.Null);
            Assert.That(payment !.Status, Is.EqualTo(PaymentStatus.Accepted));
        }
        public async Task PaymentCanBeRejected()
        {
            var service = BuildPaymentService();
            var request = PaymentRequestBuilder.RequestToBeRejected();

            var response = await service.ProcessPayment(request);

            Assert.That(response.Status, Is.EqualTo(PaymentStatus.Rejected));
            Assert.That(response.Id, Is.Not.EqualTo(Guid.Empty));
            Assert.That(response.BankTransactionId, Is.Not.EqualTo(Guid.Empty));
        }
        public async Task RejectedPaymentReturnsDataFromRepository()
        {
            var service = BuildPaymentService();

            var request  = PaymentRequestBuilder.RequestToBeRejected();
            var response = await service.ProcessPayment(request);

            var payment = service.GetPaymentById(response.Id);

            Assert.That(payment, Is.Not.Null);
            Assert.That(payment !.Status, Is.EqualTo(PaymentStatus.Rejected));
        }
        public async Task TwoPaymentsHaveDifferentIds()
        {
            var bankService = new FakeAquiringBankService();
            var payment1    = PaymentRequestBuilder.ValidPaymentRequest();
            var payment2    = PaymentRequestBuilder.ValidPaymentRequest();

            payment2.Amount     = 120.0m;
            payment2.NameOnCard = "A.N. Other";

            var result1 = await bankService.ProcessPayment(payment1);

            var result2 = await bankService.ProcessPayment(payment2);

            Assert.That(result1.TransactionId, Is.Not.EqualTo(result2.TransactionId));
        }
        public void FailingBankHasDataInRepository()
        {
            var failingBank = new Mock <IAquiringBankService>();

            failingBank.Setup(r => r.ProcessPayment(It.IsAny <PaymentRequest>()))
            .ThrowsAsync(new InvalidOperationException("fail"));

            var paymentsRepo = new FakePaymentRepository();

            var service = new PaymentService(failingBank.Object,
                                             paymentsRepo,
                                             NullLogger <PaymentService> .Instance);

            var request = PaymentRequestBuilder.ValidPaymentRequest();

            Assert.ThrowsAsync <InvalidOperationException>(() => service.ProcessPayment(request));

            var savedItem = paymentsRepo.AllData().FirstOrDefault();

            Assert.That(savedItem, Is.Not.Null);
            Assert.That(savedItem.Status, Is.EqualTo(PaymentStatus.Received));
            Assert.That(savedItem.BankTransactionId, Is.Null);
        }