auditionadmin/tests/Feature/app/Actions/Tabulation/EnterPrelimScoreTest.php

167 lines
7.0 KiB
PHP

<?php
use App\Actions\Tabulation\EnterPrelimScore;
use App\Exceptions\AuditionAdminException;
use App\Models\Audition;
use App\Models\AuditLogEntry;
use App\Models\Entry;
use App\Models\PrelimDefinition;
use App\Models\PrelimScoreSheet;
use App\Models\Room;
use App\Models\ScoringGuide;
use App\Models\SubscoreDefinition;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
// Generate Scoring Guide
$this->prelimScoringGuide = ScoringGuide::factory()->create(['id' => 1000]);
SubscoreDefinition::create([
'id' => 1001,
'scoring_guide_id' => $this->prelimScoringGuide->id,
'name' => 'Scale',
'max_score' => 100,
'weight' => 1,
'display_order' => 1,
'tiebreak_order' => 3,
'for_seating' => '1',
'for_advance' => '0',
]);
SubscoreDefinition::create([
'id' => 1002,
'scoring_guide_id' => $this->prelimScoringGuide->id,
'name' => 'Etude 1',
'max_score' => 100,
'weight' => 2,
'display_order' => 2,
'tiebreak_order' => 1,
'for_seating' => '1',
'for_advance' => '1',
]);
SubscoreDefinition::create([
'id' => 1003,
'scoring_guide_id' => $this->prelimScoringGuide->id,
'name' => 'Etude 2',
'max_score' => 100,
'weight' => 2,
'display_order' => 3,
'tiebreak_order' => 2,
'for_seating' => '0',
'for_advance' => '1',
]);
SubscoreDefinition::where('id', '<', 900)->delete();
$this->finalsRoom = Room::factory()->create();
$this->prelimRoom = Room::factory()->create();
$this->audition = Audition::factory()->create(['room_id' => $this->finalsRoom->id]);
$this->prelimDefinition = PrelimDefinition::create([
'room_id' => $this->prelimRoom->id,
'audition_id' => $this->audition->id,
'scoring_guide_id' => $this->prelimScoringGuide->id,
'passing_score' => 60,
]);
$this->judge1 = User::factory()->create();
$this->judge2 = User::factory()->create();
$this->prelimRoom->judges()->attach($this->judge1->id);
$this->prelimRoom->judges()->attach($this->judge2->id);
$this->entry1 = Entry::factory()->create(['audition_id' => $this->audition->id]);
$this->entry2 = Entry::factory()->create(['audition_id' => $this->audition->id]);
$this->scribe = app(EnterPrelimScore::class);
$this->possibleScoreArray = [
1001 => 10,
1002 => 11,
1003 => 12,
];
$this->anotherPossibleScoreArray = [
1001 => 20,
1002 => 21,
1003 => 22,
];
});
it('can enter a prelim score', function () {
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
expect($this->entry1->prelimScoreSheets()->count())->toBe(1)
->and($this->entry1->prelimScoreSheets()->first()->total)->toBe(11.2);
($this->scribe)($this->judge1, $this->entry2, $this->anotherPossibleScoreArray);
expect($this->entry2->prelimScoreSheets()->count())->toBe(1)
->and($this->entry2->prelimScoreSheets()->first()->total)->toBe(21.2);
});
it('will not enter a score for a judge that does not exist', function () {
$fakeJudge = User::factory()->make();
($this->scribe)($fakeJudge, $this->entry1, $this->possibleScoreArray);
})->throws(AuditionAdminException::class, 'User does not exist');
it('will not enter a score for an entry that does not exist', function () {
$fakeEntry = Entry::factory()->make();
($this->scribe)($this->judge1, $fakeEntry, $this->possibleScoreArray);
})->throws(AuditionAdminException::class, 'Entry does not exist');
it('will not score an entry if the audition seats are published', function () {
$this->audition->addFlag('seats_published');
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
})->throws(AuditionAdminException::class, 'Cannot score an entry in an audition where seats are published');
it('will not score an entry if the judge is not assigned to judge the entry', function () {
$fakeJudge = User::factory()->create();
($this->scribe)($fakeJudge, $this->entry1, $this->possibleScoreArray);
})->throws(AuditionAdminException::class, 'This judge is not assigned to judge this entry');
it('can modify an existing score sheet', function () {
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
$scoreSheet = PrelimScoreSheet::first();
($this->scribe)($this->judge1, $this->entry1, $this->anotherPossibleScoreArray, $scoreSheet);
expect($this->entry1->prelimScoreSheets()->count())->toBe(1)
->and($this->entry1->prelimScoreSheets()->first()->total)->toBe(21.2);
});
it('will not change the judge on a score sheet', function () {
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
$scoreSheet = PrelimScoreSheet::first();
($this->scribe)($this->judge2, $this->entry1, $this->anotherPossibleScoreArray, $scoreSheet);
})->throws(AuditionAdminException::class, 'Existing score sheet is from a different judge');
it('will not accept a second score sheet for a judge ane entry', function () {
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
($this->scribe)($this->judge1, $this->entry1, $this->anotherPossibleScoreArray);
})->throws(AuditionAdminException::class, 'That judge has already entered a prelim score for that entry');
it('will not change the entry on a score sheet', function () {
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
$scoreSheet = PrelimScoreSheet::first();
($this->scribe)($this->judge1, $this->entry2, $this->anotherPossibleScoreArray, $scoreSheet);
})->throws(AuditionAdminException::class, 'Existing score sheet is for a different entry');
it('will not accept an incorrect number of subscores', function () {
array_pop($this->possibleScoreArray);
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
})->throws(AuditionAdminException::class, 'Invalid number of scores');
it('will not accept an invalid subscores', function () {
array_pop($this->possibleScoreArray);
$this->possibleScoreArray[3001] = 100;
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
})->throws(AuditionAdminException::class, 'Invalid Score Submission');
it('will. not accept a subscore in excess of its maximum', function () {
$this->possibleScoreArray[1001] = 1500;
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
})->throws(AuditionAdminException::class, 'Supplied subscore exceeds maximum allowed');
it('removes a no-show flag from an entry', function () {
$this->entry1->addFlag('no_show');
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
expect($this->entry1->hasFlag('no_show'))->toBeFalse();
});
it('logs score entry', function () {
($this->scribe)($this->judge1, $this->entry1, $this->possibleScoreArray);
$logEntry = AuditLogEntry::orderBy('id', 'desc')->first();
expect($logEntry->message)->toStartWith('Entered prelim score for entry id ');
});