auditionadmin/tests/Feature/app/Http/Controllers/Admin/EnsembleControllerTest.php

210 lines
8.9 KiB
PHP

<?php
use App\Models\Audition;
use App\Models\Ensemble;
use App\Models\Entry;
use App\Models\Event;
use App\Models\Seat;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->ensemble = Ensemble::create([
'name' => 'Wind Ensemble',
'rank' => 1,
'code' => 'we',
'event_id' => Event::factory()->create()->id,
]);
});
describe('EnsembleController::index', function () {
it('denies access to non-admin users', function () {
$this->get(route('admin.ensembles.index'))->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.ensembles.index'))->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.ensembles.index'))->assertRedirect(route('dashboard'));
});
it('shows an index of events', function () {
actAsAdmin();
$this->get(route('admin.ensembles.index'))->assertOk()
->assertSee($this->ensemble->name);
});
});
describe('EnsembleController::store', function () {
it('denies access to non-admin users', function () {
$this->post(route('admin.ensembles.store'))->assertRedirect(route('home'));
actAsNormal();
$this->post(route('admin.ensembles.store'))->assertRedirect(route('dashboard'));
actAsTab();
$this->post(route('admin.ensembles.store'))->assertRedirect(route('dashboard'));
});
it('creates an ensemble', function () {
actAsAdmin();
$this->post(route('admin.ensembles.store'), [
'name' => 'New Ensemble',
'code' => 'ne',
'event_id' => Event::factory()->create()->id,
])->assertRedirect(route('admin.ensembles.index'))->assertSessionHas('success');
});
});
describe('EnsembleController::destroy', function () {
it('denies access to non-admin users', function () {
$this->delete(route('admin.ensembles.destroy', $this->ensemble))->assertRedirect(route('home'));
actAsNormal();
$this->delete(route('admin.ensembles.destroy', $this->ensemble))->assertRedirect(route('dashboard'));
actAsTab();
$this->delete(route('admin.ensembles.destroy', $this->ensemble))->assertRedirect(route('dashboard'));
});
it('will not destroy an ensemble with seated students', function () {
actAsAdmin();
$audition = Audition::factory()->create();
$entry = Entry::factory()->create();
Seat::create([
'ensemble_id' => $this->ensemble->id,
'audition_id' => $audition->id,
'seat' => 3,
'entry_id' => $entry->id,
]);
$this->delete(route('admin.ensembles.destroy', $this->ensemble))->assertRedirect(route('admin.ensembles.index'))
->assertSessionHas('error', 'Ensemble has students seated and cannot be deleted');
});
it('can delete an ensemble', function () {
$startCount = Ensemble::count();
actAsAdmin();
$this->delete(route('admin.ensembles.destroy', $this->ensemble))->assertRedirect(route('admin.ensembles.index'))
->assertSessionHas('success', 'Ensemble deleted successfully');
expect(Ensemble::count())->toEqual($startCount - 1);
});
});
describe('EnsembleController::update', function () {
it('denies access to non-admin users', function () {
$this->patch(route('admin.ensembles.update', $this->ensemble))->assertRedirect(route('home'));
actAsNormal();
$this->patch(route('admin.ensembles.update', $this->ensemble))->assertRedirect(route('dashboard'));
actAsTab();
$this->patch(route('admin.ensembles.update', $this->ensemble))->assertRedirect(route('dashboard'));
});
it('can update an event', function () {
$event = Event::factory()->create();
actAsAdmin();
$response = $this->patch(route('admin.ensembles.update', $this->ensemble), [
'name' => 'Wind Ensemble Restart',
'code' => 'we2',
'event_id' => $event->id,
]);
$response->assertRedirect(route('admin.ensembles.index'))
->assertSessionHas('success', 'Ensemble updated successfully');
});
});
describe('EnsembleController::seatingLimits with no ensemble', function () {
it('denies access to non-admin users', function () {
$this->get(route('admin.ensembles.seatingLimits'))->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.ensembles.seatingLimits'))->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.ensembles.seatingLimits'))->assertRedirect(route('dashboard'));
});
it('returns a page to choose and ensemble for which to set limits', function () {
actAsAdmin();
$response = $this->get(route('admin.ensembles.seatingLimits'))->assertOk()
->assertViewIs('admin.ensembles.seatingLimits')
->assertViewHas('ensembles');
expect($response->viewData('ensemble')->exists)->toBeFalse()
->and($response->viewData('ensembles')->first()->id)->toEqual($this->ensemble->id)
->and($response->viewData('limits'))->toBe([]);
});
});
describe('EnsembleController::seatingLimits get with ensemble', function () {
it('denies access to non-admin users', function () {
$this->get(route('admin.ensembles.seatingLimits', $this->ensemble))->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.ensembles.seatingLimits', $this->ensemble))->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.ensembles.seatingLimits', $this->ensemble))->assertRedirect(route('dashboard'));
});
it('displays a form with fields for every audition to set the max for this ensemble', function () {
actAsAdmin();
$auditions = Audition::factory()->count(5)->create(['event_id' => $this->ensemble->event_id]);
DB::table('seating_limits')->insert([
'ensemble_id' => $this->ensemble->id,
'audition_id' => $auditions[0]->id,
'maximum_accepted' => 6,
]);
$response = $this->get(route('admin.ensembles.seatingLimits.ensemble.set', $this->ensemble))->assertOk();
foreach (Audition::all() as $audition) {
$response->assertSee('audition['.$audition->id.']');
}
});
});
describe('EnsembleController::seatingLimitsSet', function () {
it('denies access to non-admin users', function () {
$this->post(route('admin.ensembles.seatingLimits.ensemble.set',
$this->ensemble))->assertRedirect(route('home'));
actAsNormal();
$this->post(route('admin.ensembles.seatingLimits.ensemble.set',
$this->ensemble))->assertRedirect(route('dashboard'));
actAsTab();
$this->post(route('admin.ensembles.seatingLimits.ensemble.set',
$this->ensemble))->assertRedirect(route('dashboard'));
});
it('sets seating limits', function () {
actAsAdmin();
$auditions = Audition::factory()->count(3)->create(['event_id' => $this->ensemble->event_id]);
$response = $this->post(route('admin.ensembles.seatingLimits.ensemble.set', $this->ensemble), [
'audition' => [
$auditions[0]->id => 5,
$auditions[1]->id => 10,
$auditions[2]->id => 20,
],
]);
$response->assertRedirect(route('admin.ensembles.seatingLimits.ensemble', $this->ensemble))
->assertSessionHas('success', 'Seating limits set for '.$this->ensemble->name);
});
});
describe('EnsembleController::updateEnsembleRank', function () {
it('denies access to non-admin users', function () {
$this->post(route('admin.ensembles.updateEnsembleRank'))->assertRedirect(route('home'));
actAsNormal();
$this->post(route('admin.ensembles.updateEnsembleRank'))->assertRedirect(route('dashboard'));
actAsTab();
$this->post(route('admin.ensembles.updateEnsembleRank'))->assertRedirect(route('dashboard'));
});
it('reorders ensembles', function () {
actAsAdmin();
$newEnsemble = Ensemble::create([
'name' => 'Alternates',
'code' => 'Alt',
'rank' => 2,
'event_id' => $this->ensemble->event_id,
]);
expect($this->ensemble->rank)->toBe(1);
expect($newEnsemble->rank)->toBe(2);
$response = $this->post(route('admin.ensembles.updateEnsembleRank'), [
'event_id' => $this->ensemble->event_id,
'order' => [
[
'id' => $this->ensemble->id,
'rank' => 2,
],
[
'id' => $newEnsemble->id,
'rank' => 1,
],
],
])->assertJson(['status' => 'success']);
$this->ensemble->refresh();
$newEnsemble->refresh();
expect($this->ensemble->rank)->toBe(2);
expect($newEnsemble->rank)->toBe(1);
});
});