234 lines
11 KiB
PHP
234 lines
11 KiB
PHP
<?php
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
|
|
use App\Actions\Development\FakeScoresForEntry;
|
|
use App\Actions\Entries\UpdateEntry;
|
|
use App\Exceptions\AuditionAdminException;
|
|
use App\Models\Audition;
|
|
use App\Models\AuditionFlag;
|
|
use App\Models\AuditLogEntry;
|
|
use App\Models\Entry;
|
|
use App\Models\Room;
|
|
use App\Models\ScoringGuide;
|
|
use App\Models\Student;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
$this->entryScribe = app(UpdateEntry::class);
|
|
$this->audition = Audition::factory()->create(
|
|
[
|
|
'minimum_grade' => 9, 'maximum_grade' => 10,
|
|
'name' => 'Flute',
|
|
]);
|
|
$this->student = Student::factory()->create(['grade' => 9]);
|
|
$this->entry = Entry::factory()->create([
|
|
'student_id' => $this->student->id,
|
|
'audition_id' => $this->audition->id,
|
|
]);
|
|
});
|
|
|
|
it('throws an exception when an invalid entry is provided', function () {
|
|
($this->entryScribe)(35, []);
|
|
})->throws(AuditionAdminException::class, 'Invalid entry provided');
|
|
|
|
it('throws an exception when a non-existent entry is provided', function () {
|
|
$newEntry = Entry::factory()->make();
|
|
($this->entryScribe)($newEntry, []);
|
|
})->throws(AuditionAdminException::class, 'Invalid entry provided');
|
|
|
|
it('will not modify an entry in an audition with published seats', function () {
|
|
$this->entry->audition->addFlag('seats_published');
|
|
$newAudition = Audition::factory()->create(['event_id' => $this->entry->audition->event_id]);
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
})->throws(AuditionAdminException::class,
|
|
'Cannot change the audition for an entry where seating for that entry\'s current audition is published');
|
|
|
|
it('will not modify an entry in an audition with published advancement', function () {
|
|
$this->entry->audition->addFlag('advancement_published');
|
|
$newAudition = Audition::factory()->create(['event_id' => $this->entry->audition->event_id]);
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
})->throws(AuditionAdminException::class,
|
|
'Cannot change the audition for an entry where advancement for that entry\'s current audition is published');
|
|
|
|
it('will not move an entry to an audition with published seating', function () {
|
|
$newAudition = Audition::factory()->create(['event_id' => $this->entry->audition->event_id]);
|
|
$newAudition->addFlag('seats_published');
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
})->throws(AuditionAdminException::class, 'Cannot change the entry to an audition with published seating');
|
|
|
|
it('will not move an entry to an audition with published advancement', function () {
|
|
$newAudition = Audition::factory()->create(['event_id' => $this->entry->audition->event_id]);
|
|
$newAudition->addFlag('advancement_published');
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
})->throws(AuditionAdminException::class, 'Cannot change the entry to an audition with published advancement');
|
|
|
|
it('will not move to an audition for which the student is too young', function () {
|
|
$newAudition = Audition::factory()->create([
|
|
'event_id' => $this->entry->audition->event_id,
|
|
'minimum_grade' => 10,
|
|
'maximum_grade' => 11,
|
|
]);
|
|
$this->entry->student->update(['grade' => 9]);
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
})->throws(AuditionAdminException::class, 'The student is too young to enter that audition');
|
|
|
|
it('will not move to an audition for which the student is too old', function () {
|
|
$newAudition = Audition::factory()->create([
|
|
'event_id' => $this->entry->audition->event_id,
|
|
'maximum_grade' => 8,
|
|
'minimum_grade' => 7,
|
|
]);
|
|
$this->entry->student->update(['grade' => 9]);
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
})->throws(AuditionAdminException::class, 'The student is too old to enter that audition');
|
|
|
|
it('will not change auditions for an entry with scores', function () {
|
|
$scoreFaker = app(FakeScoresForEntry::class);
|
|
$newAudition = Audition::factory()->create([
|
|
'event_id' => $this->entry->audition->event_id,
|
|
'minimum_grade' => 9,
|
|
'maximum_grade' => 10,
|
|
]);
|
|
$scoringGuide = ScoringGuide::factory()->create();
|
|
$judge1 = User::factory()->create();
|
|
$judge2 = User::factory()->create();
|
|
$room = Room::factory()->create();
|
|
$room->addJudge($judge1);
|
|
$room->addJudge($judge2);
|
|
$this->entry->audition->update([
|
|
'scoring_guide_id' => $scoringGuide->id,
|
|
'room_id' => $room->id,
|
|
'order_in_room' => 1,
|
|
]);
|
|
$scoreFaker($this->entry);
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
})->throws(AuditionAdminException::class, 'Cannot change the audition for an entry with scores');
|
|
|
|
it(('will not change the audition to one in which the student is already entered'), function () {
|
|
$newAudition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 10]);
|
|
Entry::create([
|
|
'student_id' => $this->student->id,
|
|
'audition_id' => $newAudition->id,
|
|
]);
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
})->throws(AuditionAdminException::class, 'That student is already entered in that audition');
|
|
|
|
it('will not set a draw number if the new audition is not drawn', function () {
|
|
$newAudition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 10]);
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
$this->entry->refresh();
|
|
expect($this->entry->draw_number)->toBeNull();
|
|
});
|
|
|
|
it('will assign the next draw number if the new audition is drawn', function () {
|
|
$newAudition = Audition::factory()
|
|
->has(Entry::factory()->count(5))
|
|
->create(['minimum_grade' => 9, 'maximum_grade' => 10]);
|
|
AuditionFlag::create(['audition_id' => $newAudition->id, 'flag_name' => 'drawn']);
|
|
$n = 1;
|
|
foreach ($newAudition->entries as $entry) {
|
|
$entry->update(['draw_number' => $n]);
|
|
$n++;
|
|
}
|
|
($this->entryScribe)($this->entry, ['audition_id' => $newAudition->id]);
|
|
expect($this->entry->draw_number)->toBe($n);
|
|
});
|
|
|
|
it('can change and entries audition', function () {
|
|
$newAudition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 10]);
|
|
($this->entryScribe)($this->entry, ['audition' => $newAudition]);
|
|
$this->entry->refresh();
|
|
$freshEntry = Entry::find($this->entry->id);
|
|
expect($freshEntry->audition_id)->toBe($newAudition->id);
|
|
});
|
|
|
|
it('can remove forAdvancement from the entry', function () {
|
|
($this->entryScribe)($this->entry, ['for_advancement' => false]);
|
|
expect($this->entry->for_advancement)->toBeFalsy();
|
|
});
|
|
|
|
it('can add forAdvancement to the entry', function () {
|
|
$this->entry->update(['for_advancement' => false]);
|
|
expect($this->entry->for_advancement)->toBeFalsy();
|
|
($this->entryScribe)($this->entry, ['for_advancement' => true]);
|
|
expect($this->entry->for_advancement)->toBeTruthy();
|
|
});
|
|
|
|
it('cannot remove forAdvancement if advancement is published', function () {
|
|
$this->entry->audition->addFlag('advancement_published');
|
|
($this->entryScribe)($this->entry, ['for_advancement' => false]);
|
|
})->throws(AuditionAdminException::class,
|
|
'Cannot remove advancement from an entry in an audition where advancement is published');
|
|
|
|
it('cannot add forAdvancement if advancement is published', function () {
|
|
$this->entry->update(['for_advancement' => false]);
|
|
expect($this->entry->for_advancement)->toBeFalsy();
|
|
$this->entry->audition->addFlag('advancement_published');
|
|
($this->entryScribe)($this->entry, ['for_advancement' => true]);
|
|
})->throws(AuditionAdminException::class,
|
|
'Cannot add advancement to an entry in an audition where advancement is published');
|
|
|
|
it('can remove forSeating from the entry', function () {
|
|
($this->entryScribe)($this->entry, ['for_seating' => false]);
|
|
expect($this->entry->for_seating)->toBeFalsy();
|
|
});
|
|
|
|
it('can add forSeating to the entry', function () {
|
|
$this->entry->update(['for_seating' => false]);
|
|
expect($this->entry->for_seating)->toBeFalsy();
|
|
($this->entryScribe)($this->entry, ['for_seating' => true]);
|
|
expect($this->entry->for_seating)->toBeTruthy();
|
|
});
|
|
|
|
it('cannot remove forSeating if seating is published', function () {
|
|
$this->entry->audition->addFlag('seats_published');
|
|
($this->entryScribe)($this->entry, ['for_seating' => false]);
|
|
})->throws(AuditionAdminException::class,
|
|
'Cannot remove seating from an entry in an audition where seats are published');
|
|
|
|
it('cannot add forSeating if seating is published', function () {
|
|
$this->entry->update(['for_seating' => false]);
|
|
expect($this->entry->for_seating)->toBeFalsy();
|
|
$this->entry->audition->addFlag('seats_published');
|
|
($this->entryScribe)($this->entry, ['for_seating' => true]);
|
|
})->throws(AuditionAdminException::class,
|
|
'Cannot add seating to an entry in an audition where seats are published');
|
|
|
|
it('logs changes', function () {
|
|
actAsAdmin();
|
|
$originalEntry = Entry::find($this->entry->id);
|
|
$newAudition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 10, 'name' => 'Alphorn']);
|
|
($this->entryScribe)($this->entry, ['audition' => $newAudition]);
|
|
$logEntry = AuditLogEntry::orderBy('id', 'desc')->first();
|
|
expect($logEntry->affected['auditions'])->toEqual([$originalEntry->audition_id, $newAudition->id])
|
|
->and($logEntry->affected['entries'])->toEqual([$this->entry->id])
|
|
->and($logEntry->affected['students'])->toEqual([$this->entry->student_id])
|
|
->and($logEntry->affected['schools'])->toEqual([$this->entry->student->school_id])
|
|
->and($logEntry->message)->toEqual('Changed entry '.$this->entry->id.' from '.$originalEntry->audition->name.' to '.$newAudition->name.'<br>');
|
|
|
|
});
|
|
|
|
it('will not change to a non-existent audition', function () {
|
|
$newAudition = Audition::factory()->make();
|
|
($this->entryScribe)($this->entry, ['audition' => $newAudition]);
|
|
})->throws(AuditionAdminException::class, 'Invalid audition provided');
|
|
|
|
it('wont change if we give it the same audition', function () {
|
|
($this->entryScribe)($this->entry, ['audition' => $this->entry->audition]);
|
|
expect($this->entry->audition_id)->toBe($this->entry->audition->id);
|
|
});
|
|
|
|
it('wont change seating if we give the same value', function () {
|
|
($this->entryScribe)($this->entry, ['for_seating' => 1]);
|
|
expect($this->entry->for_seating)->toBe($this->entry->for_seating);
|
|
});
|
|
|
|
it('wont change advancement if we give the same value', function () {
|
|
($this->entryScribe)($this->entry, ['for_advancement' => 1]);
|
|
expect($this->entry->for_advancement)->toBe($this->entry->for_advancement);
|
|
});
|