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();