From bdaf18b6c3f43430238961ecb257655911e69e8b Mon Sep 17 00:00:00 2001 From: Matt Young Date: Sun, 14 Jul 2024 17:06:10 -0500 Subject: [PATCH] Update EnterScore action to modify a scoreSheet as well as create a new one --- app/Actions/Tabulation/EnterScore.php | 46 +++++++++++++----- tests/Feature/Actions/EnterScoreTest.php | 59 +++++++++++++++++++++++- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/app/Actions/Tabulation/EnterScore.php b/app/Actions/Tabulation/EnterScore.php index b8c01ad..a3fab91 100644 --- a/app/Actions/Tabulation/EnterScore.php +++ b/app/Actions/Tabulation/EnterScore.php @@ -16,21 +16,36 @@ use Illuminate\Support\Facades\DB; class EnterScore { // TODO implement this action every place that can save a score - public function __invoke(User $user, Entry $entry, array $scores): ScoreSheet + /** + * @param User $user A user acting as the judge for this sheet + * @param Entry $entry An entry to which this score should be assigned + * @param array $scores Scores to be entered in the form of SubscoreID => score + * + * @throws ScoreEntryException + */ + public function __invoke(User $user, Entry $entry, array $scores, ScoreSheet|false $scoreSheet = false): ScoreSheet { $scores = collect($scores); $this->basicChecks($user, $entry, $scores); $this->checkJudgeAssignment($user, $entry); - $this->checkForExistingScore($user, $entry); + $this->checkForExistingScore($user, $entry, $scoreSheet); $this->validateScoresSubmitted($entry, $scores); $entry->removeFlag('no_show'); - $newScoreSheet = ScoreSheet::create([ - 'user_id' => $user->id, - 'entry_id' => $entry->id, - 'subscores' => $this->subscoresForStorage($entry, $scores), - ]); + if ($scoreSheet instanceof ScoreSheet) { + $scoreSheet->update([ + 'user_id' => $user->id, + 'entry_id' => $entry->id, + 'subscores' => $this->subscoresForStorage($entry, $scores), + ]); + } else { + $scoreSheet = ScoreSheet::create([ + 'user_id' => $user->id, + 'entry_id' => $entry->id, + 'subscores' => $this->subscoresForStorage($entry, $scores), + ]); + } - return $newScoreSheet; + return $scoreSheet; } protected function subscoresForStorage(Entry $entry, Collection $scores) @@ -47,10 +62,19 @@ class EnterScore return $subscores; } - protected function checkForExistingScore(User $user, Entry $entry) + protected function checkForExistingScore(User $user, Entry $entry, $existingScoreSheet) { - if (ScoreSheet::where('user_id', $user->id)->where('entry_id', $entry->id)->exists()) { - throw new ScoreEntryException('That judge has already entered scores for that entry'); + if (! $existingScoreSheet) { + if (ScoreSheet::where('user_id', $user->id)->where('entry_id', $entry->id)->exists()) { + throw new ScoreEntryException('That judge has already entered scores for that entry'); + } + } else { + if ($existingScoreSheet->user_id !== $user->id) { + throw new ScoreEntryException('Existing score sheet is from a different judge'); + } + if ($existingScoreSheet->entry_id !== $entry->id) { + throw new ScoreEntryException('Existing score sheet is for a different entry'); + } } } diff --git a/tests/Feature/Actions/EnterScoreTest.php b/tests/Feature/Actions/EnterScoreTest.php index b9dd140..3d668bd 100644 --- a/tests/Feature/Actions/EnterScoreTest.php +++ b/tests/Feature/Actions/EnterScoreTest.php @@ -14,7 +14,6 @@ use Illuminate\Support\Facades\App; uses(RefreshDatabase::class); beforeEach(function () { - #$this->scoreEntry = new EnterScore(); $this->scoreEntry = App::make(EnterScore::class); }); @@ -185,3 +184,61 @@ it('throws an exception of the entry already has a score by the judge', function // Assert enterScore($judge, $entry, $scores); })->throws(ScoreEntryException::class, 'That judge has already entered scores for that entry'); +it('allows an existing sore sheet to be updated', function() { + // Arrange + loadSampleAudition(); + $judge = User::factory()->create(); + $entry = Entry::factory()->create(['audition_id' => 1000]); + $entry->addFlag('no_show'); + Room::find(1000)->addJudge($judge); + $scores = [ + 1001 => 98, + 1002 => 90, + 1003 => 87, + 1004 => 78, + 1005 => 98, + ]; + enterScore($judge, $entry, $scores); + // Act + $scoreToEdit = ScoreSheet::where('user_id', $judge->id)->where('entry_id', $entry->id)->first(); + expect($scoreToEdit->exists())->toBeTrue(); + $newScores = [ + 1001 => 40, + 1002 => 41, + 1003 => 42, + 1004 => 43, + 1005 => 44, + ]; + $pencil = App::make(EnterScore::class); + $pencil($judge, $entry, $newScores, $scoreToEdit); + $desiredReturn = [ + 1001 => [ + 'score' => 40, + 'subscore_id' => 1001, + 'subscore_name' => 'Scale', + ], + 1002 => [ + 'score' => 41, + 'subscore_id' => 1002, + 'subscore_name' => 'Etude 1', + ], + 1003 => [ + 'score' => 42, + 'subscore_id' => 1003, + 'subscore_name' => 'Etude 2', + ], + 1004 => [ + 'score' => 43, + 'subscore_id' => 1004, + 'subscore_name' => 'Sight Reading', + ], + 1005 => [ + 'score' => 44, + 'subscore_id' => 1005, + 'subscore_name' => 'Tone', + ], + ]; + $checkScoreSheet = ScoreSheet::where('user_id', $judge->id)->where('entry_id', $entry->id)->first(); + expect($checkScoreSheet->exists())->toBeTrue() + ->and($checkScoreSheet->subscores)->toBe($desiredReturn); +});