From 3f9ff57785cb230900ada3933faec2066368fcd8 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Fri, 11 Nov 2016 10:30:02 -0500 Subject: [PATCH] 2.9 - Handling Failed Charges --- app/Billing/FakePaymentGateway.php | 3 +++ app/Billing/PaymentFailedException.php | 5 +++++ .../Controllers/ConcertOrdersController.php | 13 ++++++++---- tests/features/PurchaseTicketsTest.php | 21 ++++++++++++++----- tests/unit/Billing/FakePaymentGatewayTest.php | 14 +++++++++++++ 5 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 app/Billing/PaymentFailedException.php diff --git a/app/Billing/FakePaymentGateway.php b/app/Billing/FakePaymentGateway.php index 5d62847..8f72e51 100644 --- a/app/Billing/FakePaymentGateway.php +++ b/app/Billing/FakePaymentGateway.php @@ -18,6 +18,9 @@ class FakePaymentGateway implements PaymentGateway public function charge($amount, $token) { + if ($token !== $this->getValidTestToken()) { + throw new PaymentFailedException; + } $this->charges[] = $amount; } diff --git a/app/Billing/PaymentFailedException.php b/app/Billing/PaymentFailedException.php new file mode 100644 index 0000000..efd1ae6 --- /dev/null +++ b/app/Billing/PaymentFailedException.php @@ -0,0 +1,5 @@ + ['required'], ]); - $concert = Concert::find($concertId); - $this->paymentGateway->charge(request('ticket_quantity') * $concert->ticket_price, request('payment_token')); - $order = $concert->orderTickets(request('email'), request('ticket_quantity')); + try { + $concert = Concert::find($concertId); + $this->paymentGateway->charge(request('ticket_quantity') * $concert->ticket_price, request('payment_token')); + $order = $concert->orderTickets(request('email'), request('ticket_quantity')); - return response()->json([], 201); + return response()->json([], 201); + } catch (PaymentFailedException $e) { + return response()->json([], 422); + } } } diff --git a/tests/features/PurchaseTicketsTest.php b/tests/features/PurchaseTicketsTest.php index 3edc82d..b1d6a84 100644 --- a/tests/features/PurchaseTicketsTest.php +++ b/tests/features/PurchaseTicketsTest.php @@ -32,26 +32,37 @@ class PurchaseTicketsTest extends TestCase /** @test */ function customer_can_purchase_concert_tickets() { - // Arrange $concert = factory(Concert::class)->create(['ticket_price' => 3250]); - // Act $this->orderTickets($concert, [ 'email' => 'john@example.com', 'ticket_quantity' => 3, 'payment_token' => $this->paymentGateway->getValidTestToken(), ]); - // Assert $this->assertResponseStatus(201); - $this->assertEquals(9750, $this->paymentGateway->totalCharges()); - $order = $concert->orders()->where('email', 'john@example.com')->first(); $this->assertNotNull($order); $this->assertEquals(3, $order->tickets()->count()); } + /** @test */ + function an_order_is_not_created_if_payment_fails() + { + $concert = factory(Concert::class)->create(['ticket_price' => 3250]); + + $this->orderTickets($concert, [ + 'email' => 'john@example.com', + 'ticket_quantity' => 3, + 'payment_token' => 'invalid-payment-token', + ]); + + $this->assertResponseStatus(422); + $order = $concert->orders()->where('email', 'john@example.com')->first(); + $this->assertNull($order); + } + /** @test */ function email_is_required_to_purchase_tickets() { diff --git a/tests/unit/Billing/FakePaymentGatewayTest.php b/tests/unit/Billing/FakePaymentGatewayTest.php index c1b0886..0e5e439 100644 --- a/tests/unit/Billing/FakePaymentGatewayTest.php +++ b/tests/unit/Billing/FakePaymentGatewayTest.php @@ -1,6 +1,7 @@ assertEquals(2500, $paymentGateway->totalCharges()); } + + /** @test */ + function charges_with_an_invalid_payment_token_fail() + { + try { + $paymentGateway = new FakePaymentGateway; + $paymentGateway->charge(2500, 'invalid-payment-token'); + } catch (PaymentFailedException $e) { + return; + } + + $this->fail(); + } }