Write tests - Write tests for what was done to this point that will be kept #11

Merged
okorpheus merged 61 commits from write-tests into master 2024-07-05 21:21:32 +00:00
5 changed files with 226 additions and 13 deletions
Showing only changes of commit d21324b71b - Show all commits

View File

@ -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']);

View File

@ -18,9 +18,10 @@
<div class="border-b border-gray-200">
<nav class="-mb-px flex" aria-label="Tabs">
<!-- Current: "border-indigo-500 text-indigo-600", Default: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700" -->
<a href="{{ request()->getPathInfo() }}?tab=detail" class="{{ $tab == 'detail' ? $active_classes : $normal_classes }}">Details</a>
<a href="{{ request()->getPathInfo() }}?tab=displayOrder" class="{{ $tab == 'displayOrder' ? $active_classes : $normal_classes }}">Display Order</a>
<a href="{{ request()->getPathInfo() }}?tab=tiebreakOrder" class="{{ $tab == 'tiebreakOrder' ? $active_classes : $normal_classes }}">Tiebreak Order</a>
<a href="{{ route('admin.scoring.edit',['guide'=>$guide, 'tab'=>'detail']) }}" class="{{ $tab == 'detail' ? $active_classes : $normal_classes }}">Details</a>
<a href="{{ route('admin.scoring.edit',['guide'=>$guide, 'tab'=>'displayOrder']) }}" class="{{ $tab == 'displayOrder' ? $active_classes : $normal_classes }}">Display Order</a>
{{-- <a href="{{ request()->getPathInfo() }}?tab=tiebreakOrder" class="{{ $tab == 'tiebreakOrder' ? $active_classes : $normal_classes }}">Tiebreak Order</a>--}}
<a href="{{ route('admin.scoring.edit',['guide'=>$guide, 'tab'=>'tiebreakOrder']) }}" class="{{ $tab == 'tiebreakOrder' ? $active_classes : $normal_classes }}">Tiebreak Order</a>
</nav>
</div>
</div>

View File

@ -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

View File

@ -0,0 +1,155 @@
<?php
use App\Models\ScoringGuide;
use App\Models\SubscoreDefinition;
use App\Settings;
use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\get;
use function Pest\Laravel\post;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->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([
'<tr',
'<td', $subscore->name, '</td>',
'<td', $subscore->max_score, '</td>',
'<td', $subscore->weight, '</td>',
'<td', ($subscore->for_seating) ? 'Yes' : 'No', '</td>',
'<td', ($subscore->for_advance) ? 'Yes' : 'No', '</td>',
], 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([
'<tr',
'<td', $subscore->name, '</td>',
'<td', $subscore->max_score, '</td>',
'<td', $subscore->weight, '</td>',
], false);
$response->assertDontSee('Yes</td>', false);
$response->assertDontSee('No</td>', 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();
});

View File

@ -0,0 +1,54 @@
<?php
use App\Models\ScoringGuide;
use App\Models\SubscoreDefinition;
use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\get;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->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,
]);
});