Create tests for app/actions/tabulation/TotalEntryScore
This commit is contained in:
parent
53ccc5a7a3
commit
c67c1ad79c
|
|
@ -19,7 +19,6 @@ class TotalEntryScores
|
|||
|
||||
public function __invoke(Entry $entry, bool $force_recalculation = false): void
|
||||
{
|
||||
// TODO Verify accuracy of calculations, particularly for olympic scoring
|
||||
if ($force_recalculation) {
|
||||
EntryTotalScore::where('entry_id', $entry->id)->delete();
|
||||
}
|
||||
|
|
@ -34,17 +33,19 @@ class TotalEntryScores
|
|||
// deal with seating scores
|
||||
// TODO: Consider a rewrite to pull the scoreSheets from the entry model so they may be preloaded
|
||||
$scoreSheets = ScoreSheet::where('entry_id', $entry->id)->orderBy('seating_total', 'desc')->get();
|
||||
|
||||
// bail out if there are not enough score sheets
|
||||
$assignedJudges = $entry->audition->judges()->count();
|
||||
if ($scoreSheets->count() == 0 || $scoreSheets->count() < $assignedJudges) {
|
||||
return;
|
||||
}
|
||||
if (auditionSetting('olympic_scoring' && $scoreSheets->count() > 2)) {
|
||||
|
||||
if (auditionSetting('olympic_scoring') && $scoreSheets->count() > 2) {
|
||||
// under olympic scoring, drop the first and last element
|
||||
$scoreSheets->shift();
|
||||
$scoreSheets->pop();
|
||||
}
|
||||
$newTotaledScore->seating_total = $scoreSheets->avg('seating_total');
|
||||
$newTotaledScore->seating_total = round($scoreSheets->avg('seating_total'), 6);
|
||||
$seatingSubscores = $requiredSubscores
|
||||
->filter(fn ($subscore) => $subscore->for_seating == true)
|
||||
->sortBy('tiebreak_order');
|
||||
|
|
@ -54,18 +55,18 @@ class TotalEntryScores
|
|||
foreach ($scoreSheets as $scoreSheet) {
|
||||
$runningTotal += $scoreSheet->subscores[$subscore->id]['score'];
|
||||
}
|
||||
$total_seating_subscores[] = $runningTotal / $scoreSheets->count();
|
||||
$total_seating_subscores[] = round($runningTotal / $scoreSheets->count(), 4);
|
||||
}
|
||||
$newTotaledScore->seating_subscore_totals = $total_seating_subscores;
|
||||
|
||||
// deal with advancement scores
|
||||
$scoreSheets = ScoreSheet::where('entry_id', $entry->id)->orderBy('advancement_total', 'desc')->get();
|
||||
if (auditionSetting('olympic_scoring' && $scoreSheets->count() > 2)) {
|
||||
if (auditionSetting('olympic_scoring') && $scoreSheets->count() > 2) {
|
||||
// under olympic scoring, drop the first and last element
|
||||
$scoreSheets->shift();
|
||||
$scoreSheets->pop();
|
||||
}
|
||||
$newTotaledScore->advancement_total = $scoreSheets->avg('advancement_total');
|
||||
$newTotaledScore->advancement_total = round($scoreSheets->avg('advancement_total'), 6);
|
||||
$advancement_subscores = $requiredSubscores
|
||||
->filter(fn ($subscore) => $subscore->for_advance == true)
|
||||
->sortBy('tiebreak_order');
|
||||
|
|
@ -75,7 +76,7 @@ class TotalEntryScores
|
|||
foreach ($scoreSheets as $scoreSheet) {
|
||||
$runningTotal += $scoreSheet->subscores[$subscore->id]['score'];
|
||||
}
|
||||
$total_advancement_subscores[] = $runningTotal / $scoreSheets->count();
|
||||
$total_advancement_subscores[] = round($runningTotal / $scoreSheets->count(), 4);
|
||||
}
|
||||
$newTotaledScore->advancement_subscore_totals = $total_advancement_subscores;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,206 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
|
||||
use App\Actions\Tabulation\EnterScore;
|
||||
use App\Actions\Tabulation\TotalEntryScores;
|
||||
use App\Models\Audition;
|
||||
use App\Models\BonusScore;
|
||||
use App\Models\Entry;
|
||||
use App\Models\EntryTotalScore;
|
||||
use App\Models\ScoreSheet;
|
||||
use App\Models\SubscoreDefinition;
|
||||
use App\Models\User;
|
||||
use App\Settings;
|
||||
use Database\Seeders\AuditionWithScoringGuideAndRoom;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
(new AuditionWithScoringGuideAndRoom)->run();
|
||||
SubscoreDefinition::where('id', '<', 900)->delete();
|
||||
$this->audition = Audition::first();
|
||||
$this->judge1 = User::factory()->create();
|
||||
$this->judge2 = User::factory()->create();
|
||||
$this->judge3 = User::factory()->create();
|
||||
$this->judge4 = User::factory()->create();
|
||||
$this->judge5 = User::factory()->create();
|
||||
$this->audition->judges()->attach([
|
||||
$this->judge1->id,
|
||||
$this->judge2->id,
|
||||
$this->judge3->id,
|
||||
$this->judge4->id,
|
||||
$this->judge5->id,
|
||||
]);
|
||||
$this->entry = Entry::factory()->create(['audition_id' => $this->audition->id]);
|
||||
$this->judge1Subscores = [
|
||||
1001 => 45,
|
||||
1002 => 87,
|
||||
1003 => 34,
|
||||
1004 => 86,
|
||||
1005 => 75,
|
||||
];
|
||||
$this->judge2Subscores = [
|
||||
1001 => 75,
|
||||
1002 => 69,
|
||||
1003 => 56,
|
||||
1004 => 89,
|
||||
1005 => 45,
|
||||
];
|
||||
$this->judge3Subscores = [
|
||||
1001 => 78,
|
||||
1002 => 56,
|
||||
1003 => 98,
|
||||
1004 => 34,
|
||||
1005 => 56,
|
||||
];
|
||||
$this->judge4Subscores = [
|
||||
1001 => 67,
|
||||
1002 => 45,
|
||||
1003 => 98,
|
||||
1004 => 43,
|
||||
1005 => 89,
|
||||
];
|
||||
$this->judge5Subscores = [
|
||||
1001 => 45,
|
||||
1002 => 97,
|
||||
1003 => 34,
|
||||
1004 => 97,
|
||||
1005 => 78,
|
||||
];
|
||||
$this->scribe = app(EnterScore::class);
|
||||
$this->calculator = app(TotalEntryScores::class);
|
||||
});
|
||||
|
||||
test('scores correctly for non-olympic scoring', function () {
|
||||
Settings::set('olympic_scoring', false);
|
||||
($this->scribe)($this->judge1, $this->entry, $this->judge1Subscores);
|
||||
($this->scribe)($this->judge2, $this->entry, $this->judge2Subscores);
|
||||
($this->scribe)($this->judge3, $this->entry, $this->judge3Subscores);
|
||||
($this->scribe)($this->judge4, $this->entry, $this->judge4Subscores);
|
||||
($this->scribe)($this->judge5, $this->entry, $this->judge5Subscores);
|
||||
$judges = [
|
||||
$this->judge1,
|
||||
$this->judge2,
|
||||
$this->judge3,
|
||||
$this->judge4,
|
||||
$this->judge5,
|
||||
];
|
||||
$expectedSeatingTotals = [
|
||||
1 => 68.125,
|
||||
2 => 74,
|
||||
3 => 61,
|
||||
4 => 60.25,
|
||||
5 => 74.75,
|
||||
];
|
||||
$expectedAdvancementTotals = [
|
||||
1 => 71.875,
|
||||
2 => 70.25,
|
||||
3 => 58.25,
|
||||
4 => 63,
|
||||
5 => 78.875,
|
||||
];
|
||||
foreach ($judges as $judge) {
|
||||
$scoreSheet = ScoreSheet::where('entry_id', $this->entry->id)->where('user_id', $judge->id)->first();
|
||||
expect($scoreSheet->seating_total)->toBe($expectedSeatingTotals[$judge->id])
|
||||
->and($scoreSheet->advancement_total)->toBe($expectedAdvancementTotals[$judge->id]);
|
||||
}
|
||||
($this->calculator)($this->entry);
|
||||
$totalScore = EntryTotalScore::where('entry_id', $this->entry->id)->first();
|
||||
expect($totalScore->seating_subscore_totals)->toBe([69.8, 70.8, 64, 62])
|
||||
->and($totalScore->advancement_subscore_totals)->toBe([68.6, 69.8, 70.8, 64])
|
||||
->and($totalScore->seating_total)->toBe(67.625)
|
||||
->and($totalScore->advancement_total)->toBe(68.45);
|
||||
});
|
||||
|
||||
test('scores correctly for olympic scoring', function () {
|
||||
Settings::set('olympic_scoring', true);
|
||||
($this->scribe)($this->judge1, $this->entry, $this->judge1Subscores);
|
||||
($this->scribe)($this->judge2, $this->entry, $this->judge2Subscores);
|
||||
($this->scribe)($this->judge3, $this->entry, $this->judge3Subscores);
|
||||
($this->scribe)($this->judge4, $this->entry, $this->judge4Subscores);
|
||||
($this->scribe)($this->judge5, $this->entry, $this->judge5Subscores);
|
||||
$judges = [
|
||||
$this->judge1,
|
||||
$this->judge2,
|
||||
$this->judge3,
|
||||
$this->judge4,
|
||||
$this->judge5,
|
||||
];
|
||||
$expectedSeatingTotals = [
|
||||
1 => 68.125,
|
||||
2 => 74,
|
||||
3 => 61,
|
||||
4 => 60.25,
|
||||
5 => 74.75,
|
||||
];
|
||||
$expectedAdvancementTotals = [
|
||||
1 => 71.875,
|
||||
2 => 70.25,
|
||||
3 => 58.25,
|
||||
4 => 63,
|
||||
5 => 78.875,
|
||||
];
|
||||
foreach ($judges as $judge) {
|
||||
$scoreSheet = ScoreSheet::where('entry_id', $this->entry->id)->where('user_id', $judge->id)->first();
|
||||
expect($scoreSheet->seating_total)->toBe($expectedSeatingTotals[$judge->id])
|
||||
->and($scoreSheet->advancement_total)->toBe($expectedAdvancementTotals[$judge->id]);
|
||||
}
|
||||
($this->calculator)($this->entry);
|
||||
$totalScore = EntryTotalScore::where('entry_id', $this->entry->id)->first();
|
||||
expect($totalScore->seating_subscore_totals)->toBe([69.6667, 70.6667, 62.6667, 66])
|
||||
->and($totalScore->advancement_subscore_totals)->toBe([69.6667, 72.6667, 67, 62.6667])
|
||||
->and($totalScore->seating_total)->toBe(67.708333)
|
||||
->and($totalScore->advancement_total)->toBe(68.375);
|
||||
});
|
||||
|
||||
test('it correctly brings in bonus scores', function () {
|
||||
Settings::set('olympic_scoring', false);
|
||||
($this->scribe)($this->judge1, $this->entry, $this->judge1Subscores);
|
||||
($this->scribe)($this->judge2, $this->entry, $this->judge2Subscores);
|
||||
($this->scribe)($this->judge3, $this->entry, $this->judge3Subscores);
|
||||
($this->scribe)($this->judge4, $this->entry, $this->judge4Subscores);
|
||||
($this->scribe)($this->judge5, $this->entry, $this->judge5Subscores);
|
||||
$judges = [
|
||||
$this->judge1,
|
||||
$this->judge2,
|
||||
$this->judge3,
|
||||
$this->judge4,
|
||||
$this->judge5,
|
||||
];
|
||||
$expectedSeatingTotals = [
|
||||
1 => 68.125,
|
||||
2 => 74,
|
||||
3 => 61,
|
||||
4 => 60.25,
|
||||
5 => 74.75,
|
||||
];
|
||||
$expectedAdvancementTotals = [
|
||||
1 => 71.875,
|
||||
2 => 70.25,
|
||||
3 => 58.25,
|
||||
4 => 63,
|
||||
5 => 78.875,
|
||||
];
|
||||
foreach ($judges as $judge) {
|
||||
$scoreSheet = ScoreSheet::where('entry_id', $this->entry->id)->where('user_id', $judge->id)->first();
|
||||
expect($scoreSheet->seating_total)->toBe($expectedSeatingTotals[$judge->id])
|
||||
->and($scoreSheet->advancement_total)->toBe($expectedAdvancementTotals[$judge->id]);
|
||||
}
|
||||
$bonusScore = BonusScore::create([
|
||||
'entry_id' => $this->entry->id,
|
||||
'user_id' => $this->judge1,
|
||||
'originally_scored_entry' => $this->entry->id,
|
||||
'score' => 6,
|
||||
]);
|
||||
($this->calculator)($this->entry);
|
||||
$totalScore = EntryTotalScore::where('entry_id', $this->entry->id)->first();
|
||||
|
||||
expect($totalScore->seating_subscore_totals)->toBe([69.8, 70.8, 64, 62])
|
||||
->and($totalScore->advancement_subscore_totals)->toBe([68.6, 69.8, 70.8, 64])
|
||||
->and($totalScore->seating_total)->toBe(67.625)
|
||||
->and($totalScore->advancement_total)->toBe(68.45)
|
||||
->and($totalScore->bonus_total)->toBe(6)
|
||||
->and($totalScore->seating_total_with_bonus)->toBe(73.625);
|
||||
});
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
use App\Models\User;
|
||||
use App\Settings;
|
||||
use Illuminate\Foundation\Testing\TestCase;
|
||||
|
||||
use function Pest\Laravel\actingAs;
|
||||
use function Pest\Laravel\artisan;
|
||||
|
||||
|
|
@ -80,5 +80,5 @@ uses()->beforeEach(function () {
|
|||
Settings::set('payment_city', 'Washington');
|
||||
Settings::set('payment_state', 'DC');
|
||||
Settings::set('payment_zip', '20500');
|
||||
Settings::set('olympic_scoring', 1);
|
||||
})->in('Feature');
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue