From 437ba6020bff082f676b7eeee615e29eb306f849 Mon Sep 17 00:00:00 2001 From: Matt Young Date: Tue, 5 Aug 2025 07:48:39 -0500 Subject: [PATCH] Comments on MakeSeatingDecisionsController.php and add test for that file --- .../MakeSeatingDecisionsController.php | 15 +++ .../MakeSeatingDecisionsControllerTest.php | 92 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 tests/Feature/app/Http/Controllers/Tabulation/Seating/MakeSeatingDecisionsControllerTest.php diff --git a/app/Http/Controllers/Tabulation/Seating/MakeSeatingDecisionsController.php b/app/Http/Controllers/Tabulation/Seating/MakeSeatingDecisionsController.php index 540bff0..8163993 100644 --- a/app/Http/Controllers/Tabulation/Seating/MakeSeatingDecisionsController.php +++ b/app/Http/Controllers/Tabulation/Seating/MakeSeatingDecisionsController.php @@ -12,6 +12,10 @@ use Illuminate\Support\Arr; use function redirect; +/** + * Selects entries for seating in an audition and saves them to the session + * for later formal seating. + */ class MakeSeatingDecisionsController extends Controller { public function draftSeats( @@ -30,6 +34,8 @@ class MakeSeatingDecisionsController extends Controller return redirect()->route('seating.audition', ['audition' => $audition->id]) ->with('error', $e->getMessage()); } + + // Pull out entries that have declined a seat in this audition $rankedEntries = $rankedEntries->reject(function ($entry) { return $entry->hasFlag('declined'); }); @@ -37,13 +43,20 @@ class MakeSeatingDecisionsController extends Controller $rankedEntries->load(['student.school']); $rankedEnsembles = Ensemble::orderBy('rank')->where('event_id', $audition->event_id)->get(); $ensembleRankOn = 1; + + // Iterate over all ensembles that exist for the event foreach ($rankedEnsembles as $ensemble) { + // If the user didn't ask for any seats in this ensemble, skip it if (! Arr::has($validated['ensemble'], $ensemble->id)) { continue; } + + // Set up an entry in the session for each ensemble we're going to seat $proposedSeatingArray[$ensembleRankOn]['ensemble_id'] = $ensemble->id; $proposedSeatingArray[$ensembleRankOn]['ensemble_name'] = $ensemble->name; $proposedSeatingArray[$ensembleRankOn]['accept_count'] = $validated['ensemble'][$ensemble->id]; + + // Pull the top rated entry for each seat in order for ($n = 1; $n <= $validated['ensemble'][$ensemble->id]; $n++) { // Escape the loop if we're out of entries if ($rankedEntries->isEmpty()) { @@ -59,6 +72,8 @@ class MakeSeatingDecisionsController extends Controller $ensembleRankOn++; } + + // Save the data to the session $sessionKeyName = 'proposedSeatingArray-'.$audition->id; $request->session()->put($sessionKeyName, $proposedSeatingArray); diff --git a/tests/Feature/app/Http/Controllers/Tabulation/Seating/MakeSeatingDecisionsControllerTest.php b/tests/Feature/app/Http/Controllers/Tabulation/Seating/MakeSeatingDecisionsControllerTest.php new file mode 100644 index 0000000..a42cbfa --- /dev/null +++ b/tests/Feature/app/Http/Controllers/Tabulation/Seating/MakeSeatingDecisionsControllerTest.php @@ -0,0 +1,92 @@ +event = Event::factory()->create(); + $this->audition = Audition::factory()->create(['event_id' => $this->event->id]); + $this->entries = Entry::factory()->count(3)->create(['audition_id' => $this->audition->id]); + $score = 100; + foreach ($this->entries as $entry) { + EntryTotalScore::create([ + 'entry_id' => $entry->id, + 'seating_total' => $score, + 'advancement_total' => $score, + 'seating_subscore_totals' => json_encode([$score, $score]), + 'advancement_subscore_totals' => json_encode([$score, $score]), + ]); + $score--; + } + $this->ensemble1 = Ensemble::factory()->create(['event_id' => $this->event->id, 'rank' => 1]); + $this->ensemble2 = Ensemble::factory()->create(['event_id' => $this->event->id, 'rank' => 2]); + $this->ensemble3 = Ensemble::factory()->create(['event_id' => $this->event->id, 'rank' => 3]); +}); + +it('saves proposed seating to the session', function () { + actAsAdmin(); + $response = $this->post(route('seating.audition.draftSeats', $this->audition), [ + 'ensemble' => [ + $this->ensemble1->id => 2, + $this->ensemble2->id => 2, + ], + ]); + $response->assertRedirect(route('seating.audition', $this->audition)); + $sessionKey = 'proposedSeatingArray-'.$this->audition->id; + $response->assertSessionHas($sessionKey, [ + 1 => [ + 'ensemble_id' => $this->ensemble1->id, + 'ensemble_name' => $this->ensemble1->name, + 'accept_count' => 2, + 'seats' => [ + 1 => [ + 'seat' => 1, + 'entry_id' => $this->entries[0]->id, + 'entry_name' => $this->entries[0]->student->full_name(), + 'entry_school' => $this->entries[0]->student->school->name, + ], + 2 => [ + 'seat' => 2, + 'entry_id' => $this->entries[1]->id, + 'entry_name' => $this->entries[1]->student->full_name(), + 'entry_school' => $this->entries[1]->student->school->name, + ], + ], + ], + 2 => [ + 'ensemble_id' => $this->ensemble2->id, + 'ensemble_name' => $this->ensemble2->name, + 'accept_count' => 2, + 'seats' => [ + 1 => [ + 'seat' => 1, + 'entry_id' => $this->entries[2]->id, + 'entry_name' => $this->entries[2]->student->full_name(), + 'entry_school' => $this->entries[2]->student->school->name, + ], + ], + ], + ]); +}); + +it('can clear proposed seats', function () { + actAsAdmin(); + $response = $this->post(route('seating.audition.draftSeats', $this->audition), [ + 'ensemble' => [ + $this->ensemble1->id => 2, + $this->ensemble2->id => 2, + ], + ]); + $response->assertRedirect(route('seating.audition', $this->audition)); + $sessionKey = 'proposedSeatingArray-'.$this->audition->id; + $response->assertSessionHas($sessionKey); + $response2 = $this->post(route('seating.audition.clearDraft', $this->audition)); + $response2->assertRedirect(route('seating.audition', $this->audition)); + $response2->assertSessionMissing($sessionKey); +});