Add Scoring Guide controller test
This commit is contained in:
parent
36da3b0e78
commit
2e8d625ab0
|
|
@ -3,14 +3,12 @@
|
|||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\SubscoreDefinitionRequest;
|
||||
use App\Models\ScoringGuide;
|
||||
use App\Models\SubscoreDefinition;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use function abort;
|
||||
use function auditionSetting;
|
||||
use function request;
|
||||
use function response;
|
||||
|
||||
|
|
@ -28,26 +26,19 @@ class ScoringGuideController extends Controller
|
|||
|
||||
public function store()
|
||||
{
|
||||
if (! Auth::user()->is_admin) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
request()->validate([
|
||||
'name' => ['required', 'unique:scoring_guides'],
|
||||
]);
|
||||
|
||||
$guide = ScoringGuide::create([
|
||||
ScoringGuide::create([
|
||||
'name' => request('name'),
|
||||
]);
|
||||
|
||||
return redirect(route('admin.scoring.index'))->with('success', 'Scoring guide created');
|
||||
}
|
||||
|
||||
public function edit(Request $request, ScoringGuide $guide, string $tab = 'detail')
|
||||
public function edit(ScoringGuide $guide, string $tab = 'detail')
|
||||
{
|
||||
if (! Auth::user()->is_admin) {
|
||||
abort(403);
|
||||
}
|
||||
if ($tab == 'tiebreakOrder') {
|
||||
$subscores = SubscoreDefinition::where('scoring_guide_id', $guide->id)->orderBy('tiebreak_order')->get();
|
||||
} else {
|
||||
|
|
@ -59,9 +50,6 @@ class ScoringGuideController extends Controller
|
|||
|
||||
public function update(ScoringGuide $guide)
|
||||
{
|
||||
if (! Auth::user()->is_admin) {
|
||||
abort(403);
|
||||
}
|
||||
request()->validate([
|
||||
'name' => ['required', 'unique:scoring_guides'],
|
||||
]);
|
||||
|
|
@ -75,12 +63,9 @@ class ScoringGuideController extends Controller
|
|||
|
||||
public function destroy(ScoringGuide $guide)
|
||||
{
|
||||
if (! Auth::user()->is_admin) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
if ($guide->auditions()->count() > 0) {
|
||||
return redirect('/admin/scoring')->with('error', 'Cannot delete scoring guide with auditions');
|
||||
return redirect('/admin/scoring')->with('error',
|
||||
'Cannot delete scoring guide being used by one or more auditions');
|
||||
}
|
||||
|
||||
$guide->delete();
|
||||
|
|
@ -88,89 +73,57 @@ class ScoringGuideController extends Controller
|
|||
return redirect('/admin/scoring')->with('success', 'Scoring guide deleted');
|
||||
}
|
||||
|
||||
public function subscore_store(Request $request, ScoringGuide $guide)
|
||||
public function subscore_store(SubscoreDefinitionRequest $request, ScoringGuide $guide)
|
||||
{
|
||||
if (! $guide->exists()) {
|
||||
abort(409);
|
||||
}
|
||||
$validateData = request()->validate([
|
||||
'name' => ['required'],
|
||||
'max_score' => ['required', 'integer'],
|
||||
'weight' => ['required', 'integer'],
|
||||
'for_seating' => ['nullable', 'boolean'],
|
||||
'for_advance' => ['nullable', 'boolean'],
|
||||
]);
|
||||
|
||||
$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;
|
||||
}
|
||||
$validateData = $request->validated();
|
||||
|
||||
// Put the new subscore at the end of the list for both display and tiebreak order
|
||||
$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;
|
||||
|
||||
$subscore = SubscoreDefinition::create([
|
||||
SubscoreDefinition::create([
|
||||
'scoring_guide_id' => $guide->id,
|
||||
'name' => $validateData['name'],
|
||||
'max_score' => $validateData['max_score'],
|
||||
'weight' => $validateData['weight'],
|
||||
'display_order' => $display_order,
|
||||
'tiebreak_order' => $tiebreak_order,
|
||||
'for_seating' => $for_seating,
|
||||
'for_advance' => $for_advance,
|
||||
'for_seating' => $validateData['for_seating'],
|
||||
'for_advance' => $validateData['for_advance'],
|
||||
]);
|
||||
|
||||
return redirect(route('admin.scoring.edit', $guide))->with('success', 'Subscore added');
|
||||
}
|
||||
|
||||
public function subscore_update(ScoringGuide $guide, SubscoreDefinition $subscore)
|
||||
{
|
||||
if (! Auth::user()->is_admin) {
|
||||
abort(403);
|
||||
}
|
||||
if (! $guide->exists() || ! $subscore->exists()) {
|
||||
abort(409);
|
||||
}
|
||||
public function subscore_update(
|
||||
SubscoreDefinitionRequest $request,
|
||||
ScoringGuide $guide,
|
||||
SubscoreDefinition $subscore
|
||||
) {
|
||||
if ($subscore->scoring_guide_id !== $guide->id) { // Make sure the subscore were updating belongs to the guide
|
||||
abort(409);
|
||||
}
|
||||
$validateData = request()->validate([
|
||||
'name' => ['required'],
|
||||
'max_score' => ['required', 'integer'],
|
||||
'weight' => ['required', 'integer'],
|
||||
'for_seating' => ['nullable', 'boolean'],
|
||||
'for_advance' => ['nullable', 'boolean'],
|
||||
]);
|
||||
|
||||
$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;
|
||||
return redirect('/admin/scoring/guides/'.$subscore->scoring_guide_id.'/edit')->with('error',
|
||||
'Cannot update a subscore for a different scoring guide');
|
||||
}
|
||||
$validateData = $validateData = $request->validated();
|
||||
|
||||
$subscore->update([
|
||||
'name' => $validateData['name'],
|
||||
'max_score' => $validateData['max_score'],
|
||||
'weight' => $validateData['weight'],
|
||||
'for_seating' => $for_seating,
|
||||
'for_advance' => $for_advance,
|
||||
'for_seating' => $validateData['for_seating'],
|
||||
'for_advance' => $validateData['for_advance'],
|
||||
]);
|
||||
|
||||
return redirect('/admin/scoring/guides/'.$guide->id.'/edit')->with('success', 'Subscore updated');
|
||||
return redirect(route('admin.scoring.edit', $guide))->with('success', 'Subscore updated');
|
||||
}
|
||||
|
||||
public function subscore_destroy(ScoringGuide $guide, SubscoreDefinition $subscore)
|
||||
{
|
||||
if (! Auth::user()->is_admin) {
|
||||
abort(403);
|
||||
}
|
||||
if (! $guide->exists() || ! $subscore->exists()) {
|
||||
abort(409);
|
||||
}
|
||||
if ($subscore->scoring_guide_id !== $guide->id) { // Make sure the subscore were updating belongs to the guide
|
||||
abort(409);
|
||||
|
||||
return redirect(route('admin.scoring.edit', $subscore->scoring_guide_id))->with('error',
|
||||
'Cannot delete a subscore for a different scoring guide');
|
||||
}
|
||||
|
||||
$subscore->delete();
|
||||
|
|
@ -181,9 +134,6 @@ class ScoringGuideController extends Controller
|
|||
|
||||
public function reorder_display(Request $request)
|
||||
{
|
||||
if (! Auth::user()->is_admin) {
|
||||
abort(403);
|
||||
}
|
||||
$order = $request->order;
|
||||
foreach ($order as $index => $id) {
|
||||
$subscore = SubscoreDefinition::find($id);
|
||||
|
|
@ -196,9 +146,6 @@ class ScoringGuideController extends Controller
|
|||
|
||||
public function reorder_tiebreak(Request $request)
|
||||
{
|
||||
if (! Auth::user()->is_admin) {
|
||||
abort(403);
|
||||
}
|
||||
$order = $request->order;
|
||||
foreach ($order as $index => $id) {
|
||||
$subscore = SubscoreDefinition::find($id);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class SubscoreDefinitionRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth()->user()->is_admin; // Only allow admins to create/update subscores
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$guideId = $this->route('guide')->id; // get the guide ID from route model binding
|
||||
$definition = $this->route('subscore')->id ?? null; // get the guide ID from route model binding
|
||||
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::unique('subscore_definitions') // name must be unique on a guide, allow for the current name
|
||||
->where(fn ($query) => $query->where('scoring_guide_id', $guideId))
|
||||
->ignore($definition),
|
||||
],
|
||||
'max_score' => ['required', 'integer'],
|
||||
'weight' => ['required', 'integer'],
|
||||
'for_seating' => ['sometimes', 'nullable'],
|
||||
'for_advance' => ['sometimes', 'nullable'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function passedValidation()
|
||||
{
|
||||
// Normalize the boolean inputs
|
||||
$this->merge([
|
||||
'for_seating' => $this->has('for_seating') ? (bool) $this->input('for_seating') : false,
|
||||
'for_advance' => $this->has('for_advance') ? (bool) $this->input('for_advance') : false,
|
||||
]);
|
||||
|
||||
// Apply your custom logic
|
||||
if (! auditionSetting('advanceTo')) {
|
||||
$this->merge(['for_seating' => true]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Observers;
|
||||
|
||||
use App\Models\ScoringGuide;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
use function auditionLog;
|
||||
|
||||
|
|
@ -10,7 +11,10 @@ class ScoringGuideObserver
|
|||
{
|
||||
public function created(ScoringGuide $scoringGuide): void
|
||||
{
|
||||
$message = 'Added scoring guide '.$scoringGuide->name.$scoringGuide->name.'(ID #'.$scoringGuide->id.')';
|
||||
if (! Schema::hasTable('audit_log_entries')) {
|
||||
return;
|
||||
}
|
||||
$message = 'Added scoring guide '.$scoringGuide->name.'(ID #'.$scoringGuide->id.')';
|
||||
$affected = ['scoring_guides' => [$scoringGuide->id]];
|
||||
auditionLog($message, $affected);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
aria-describedby="comments-description"
|
||||
name="{{ $name }}"
|
||||
type="checkbox"
|
||||
value="1"
|
||||
@if($checked) checked @endif
|
||||
{{ $attributes->merge(['class' => "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"]) }}>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ it('assigns a user to a school', function () {
|
|||
});
|
||||
|
||||
it('logs the assignment of the user to the school', function () {
|
||||
$this->user->save();
|
||||
($this->assigner)($this->user, $this->school);
|
||||
$logEntry = AuditLogEntry::orderBy('id', 'desc')->first();
|
||||
expect($logEntry->message)->toEqual('Added '.$this->user->full_name().' to '.$this->school->name);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,399 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Audition;
|
||||
use App\Models\ScoringGuide;
|
||||
use App\Models\SubscoreDefinition;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
describe('ScoringGuideController::index', function () {
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->get(route('admin.scoring.index'))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->get(route('admin.scoring.index'))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->get(route('admin.scoring.index'))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
it('ensures that auditions with null for scoring_guide_id are set to zero', function () {
|
||||
$audition = Audition::factory()->create();
|
||||
actAsAdmin();
|
||||
$this->get(route('admin.scoring.index'));
|
||||
$audition->refresh();
|
||||
expect($audition->scoring_guide_id)->toEqual(0);
|
||||
});
|
||||
it('shows the scoring guide index page', function () {
|
||||
actAsAdmin();
|
||||
$this->get(route('admin.scoring.index'))
|
||||
->assertOk()
|
||||
->assertViewHas('guides')
|
||||
->assertViewIs('admin.scoring.index');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::store', function () {
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->post(route('admin.scoring.store'))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->post(route('admin.scoring.store'))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->post(route('admin.scoring.store'))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
it('stores a scoring guide', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->post(route('admin.scoring.store'), [
|
||||
'name' => 'Test Guide',
|
||||
]);
|
||||
$response->assertRedirect(route('admin.scoring.index'));
|
||||
expect(ScoringGuide::count())->toEqual(2)
|
||||
->and(ScoringGuide::orderBy('id', 'desc')->first())->toBeInstanceOf(ScoringGuide::class)
|
||||
->and(ScoringGuide::orderBy('id', 'desc')->first()->name)->toEqual('Test Guide');
|
||||
});
|
||||
it('will not store a scoring guide with a blank name', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->post(route('admin.scoring.store'), [
|
||||
'name' => '',
|
||||
]);
|
||||
$response->assertSessionHasErrors('name');
|
||||
expect(ScoringGuide::count())->toEqual(1);
|
||||
});
|
||||
it('will not store a scoring guide with a duplicate name', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->post(route('admin.scoring.store'), [
|
||||
'name' => 'Test Guide',
|
||||
]);
|
||||
$response = $this->post(route('admin.scoring.store'), [
|
||||
'name' => 'Test Guide',
|
||||
]);
|
||||
$response->assertSessionHasErrors('name');
|
||||
expect(ScoringGuide::count())->toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::edit', function () {
|
||||
beforeEach(function () {
|
||||
$this->guide = ScoringGuide::factory()->create();
|
||||
});
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->get(route('admin.scoring.edit', $this->guide))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->get(route('admin.scoring.edit', $this->guide))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->get(route('admin.scoring.edit', $this->guide))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
it('shows the scoring guide edit page', function () {
|
||||
actAsAdmin();
|
||||
$this->get(route('admin.scoring.edit', $this->guide))
|
||||
->assertOk()
|
||||
->assertViewIs('admin.scoring.edit')
|
||||
->assertViewHas('guide')
|
||||
->assertViewHas('subscores')
|
||||
->assertViewHas('tab');
|
||||
});
|
||||
it('includes links to other tabs for managing subscore order', function () {
|
||||
actAsAdmin();
|
||||
$this->get(route('admin.scoring.edit', $this->guide))
|
||||
->assertSeeInOrder(['href', route('admin.scoring.edit', $this->guide, ['tab' => 'detail'])])
|
||||
->assertSeeInOrder(['href', route('admin.scoring.edit', $this->guide, ['tab' => 'displayOrder'])])
|
||||
->assertSeeInOrder(['href', route('admin.scoring.edit', $this->guide, ['tab' => 'tiebreakOrder'])]);
|
||||
});
|
||||
it('includes forms to edit each subscore', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->get(route('admin.scoring.edit', $this->guide));
|
||||
foreach (SubscoreDefinition::all() as $subscore) {
|
||||
$response->assertSeeInOrder([
|
||||
'POST', 'action', route('admin.scoring.subscore_update', [$this->guide, 'subscore' => $subscore->id]),
|
||||
]);
|
||||
}
|
||||
});
|
||||
it('gets subscores in the correct order fo the specified tab', function () {
|
||||
$tbOrderOn = 1;
|
||||
$displayOrderOn = 10;
|
||||
SubscoreDefinition::truncate();
|
||||
$id = $this->guide->id;
|
||||
$ss1 = SubscoreDefinition::create([
|
||||
'display_order' => 2,
|
||||
'tiebreak_order' => 2,
|
||||
'name' => 'ss1',
|
||||
'scoring_guide_id' => $id,
|
||||
'max_score' => 100,
|
||||
'weight' => 1,
|
||||
'for_advance' => 1,
|
||||
'for_seating' => 1,
|
||||
]);
|
||||
$ss2 = SubscoreDefinition::create([
|
||||
'display_order' => 1,
|
||||
'tiebreak_order' => 3,
|
||||
'name' => 'ss1',
|
||||
'scoring_guide_id' => $id,
|
||||
'max_score' => 100,
|
||||
'weight' => 1,
|
||||
'for_advance' => 1,
|
||||
'for_seating' => 1,
|
||||
]);
|
||||
$ss3 = SubscoreDefinition::create([
|
||||
'display_order' => 3,
|
||||
'tiebreak_order' => 1,
|
||||
'name' => 'ss1',
|
||||
'scoring_guide_id' => $id,
|
||||
'max_score' => 100,
|
||||
'weight' => 1,
|
||||
'for_advance' => 1,
|
||||
'for_seating' => 1,
|
||||
]);
|
||||
actAsAdmin();
|
||||
$response = $this->get(route('admin.scoring.edit', [$this->guide, 'tab' => 'displayOrder']));
|
||||
expect($response->viewData('subscores')[0]->id)->toEqual($ss2->id);
|
||||
$response = $this->get(route('admin.scoring.edit', [$this->guide, 'tab' => 'detail']));
|
||||
expect($response->viewData('subscores')[0]->id)->toEqual($ss2->id);
|
||||
$response = $this->get(route('admin.scoring.edit', [$this->guide, 'tab' => 'tiebreakOrder']));
|
||||
expect($response->viewData('subscores')[0]->id)->toEqual($ss3->id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::update', function () {
|
||||
beforeEach(function () {
|
||||
$this->guide = ScoringGuide::factory()->create();
|
||||
});
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->patch(route('admin.scoring.update', $this->guide))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->patch(route('admin.scoring.update', $this->guide))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->patch(route('admin.scoring.update', $this->guide))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
it('updates a scoring guide', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->patch(route('admin.scoring.update', $this->guide), [
|
||||
'name' => 'Test Guide',
|
||||
]);
|
||||
$response->assertRedirect(route('admin.scoring.edit', $this->guide));
|
||||
expect(ScoringGuide::count())->toEqual(2) // Accounts for guide 0 - no guide assigned
|
||||
->and(ScoringGuide::orderBy('id', 'desc')->first())->toBeInstanceOf(ScoringGuide::class)
|
||||
->and(ScoringGuide::orderBy('id', 'desc')->first()->name)->toEqual('Test Guide');
|
||||
});
|
||||
it('will not duplicate a scoring guide name', function () {
|
||||
actAsAdmin();
|
||||
ScoringGuide::create(['name' => 'Dont Copy Me Bro']);
|
||||
$response = $this->patch(route('admin.scoring.update', $this->guide), [
|
||||
'name' => 'Dont Copy Me Bro',
|
||||
]);
|
||||
$response->assertSessionHasErrors('name');
|
||||
expect($this->guide->fresh()->name)->not()->toEqual('Dont Copy Me Bro');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::destroy', function () {
|
||||
beforeEach(function () {
|
||||
$this->guide = ScoringGuide::factory()->create();
|
||||
});
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->delete(route('admin.scoring.destroy', $this->guide))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->delete(route('admin.scoring.destroy', $this->guide))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->delete(route('admin.scoring.destroy', $this->guide))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
it('deletes a scoring guide', function () {
|
||||
actAsAdmin();
|
||||
$this->delete(route('admin.scoring.destroy', $this->guide))
|
||||
->assertRedirect(route('admin.scoring.index'));
|
||||
expect(ScoringGuide::count())->toEqual(1);
|
||||
expect(ScoringGuide::find($this->guide->id))->toBeNull();
|
||||
});
|
||||
it('will not delete a scoring guide that is assigned to an audition', function () {
|
||||
$audition = Audition::factory()->create(['scoring_guide_id' => $this->guide->id]);
|
||||
actAsAdmin();
|
||||
$this->delete(route('admin.scoring.destroy', $this->guide))
|
||||
->assertRedirect(route('admin.scoring.index'))
|
||||
->assertSessionHas('error', 'Cannot delete scoring guide being used by one or more auditions');
|
||||
expect(ScoringGuide::count())->toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::subscore_store', function () {
|
||||
beforeEach(function () {
|
||||
$this->guide = ScoringGuide::factory()->create();
|
||||
});
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->post(route('admin.scoring.subscore_store',
|
||||
[$this->guide, 'subscore' => $this->guide->id]))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->post(route('admin.scoring.subscore_store',
|
||||
[$this->guide, 'subscore' => $this->guide->id]))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->post(route('admin.scoring.subscore_store',
|
||||
[$this->guide, 'subscore' => $this->guide->id]))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
it('creates a subscore', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->post(route('admin.scoring.subscore_store', [$this->guide, 'subscore' => $this->guide->id]), [
|
||||
'name' => 'Test Subscore',
|
||||
'max_score' => 150,
|
||||
'weight' => 3,
|
||||
'for_advance' => 'on',
|
||||
'for_seating' => 'on',
|
||||
]);
|
||||
$response->assertRedirect(route('admin.scoring.edit', [$this->guide]));
|
||||
expect(SubscoreDefinition::orderBy('id', 'desc')->first()->name)->toEqual('Test Subscore');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::subscore_update', function () {
|
||||
beforeEach(function () {
|
||||
$this->guide = ScoringGuide::factory()->create();
|
||||
$this->testSubscore = SubscoreDefinition::first();
|
||||
$this->testSubscore->name = 'Test Subscore';
|
||||
$this->testSubscore->save();
|
||||
});
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->patch(route('admin.scoring.subscore_update',
|
||||
[$this->guide, 'subscore' => $this->testSubscore->id]))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->patch(route('admin.scoring.subscore_update',
|
||||
[$this->guide, 'subscore' => $this->testSubscore->id]))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->patch(route('admin.scoring.subscore_update',
|
||||
[$this->guide, 'subscore' => $this->testSubscore->id]))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
|
||||
it('can update a subscore', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->patch(route('admin.scoring.subscore_update',
|
||||
['subscore' => $this->testSubscore->id, $this->guide]), [
|
||||
'name' => 'New Name',
|
||||
'max_score' => 150,
|
||||
'weight' => 3,
|
||||
'for_advance' => 'on',
|
||||
'for_seating' => 'on',
|
||||
]);
|
||||
$response->assertRedirect(route('admin.scoring.edit', [$this->guide]));
|
||||
expect(SubscoreDefinition::find($this->testSubscore->id)->name)->toEqual('New Name');
|
||||
});
|
||||
|
||||
it('can update a subscore without changing name', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->patch(route('admin.scoring.subscore_update',
|
||||
['subscore' => $this->testSubscore->id, $this->guide]), [
|
||||
'name' => 'Test Subscore',
|
||||
'max_score' => 90,
|
||||
'weight' => 3,
|
||||
'for_advance' => 'on',
|
||||
'for_seating' => 'on',
|
||||
]);
|
||||
$response->assertRedirect(route('admin.scoring.edit', [$this->guide]));
|
||||
expect(SubscoreDefinition::find($this->testSubscore->id)->name)->toEqual('Test Subscore')
|
||||
->and(SubscoreDefinition::find($this->testSubscore->id)->max_score)->toEqual(90);
|
||||
});
|
||||
|
||||
it('will not update a subscore for a different guide', function () {
|
||||
$guide2 = ScoringGuide::factory()->create();
|
||||
actAsAdmin();
|
||||
$response = $this->patch(route('admin.scoring.subscore_update',
|
||||
['subscore' => $this->testSubscore->id, $guide2]), [
|
||||
'name' => 'Test Subscore',
|
||||
'max_score' => 90,
|
||||
'weight' => 3,
|
||||
'for_advance' => 'on',
|
||||
'for_seating' => 'on',
|
||||
]
|
||||
);
|
||||
$response->assertSessionHas('error', 'Cannot update a subscore for a different scoring guide')
|
||||
->assertRedirect(route('admin.scoring.edit', [$this->guide]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::subscore_destroy', function () {
|
||||
beforeEach(function () {
|
||||
$this->guide = ScoringGuide::factory()->create();
|
||||
$this->testSubscore = SubscoreDefinition::first();
|
||||
$this->testSubscore->name = 'Test Subscore';
|
||||
$this->testSubscore->save();
|
||||
});
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->delete(route('admin.scoring.subscore_destroy',
|
||||
['subscore' => $this->guide, $this->testSubscore->id]))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->delete(route('admin.scoring.subscore_destroy',
|
||||
['subscore' => $this->guide, $this->testSubscore->id]))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->delete(route('admin.scoring.subscore_destroy',
|
||||
['subscore' => $this->guide, $this->testSubscore->id]))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
it('can delete a subscore', function () {
|
||||
actAsAdmin();
|
||||
$response = $this->delete(route('admin.scoring.subscore_destroy',
|
||||
['subscore' => $this->guide, $this->testSubscore->id]));
|
||||
$response->assertRedirect(route('admin.scoring.edit', [$this->guide]));
|
||||
expect(SubscoreDefinition::find($this->testSubscore->id))->toBeNull();
|
||||
});
|
||||
it('will not delete a subscore for a different guide', function () {
|
||||
$guide2 = ScoringGuide::factory()->create();
|
||||
actAsAdmin();
|
||||
$response = $this->delete(route('admin.scoring.subscore_destroy',
|
||||
[$guide2, $this->testSubscore->id]));
|
||||
expect(SubscoreDefinition::find($this->testSubscore->id))->not()->toBeNull();
|
||||
$response->assertSessionHas('error', 'Cannot delete a subscore for a different scoring guide')
|
||||
->assertRedirect(route('admin.scoring.edit', $this->guide));
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::reorder_display', function () {
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->post(route('admin.scoring.reorder_display'))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->post(route('admin.scoring.reorder_display'))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->post(route('admin.scoring.reorder_display'))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
|
||||
it('can reorder display order', function () {
|
||||
$sg = ScoringGuide::factory()->create();
|
||||
SubscoreDefinition::truncate();
|
||||
$ss1 = SubscoreDefinition::factory()->create(['scoring_guide_id' => $sg->id, 'display_order' => 1]);
|
||||
$ss2 = SubscoreDefinition::factory()->create(['scoring_guide_id' => $sg->id, 'display_order' => 2]);
|
||||
$ss3 = SubscoreDefinition::factory()->create(['scoring_guide_id' => $sg->id, 'display_order' => 3]);
|
||||
|
||||
actAsAdmin();
|
||||
$response = $this->post(route('admin.scoring.reorder_display'), [
|
||||
'order' => [$ss2->id, $ss1->id, $ss3->id],
|
||||
]);
|
||||
$response->assertJson(['status' => 'success']);
|
||||
$ss1->refresh();
|
||||
$ss2->refresh();
|
||||
$ss3->refresh();
|
||||
expect($ss1->display_order)->toEqual(2);
|
||||
expect($ss2->display_order)->toEqual(1);
|
||||
expect($ss3->display_order)->toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ScoringGuideController::reorder_tiebreak', function () {
|
||||
it('denies access to a non-admin user', function () {
|
||||
$this->post(route('admin.scoring.reorder_tiebreak'))->assertRedirect(route('home'));
|
||||
actAsNormal();
|
||||
$this->post(route('admin.scoring.reorder_tiebreak'))->assertRedirect(route('dashboard'));
|
||||
actAsTab();
|
||||
$this->post(route('admin.scoring.reorder_tiebreak'))->assertRedirect(route('dashboard'));
|
||||
});
|
||||
|
||||
it('can reorder display order', function () {
|
||||
$sg = ScoringGuide::factory()->create();
|
||||
SubscoreDefinition::truncate();
|
||||
$ss1 = SubscoreDefinition::factory()->create(['scoring_guide_id' => $sg->id, 'tiebreak_order' => 1]);
|
||||
$ss2 = SubscoreDefinition::factory()->create(['scoring_guide_id' => $sg->id, 'tiebreak_order' => 2]);
|
||||
$ss3 = SubscoreDefinition::factory()->create(['scoring_guide_id' => $sg->id, 'tiebreak_order' => 3]);
|
||||
|
||||
actAsAdmin();
|
||||
$response = $this->post(route('admin.scoring.reorder_tiebreak'), [
|
||||
'order' => [$ss3->id, $ss2->id, $ss1->id],
|
||||
]);
|
||||
$response->assertJson(['status' => 'success']);
|
||||
$ss1->refresh();
|
||||
$ss2->refresh();
|
||||
$ss3->refresh();
|
||||
expect($ss1->tiebreak_order)->toEqual(3);
|
||||
expect($ss2->tiebreak_order)->toEqual(2);
|
||||
expect($ss3->tiebreak_order)->toEqual(1);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue