From 579a0a2fc37b2628df109b17c68725500b400c37 Mon Sep 17 00:00:00 2001 From: Matt Young Date: Mon, 15 Jul 2024 23:32:32 -0500 Subject: [PATCH] Bonus Score Entry #20 Implement bonus scores Bonus score entry by judges is complete. --- .../Judging/BonusScoreEntryController.php | 31 +++++++++ .../Judging/BonusScoreRecordController.php | 28 ++++++++ .../views/components/form/field.blade.php | 5 +- .../judging/bonus_entry_score_sheet.blade.php | 16 +++++ .../judging/bonus_score_entry_list.blade.php | 9 ++- routes/judging.php | 6 +- .../Pages/JudgingBonusScoreEntryTest.php | 68 +++++++++++++++++++ 7 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 app/Http/Controllers/Judging/BonusScoreEntryController.php create mode 100644 app/Http/Controllers/Judging/BonusScoreRecordController.php create mode 100644 resources/views/judging/bonus_entry_score_sheet.blade.php create mode 100644 tests/Feature/Pages/JudgingBonusScoreEntryTest.php diff --git a/app/Http/Controllers/Judging/BonusScoreEntryController.php b/app/Http/Controllers/Judging/BonusScoreEntryController.php new file mode 100644 index 0000000..447d160 --- /dev/null +++ b/app/Http/Controllers/Judging/BonusScoreEntryController.php @@ -0,0 +1,31 @@ +id)->where('user_id', Auth::user()->id)->exists()) { + return redirect()->route('judging.bonusScore.EntryList', $entry->audition)->with('error', 'You have already judged that entry'); + } + /** @var BonusScoreDefinition $bonusScore */ + $bonusScore = $entry->audition->bonusScore()->first(); + if (! $bonusScore->judges->contains(auth()->id())) { + return redirect()->route('judging.index')->with('error', 'You are not assigned to judge this entry'); + } + $maxScore = $bonusScore->max_score; + $bonusName = $bonusScore->name; + + return view('judging.bonus_entry_score_sheet', compact('entry', 'maxScore', 'bonusName')); + + } +} diff --git a/app/Http/Controllers/Judging/BonusScoreRecordController.php b/app/Http/Controllers/Judging/BonusScoreRecordController.php new file mode 100644 index 0000000..911fe3d --- /dev/null +++ b/app/Http/Controllers/Judging/BonusScoreRecordController.php @@ -0,0 +1,28 @@ +validate([ + 'score' => 'required|integer', + ]); + try { + $enterBonusScore(Auth::user(), $entry, $validData['score']); + } catch (ScoreEntryException $ex) { + return redirect()->back()->with('error', 'Score Entry Error - '.$ex->getMessage()); + } + + return redirect()->route('judging.bonusScore.EntryList', $entry->audition)->with('Score Recorded Successfully'); + } +} diff --git a/resources/views/components/form/field.blade.php b/resources/views/components/form/field.blade.php index 458bfbc..f1b2622 100644 --- a/resources/views/components/form/field.blade.php +++ b/resources/views/components/form/field.blade.php @@ -3,13 +3,14 @@ 'type' => 'text', 'label' => false, 'colspan' => '1', - 'label_text' => false + 'label_text' => false, + 'id'=>null ]) @php $label_classes = "block text-sm font-medium leading-6 text-gray-900"; $inputClasses = "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"; $inputAttributes = [ - 'id' => $name, + 'id' => $id ?? $name, 'name' => $name, 'type' => $type, 'class' => $inputClasses, diff --git a/resources/views/judging/bonus_entry_score_sheet.blade.php b/resources/views/judging/bonus_entry_score_sheet.blade.php new file mode 100644 index 0000000..b065773 --- /dev/null +++ b/resources/views/judging/bonus_entry_score_sheet.blade.php @@ -0,0 +1,16 @@ + + Enter {{ $bonusName }} Score + + {{ $entry->audition->name }} {{$entry->draw_number}} + + + Enter {{ $bonusName }} Score + + + diff --git a/resources/views/judging/bonus_score_entry_list.blade.php b/resources/views/judging/bonus_score_entry_list.blade.php index c5bed92..f70fb3f 100644 --- a/resources/views/judging/bonus_score_entry_list.blade.php +++ b/resources/views/judging/bonus_score_entry_list.blade.php @@ -15,11 +15,18 @@ @foreach($entries as $entry) - {{ $audition->name }} {{ $entry->draw_number }} @if($scores->has($entry->id)) + {{ $audition->name }} {{ $entry->draw_number }} {{ $scores[$entry->id]->score }} {{ $scores[$entry->id]->originallyScoredEntry->audition->name }} {{ Carbon::create($scores[$entry->id]->created_at)->setTimezone('America/Chicago')->format('m/d/y H:i') }} + @else + + + + {{ $audition->name }} {{ $entry->draw_number }} + + @endif diff --git a/routes/judging.php b/routes/judging.php index 6dae2e7..f5b59ab 100644 --- a/routes/judging.php +++ b/routes/judging.php @@ -1,7 +1,9 @@ prefix('judging // Bonus score judging routes Route::middleware(['auth', 'verified', CheckIfCanJudge::class])->prefix('judging/bonus_scores')->group(function () { - Route::get('/{audition}', BonusScoreEntryListController::class)->name('judging.bonusScore.EntryList'); + Route::get('/{audition}', BonusScoreEntryListController::class)->name('judging.bonusScore.EntryList'); // List of entries in an audition + Route::get('/entries/{entry}', BonusScoreEntryController::class)->name('judging.bonusScore.entry'); // Form to enter an entries score + Route::post('/entries/{entry}', BonusScoreRecordController::class)->name('judging.bonusScores.recordScore'); // Record the score }); diff --git a/tests/Feature/Pages/JudgingBonusScoreEntryTest.php b/tests/Feature/Pages/JudgingBonusScoreEntryTest.php new file mode 100644 index 0000000..410514f --- /dev/null +++ b/tests/Feature/Pages/JudgingBonusScoreEntryTest.php @@ -0,0 +1,68 @@ +get(route('judging.bonusScore.entry', 1)); + $response->assertRedirect(route('home')); +}); +it('denies access to a user not assigned to judge this bonus score', function () { + $bonusScore = BonusScoreDefinition::factory()->create(); + $audition = Audition::factory()->create(); + $audition->bonusScore()->attach($bonusScore->id); + $entry = Entry::factory()->create(['audition_id' => $audition->id]); + $room = Room::factory()->create(); + $user = User::factory()->create(); + $room->addJudge($user->id); + actingAs($user); + $this->get(route('judging.bonusScore.entry', $entry->id)) + ->assertRedirect(route('judging.index')) + ->assertSessionHas('error', 'You are not assigned to judge this entry'); +}); +it('denies access if a score already exists for the entry by the user', function () { + $entry = Entry::factory()->create(); + $judge = User::factory()->create(); + $bonusScoreDefinition = BonusScoreDefinition::factory()->create(); + $bonusScoreDefinition->judges()->attach($judge->id); + BonusScore::create([ + 'entry_id' => $entry->id, + 'user_id' => $judge->id, + 'originally_scored_entry' => $entry->id, + 'score' => 42, + ]); + actingAs($judge); + $this->get(route('judging.bonusScore.entry', $entry)) + ->assertRedirect(route('judging.bonusScore.EntryList', $entry->audition)) + ->assertSessionHas('error', 'You have already judged that entry'); +}); +it('has a proper score entry form for a valid request', function () { + // Arrange + $audition = Audition::factory()->create(); + $bonusScore = BonusScoreDefinition::factory()->create(['max_score' => 100]); + $bonusScore->auditions()->attach($audition->id); + $entry = Entry::factory()->create(['audition_id' => $audition->id]); + $judge = User::factory()->create(); + $bonusScore->judges()->attach($judge->id); + actingAs($judge); + // Act & Assert + $request = $this->get(route('judging.bonusScore.entry', $entry)); + $request->assertOk() + ->assertFormExists('#score-entry-for-'.$entry->id, function (AssertForm $form) use ($entry) { + $form->hasCSRF() + ->hasMethod('POST') + ->hasAction(route('judging.bonusScores.recordScore', $entry)) + ->containsInput(['name' => 'score']) + ->containsButton(['type' => 'submit']); + }); +});