auditionadmin/tests/Feature/app/Actions/Entries/CreateEntriesTest.php

141 lines
6.6 KiB
PHP

<?php
use App\Actions\Entries\CreateEntry;
use App\Exceptions\AuditionAdminException;
use App\Models\Audition;
use App\Models\AuditionFlag;
use App\Models\Entry;
use App\Models\Student;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->scribe = app(CreateEntry::class);
});
it('can create an entry', function () {
$student = Student::factory()->create(['grade' => 9]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
$this->scribe->createEntry($student, $audition);
$thisEntry = Entry::where('student_id', $student->id)->first();
expect($thisEntry)->toBeInstanceOf(Entry::class);
});
it('is invokable', function () {
$student = Student::factory()->create(['grade' => 9]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
($this->scribe)($student, $audition);
$thisEntry = Entry::where('student_id', $student->id)->first();
expect($thisEntry)->toBeInstanceOf(Entry::class);
});
it('accepts integer IDs as well as models for arguments', function () {
$student = Student::factory()->create(['grade' => 9]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
$this->scribe->createEntry($student->id, $audition->id);
$thisEntry = Entry::where('student_id', $student->id)->first();
expect($thisEntry)->toBeInstanceOf(Entry::class);
});
it('defaults to entering seating and advancement', function () {
$student = Student::factory()->create(['grade' => 9]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
$this->scribe->createEntry($student, $audition);
$thisEntry = Entry::where('student_id', $student->id)->first();
expect($thisEntry->for_seating)->toBeTruthy()
->and($thisEntry->for_advancement)->toBeTruthy();
});
it('allows setting only seating', function () {
$student = Student::factory()->create(['grade' => 9]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
$this->scribe->createEntry($student, $audition, 'seating');
$thisEntry = Entry::where('student_id', $student->id)->first();
expect($thisEntry->for_seating)->toBeTruthy()
->and($thisEntry->for_advancement)->toBeFalsy();
});
test('allows setting only advancement', function () {
$student = Student::factory()->create(['grade' => 9]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
$this->scribe->createEntry($student, $audition, for_advancement: true);
$thisEntry = Entry::where('student_id', $student->id)->first();
expect($thisEntry->for_seating)->toBeFalsy()
->and($thisEntry->for_advancement)->toBeTruthy();
});
it('does not assign a draw number if the audition is not drawn', function () {
$student = Student::factory()->create(['grade' => 9]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
$this->scribe->createEntry($student, $audition);
$thisEntry = Entry::where('student_id', $student->id)->first();
expect($thisEntry->draw_number)->toBeNull();
});
it('assigns the next available draw number if the audition is drawn', function () {
$audition = Audition::factory()
->has(Entry::factory()->count(5))
->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'drawn']);
$n = 1;
foreach ($audition->entries as $entry) {
$entry->update(['draw_number' => $n]);
$n++;
}
$student = Student::factory()->create(['grade' => 9]);
$this->scribe->createEntry($student, $audition);
$thisEntry = Entry::where('student_id', $student->id)->first();
expect($thisEntry->draw_number)->toEqual($n);
});
it('throws an exception if the audition seating is published', function () {
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'seats_published']);
$student = Student::factory()->create(['grade' => 9]);
$this->scribe->createEntry($student, $audition);
})->throws(AuditionAdminException::class, 'Cannot add an entry to an audition where seats are published');
it('throws an exception if the audition advancement is published', function () {
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'advancement_published']);
$student = Student::factory()->create(['grade' => 9]);
$this->scribe->createEntry($student, $audition);
})->throws(AuditionAdminException::class, 'Cannot add an entry to an audition where advancement is published');
it('throws an exception if the student does not exist', function () {
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
$student = Student::factory()->make(['grade' => 9]);
$this->scribe->createEntry($student, $audition);
})->throws(AuditionAdminException::class, 'Invalid student provided');
it('throws an exception if the audition does not exist', function () {
$audition = Audition::factory()->make(['minimum_grade' => 9, 'maximum_grade' => 12]);
$student = Student::factory()->create(['grade' => 9]);
$this->scribe->createEntry($student, $audition);
})->throws(AuditionAdminException::class, 'Invalid audition provided');
it('throws an exception if the student is already entered in the audition', function () {
$og_entry = Entry::factory()->create();
$this->scribe->createEntry($og_entry->student, $og_entry->audition);
})->throws(AuditionAdminException::class, 'That student is already entered in that audition');
it('throws and exception if the student is below the minimum grade for the audition', function () {
$student = Student::factory()->create(['grade' => 8]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]);
$this->scribe->createEntry($student, $audition);
})->throws(AuditionAdminException::class, 'The grade of the student does not meet the minimum for that audition');
it('throws and exception if the student is above the maximum grade for the audition', function () {
$student = Student::factory()->create(['grade' => 12]);
$audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 10]);
$this->scribe->createEntry($student, $audition);
})->throws(AuditionAdminException::class, 'The grade of the student exceeds the maximum for that audition');