189 lines
6.0 KiB
PHP
189 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Http\Controllers\Tabulation;
|
|
|
|
use App\Models\Audition;
|
|
use App\Models\Entry;
|
|
use App\Models\EntryTotalScore;
|
|
use App\Models\Room;
|
|
use App\Models\ScoringGuide;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
Cache::flush();
|
|
});
|
|
|
|
it('displays audition seating status data correctly', function () {
|
|
// Create an audition with entries
|
|
$scoringGuide = ScoringGuide::factory()->create();
|
|
$room = Room::factory()->create();
|
|
$audition = Audition::factory()->create(['scoring_guide_id' => $scoringGuide->id, 'room_id' => $room->id]);
|
|
$judge = User::factory()->create();
|
|
$room->judges()->attach($judge);
|
|
|
|
// Create some scored entries
|
|
$scoredEntries = Entry::factory()
|
|
->count(3)
|
|
->for($audition)
|
|
->create(['for_seating' => true]);
|
|
foreach ($scoredEntries as $scoredEntry) {
|
|
EntryTotalScore::create([
|
|
'entry_id' => $scoredEntry->id,
|
|
'seating_total' => 10,
|
|
'advancement_total' => 10,
|
|
'seating_subscore_totals' => json_encode([10, 10]),
|
|
'advancement_subscore_totals' => json_encode([10, 10]),
|
|
'bonus_total' => null,
|
|
]);
|
|
}
|
|
|
|
// Create some unscored entries
|
|
Entry::factory()
|
|
->count(2)
|
|
->for($audition)
|
|
->create(['for_seating' => true]);
|
|
|
|
// Create a no-show entry
|
|
$noShowEntry = Entry::factory()
|
|
->for($audition)
|
|
->create(['for_seating' => true]);
|
|
$noShowEntry->addFlag('no_show');
|
|
|
|
actAsTab();
|
|
|
|
$response = $this->get(route('seating.status'));
|
|
|
|
$response->assertOk()
|
|
->assertViewIs('tabulation.status')
|
|
->assertViewHas('auditionData');
|
|
|
|
$auditionData = $response->viewData('auditionData');
|
|
$displayedAudition = $auditionData[$audition->id];
|
|
|
|
expect($displayedAudition['totalEntriesCount'])->toBe(6)
|
|
->and($displayedAudition['scoredEntriesCount'])->toBe(4) // 3 scored + 1 no-show
|
|
->and($displayedAudition['scoringComplete'])->toBeFalse()
|
|
->and($displayedAudition['seatsPublished'])->toBeFalse();
|
|
});
|
|
|
|
it('calculates scoring percentage correctly', function () {
|
|
// Create an audition with entries
|
|
$scoringGuide = ScoringGuide::factory()->create();
|
|
$room = Room::factory()->create();
|
|
$audition = Audition::factory()->create(['scoring_guide_id' => $scoringGuide->id, 'room_id' => $room->id]);
|
|
$judge = User::factory()->create();
|
|
$room->judges()->attach($judge);
|
|
|
|
// Create 4 scored and 1 unscored entry
|
|
$scoredEntries = Entry::factory()
|
|
->count(4)
|
|
->for($audition)
|
|
->create(['for_seating' => true]);
|
|
foreach ($scoredEntries as $scoredEntry) {
|
|
EntryTotalScore::create([
|
|
'entry_id' => $scoredEntry->id,
|
|
'seating_total' => 10,
|
|
'advancement_total' => 10,
|
|
'seating_subscore_totals' => json_encode([10, 10]),
|
|
'advancement_subscore_totals' => json_encode([10, 10]),
|
|
'bonus_total' => null,
|
|
]);
|
|
}
|
|
|
|
Entry::factory()
|
|
->for($audition)
|
|
->create(['for_seating' => true]);
|
|
|
|
actAsTab();
|
|
|
|
$response = $this->get(route('seating.status'));
|
|
$auditionData = $response->viewData('auditionData');
|
|
|
|
expect($auditionData[$audition->id]['scoredPercentage'])->toBe(80.0);
|
|
});
|
|
|
|
it('shows audition as complete when all entries are scored', function () {
|
|
// Create an audition with entries
|
|
$scoringGuide = ScoringGuide::factory()->create();
|
|
$room = Room::factory()->create();
|
|
$audition = Audition::factory()->create(['scoring_guide_id' => $scoringGuide->id, 'room_id' => $room->id]);
|
|
$judge = User::factory()->create();
|
|
$room->judges()->attach($judge);
|
|
|
|
// Create only scored entries
|
|
$scoredEntries = Entry::factory()
|
|
->count(5)
|
|
->for($audition)
|
|
->create(['for_seating' => true]);
|
|
foreach ($scoredEntries as $scoredEntry) {
|
|
EntryTotalScore::create([
|
|
'entry_id' => $scoredEntry->id,
|
|
'seating_total' => 10,
|
|
'advancement_total' => 10,
|
|
'seating_subscore_totals' => json_encode([10, 10]),
|
|
'advancement_subscore_totals' => json_encode([10, 10]),
|
|
'bonus_total' => null,
|
|
]);
|
|
}
|
|
|
|
actAsTab();
|
|
|
|
$response = $this->get(route('seating.status'));
|
|
$auditionData = $response->viewData('auditionData');
|
|
|
|
expect($auditionData[$audition->id]['scoringComplete'])->toBeTrue();
|
|
});
|
|
|
|
it('shows published status correctly', function () {
|
|
$audition = Audition::factory()->create();
|
|
|
|
// Create a seats_published flag
|
|
$audition->addFlag('seats_published');
|
|
|
|
actAsTab();
|
|
|
|
$response = $this->get(route('seating.status'));
|
|
$auditionData = $response->viewData('auditionData');
|
|
|
|
expect($auditionData[$audition->id]['seatsPublished'])->toBeTrue();
|
|
});
|
|
|
|
it('handles auditions with no entries correctly', function () {
|
|
$audition = Audition::factory()->create();
|
|
|
|
actAsTab();
|
|
|
|
$response = $this->get(route('seating.status'));
|
|
$auditionData = $response->viewData('auditionData');
|
|
|
|
expect($auditionData[$audition->id]['scoredPercentage'])->toBe(100)
|
|
->and($auditionData[$audition->id]['totalEntriesCount'])->toBe(0)
|
|
->and($auditionData[$audition->id]['scoredEntriesCount'])->toBe(0)
|
|
->and($auditionData[$audition->id]['scoringComplete'])->toBeTrue();
|
|
});
|
|
|
|
it('uses caching for audition score calculation', function () {
|
|
$audition = Audition::factory()->create();
|
|
Entry::factory()
|
|
->count(3)
|
|
->for($audition)
|
|
->create(['for_seating' => true]);
|
|
|
|
actAsTab();
|
|
|
|
// The first request should set the cache
|
|
$this->get(route('seating.status'));
|
|
|
|
expect(Cache::has('seating_status_audition_totaler_throttle'))->toBeTrue();
|
|
|
|
// The second request should use cached data
|
|
$this->get(route('seating.status'));
|
|
|
|
// Cache should still exist
|
|
expect(Cache::has('seating_status_audition_totaler_throttle'))->toBeTrue();
|
|
})->skip();
|