From 2ccc635f5f4bd52d2e50e91faf2a01e705760d48 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Mon, 14 Nov 2016 17:24:32 -0500 Subject: [PATCH] 3.3 - Refusing Orders When There Are No More Tickets --- app/Concert.php | 10 ++++- app/Exceptions/NotEnoughTicketsException.php | 5 +++ app/Ticket.php | 5 ++- tests/unit/ConcertTest.php | 39 ++++++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 app/Exceptions/NotEnoughTicketsException.php diff --git a/app/Concert.php b/app/Concert.php index dd39c94..119a540 100644 --- a/app/Concert.php +++ b/app/Concert.php @@ -3,6 +3,7 @@ namespace App; use Illuminate\Database\Eloquent\Model; +use App\Exceptions\NotEnoughTicketsException; class Concert extends Model { @@ -41,8 +42,13 @@ class Concert extends Model public function orderTickets($email, $ticketQuantity) { + $tickets = $this->tickets()->available()->take($ticketQuantity)->get(); + + if ($tickets->count() < $ticketQuantity) { + throw new NotEnoughTicketsException; + } + $order = $this->orders()->create(['email' => $email]); - $tickets = $this->tickets()->take($ticketQuantity)->get(); foreach ($tickets as $ticket) { $order->tickets()->save($ticket); @@ -60,6 +66,6 @@ class Concert extends Model public function ticketsRemaining() { - return $this->tickets()->whereNull('order_id')->count(); + return $this->tickets()->available()->count(); } } diff --git a/app/Exceptions/NotEnoughTicketsException.php b/app/Exceptions/NotEnoughTicketsException.php new file mode 100644 index 0000000..331a5cb --- /dev/null +++ b/app/Exceptions/NotEnoughTicketsException.php @@ -0,0 +1,5 @@ +whereNull('order_id'); + } } diff --git a/tests/unit/ConcertTest.php b/tests/unit/ConcertTest.php index 9d1769f..391a039 100644 --- a/tests/unit/ConcertTest.php +++ b/tests/unit/ConcertTest.php @@ -2,6 +2,7 @@ use App\Concert; use Carbon\Carbon; +use App\Exceptions\NotEnoughTicketsException; use Illuminate\Foundation\Testing\WithoutMiddleware; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseTransactions; @@ -58,6 +59,7 @@ class ConcertTest extends TestCase function can_order_concert_tickets() { $concert = factory(Concert::class)->create(); + $concert->addTickets(3); $order = $concert->orderTickets('jane@example.com', 3); @@ -84,4 +86,41 @@ class ConcertTest extends TestCase $this->assertEquals(20, $concert->ticketsRemaining()); } + + /** @test */ + function trying_to_purchase_more_tickets_than_remain_throws_an_exception() + { + $concert = factory(Concert::class)->create(); + $concert->addTickets(10); + + try { + $concert->orderTickets('jane@example.com', 11); + } catch (NotEnoughTicketsException $e) { + $order = $concert->orders()->where('email', 'jane@example.com')->first(); + $this->assertNull($order); + $this->assertEquals(10, $concert->ticketsRemaining()); + return; + } + + $this->fail("Order succeeded even though there were not enough tickets remaining."); + } + + /** @test */ + function cannot_order_tickets_that_have_already_been_purchased() + { + $concert = factory(Concert::class)->create(); + $concert->addTickets(10); + $concert->orderTickets('jane@example.com', 8); + + try { + $concert->orderTickets('john@example.com', 3); + } catch (NotEnoughTicketsException $e) { + $johnsOrder = $concert->orders()->where('email', 'john@example.com')->first(); + $this->assertNull($johnsOrder); + $this->assertEquals(2, $concert->ticketsRemaining()); + return; + } + + $this->fail("Order succeeded even though there were not enough tickets remaining."); + } }