100 - Namespacing Our Test Suite

This commit is contained in:
Adam Wathan
2017-05-02 15:42:01 -04:00
parent 01602b46d4
commit bed85c66c1
18 changed files with 80 additions and 55 deletions

View File

@@ -0,0 +1,68 @@
<?php
namespace Tests\Feature;
use App\User;
use Tests\TestCase;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class PromoterLoginTest extends TestCase
{
use DatabaseMigrations;
/** @test */
function logging_in_with_valid_credentials()
{
$this->disableExceptionHandling();
$user = factory(User::class)->create([
'email' => 'jane@example.com',
'password' => bcrypt('super-secret-password'),
]);
$response = $this->post('/login', [
'email' => 'jane@example.com',
'password' => 'super-secret-password',
]);
$response->assertRedirect('/backstage/concerts');
$this->assertTrue(Auth::check());
$this->assertTrue(Auth::user()->is($user));
}
/** @test */
function logging_in_with_invalid_credentials()
{
$this->disableExceptionHandling();
$user = factory(User::class)->create([
'email' => 'jane@example.com',
'password' => bcrypt('super-secret-password'),
]);
$response = $this->post('/login', [
'email' => 'jane@example.com',
'password' => 'not-the-right-password',
]);
$response->assertRedirect('/login');
$response->assertSessionHasErrors('email');
$this->assertFalse(Auth::check());
}
/** @test */
function logging_in_with_an_account_that_does_not_exist()
{
$this->disableExceptionHandling();
$response = $this->post('/login', [
'email' => 'nobody@example.com',
'password' => 'not-the-right-password',
]);
$response->assertRedirect('/login');
$response->assertSessionHasErrors('email');
$this->assertFalse(Auth::check());
}
}

View File

