auditionadmin/tests-old/Feature/Actions/EnterBonusScoreTest.php

135 lines
5.8 KiB
PHP

<?php
use App\Actions\Tabulation\EnterBonusScore;
use App\Exceptions\ScoreEntryException;
use App\Models\Audition;
use App\Models\BonusScore;
use App\Models\BonusScoreDefinition;
use App\Models\Entry;
use App\Models\Student;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\App;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->enterBonusScore = App::make(EnterBonusScore::class);
});
it('rejects a non existent entry', function () {
$judge = User::factory()->create();
$entry = Entry::factory()->make();
$this->enterBonusScore->__invoke($judge, $entry, 42);
})->throws(ScoreEntryException::class, 'Invalid entry provided');
it('rejects a non existent judge', function () {
$judge = User::factory()->make();
$entry = Entry::factory()->create();
$this->enterBonusScore->__invoke($judge, $entry, 42);
})->throws(ScoreEntryException::class, 'Invalid judge provided');
it('rejects a submission if the entries audition does not have a bonus score', function () {
$judge = User::factory()->create();
$entry = Entry::factory()->create();
$this->enterBonusScore->__invoke($judge, $entry, 42);
})->throws(ScoreEntryException::class, 'Entry does not have a bonus score');
it('rejects a submission if the entry already has a score from the given judge', function () {
// Arrange
$judge = User::factory()->create();
$bonusScore = BonusScoreDefinition::factory()->create();
$entry = Entry::factory()->create();
$entry->audition->bonusScore()->attach($bonusScore->id);
$score = BonusScore::create([
'entry_id' => $entry->id,
'user_id' => $judge->id,
'originally_scored_entry' => $entry->id,
'score' => 42,
]);
// Act & Assert
$this->enterBonusScore->__invoke($judge, $entry, 43);
})->throws(ScoreEntryException::class, 'That judge has already scored that entry');
it('rejects a submission for a judge not assigned to judge that bonus score', function () {
// Arrange
$judge = User::factory()->create();
$bonusScore = BonusScoreDefinition::factory()->create();
$entry = Entry::factory()->create();
$entry->audition->bonusScore()->attach($bonusScore->id);
// Act & Assert
$this->enterBonusScore->__invoke($judge, $entry, 43);
})->throws(ScoreEntryException::class, 'That judge is not assigned to judge that bonus score');
it('rejects a submission for a score that exceeds the maximum', function () {
// Arrange
$judge = User::factory()->create();
$bonusScore = BonusScoreDefinition::factory()->create(['max_score' => 50]);
$bonusScore->judges()->attach($judge);
$entry = Entry::factory()->create();
$entry->audition->bonusScore()->attach($bonusScore->id);
// Act & Assert
$this->enterBonusScore->__invoke($judge, $entry, 51);
})->throws(ScoreEntryException::class, 'That score exceeds the maximum');
it('records a valid bonus score submission on the submitted entry', function () {
// Arrange
$judge = User::factory()->create();
$bonusScore = BonusScoreDefinition::factory()->create(['max_score' => 100]);
$entry = Entry::factory()->create();
$entry->audition->bonusScore()->attach($bonusScore->id);
$bonusScore->judges()->attach($judge);
// Act & Assert
$this->enterBonusScore->__invoke($judge, $entry, 42);
expect(
BonusScore::where('entry_id', $entry->id)
->where('user_id', $judge->id)
->where('score', 42)->exists())
->toBeTrue();
});
it('records a valid bonus score on all related entries', function () {
// Arrange
$judge = User::factory()->create();
$bonusScore = BonusScoreDefinition::factory()->create(['name' => 'Saxophone Improvisation', 'max_score' => 100]);
$bonusScore->judges()->attach($judge);
$jazzAltoAudition = Audition::factory()->create(['name' => 'Jazz Alto Saxophone']);
$jazzTenorAudition = Audition::factory()->create(['name' => 'Jazz Tenor Saxophone']);
$jazzBariAudition = Audition::factory()->create(['name' => 'Jazz Bari Saxophone']);
$bonusScore->auditions()->attach($jazzAltoAudition->id);
$bonusScore->auditions()->attach($jazzTenorAudition->id);
$bonusScore->auditions()->attach($jazzBariAudition->id);
$saxStudent = Student::factory()->create();
$jazzAltoEntry = Entry::factory()->create([
'student_id' => $saxStudent->id, 'audition_id' => $jazzAltoAudition->id,
]);
$jazzTenorEntry = Entry::factory()->create(['student_id' => $saxStudent->id,
'audition_id' => $jazzTenorAudition->id,
]);
$jazzBariEntry = Entry::factory()->create(['student_id' => $saxStudent->id, 'audition_id' => $jazzBariAudition->id,
]);
Entry::factory()->count(4)->create(['audition_id' => $jazzAltoAudition->id]);
Entry::factory()->count(4)->create(['audition_id' => $jazzTenorAudition->id]);
Entry::factory()->count(4)->create(['audition_id' => $jazzBariAudition->id]);
// Act
$this->enterBonusScore->__invoke($judge, $jazzAltoEntry, 42);
// Assert
expect(
BonusScore::where('entry_id', $jazzAltoEntry->id)
->where('user_id', $judge->id)
->where('originally_scored_entry', $jazzAltoEntry->id)
->where('score', 42)->exists())
->toBeTrue()
->and(BonusScore::count())->toBe(3)
->and(
BonusScore::where('entry_id', $jazzTenorEntry->id)
->where('user_id', $judge->id)
->where('originally_scored_entry', $jazzAltoEntry->id)
->where('score', 42)->exists())
->toBeTrue()
->and(
BonusScore::where('entry_id', $jazzBariEntry->id)
->where('user_id', $judge->id)
->where('originally_scored_entry', $jazzAltoEntry->id)
->where('score', 42)->exists())
->toBeTrue();
});