3.3 - Refusing Orders When There Are No More Tickets

This commit is contained in:
Adam Wathan
2016-11-14 17:24:32 -05:00
parent 53a69777ea
commit 2ccc635f5f
4 changed files with 56 additions and 3 deletions

View File

@@ -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();
}
}

View File

@@ -0,0 +1,5 @@
<?php
namespace App\Exceptions;
class NotEnoughTicketsException extends \RuntimeException {}

View File

@@ -6,5 +6,8 @@ use Illuminate\Database\Eloquent\Model;
class Ticket extends Model
{
//
public function scopeAvailable($query)
{
return $query->whereNull('order_id');
}
}

View File

@@ -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.");
}
}