Removed unused EntryScoreController
This commit is contained in:
parent
8370810c03
commit
1cc43c1bce
|
|
@ -85,6 +85,7 @@ class EnterScore
|
||||||
if (! $scores->keys()->contains($subscore->id)) {
|
if (! $scores->keys()->contains($subscore->id)) {
|
||||||
throw new AuditionAdminException('Invalid Score Submission');
|
throw new AuditionAdminException('Invalid Score Submission');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($scores[$subscore->id] > $subscore->max_score) {
|
if ($scores[$subscore->id] > $subscore->max_score) {
|
||||||
throw new AuditionAdminException('Supplied subscore exceeds maximum allowed');
|
throw new AuditionAdminException('Supplied subscore exceeds maximum allowed');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ use Illuminate\Http\Request;
|
||||||
|
|
||||||
use function to_route;
|
use function to_route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for tabulation enter noshow menu option
|
||||||
|
*/
|
||||||
class EntryFlagController extends Controller
|
class EntryFlagController extends Controller
|
||||||
{
|
{
|
||||||
public function noShowSelect()
|
public function noShowSelect()
|
||||||
|
|
@ -30,11 +33,11 @@ class EntryFlagController extends Controller
|
||||||
// If any results are published, get gone
|
// If any results are published, get gone
|
||||||
if ($entry->audition->hasFlag('seats_published')) {
|
if ($entry->audition->hasFlag('seats_published')) {
|
||||||
return to_route('entry-flags.noShowSelect')->with('error',
|
return to_route('entry-flags.noShowSelect')->with('error',
|
||||||
'Cannot enter a no-show for an entry in an audition where seats are published');
|
'Cannot enter a no-show or failed-prelim for an entry in an audition where seats are published');
|
||||||
}
|
}
|
||||||
if ($entry->audition->hasFlag('advancement_published')) {
|
if ($entry->audition->hasFlag('advancement_published')) {
|
||||||
return to_route('entry-flags.noShowSelect')->with('error',
|
return to_route('entry-flags.noShowSelect')->with('error',
|
||||||
'Cannot enter a no-show for an entry in an audition where advancement is published');
|
'Cannot enter a no-show or failed-prelim for an entry in an audition where advancement is published');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($entry->hasFlag('no_show')) {
|
if ($entry->hasFlag('no_show')) {
|
||||||
|
|
@ -43,6 +46,12 @@ class EntryFlagController extends Controller
|
||||||
$submitRouteName = 'entry-flags.undoNoShow';
|
$submitRouteName = 'entry-flags.undoNoShow';
|
||||||
$cardHeading = 'Undo No-Show';
|
$cardHeading = 'Undo No-Show';
|
||||||
$method = 'DELETE';
|
$method = 'DELETE';
|
||||||
|
} elseif ($entry->hasFlag('failed_prelim')) {
|
||||||
|
$formId = 'no-show-cancellation-form';
|
||||||
|
$buttonName = 'Remove Failed Prelim';
|
||||||
|
$submitRouteName = 'entry-flags.undoNoShow';
|
||||||
|
$cardHeading = 'Undo Failed-Prelim';
|
||||||
|
$method = 'DELETE';
|
||||||
} else {
|
} else {
|
||||||
$formId = 'no-show-confirmation-form';
|
$formId = 'no-show-confirmation-form';
|
||||||
$buttonName = 'Confirm No Show';
|
$buttonName = 'Confirm No Show';
|
||||||
|
|
@ -85,21 +94,32 @@ class EntryFlagController extends Controller
|
||||||
{
|
{
|
||||||
if ($entry->audition->hasFlag('seats_published')) {
|
if ($entry->audition->hasFlag('seats_published')) {
|
||||||
return to_route('entry-flags.noShowSelect')->with('error',
|
return to_route('entry-flags.noShowSelect')->with('error',
|
||||||
'Cannot undo a no-show for an entry in an audition where seats are published');
|
'Cannot undo a no-show or failed-prelim for an entry in an audition where seats are published');
|
||||||
}
|
}
|
||||||
if ($entry->audition->hasFlag('advancement_published')) {
|
if ($entry->audition->hasFlag('advancement_published')) {
|
||||||
return to_route('entry-flags.noShowSelect')->with('error',
|
return to_route('entry-flags.noShowSelect')->with('error',
|
||||||
'Cannot undo a no-show for an entry in an audition where advancement is published');
|
'Cannot undo a no-show or failed-prelim for an entry in an audition where advancement is published');
|
||||||
}
|
}
|
||||||
|
|
||||||
$entry->removeFlag('no_show');
|
$entry->removeFlag('no_show');
|
||||||
|
$entry->removeFlag('failed_prelim');
|
||||||
|
|
||||||
return to_route('entry-flags.noShowSelect')->with('success',
|
return to_route('entry-flags.noShowSelect')->with('success',
|
||||||
'No Show status has been removed for '.$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.').');
|
$entry->audition->name.' #'.$entry->draw_number.' (ID: '.$entry->id.') may now be scored.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function undoDecline(Entry $entry)
|
public function undoDecline(Entry $entry)
|
||||||
{
|
{
|
||||||
|
if ($entry->audition->hasFlag('seats_published')) {
|
||||||
|
return redirect()->back()
|
||||||
|
->with('error', 'Cannot undo a decline for an entry in an audition where seats are published');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($entry->audition->hasFlag('advancement_published')) {
|
||||||
|
return redirect()->back()
|
||||||
|
->with('error', 'Cannot undo a no-show or failed-prelim for an entry in an audition where advancement is published');
|
||||||
|
}
|
||||||
|
|
||||||
$entry->removeFlag('declined');
|
$entry->removeFlag('declined');
|
||||||
|
|
||||||
return redirect()->back()->with('success', 'Decline cleared');
|
return redirect()->back()->with('success', 'Decline cleared');
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Http\Controllers\Tabulation;
|
namespace App\Http\Controllers\Tabulation;
|
||||||
|
|
||||||
use App\Actions\Tabulation\EnterScore;
|
use App\Actions\Tabulation\EnterScore;
|
||||||
use App\Exceptions\ScoreEntryException;
|
use App\Exceptions\AuditionAdminException;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
use App\Models\EntryTotalScore;
|
use App\Models\EntryTotalScore;
|
||||||
|
|
@ -12,6 +12,9 @@ use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides functionality for entering judge scores from the admin side.
|
||||||
|
*/
|
||||||
class ScoreController extends Controller
|
class ScoreController extends Controller
|
||||||
{
|
{
|
||||||
public function chooseEntry()
|
public function chooseEntry()
|
||||||
|
|
@ -25,7 +28,6 @@ class ScoreController extends Controller
|
||||||
|
|
||||||
public function destroyScore(ScoreSheet $score)
|
public function destroyScore(ScoreSheet $score)
|
||||||
{
|
{
|
||||||
EntryTotalScore::where('entry_id', $score->entry_id)->delete();
|
|
||||||
if ($score->entry->audition->hasFlag('seats_published')) {
|
if ($score->entry->audition->hasFlag('seats_published')) {
|
||||||
return redirect()->back()->with('error', 'Cannot delete scores for an entry where seats are published');
|
return redirect()->back()->with('error', 'Cannot delete scores for an entry where seats are published');
|
||||||
}
|
}
|
||||||
|
|
@ -33,6 +35,7 @@ class ScoreController extends Controller
|
||||||
return redirect()->back()->with('error',
|
return redirect()->back()->with('error',
|
||||||
'Cannot delete scores for an entry where advancement is published');
|
'Cannot delete scores for an entry where advancement is published');
|
||||||
}
|
}
|
||||||
|
EntryTotalScore::where('entry_id', $score->entry_id)->delete();
|
||||||
$score->delete();
|
$score->delete();
|
||||||
|
|
||||||
return redirect()->back()->with('success', 'Score Deleted');
|
return redirect()->back()->with('success', 'Score Deleted');
|
||||||
|
|
@ -41,7 +44,7 @@ class ScoreController extends Controller
|
||||||
public function entryScoreSheet(Request $request)
|
public function entryScoreSheet(Request $request)
|
||||||
{
|
{
|
||||||
$existing_sheets = [];
|
$existing_sheets = [];
|
||||||
$entry = Entry::with(['student', 'audition.room.judges'])->find($request->input('entry_id'));
|
$entry = Entry::with(['student', 'audition.room.judges'])->findOrFail($request->input('entry_id'));
|
||||||
|
|
||||||
$publishedCheck = $this->checkIfPublished($entry);
|
$publishedCheck = $this->checkIfPublished($entry);
|
||||||
if ($publishedCheck) {
|
if ($publishedCheck) {
|
||||||
|
|
@ -58,9 +61,7 @@ class ScoreController extends Controller
|
||||||
}
|
}
|
||||||
$scoring_guide = $entry->audition->scoringGuide;
|
$scoring_guide = $entry->audition->scoringGuide;
|
||||||
$subscores = $entry->audition->scoringGuide->subscores->sortBy('display_order');
|
$subscores = $entry->audition->scoringGuide->subscores->sortBy('display_order');
|
||||||
if (! $entry) {
|
|
||||||
return redirect()->route('tabulation.chooseEntry')->with('error', 'Entry not found');
|
|
||||||
}
|
|
||||||
if ($entry->hasFlag('no_show')) {
|
if ($entry->hasFlag('no_show')) {
|
||||||
session()->flash('error',
|
session()->flash('error',
|
||||||
'This entry is marked as a no-show. Entering a score will remove the no-show flag');
|
'This entry is marked as a no-show. Entering a score will remove the no-show flag');
|
||||||
|
|
@ -76,20 +77,32 @@ class ScoreController extends Controller
|
||||||
if ($publishedCheck) {
|
if ($publishedCheck) {
|
||||||
return $publishedCheck;
|
return $publishedCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here we process the submission from the scoring form.
|
||||||
|
* We're expecting submitted data to include an array for each judge.
|
||||||
|
* Each array should be called judge+ the judges ID number
|
||||||
|
* The array should have a key for each subscore and the value of the score submitted
|
||||||
|
*/
|
||||||
foreach ($request->all() as $key => $value) {
|
foreach ($request->all() as $key => $value) {
|
||||||
|
// We're not interested in submission values that don't ahve judge in the name
|
||||||
if (! str_contains($key, 'judge')) {
|
if (! str_contains($key, 'judge')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// Extract the judge ID from the field name and load the user
|
||||||
$judge_id = str_replace('judge', '', $key);
|
$judge_id = str_replace('judge', '', $key);
|
||||||
$judge = User::find($judge_id);
|
$judge = User::find($judge_id);
|
||||||
|
|
||||||
|
// Check for existing scores, if so, tell EnterScores action that we're updating it, otherwise a new score
|
||||||
$existingScore = ScoreSheet::where('entry_id', $entry->id)
|
$existingScore = ScoreSheet::where('entry_id', $entry->id)
|
||||||
->where('user_id', $judge->id)->first();
|
->where('user_id', $judge->id)->first();
|
||||||
if ($existingScore === null) {
|
if ($existingScore === null) {
|
||||||
$existingScore = false;
|
$existingScore = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$scoreRecorder($judge, $entry, $value, $existingScore);
|
$scoreRecorder($judge, $entry, $value, $existingScore);
|
||||||
} catch (ScoreEntryException $e) {
|
} catch (AuditionAdminException $e) {
|
||||||
return redirect()->route('scores.entryScoreSheet', ['entry_id' => $entry->id])
|
return redirect()->route('scores.entryScoreSheet', ['entry_id' => $entry->id])
|
||||||
->with('error', $e->getMessage());
|
->with('error', $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<div class="relative flex items-start">
|
<div class="relative flex items-start">
|
||||||
<div class="flex h-6 items-center">
|
<div class="flex h-6 items-center">
|
||||||
<input id="{{ $id }}" name="{{ $name }}" type="radio" value="{{ $value }}" @if($checked) checked @endif class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
<input id="{{ $id }}" name="{{ $name }}" type="radio" value="{{ $value }}" @if($checked) checked @endif {{ $attributes }} class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3 text-sm leading-6">
|
<div class="ml-3 text-sm leading-6">
|
||||||
<label for="no-filter" class="font-medium text-gray-900">{{ $option_text }}</label>
|
<label for="no-filter" class="font-medium text-gray-900">{{ $option_text }}</label>
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,16 @@
|
||||||
</div>
|
</div>
|
||||||
</x-card.card>
|
</x-card.card>
|
||||||
@endif
|
@endif
|
||||||
<x-card.card class="mx-auto max-w-md" x-show="showButton" x-cloak>
|
<x-card.card class="mx-auto max-w-md" x-show="showButton" x-cloak x-data="{ selected: 'noshow' }">
|
||||||
<x-card.heading>{{ $cardHeading }}</x-card.heading>
|
<x-card.heading>
|
||||||
|
@if($method !== "DELETE")
|
||||||
|
<span x-text="selected === 'noshow' ? 'Confirm No Show' : 'Confirm Fail Prelim'"></span>
|
||||||
|
@else
|
||||||
|
{{ $buttonName }}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
</x-card.heading>
|
||||||
<x-card.list.body>
|
<x-card.list.body>
|
||||||
<x-card.list.row>
|
<x-card.list.row>
|
||||||
{{ $entry->student->full_name() }}
|
{{ $entry->student->full_name() }}
|
||||||
|
|
@ -37,14 +45,21 @@
|
||||||
{{ $entry->audition->name }} #{{ $entry->draw_number ?? ' no draw number' }}
|
{{ $entry->audition->name }} #{{ $entry->draw_number ?? ' no draw number' }}
|
||||||
</x-card.list.row>
|
</x-card.list.row>
|
||||||
</x-card.list.body>
|
</x-card.list.body>
|
||||||
<x-form.form method="{{ $method }}" action="{{route($submitRouteName, $entry)}}" id="{{ $formId }}">
|
<x-form.form method="{{ $method }}" action="{{route($submitRouteName, $entry)}}" id="{{ $formId }}" >
|
||||||
<x-form.footer class="mb-4">
|
<x-form.footer class="mb-4">
|
||||||
@if($buttonName == "Confirm No Show")
|
@if($buttonName == "Confirm No Show")
|
||||||
<x-form.option name="noshow-type" value="noshow" id="noshowoption" option_text="No-Show" checked/>
|
<x-form.option name="noshow-type" value="noshow" id="noshowoption" option_text="No-Show" checked x-on:click="selected = 'noshow'" />
|
||||||
<x-form.option name="noshow-type" value="failprelim" id="failprelimoption" option_text="Fail Prelim"/>
|
<x-form.option name="noshow-type" value="failprelim" id="failprelimoption" option_text="Fail Prelim" x-on:click="selected = 'failprelim'"/>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<x-form.button type="submit">{{ $buttonName }}</x-form.button>
|
<x-form.button type="submit">
|
||||||
|
@if($method !== "DELETE")
|
||||||
|
<span x-text="selected === 'noshow' ? 'Confirm No Show' : 'Confirm Fail Prelim'"></span>
|
||||||
|
@else
|
||||||
|
{{ $buttonName }}
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</x-form.button>
|
||||||
</x-form.footer>
|
</x-form.footer>
|
||||||
</x-form.form>
|
</x-form.form>
|
||||||
</x-card.card>
|
</x-card.card>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,200 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Entry;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->entry = Entry::factory()->create();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('EntryFlagController::noShowSelect', function () {
|
||||||
|
it('presents a from to choose an entry by ID', function () {
|
||||||
|
actAsTab();
|
||||||
|
$this->get(route('entry-flags.noShowSelect'))->assertOk()
|
||||||
|
->assertViewis('tabulation.choose_entry')
|
||||||
|
->assertSee(route('entry-flags.confirmNoShow'));
|
||||||
|
});
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
$this->get(route('entry-flags.noShowSelect'))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->get(route('entry-flags.noShowSelect'))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('EntryFlagController::noShowConfirm', function () {
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
$this->get(route('entry-flags.noShowSelect'))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->get(route('entry-flags.noShowSelect'))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('shows a form to enter a no-show or failed-prelim if the entry has no flags', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->get(route('entry-flags.confirmNoShow', ['entry_id' => $this->entry->id]));
|
||||||
|
$response->assertOk()
|
||||||
|
->assertViewIs('tabulation.no_show_confirm')
|
||||||
|
->assertSee('No-Show')
|
||||||
|
->assertSee('Fail Prelim');
|
||||||
|
});
|
||||||
|
it('does not entertain an invalid entry id', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->get(route('entry-flags.confirmNoShow', ['entry_id' => 999999999]));
|
||||||
|
$response->assertRedirect();
|
||||||
|
});
|
||||||
|
it('does not allow us to set a flag if the relevant audition seats are published', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$this->entry->audition->addFlag('seats_published');
|
||||||
|
$response = $this->get(route('entry-flags.confirmNoShow', ['entry_id' => $this->entry->id]));
|
||||||
|
$response->assertRedirect(route('entry-flags.noShowSelect'))
|
||||||
|
->assertSessionHas('error',
|
||||||
|
'Cannot enter a no-show or failed-prelim for an entry in an audition where seats are published');
|
||||||
|
});
|
||||||
|
it('does not allow us to set a flag if the relevant audition advancement is published', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$this->entry->audition->addFlag('advancement_published');
|
||||||
|
$response = $this->get(route('entry-flags.confirmNoShow', ['entry_id' => $this->entry->id]));
|
||||||
|
$response->assertRedirect(route('entry-flags.noShowSelect'))
|
||||||
|
->assertSessionHas('error',
|
||||||
|
'Cannot enter a no-show or failed-prelim for an entry in an audition where advancement is published');
|
||||||
|
});
|
||||||
|
it('returns the appropriate form if the entry is already a no-show', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$this->entry->addFlag('no_show');
|
||||||
|
$response = $this->get(route('entry-flags.confirmNoShow', ['entry_id' => $this->entry->id]));
|
||||||
|
$response->assertOk()
|
||||||
|
->assertSee('Remove No Show');
|
||||||
|
});
|
||||||
|
it('returns the appropriate form if the entry is already a failed-prelim', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$this->entry->addFlag('failed_prelim');
|
||||||
|
$response = $this->get(route('entry-flags.confirmNoShow', ['entry_id' => $this->entry->id]));
|
||||||
|
$response->assertOk()
|
||||||
|
->assertSee('Remove Failed Prelim');
|
||||||
|
});
|
||||||
|
it('shows scores if they exist', function () {
|
||||||
|
$judge = User::factory()->create();
|
||||||
|
DB::table('score_sheets')->insert([
|
||||||
|
'entry_id' => $this->entry->id,
|
||||||
|
'user_id' => $judge->id,
|
||||||
|
'subscores' => json_encode([
|
||||||
|
3 => [
|
||||||
|
'score' => 12,
|
||||||
|
'subscore_id' => 3,
|
||||||
|
'subscore_name' => 'Subscore 3',
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
'seating_total' => 35,
|
||||||
|
'advancement_total' => 35,
|
||||||
|
]);
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->get(route('entry-flags.confirmNoShow', ['entry_id' => $this->entry->id]));
|
||||||
|
$response->assertOk()
|
||||||
|
->assertViewIs('tabulation.no_show_confirm')
|
||||||
|
->assertSee('Subscore 3');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('EntryFlagController::enterNoShow', function () {
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
$this->post(route('entry-flags.enterNoShow', $this->entry))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->post(route('entry-flags.enterNoShow', $this->entry))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('passes exception from AuditionAdminException', function () {
|
||||||
|
$this->entry->audition->addFlag('seats_published');
|
||||||
|
actAsAdmin();
|
||||||
|
$resposne = $this->post(route('entry-flags.enterNoShow', $this->entry), [
|
||||||
|
'noshow-type' => 'noshow',
|
||||||
|
]);
|
||||||
|
$resposne->assertRedirect(route('entry-flags.noShowSelect'))
|
||||||
|
->assertSessionHas('error',
|
||||||
|
'Cannot enter a no-show for an entry in an audition where seats are published');
|
||||||
|
});
|
||||||
|
it('can set a flag', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->post(route('entry-flags.enterNoShow', $this->entry), [
|
||||||
|
'noshow-type' => 'noshow',
|
||||||
|
]);
|
||||||
|
$response->assertRedirect(route('entry-flags.noShowSelect'))->assertSessionHas('success');
|
||||||
|
expect($this->entry->fresh()->hasFlag('no_show'))->toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('EntryFlagController::removeNoShow', function () {
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
$this->delete(route('entry-flags.undoNoShow', $this->entry))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->delete(route('entry-flags.undoNoShow', $this->entry))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('removes a no-show flag', function () {
|
||||||
|
$this->entry->addFlag('no_show');
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->delete(route('entry-flags.undoNoShow', $this->entry));
|
||||||
|
$response->assertRedirect(route('entry-flags.noShowSelect'))->assertSessionHas('success');
|
||||||
|
expect($this->entry->fresh()->hasFlag('no_show'))->toBeFalse();
|
||||||
|
});
|
||||||
|
it('removes a failed-prelim flag', function () {
|
||||||
|
$this->entry->addFlag('failed_prelim');
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->delete(route('entry-flags.undoNoShow', $this->entry));
|
||||||
|
$response->assertRedirect(route('entry-flags.noShowSelect'))->assertSessionHas('success');
|
||||||
|
expect($this->entry->fresh()->hasFlag('failed_prelim'))->toBeFalse();
|
||||||
|
});
|
||||||
|
it('will not remove flags if the audition seats are published', function () {
|
||||||
|
$this->entry->addFlag('failed_prelim');
|
||||||
|
$this->entry->audition->addFlag('seats_published');
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->delete(route('entry-flags.undoNoShow', $this->entry));
|
||||||
|
$response->assertRedirect(route('entry-flags.noShowSelect'))
|
||||||
|
->assertSessionHas('error',
|
||||||
|
'Cannot undo a no-show or failed-prelim for an entry in an audition where seats are published');
|
||||||
|
expect($this->entry->fresh()->hasFlag('failed_prelim'))->toBeTrue();
|
||||||
|
});
|
||||||
|
it('will not remove flags if the audition advancement is published', function () {
|
||||||
|
$this->entry->addFlag('failed_prelim');
|
||||||
|
$this->entry->audition->addFlag('advancement_published');
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->delete(route('entry-flags.undoNoShow', $this->entry));
|
||||||
|
$response->assertRedirect(route('entry-flags.noShowSelect'))
|
||||||
|
->assertSessionHas('error',
|
||||||
|
'Cannot undo a no-show or failed-prelim for an entry in an audition where advancement is published');
|
||||||
|
expect($this->entry->fresh()->hasFlag('failed_prelim'))->toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('EntryFlagController::undoDecline', function () {
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
$this->delete(route('entry-flags.undoDecline', $this->entry))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->delete(route('entry-flags.undoDecline', $this->entry))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('removes a declined flag', function () {
|
||||||
|
$this->entry->addFlag('declined');
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->delete(route('entry-flags.undoDecline', $this->entry));
|
||||||
|
$response->assertRedirect()->assertSessionHas('success');
|
||||||
|
expect($this->entry->fresh()->hasFlag('declined'))->toBeFalse();
|
||||||
|
});
|
||||||
|
it('will not remove flags if the audition seats are published', function () {
|
||||||
|
$this->entry->addFlag('declined');
|
||||||
|
$this->entry->audition->addFlag('seats_published');
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->delete(route('entry-flags.undoDecline', $this->entry));
|
||||||
|
$response->assertRedirect()
|
||||||
|
->assertSessionHas('error',
|
||||||
|
'Cannot undo a decline for an entry in an audition where seats are published');
|
||||||
|
expect($this->entry->fresh()->hasFlag('declined'))->toBeTrue();
|
||||||
|
});
|
||||||
|
it('will not remove flags if the audition advancement is published', function () {
|
||||||
|
$this->entry->addFlag('declined');
|
||||||
|
$this->entry->audition->addFlag('advancement_published');
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->delete(route('entry-flags.undoDecline', $this->entry));
|
||||||
|
$response->assertRedirect()
|
||||||
|
->assertSessionHas('error',
|
||||||
|
'Cannot undo a no-show or failed-prelim for an entry in an audition where advancement is published');
|
||||||
|
expect($this->entry->fresh()->hasFlag('declined'))->toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,283 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Entry;
|
||||||
|
use App\Models\Room;
|
||||||
|
use App\Models\ScoreSheet;
|
||||||
|
use App\Models\ScoringGuide;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->scoringGuide = ScoringGuide::factory()->create();
|
||||||
|
$this->user = User::factory()->create();
|
||||||
|
$this->entry = Entry::factory()->create();
|
||||||
|
$this->entry->audition->update(['scoring_guide_id' => $this->scoringGuide->id]);
|
||||||
|
$this->room = Room::factory()->create();
|
||||||
|
$this->entry->audition->update(['room_id' => $this->room->id]);
|
||||||
|
$this->judge1 = User::factory()->create();
|
||||||
|
$this->judge2 = User::factory()->create();
|
||||||
|
$this->room->addJudge($this->judge1);
|
||||||
|
$this->room->addJudge($this->judge2);
|
||||||
|
DB::table('score_sheets')->insert([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'entry_id' => $this->entry->id,
|
||||||
|
'subscores' => json_encode([12, 3, 5]),
|
||||||
|
'seating_total' => 1,
|
||||||
|
'advancement_total' => 1,
|
||||||
|
]);
|
||||||
|
$this->scoreSheet = ScoreSheet::first();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ScoreController::chooseEntry', function () {
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
$this->get(route('scores.chooseEntry'))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->get(route('scores.chooseEntry'))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('provides a form to enter an entry id to select an entry to score', function () {
|
||||||
|
actAsTab();
|
||||||
|
$this->get(route('scores.chooseEntry'))->assertOk();
|
||||||
|
actAsAdmin();
|
||||||
|
$this->get(route('scores.chooseEntry'))->assertOk()->assertViewIs('tabulation.choose_entry');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ScoreController::destroyScore', function () {
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
|
||||||
|
$this->delete(route('scores.destroy', $this->scoreSheet))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->delete(route('scores.destroy', $this->scoreSheet))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deletes a score sheet', function () {
|
||||||
|
actAsTab();
|
||||||
|
$response = $this->from(route('scores.chooseEntry'))->delete(route('scores.destroy', $this->scoreSheet));
|
||||||
|
$response->assertRedirect(route('scores.chooseEntry'));
|
||||||
|
expect(ScoreSheet::count())->toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will not delete a score if seats are published in the relative audition', function () {
|
||||||
|
$this->entry->audition->addFlag('seats_published');
|
||||||
|
actAsTab();
|
||||||
|
|
||||||
|
$response = $this->from(route('scores.chooseEntry'))->delete(route('scores.destroy', $this->scoreSheet));
|
||||||
|
$response->assertRedirect(route('scores.chooseEntry'))->assertSessionHas('error',
|
||||||
|
'Cannot delete scores for an entry where seats are published');
|
||||||
|
expect(ScoreSheet::count())->toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will not delete a score if advancement is published in the relative audition', function () {
|
||||||
|
$this->entry->audition->addFlag('advancement_published');
|
||||||
|
actAsTab();
|
||||||
|
|
||||||
|
$response = $this->from(route('scores.chooseEntry'))->delete(route('scores.destroy', $this->scoreSheet));
|
||||||
|
$response->assertRedirect(route('scores.chooseEntry'))->assertSessionHas('error',
|
||||||
|
'Cannot delete scores for an entry where advancement is published');
|
||||||
|
expect(ScoreSheet::count())->toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ScoreController::entryScoreSheet', function () {
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
$this->get(route('scores.entryScoreSheet', $this->entry))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->get(route('scores.entryScoreSheet', $this->entry))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('provides a form to enter a score for an entry', function () {
|
||||||
|
actAsTab();
|
||||||
|
|
||||||
|
$response = $this->get(route('scores.entryScoreSheet', [
|
||||||
|
'entry_id' => $this->entry->id,
|
||||||
|
]));
|
||||||
|
$response->assertOk()->assertSee(route('scores.saveEntryScoreSheet', $this->entry))
|
||||||
|
->assertSee($this->judge1->full_name())
|
||||||
|
->assertSee($this->judge2->full_name());
|
||||||
|
foreach ($this->scoringGuide->subscores as $subscore) {
|
||||||
|
$response->assertSee($subscore->name)
|
||||||
|
->assertSee('judge'.$this->judge1->id.'['.$subscore->id.']')
|
||||||
|
->assertSee('judge'.$this->judge2->id.'['.$subscore->id.']');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it('alerts us if the entry is a no-show', function () {
|
||||||
|
actAsTab();
|
||||||
|
$this->entry->addFlag('no_show');
|
||||||
|
$response = $this->get(route('scores.entryScoreSheet', [
|
||||||
|
'entry_id' => $this->entry->id,
|
||||||
|
]));
|
||||||
|
$response->assertOk()->assertSee(route('scores.saveEntryScoreSheet', $this->entry))
|
||||||
|
->assertSee('This entry is marked as a no-show');
|
||||||
|
});
|
||||||
|
it('alerts us if the entry already has scores and shows the old scores', function () {
|
||||||
|
actAsTab();
|
||||||
|
DB::table('score_sheets')->insert([
|
||||||
|
'user_id' => $this->judge1->id,
|
||||||
|
'entry_id' => $this->entry->id,
|
||||||
|
'seating_total' => 98,
|
||||||
|
'advancement_total' => 98,
|
||||||
|
'subscores' => json_encode([
|
||||||
|
$this->scoringGuide->subscores[0]->id => [
|
||||||
|
'score' => 13,
|
||||||
|
'subscore_id' => $this->scoringGuide->subscores[0]->id,
|
||||||
|
'subscore_name' => $this->scoringGuide->subscores[0]->name,
|
||||||
|
],
|
||||||
|
$this->scoringGuide->subscores[1]->id => [
|
||||||
|
'score' => 23,
|
||||||
|
'subscore_id' => $this->scoringGuide->subscores[1]->id,
|
||||||
|
'subscore_name' => $this->scoringGuide->subscores[1]->name,
|
||||||
|
],
|
||||||
|
$this->scoringGuide->subscores[2]->id => [
|
||||||
|
'score' => 33,
|
||||||
|
'subscore_id' => $this->scoringGuide->subscores[2]->id,
|
||||||
|
'subscore_name' => $this->scoringGuide->subscores[2]->name,
|
||||||
|
],
|
||||||
|
$this->scoringGuide->subscores[3]->id => [
|
||||||
|
'score' => 43,
|
||||||
|
'subscore_id' => $this->scoringGuide->subscores[3]->id,
|
||||||
|
'subscore_name' => $this->scoringGuide->subscores[3]->name,
|
||||||
|
],
|
||||||
|
$this->scoringGuide->subscores[4]->id => [
|
||||||
|
'score' => 53,
|
||||||
|
'subscore_id' => $this->scoringGuide->subscores[4]->id,
|
||||||
|
'subscore_name' => $this->scoringGuide->subscores[4]->name,
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
$response = $this->get(route('scores.entryScoreSheet', [
|
||||||
|
'entry_id' => $this->entry->id,
|
||||||
|
]));
|
||||||
|
$response->assertOk()->assertSee(route('scores.saveEntryScoreSheet', $this->entry))
|
||||||
|
->assertSee('Scores exist')
|
||||||
|
->assertSee('13')
|
||||||
|
->assertSee('23')
|
||||||
|
->assertSee('33')
|
||||||
|
->assertSee('43')
|
||||||
|
->assertSee('53');
|
||||||
|
});
|
||||||
|
it('will not give us a form if seats are published in the relative audition', function () {
|
||||||
|
actAsTab();
|
||||||
|
$this->entry->audition->addFlag('seats_published');
|
||||||
|
$response = $this->get(route('scores.entryScoreSheet', [
|
||||||
|
'entry_id' => $this->entry->id,
|
||||||
|
]));
|
||||||
|
$response->assertRedirect(route('scores.chooseEntry'))->assertSessionHas('error',
|
||||||
|
'Cannot enter scores for entry '.$this->entry->id.'. '.$this->entry->audition->name.' seats are published');
|
||||||
|
});
|
||||||
|
it('will not give us a form if advancement is published in the relative audition', function () {
|
||||||
|
actAsTab();
|
||||||
|
$this->entry->audition->addFlag('advancement_published');
|
||||||
|
$response = $this->get(route('scores.entryScoreSheet', [
|
||||||
|
'entry_id' => $this->entry->id,
|
||||||
|
]));
|
||||||
|
$response->assertRedirect(route('scores.chooseEntry'))->assertSessionHas('error',
|
||||||
|
'Cannot enter scores for entry '.$this->entry->id.'. '.$this->entry->audition->name.' advancement is published');
|
||||||
|
});
|
||||||
|
it('deals with an invalid entry', function () {
|
||||||
|
actAsTab();
|
||||||
|
$this->entry->audition->addFlag('seats_published');
|
||||||
|
$response = $this->get(route('scores.entryScoreSheet', [
|
||||||
|
'entry_id' => 308,
|
||||||
|
]));
|
||||||
|
$response->assertNotFound();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ScoreController::saveEntryScoreSheet', function () {
|
||||||
|
it('does not allow access to guests or normal users', function () {
|
||||||
|
$this->post(route('scores.saveEntryScoreSheet', $this->entry))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->post(route('scores.saveEntryScoreSheet', $this->entry))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('will not post scores to an entry in an audition with published seats', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$this->entry->audition->addFlag('seats_published');
|
||||||
|
$this->post(route('scores.saveEntryScoreSheet', $this->entry))
|
||||||
|
->assertRedirect(route('scores.chooseEntry'))->assertSessionHas('error',
|
||||||
|
'Cannot enter scores for entry '.$this->entry->id.'. '.$this->entry->audition->name.' seats are published');
|
||||||
|
});
|
||||||
|
it('will not post scores to an entry in an audition with published advancement', function () {
|
||||||
|
actAsAdmin();
|
||||||
|
$this->entry->audition->addFlag('advancement_published');
|
||||||
|
$this->post(route('scores.saveEntryScoreSheet', $this->entry))
|
||||||
|
->assertRedirect(route('scores.chooseEntry'))->assertSessionHas('error',
|
||||||
|
'Cannot enter scores for entry '.$this->entry->id.'. '.$this->entry->audition->name.' advancement is published');
|
||||||
|
});
|
||||||
|
it('records scores', function () {
|
||||||
|
actAsTab();
|
||||||
|
ScoreSheet::truncate();
|
||||||
|
$response = $this->post(route('scores.saveEntryScoreSheet', $this->entry), [
|
||||||
|
'judge'.$this->judge1->id => [
|
||||||
|
$this->scoringGuide->subscores[0]->id => 15,
|
||||||
|
$this->scoringGuide->subscores[1]->id => 25,
|
||||||
|
$this->scoringGuide->subscores[2]->id => 45,
|
||||||
|
$this->scoringGuide->subscores[3]->id => 55,
|
||||||
|
$this->scoringGuide->subscores[4]->id => 65,
|
||||||
|
],
|
||||||
|
'judge'.$this->judge2->id => [
|
||||||
|
$this->scoringGuide->subscores[0]->id => 10,
|
||||||
|
$this->scoringGuide->subscores[1]->id => 20,
|
||||||
|
$this->scoringGuide->subscores[2]->id => 40,
|
||||||
|
$this->scoringGuide->subscores[3]->id => 50,
|
||||||
|
$this->scoringGuide->subscores[4]->id => 60,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$response->assertRedirect(route('scores.chooseEntry'))->assertSessionHas('success');
|
||||||
|
expect(ScoreSheet::count())->toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('if student was marked as a no-show, undo that', function () {
|
||||||
|
actAsTab();
|
||||||
|
ScoreSheet::truncate();
|
||||||
|
$this->entry->addFlag('no_show');
|
||||||
|
$response = $this->post(route('scores.saveEntryScoreSheet', $this->entry), [
|
||||||
|
'judge'.$this->judge1->id => [
|
||||||
|
$this->scoringGuide->subscores[0]->id => 15,
|
||||||
|
$this->scoringGuide->subscores[1]->id => 25,
|
||||||
|
$this->scoringGuide->subscores[2]->id => 45,
|
||||||
|
$this->scoringGuide->subscores[3]->id => 55,
|
||||||
|
$this->scoringGuide->subscores[4]->id => 65,
|
||||||
|
],
|
||||||
|
'judge'.$this->judge2->id => [
|
||||||
|
$this->scoringGuide->subscores[0]->id => 10,
|
||||||
|
$this->scoringGuide->subscores[1]->id => 20,
|
||||||
|
$this->scoringGuide->subscores[2]->id => 40,
|
||||||
|
$this->scoringGuide->subscores[3]->id => 50,
|
||||||
|
$this->scoringGuide->subscores[4]->id => 60,
|
||||||
|
],
|
||||||
|
'distractor' => 'nonsense',
|
||||||
|
]);
|
||||||
|
$response->assertRedirect(route('scores.chooseEntry'))->assertSessionHas('success');
|
||||||
|
expect(ScoreSheet::count())->toBe(2);
|
||||||
|
$this->entry->refresh();
|
||||||
|
expect($this->entry->hasFlag('no_show'))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes exceptions from the EnterScore action', function () {
|
||||||
|
actAsTab();
|
||||||
|
ScoreSheet::truncate();
|
||||||
|
$this->entry->addFlag('no_show');
|
||||||
|
$response = $this->post(route('scores.saveEntryScoreSheet', $this->entry), [
|
||||||
|
'judge'.$this->judge1->id => [
|
||||||
|
$this->scoringGuide->subscores[0]->id => 15,
|
||||||
|
$this->scoringGuide->subscores[1]->id => 25,
|
||||||
|
$this->scoringGuide->subscores[2]->id => 45,
|
||||||
|
$this->scoringGuide->subscores[3]->id => 55,
|
||||||
|
$this->scoringGuide->subscores[4]->id => 65,
|
||||||
|
9278 => 33,
|
||||||
|
],
|
||||||
|
'judge'.$this->judge2->id => [
|
||||||
|
$this->scoringGuide->subscores[0]->id => 10,
|
||||||
|
$this->scoringGuide->subscores[1]->id => 20,
|
||||||
|
$this->scoringGuide->subscores[2]->id => 40,
|
||||||
|
$this->scoringGuide->subscores[3]->id => 50,
|
||||||
|
$this->scoringGuide->subscores[4]->id => 60,
|
||||||
|
],
|
||||||
|
'distractor' => 'nonsense',
|
||||||
|
]);
|
||||||
|
$response->assertRedirect(route('scores.entryScoreSheet', ['entry_id' => $this->entry->id]))->assertSessionHas('error', 'Invalid number of scores');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue