auditionadmin/tests/Feature/Pages/EntriesIndexTest.php

182 lines
6.1 KiB
PHP

<?php
use App\Models\Audition;
use App\Models\Entry;
use App\Models\School;
use App\Models\Student;
use App\Models\User;
use App\Settings;
use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\actingAs;
use function Pest\Laravel\delete;
use function Pest\Laravel\get;
use function Pest\Laravel\post;
uses(RefreshDatabase::class);
beforeEach(function () {
Settings::set('auditionAbbreviation', 'SBDA');
Settings::set('advanceTo', 'OMEA');
$this->school = School::factory()->create();
$this->user = User::factory()->create(['school_id' => $this->school->id]);
});
it('works for a user with a school', function () {
actingAs($this->user)
->get(route('entries.index'))
->assertOk();
});
it('denies a user without a school', function () {
get(route('entries.index'))
->assertRedirect(route('home'));
actingAs(User::factory()->create())
->get(route('entries.index'))
->assertForbidden();
});
it('has appropriate students in JS array for select', function () {
// Arrange
$student = Student::factory()->create(['school_id' => $this->school->id]);
// Act & Assert
actingAs($this->user);
get(route('entries.index'))
->assertSeeInOrder([
'id: ',
$student->id,
'name: ',
$student->full_name(true),
], false); // The false parameter makes the assertion case-sensitive and allows for HTML tags
});
it('has auditions in JS array for select', function () {
// Arrange
$auditions = Audition::factory()->count(5)->create();
// Act & Assert
actingAs($this->user);
$response = get(route('entries.index'));
foreach ($auditions as $audition) {
$response->assertSeeInOrder([
'id: ',
$audition->id,
'name: ',
$audition->name,
'minGrade: ',
$audition->minimum_grade,
'maxGrade: ',
$audition->maximum_grade,
], false);
}
});
it('shows existing entries in a table', function () {
// Arrange
$students = Student::factory()->count(5)->create(['school_id' => $this->school->id]);
$entries = [];
foreach ($students as $student) {
$entries[] = Entry::factory()->create(['student_id' => $student->id]);
}
foreach ($students as $student) {
Entry::class::factory()->create(['student_id' => $student->id]);
}
// Act & Assert
actingAs($this->user);
$response = get(route('entries.index'));
foreach ($entries as $entry) {
$response->
assertSeeInOrder([
'<td',
$entry->student->full_name(true),
$entry->student->grade,
$entry->audition->name,
'</td>',
], false);
}
});
it('shows a delete link for entries whose deadline is not past', function () {
// Arrange
$openAudition = Audition::factory()->create();
$closedAudition = Audition::factory()->closed()->create();
$student = Student::factory()->create(['school_id' => $this->school->id]);
$pendingEntry = Entry::factory()->create(['audition_id' => $openAudition->id, 'student_id' => $student->id]);
$protectedEntry = Entry::factory()->create(['audition_id' => $closedAudition->id, 'student_id' => $student->id]);
// Act & Assert
actingAs($this->user);
get(route('entries.index'))
->assertSee(route('entries.destroy', $pendingEntry))
->assertDontSee(route('entries.destroy', $protectedEntry));
});
it('shows appropriate flags for entry types when advancement is enabled', function () {
// Arrange
$student = Student::factory()->create(['school_id' => $this->school->id]);
$auditionOnlyEntry = Entry::factory()->seatingOnly()->create(['student_id' => $student->id]);
$advanceOnlyEntry = Entry::factory()->advanceOnly()->create(['student_id' => $student->id]);
$bothEntry = Entry::factory()->create(['student_id' => $student->id]);
// Act & Assert
actingAs($this->user);
get(route('entries.index'))
->assertOk()
->assertSee('is entered for seating. Entry ID '.$bothEntry->id)
->assertSee('is entered for advancement. Entry ID '.$bothEntry->id)
->assertSee('is entered for seating. Entry ID '.$auditionOnlyEntry->id)
->assertSee('is not entered for advancement. Entry ID '.$auditionOnlyEntry->id)
->assertSee('is entered for advancement. Entry ID '.$advanceOnlyEntry->id)
->assertSee('is not entered for seating. Entry ID '.$advanceOnlyEntry->id);
});
it('accepts a valid entry', function () {
// Arrange
$student = Student::factory()->create(['school_id' => $this->school->id]);
$audition = Audition::factory()->create();
// Act & Assert
actingAs($this->user);
$response = post(route('entries.store'), [
'student_id' => $student->id,
'audition_id' => $audition->id,
]);
/** @noinspection PhpUnhandledExceptionInspection */
$response->assertSessionHasNoErrors();
$response->assertRedirect(route('entries.index'));
$this->assertDatabaseHas('entries', [
'student_id' => $student->id,
'audition_id' => $audition->id,
]);
});
it('deletes an entry', function () {
// Arrange
$student = Student::factory()->create(['school_id' => $this->school->id]);
$audition = Audition::factory()->create(['name' => 'Flute']);
$entry = Entry::factory()->create(['student_id' => $student->id, 'audition_id' => $audition->id]);
// Act
actingAs($this->user);
$response = delete(route('entries.destroy', $entry));
/** @noinspection PhpUnhandledExceptionInspection */
$response
->assertSessionHasNoErrors()
->assertRedirect(route('entries.index'));
// Assert
$this->assertDatabaseMissing('entries', [
'id' => $entry->id,
]);
});
it('shows entry type checkboxes only when advancement is enabled', function () {
// Arrange
Settings::set('advanceTo', 'OMEA');
// Act & Assert
actingAs($this->user);
get(route('entries.index'))
->assertSee('Enter for');
Settings::set('advanceTo', null);
get(route('entries.index'))
->assertDontSee('Enter for');
});