From 98b466beb68d877c22258833b41b09c9fc8eb401 Mon Sep 17 00:00:00 2001 From: Matt Young Date: Wed, 10 Jul 2024 02:43:21 -0500 Subject: [PATCH] CalculateEntryScore is functional --- app/Actions/Tabulation/AllJudgesCount.php | 56 +++++++- app/Http/Controllers/TestController.php | 26 +++- app/Providers/CalculateEntryScoreProvider.php | 2 + resources/views/test.blade.php | 7 +- .../AllJudgesCountTest.php | 135 ++++++++++++++++++ 5 files changed, 219 insertions(+), 7 deletions(-) create mode 100644 tests/Feature/Actions/CalculateEntryScore/AllJudgesCountTest.php diff --git a/app/Actions/Tabulation/AllJudgesCount.php b/app/Actions/Tabulation/AllJudgesCount.php index 6874d77..2e2655a 100644 --- a/app/Actions/Tabulation/AllJudgesCount.php +++ b/app/Actions/Tabulation/AllJudgesCount.php @@ -1,13 +1,67 @@ calculator = new CalculateScoreSheetTotal(); + } + public function calculate(string $mode, Entry $entry): array { - return ['vinita'=>'hornets']; + $this->basicValidation($mode, $entry); + $this->areAllJudgesIn($entry); + $this->areAllJudgesValid($entry); + return $this->getJudgeTotals($mode, $entry); + } + + protected function getJudgeTotals($mode, Entry $entry) + { + $scores = []; + foreach ($entry->audition->judges as $judge) { + $scores[] = $this->calculator->__invoke($mode, $entry, $judge); + } + for ($i = 0; $i < count($scores[0]); $i++) { + $sums[] = $scores[0][$i] + $scores[1][$i]; + } + + return $sums; + } + + protected function basicValidation($mode, $entry): void + { + if ($mode !== 'seating' && $mode !== 'advancement') { + throw new TabulationException('Mode must be seating or advancement'); + } + + if (! $entry->exists()) { + throw new TabulationException('Invalid entry specified'); + } + } + + protected function areAllJudgesIn(Entry $entry): void + { + $assignedJudgeCount = $entry->audition->judges->count(); + if ($entry->scoreSheets->count() !== $assignedJudgeCount) { + throw new TabulationException('Not all score sheets are in'); + } + } + + protected function areAllJudgesValid(Entry $entry): void + { + $validJudgeIds = $entry->audition->judges->pluck('id')->sort()->toArray(); + $existingJudgeIds = $entry->scoreSheets->pluck('user_id')->sort()->toArray(); + if ($validJudgeIds !== $existingJudgeIds) { + throw new TabulationException('Score exists from a judge not assigned to this audition'); + } } } diff --git a/app/Http/Controllers/TestController.php b/app/Http/Controllers/TestController.php index 2c336c3..21b2b16 100644 --- a/app/Http/Controllers/TestController.php +++ b/app/Http/Controllers/TestController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Actions\Tabulation\CalculateEntryScore; +use App\Exceptions\TabulationException; use App\Models\Entry; class TestController extends Controller @@ -15,8 +16,29 @@ class TestController extends Controller public function flashTest() { - $test = $this->bigCalc->calculate('seating', Entry::find(1127))['vinita']; + $entries = Entry::forSeating()->with('student')->where('audition_id', 19)->get(); + $rows = []; + foreach ($entries as $entry) { + try { + $totalScore = $this->bigCalc->calculate('seating', $entry)[0]; + } catch (TabulationException $ex){ + $totalScore = '--'; + } + $rows[] = [ + 'name' => $entry->student->full_name(), + 'totalScore' => $totalScore, + ]; + } - return view('test', compact('test')); +// try { +// $test = $this->bigCalc->calculate('seating', Entry::find(1061))[0]; +// } catch (TabulationException $ex) { +// dd($ex); +// } + + + + + return view('test', compact('rows')); } } diff --git a/app/Providers/CalculateEntryScoreProvider.php b/app/Providers/CalculateEntryScoreProvider.php index 39bffcc..8d0a2d1 100644 --- a/app/Providers/CalculateEntryScoreProvider.php +++ b/app/Providers/CalculateEntryScoreProvider.php @@ -4,6 +4,7 @@ namespace App\Providers; use App\Actions\Tabulation\AllJudgesCount; use App\Actions\Tabulation\CalculateEntryScore; +use App\Actions\Tabulation\CalculateScoreSheetTotal; use Illuminate\Support\ServiceProvider; class CalculateEntryScoreProvider extends ServiceProvider @@ -13,6 +14,7 @@ class CalculateEntryScoreProvider extends ServiceProvider */ public function register(): void { + $this->app->singleton(CalculateScoreSheetTotal::class, CalculateScoreSheetTotal::class); $this->app->singleton(CalculateEntryScore::class, AllJudgesCount::class); } diff --git a/resources/views/test.blade.php b/resources/views/test.blade.php index 2a17e73..f891ab6 100644 --- a/resources/views/test.blade.php +++ b/resources/views/test.blade.php @@ -7,9 +7,8 @@ @inject('drawService', 'App\Services\DrawService') Test Page - @php - - @endphp - Test value: {{ $test }} + @foreach($rows as $row) + {{ $row['name'] }} - {{ $row['totalScore'] }}
+ @endforeach
diff --git a/tests/Feature/Actions/CalculateEntryScore/AllJudgesCountTest.php b/tests/Feature/Actions/CalculateEntryScore/AllJudgesCountTest.php new file mode 100644 index 0000000..f916a38 --- /dev/null +++ b/tests/Feature/Actions/CalculateEntryScore/AllJudgesCountTest.php @@ -0,0 +1,135 @@ +calculate('WRONG', Entry::factory()->create()); +})->throws(TabulationException::class, 'Mode must be seating or advancement'); + +it('throws an exception if entry is not valid', function () { + // Arrange + $calculator = new AllJudgesCount(); + // Act + $calculator->calculate('seating', Entry::factory()->make()); + // Assert +})->throws(TabulationException::class, 'Invalid entry specified'); +it('throws an exception if entry is missing judge scores', function () { + // Arrange + loadSampleAudition(); + $judge1 = User::factory()->create(); + $judge2 = User::factory()->create(); + Room::find(1000)->addJudge($judge1); + Room::find(1000)->addJudge($judge2); + $entry = Entry::factory()->create(['audition_id' => 1000]); + $scores = [ + 1001 => 50, + 1002 => 60, + 1003 => 70, + 1004 => 80, + 1005 => 90, + ]; + $calculator = new AllJudgesCount(); + enterScore($judge1, $entry, $scores); + // Act + $calculator->calculate('seating', $entry); + // Assert +})->throws(TabulationException::class, 'Not all score sheets are in'); + +it('throws an exception if a score exists from an invalid judge', function () { + // Arrange + loadSampleAudition(); + $judge1 = User::factory()->create(); + $judge2 = User::factory()->create(); + $judge3 = User::factory()->create(); + Room::find(1000)->addJudge($judge1); + Room::find(1000)->addJudge($judge2); + $entry = Entry::factory()->create(['audition_id' => 1000]); + $scores = [ + 1001 => 50, + 1002 => 60, + 1003 => 70, + 1004 => 80, + 1005 => 90, + ]; + $calculator = new AllJudgesCount(); + enterScore($judge1, $entry, $scores); + $scoreSheetToSpoof = enterScore($judge2, $entry, $scores); + $scoreSheetToSpoof->update(['user_id' => $judge3->id]); + // Act + $calculator->calculate('seating', $entry); + // Assert +})->throws(TabulationException::class, 'Score exists from a judge not assigned to this audition'); + +it('correctly calculates scores for seating', function () { + // Arrange + loadSampleAudition(); + $judge1 = User::factory()->create(); + $judge2 = User::factory()->create(); + Room::find(1000)->addJudge($judge1); + Room::find(1000)->addJudge($judge2); + $entry = Entry::factory()->create(['audition_id' => 1000]); + $scores = [ + 1001 => 50, + 1002 => 60, + 1003 => 70, + 1004 => 80, + 1005 => 90, + ]; + $scores2 = [ + 1001 => 55, + 1002 => 65, + 1003 => 75, + 1004 => 85, + 1005 => 95, + ]; + $calculator = new AllJudgesCount(); + enterScore($judge1, $entry, $scores); + enterScore($judge2, $entry, $scores2); + // Act + $finalScores = $calculator->calculate('seating', $entry); + // Assert + $expectedScores = [142.5, 165, 125, 145, 105]; + expect($finalScores)->toBe($expectedScores); +}); + +it('correctly calculates scores for advancement', function () { + // Arrange + loadSampleAudition(); + $judge1 = User::factory()->create(); + $judge2 = User::factory()->create(); + Room::find(1000)->addJudge($judge1); + Room::find(1000)->addJudge($judge2); + $entry = Entry::factory()->create(['audition_id' => 1000]); + $scores = [ + 1001 => 50, + 1002 => 60, + 1003 => 70, + 1004 => 80, + 1005 => 90, + ]; + $scores2 = [ + 1001 => 55, + 1002 => 65, + 1003 => 75, + 1004 => 85, + 1005 => 95, + ]; + $calculator = new AllJudgesCount(); + enterScore($judge1, $entry, $scores); + enterScore($judge2, $entry, $scores2); + // Act + $finalScores = $calculator->calculate('advancement', $entry); + // Assert + $expectedScores = [152.5, 185, 165, 125, 145]; + expect($finalScores)->toBe($expectedScores); +});