From d21324b71b716bd4957876357b7ca6314a14b7e7 Mon Sep 17 00:00:00 2001 From: Matt Young Date: Fri, 5 Jul 2024 14:30:57 -0500 Subject: [PATCH] ScoringGuidePage Tests --- .../Admin/ScoringGuideController.php | 21 ++- .../views/admin/scoring/edit-tabs.blade.php | 7 +- routes/admin.php | 2 +- .../Setup/ScoringGuideEditDetailsTest.php | 155 ++++++++++++++++++ .../Pages/Setup/ScoringGuideOrderTabsTest.php | 54 ++++++ 5 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 tests/Feature/Pages/Setup/ScoringGuideEditDetailsTest.php create mode 100644 tests/Feature/Pages/Setup/ScoringGuideOrderTabsTest.php diff --git a/app/Http/Controllers/Admin/ScoringGuideController.php b/app/Http/Controllers/Admin/ScoringGuideController.php index 0e84a5c..efbf8aa 100644 --- a/app/Http/Controllers/Admin/ScoringGuideController.php +++ b/app/Http/Controllers/Admin/ScoringGuideController.php @@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use function abort; +use function auditionSetting; use function request; use function response; @@ -42,12 +43,11 @@ class ScoringGuideController extends Controller return redirect(route('admin.scoring.index'))->with('success', 'Scoring guide created'); } - public function edit(Request $request, ScoringGuide $guide) + public function edit(Request $request, ScoringGuide $guide, string $tab = 'detail') { if (! Auth::user()->is_admin) { abort(403); } - $tab = $request->query('tab') ?? 'detail'; if ($tab == 'tiebreakOrder') { $subscores = SubscoreDefinition::where('scoring_guide_id', $guide->id)->orderBy('tiebreak_order')->get(); } else { @@ -90,9 +90,6 @@ class ScoringGuideController extends Controller public function subscore_store(Request $request, ScoringGuide $guide) { - if (! Auth::user()->is_admin) { - abort(403); - } if (! $guide->exists()) { abort(409); } @@ -106,6 +103,9 @@ class ScoringGuideController extends Controller $for_seating = $request->has('for_seating') ? (bool) $request->input('for_seating') : false; $for_advance = $request->has('for_advance') ? (bool) $request->input('for_advance') : false; + if (! auditionSetting('advanceTo')) { + $for_seating = true; + } $display_order = SubscoreDefinition::where('scoring_guide_id', '=', $guide->id)->max('display_order') + 1; $tiebreak_order = SubscoreDefinition::where('scoring_guide_id', '=', $guide->id)->max('tiebreak_order') + 1; @@ -121,7 +121,7 @@ class ScoringGuideController extends Controller 'for_advance' => $for_advance, ]); - return redirect('/admin/scoring/guides/'.$guide->id.'/edit')->with('success', 'Subscore added'); + return redirect(route('admin.scoring.edit', $guide))->with('success', 'Subscore added'); } public function subscore_update(ScoringGuide $guide, SubscoreDefinition $subscore) @@ -146,6 +146,10 @@ class ScoringGuideController extends Controller $for_seating = request()->has('for_seating') ? (bool) request()->input('for_seating') : false; $for_advance = request()->has('for_advance') ? (bool) request()->input('for_advance') : false; + if (! auditionSetting('advanceTo')) { + $for_seating = true; + } + $subscore->update([ 'name' => $validateData['name'], 'max_score' => $validateData['max_score'], @@ -175,7 +179,6 @@ class ScoringGuideController extends Controller } - public function reorder_display(Request $request) { if (! Auth::user()->is_admin) { @@ -184,7 +187,7 @@ class ScoringGuideController extends Controller $order = $request->order; foreach ($order as $index => $id) { $subscore = SubscoreDefinition::find($id); - $subscore->update(['display_order' => $index]); + $subscore->update(['display_order' => $index + 1]); } return response()->json(['status' => 'success']); @@ -199,7 +202,7 @@ class ScoringGuideController extends Controller $order = $request->order; foreach ($order as $index => $id) { $subscore = SubscoreDefinition::find($id); - $subscore->update(['tiebreak_order' => $index]); + $subscore->update(['tiebreak_order' => $index + 1]); } return response()->json(['status' => 'success']); diff --git a/resources/views/admin/scoring/edit-tabs.blade.php b/resources/views/admin/scoring/edit-tabs.blade.php index 20ae7ba..dcd74b5 100644 --- a/resources/views/admin/scoring/edit-tabs.blade.php +++ b/resources/views/admin/scoring/edit-tabs.blade.php @@ -18,9 +18,10 @@
diff --git a/routes/admin.php b/routes/admin.php index 4a2d5b9..aae16f1 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -49,7 +49,7 @@ Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')-> Route::prefix('scoring')->controller(\App\Http\Controllers\Admin\ScoringGuideController::class)->group(function () { Route::get('/', 'index')->name('admin.scoring.index'); // Scoring Setup Homepage Route::post('/guides', 'store')->name('admin.scoring.store'); // Save a new scoring guide - Route::get('/guides/{guide}/edit', 'edit')->name('admin.scoring.edit'); // Edit scoring guide + Route::get('/guides/{guide}/edit/{tab?}', 'edit')->name('admin.scoring.edit'); // Edit scoring guide Route::patch('/guides/{guide}/edit', 'update')->name('admin.scoring.update'); // Save changes to audition guide (rename) Route::post('/guides/{guide}/subscore', 'subscore_store')->name('admin.scoring.subscore_store'); // Save a new subscore Route::patch('/guides/{guide}/subscore/{subscore}', 'subscore_update')->name('admin.scoring.subscore_update'); // Modify a subscore diff --git a/tests/Feature/Pages/Setup/ScoringGuideEditDetailsTest.php b/tests/Feature/Pages/Setup/ScoringGuideEditDetailsTest.php new file mode 100644 index 0000000..a53cb82 --- /dev/null +++ b/tests/Feature/Pages/Setup/ScoringGuideEditDetailsTest.php @@ -0,0 +1,155 @@ +scoringGuide = ScoringGuide::factory()->create(); + $this->subscores = SubscoreDefinition::factory()->count(3)->create([ + 'scoring_guide_id' => $this->scoringGuide->id, + ]); +}); +it('shows the details of a scoring guide', function () { + actAsAdmin(); + $response = get(route('admin.scoring.edit', $this->scoringGuide)); + $response->assertOk(); + $response->assertSee($this->scoringGuide->name); + foreach ($this->subscores as $subscore) { + $response->assertSeeInOrder([ + 'name, '', + 'max_score, '', + 'weight, '', + 'for_seating) ? 'Yes' : 'No', '', + 'for_advance) ? 'Yes' : 'No', '', + ], false); + } + Settings::set('advanceTo', ''); + $response = get(route('admin.scoring.edit', $this->scoringGuide)); + $response->assertOk(); + $response->assertSee($this->scoringGuide->name); + foreach ($this->subscores as $subscore) { + $response->assertSeeInOrder([ + 'name, '', + 'max_score, '', + 'weight, '', + ], false); + $response->assertDontSee('Yes', false); + $response->assertDontSee('No', false); + } +}); +it('includes a form to add a subscore', function () { + // Arrange + actAsAdmin(); + // Act & Assert + $response = get(route('admin.scoring.edit', $this->scoringGuide)); + $response->assertOk(); + $response->assertSee(route('admin.scoring.subscore_store', $this->scoringGuide)); +}); +it('can create a subscore', function () { + // Arrange + actAsAdmin(); + $formData = [ + 'name' => 'New Subscore', + 'max_score' => 32, + 'weight' => 1, + 'for_seating' => 1, + ]; + // Act + $response = $this->post(route('admin.scoring.subscore_store', $this->scoringGuide), $formData); + // Assert + /** @noinspection PhpUnhandledExceptionInspection */ + $response->assertSessionHasNoErrors() + ->assertRedirect(route('admin.scoring.edit', $this->scoringGuide)); + $this->assertDatabaseHas('subscore_definitions', $formData); + +}); +it('sets for_seating true for new subscores when advancement is not enabled', function () { + Settings::set('advanceTo', ''); + actAsAdmin(); + $formData = [ + 'name' => 'New Subscore', + 'max_score' => 32, + 'weight' => 1, + ]; + $response = $this->post(route('admin.scoring.subscore_store', $this->scoringGuide), $formData); + $response->assertSessionHasNoErrors() + ->assertRedirect(route('admin.scoring.edit', $this->scoringGuide)); + $this->assertDatabaseHas('subscore_definitions', $formData); + $newSubscore = SubscoreDefinition::where('name', 'New Subscore')->first(); + expect($newSubscore->for_seating)->toBeTruthy(); +}); +it('only allows an admin to create a subscore', function () { + // Arrange + $formData = [ + 'name' => 'New Subscore', + 'max_score' => 32, + 'weight' => 1, + 'for_seating' => 1, + ]; + // Act & Assert + $response = post(route('admin.scoring.subscore_store', $this->scoringGuide), $formData); + $response->assertRedirect(route('home')); + actAsNormal(); + $response = $this->post(route('admin.scoring.subscore_store', $this->scoringGuide), $formData); + $response->assertRedirect(route('dashboard')) + ->assertSessionHas('error', 'You are not authorized to perform this action'); +}); +it('allows a subscore to be modified', function () { + // Arrange + $subscore = SubscoreDefinition::factory()->create([ + 'scoring_guide_id' => $this->scoringGuide->id, + ]); + $formData = [ + 'name' => 'Changed Name', + 'max_score' => 32, + 'weight' => 1, + 'for_seating' => 1, + ]; + // Act & Assert + actAsAdmin(); + $response = $this->patch(route('admin.scoring.subscore_update', [$this->scoringGuide, $subscore]), $formData); + /** @noinspection PhpUnhandledExceptionInspection */ + $response->assertSessionHasNoErrors() + ->assertRedirect(route('admin.scoring.edit', $this->scoringGuide)) + ->assertSessionHas('success', 'Subscore updated'); + $subscore = SubscoreDefinition::find($subscore->id); + expect($subscore->name)->toBe('Changed Name') + ->and($subscore->max_score)->toBe(32) + ->and($subscore->weight)->toBe(1) + ->and($subscore->for_seating)->toBeTruthy() + ->and($subscore->for_advance)->toBeFalsy(); +}); +it('sets for_seating true if advance is not enabled when modifying a subscore', function () { + // Arrange + Settings::set('advanceTo', ''); + $subscore = SubscoreDefinition::factory()->create([ + 'scoring_guide_id' => $this->scoringGuide->id, + ]); + $formData = [ + 'name' => 'Changed Name', + 'max_score' => 32, + 'weight' => 1, + ]; + // Act & Assert + actAsAdmin(); + $response = $this->patch(route('admin.scoring.subscore_update', [$this->scoringGuide, $subscore]), $formData); + /** @noinspection PhpUnhandledExceptionInspection */ + $response->assertSessionHasNoErrors() + ->assertRedirect(route('admin.scoring.edit', $this->scoringGuide)) + ->assertSessionHas('success', 'Subscore updated'); + $subscore = SubscoreDefinition::find($subscore->id); + expect($subscore->name)->toBe('Changed Name') + ->and($subscore->max_score)->toBe(32) + ->and($subscore->weight)->toBe(1) + ->and($subscore->for_seating)->toBeTruthy() + ->and($subscore->for_advance)->toBeFalsy(); +}); diff --git a/tests/Feature/Pages/Setup/ScoringGuideOrderTabsTest.php b/tests/Feature/Pages/Setup/ScoringGuideOrderTabsTest.php new file mode 100644 index 0000000..fb0ee46 --- /dev/null +++ b/tests/Feature/Pages/Setup/ScoringGuideOrderTabsTest.php @@ -0,0 +1,54 @@ +scoringGuide = ScoringGuide::factory()->create(); + $this->subscores = SubscoreDefinition::factory()->count(6)->create([ + 'scoring_guide_id' => $this->scoringGuide->id, + ]); +}); + +it('shows subscores in display or tiebreak order', function () { + $scoringGuide = ScoringGuide::factory()->create(); + $fourthSubscore = SubscoreDefinition::factory()->create([ + 'scoring_guide_id' => $scoringGuide->id, + 'display_order' => 4, + 'tiebreak_order' => 3, + ]); + $firstSubscore = SubscoreDefinition::factory()->create([ + 'scoring_guide_id' => $scoringGuide->id, + 'display_order' => 1, + 'tiebreak_order' => 4, + ]); + $thirdSubscore = SubscoreDefinition::factory()->create([ + 'scoring_guide_id' => $scoringGuide->id, + 'display_order' => 3, + 'tiebreak_order' => 2, + ]); + $secondSubscore = SubscoreDefinition::factory()->create([ + 'scoring_guide_id' => $scoringGuide->id, + 'display_order' => 2, + 'tiebreak_order' => 1, + ]); + actAsAdmin(); + $response = get(route('admin.scoring.edit', ['guide' => $scoringGuide, 'tab' => 'displayOrder'])); + $response->assertOk()->assertSee('Subscore Display Order')->assertSeeInOrder([ + $firstSubscore->name, + $secondSubscore->name, + $thirdSubscore->name, + $fourthSubscore->name, + ]); + $response = get(route('admin.scoring.edit', ['guide' => $scoringGuide, 'tab' => 'tiebreakOrder'])); + $response->assertOk()->assertSee('Subscore Display Order')->assertSeeInOrder([ + $secondSubscore->name, + $thirdSubscore->name, + $fourthSubscore->name, + $firstSubscore->name, + ]); +});