Rewrite tabulation #14
|
|
@ -1,13 +1,67 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
|
||||
namespace App\Actions\Tabulation;
|
||||
|
||||
use App\Exceptions\TabulationException;
|
||||
use App\Models\Entry;
|
||||
|
||||
class AllJudgesCount implements CalculateEntryScore
|
||||
{
|
||||
protected CalculateScoreSheetTotal $calculator;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@
|
|||
@inject('drawService', 'App\Services\DrawService')
|
||||
<x-layout.app>
|
||||
<x-slot:page_title>Test Page</x-slot:page_title>
|
||||
@php
|
||||
|
||||
@endphp
|
||||
Test value: {{ $test }}
|
||||
@foreach($rows as $row)
|
||||
{{ $row['name'] }} - {{ $row['totalScore'] }}<hr>
|
||||
@endforeach
|
||||
|
||||
</x-layout.app>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
|
||||
use App\Actions\Tabulation\AllJudgesCount;
|
||||
use App\Exceptions\TabulationException;
|
||||
use App\Models\Entry;
|
||||
use App\Models\Room;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
it('throws an exception if mode is not seating or advancement', function () {
|
||||
$calculator = new AllJudgesCount();
|
||||
$calculator->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);
|
||||
});
|
||||
Loading…
Reference in New Issue