@@ -0,0 +1,243 @@
<?php
namespace Tests\Feature;
use App\Concert;
use Tests\TestCase;
use App\Facades\TicketCode;
use App\Billing\PaymentGateway;
use App\Billing\FakePaymentGateway;
use App\Mail\OrderConfirmationEmail;
use Illuminate\Support\Facades\Mail;
use App\Facades\OrderConfirmationNumber;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class PurchaseTicketsTest extends TestCase
{
use DatabaseMigrations;
protected function setUp()
{
parent::setUp();
$this->paymentGateway = new FakePaymentGateway;
$this->app->instance(PaymentGateway::class, $this->paymentGateway);
Mail::fake();
}
private function orderTickets($concert, $params)
{
$savedRequest = $this->app['request'];
$this->response = $this->json('POST', "/concerts/{$concert->id}/orders", $params);
$this->app['request'] = $savedRequest;
}
private function assertResponseStatus($status)
{
$this->response->assertStatus($status);
}
private function seeJsonSubset($data)
{
$this->response->assertJson($data);
}
private function decodeResponseJson()
{
return $this->response->decodeResponseJson();
}
private function assertValidationError($field)
{
$this->assertResponseStatus(422);
$this->assertArrayHasKey($field, $this->decodeResponseJson());
}
/** @test */
function customer_can_purchase_tickets_to_a_published_concert()
{
$this->disableExceptionHandling();
OrderConfirmationNumber::shouldReceive('generate')->andReturn('ORDERCONFIRMATION1234');
TicketCode::shouldReceive('generateFor')->andReturn('TICKETCODE1', 'TICKETCODE2', 'TICKETCODE3');
$concert = factory(Concert::class)->states('published')->create(['ticket_price' => 3250])->addTickets(3);
$this->orderTickets($concert, [
'email' => 'john@example.com',
'ticket_quantity' => 3,
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertResponseStatus(201);
$this->seeJsonSubset([
'confirmation_number' => 'ORDERCONFIRMATION1234',
'email' => 'john@example.com',
'amount' => 9750,
'tickets' => [
['code' => 'TICKETCODE1'],
['code' => 'TICKETCODE2'],
['code' => 'TICKETCODE3'],
]
]);
$this->assertEquals(9750, $this->paymentGateway->totalCharges());
$this->assertTrue($concert->hasOrderFor('john@example.com'));
$order = $concert->ordersFor('john@example.com')->first();
$this->assertEquals(3, $order->ticketQuantity());
Mail::assertSent(OrderConfirmationEmail::class, function ($mail) use ($order) {
return $mail->hasTo('john@example.com')
&& $mail->order->id == $order->id;
});
}
/** @test */
function cannot_purchase_tickets_to_an_unpublished_concert()
{
$concert = factory(Concert::class)->states('unpublished')->create()->addTickets(3);
$this->orderTickets($concert, [
'email' => 'john@example.com',
'ticket_quantity' => 3,
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertResponseStatus(404);
$this->assertFalse($concert->hasOrderFor('john@example.com'));
$this->assertEquals(0, $this->paymentGateway->totalCharges());
}
/** @test */
function an_order_is_not_created_if_payment_fails()
{
$concert = factory(Concert::class)->states('published')->create(['ticket_price' => 3250])->addTickets(3);
$this->orderTickets($concert, [
'email' => 'john@example.com',
'ticket_quantity' => 3,
'payment_token' => 'invalid-payment-token',
]);
$this->assertResponseStatus(422);
$this->assertFalse($concert->hasOrderFor('john@example.com'));
$this->assertEquals(3, $concert->ticketsRemaining());
}
/** @test */
function cannot_purchase_more_tickets_than_remain()
{
$concert = factory(Concert::class)->states('published')->create()->addTickets(50);
$this->orderTickets($concert, [
'email' => 'john@example.com',
'ticket_quantity' => 51,
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertResponseStatus(422);
$this->assertFalse($concert->hasOrderFor('john@example.com'));
$this->assertEquals(0, $this->paymentGateway->totalCharges());
$this->assertEquals(50, $concert->ticketsRemaining());
}
/** @test */
function cannot_purchase_tickets_another_customer_is_already_trying_to_purchase()
{
$this->disableExceptionHandling();
$concert = factory(Concert::class)->states('published')->create([
'ticket_price' => 1200
])->addTickets(3);
$this->paymentGateway->beforeFirstCharge(function ($paymentGateway) use ($concert) {
$this->orderTickets($concert, [
'email' => 'personB@example.com',
'ticket_quantity' => 1,
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertResponseStatus(422);
$this->assertFalse($concert->hasOrderFor('personB@example.com'));
$this->assertEquals(0, $this->paymentGateway->totalCharges());
});
$this->orderTickets($concert, [
'email' => 'personA@example.com',
'ticket_quantity' => 3,
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertEquals(3600, $this->paymentGateway->totalCharges());
$this->assertTrue($concert->hasOrderFor('personA@example.com'));
$this->assertEquals(3, $concert->ordersFor('personA@example.com')->first()->ticketQuantity());
}
/** @test */
function email_is_required_to_purchase_tickets()
{
$concert = factory(Concert::class)->states('published')->create();
$this->orderTickets($concert, [
'ticket_quantity' => 3,
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertValidationError('email');
}
/** @test */
function email_must_be_valid_to_purchase_tickets()
{
$concert = factory(Concert::class)->states('published')->create();
$this->orderTickets($concert, [
'email' => 'not-an-email-address',
'ticket_quantity' => 3,
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertValidationError('email');
}
/** @test */
function ticket_quantity_is_required_to_purchase_tickets()
{
$concert = factory(Concert::class)->states('published')->create();
$this->orderTickets($concert, [
'email' => 'john@example.com',
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertValidationError('ticket_quantity');
}
/** @test */
function ticket_quantity_must_be_at_least_1_to_purchase_tickets()
{
$concert = factory(Concert::class)->states('published')->create();
$this->orderTickets($concert, [
'email' => 'john@example.com',
'ticket_quantity' => 0,
'payment_token' => $this->paymentGateway->getValidTestToken(),
]);
$this->assertValidationError('ticket_quantity');
}
/** @test */
function payment_token_is_required()
{
$concert = factory(Concert::class)->states('published')->create();
$this->orderTickets($concert, [
'email' => 'john@example.com',
'ticket_quantity' => 3,
]);
$this->assertValidationError('payment_token');
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Tests\Feature;
use App\Concert;
use Carbon\Carbon;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ViewConcertListingTest extends TestCase
{
use DatabaseMigrations;
/** @test */
function user_can_view_a_published_concert_listing()
{
$concert = factory(Concert::class)->states('published')->create([
'title' => 'The Red Chord',
'subtitle' => 'with Animosity and Lethargy',
'date' => Carbon::parse('December 13, 2016 8:00pm'),
'ticket_price' => 3250,
'venue' => 'The Mosh Pit',
'venue_address' => '123 Example Lane',
'city' => 'Laraville',
'state' => 'ON',
'zip' => '17916',
'additional_information' => 'For tickets, call (555) 555-5555.',
]);
$response = $this->get('/concerts/'.$concert->id);
$response->assertStatus(200);
$response->assertSee('The Red Chord');
$response->assertSee('with Animosity and Lethargy');
$response->assertSee('December 13, 2016');
$response->assertSee('8:00pm');
$response->assertSee('32.50');
$response->assertSee('The Mosh Pit');
$response->assertSee('123 Example Lane');
$response->assertSee('Laraville, ON 17916');
$response->assertSee('For tickets, call (555) 555-5555.');
}
/** @test */
function user_cannot_view_unpublished_concert_listings()
{
$concert = factory(Concert::class)->states('unpublished')->create();
$response = $this->get('/concerts/'.$concert->id);
$response->assertStatus(404);
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Tests\Feature;
use App\Order;
use App\Ticket;
use App\Concert;
use Carbon\Carbon;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ViewOrderTest extends TestCase
{
use DatabaseMigrations;
/** @test */
function user_can_view_their_order_confirmation()
{
$this->disableExceptionHandling();
$concert = factory(Concert::class)->create([
'title' => 'The Red Chord',
'subtitle' => 'with Animosity and Lethargy',
'date' => Carbon::parse('March 12, 2017 8:00pm'),
'ticket_price' => 4250,
'venue' => 'The Mosh Pit',
'venue_address' => '123 Example Lane',
'city' => 'Laraville',
'state' => 'ON',
'zip' => '17916',
]);
$order = factory(Order::class)->create([
'confirmation_number' => 'ORDERCONFIRMATION1234',
'card_last_four' => '1881',
'amount' => 8500,
'email' => 'john@example.com',
]);
$ticketA = factory(Ticket::class)->create([
'concert_id' => $concert->id,
'order_id' => $order->id,
'code' => 'TICKETCODE123'
]);
$ticketB = factory(Ticket::class)->create([
'concert_id' => $concert->id,
'order_id' => $order->id,
'code' => 'TICKETCODE456'
]);
$response = $this->get("/orders/ORDERCONFIRMATION1234");
$response->assertStatus(200);
$response->assertViewHas('order', function ($viewOrder) use ($order) {
return $order->id === $viewOrder->id;
});
$response->assertSee('ORDERCONFIRMATION1234');
$response->assertSee('$85.00');
$response->assertSee('**** **** **** 1881');
$response->assertSee('TICKETCODE123');
$response->assertSee('TICKETCODE456');
$response->assertSee('The Red Chord');
$response->assertSee('with Animosity and Lethargy');
$response->assertSee('The Mosh Pit');
$response->assertSee('123 Example Lane');
$response->assertSee('Laraville, ON');
$response->assertSee('17916');
$response->assertSee('john@example.com');
$response->assertSee('2017-03-12 20:00');
}
}