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 160 additions and 10 deletions
Showing only changes of commit af9bc432a3 - Show all commits

View File

@ -14,16 +14,14 @@ use function compact;
use function redirect;
use function request;
use function response;
use function to_route;
use function view;
class AuditionController extends Controller
{
public function index()
{
if (! Auth::user()->is_admin) {
abort(403);
}
$auditions = Audition::with(['event', 'entries'])->orderBy('score_order')->orderBy('created_at', 'desc')->get();
$auditions = Audition::with(['event'])->withCount('entries')->orderBy('score_order')->orderBy('created_at', 'desc')->get();
return view('admin.auditions.index', ['auditions' => $auditions]);
}
@ -68,7 +66,7 @@ class AuditionController extends Controller
'for_advancement' => $validData['for_advancement'],
]);
return redirect('/admin/auditions');
return to_route('admin.auditions.index')->with('success', 'Audition created successfully');
}
public function edit(Audition $audition)
@ -112,7 +110,7 @@ class AuditionController extends Controller
'for_advancement' => $validData['for_advancement'],
]);
return redirect('/admin/auditions');
return to_route('admin.auditions.index')->with('success', 'Audition updated successfully');
}
public function reorder(Request $request)

View File

@ -62,4 +62,17 @@ class AuditionFactory extends Factory
fn (array $attributes) => ['entry_deadline' => $entryDeadline ?? Carbon::yesterday()]
);
}
public function seatingOnly(): self
{
return $this->state(
fn (array $attributes) => ['for_advancement' => 0]
);
}
public function advancementOnly(): self
{
return $this->state(
fn (array $attributes) => ['for_seating' => 0]
);
}
}

View File

@ -1,11 +1,11 @@
<x-layout.app>
<x-slot:page_title>Audition Administration</x-slot:page_title>
<x-card.card>
<x-table.table with_title_area sortable="false">
<x-table.table with_title_area sortable="false" id="auditions-table">
<x-slot:title class="ml-3">Auditions</x-slot:title>
<x-slot:subtitle class="ml-3">Drag to reorder. Double click to edit.</x-slot:subtitle>
<x-slot:title_block_right class="mr-3">
<x-form.button href="/admin/auditions/create">New Audition</x-form.button>
<x-form.button href="{{ route('admin.auditions.create') }}">New Audition</x-form.button>
</x-slot:title_block_right>
<thead>
@ -27,7 +27,7 @@
<div x-data="sortableList()" x-init="init">
<x-table.body id="sortable-list">
@foreach($auditions as $audition)
<tr data-id="{{ $audition->id }}"
<tr data-id="{{ $audition->id }}" id="auditionRow-{{ $audition->id }}"
@dblclick="window.location.href='/admin/auditions/{{ $audition->id }}/edit'">
<x-table.td>{{ $audition->event->name }}</x-table.td>
<x-table.td>{{ $audition->name }}</x-table.td>
@ -50,7 +50,7 @@
@endif
</x-table.td>
@endif
<x-table.td>{{ $audition->entries->count() }}</x-table.td>
<x-table.td>{{ $audition->entries_count }}</x-table.td>
</tr>
@endforeach
</x-table.body>

View File

@ -0,0 +1,90 @@
<?php
use App\Models\Audition;
use App\Models\Event;
use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\get;
use function Pest\Laravel\post;
uses(RefreshDatabase::class);
it('allows only an admin to manage auditions', function () {
get((route('admin.auditions.create')))
->assertRedirect(route('home'));
actAsNormal();
get((route('admin.auditions.create')))
->assertRedirect('/dashboard')
->assertSessionHas('error', 'You are not authorized to perform this action');
actasAdmin();
get((route('admin.auditions.create')))
->assertOk();
});
it('shows necessary fields', function () {
// Arrange
actAsAdmin();
// Act & Assert
get(route('admin.auditions.create'))
->assertOk()
->assertSee(route('admin.auditions.store'))
->assertSee('name="event_id"', false)
->assertSee('name="name"', false)
->assertSee('name="entry_deadline"', false)
->assertSee('name="entry_fee"', false)
->assertSee('name="minimum_grade"', false)
->assertSee('name="maximum_grade"', false)
->assertSee('name="for_seating"', false)
->assertSee('name="for_advancement"', false);
});
it('allows an administrator to create auditions', function () {
// Arrange
$newEvent = Event::factory()->create();
$changes = [
'event_id' => $newEvent->id,
'name' => 'New Name',
'entry_deadline' => '1978-01-01',
'entry_fee' => 10000,
'minimum_grade' => 3,
'maximum_grade' => 8,
'for_advancement' => 'on',
];
actAsAdmin();
// Act
$response = post(route('admin.auditions.store'), $changes);
// Assert
/** @noinspection PhpUnhandledExceptionInspection */
$response->assertRedirect(route('admin.auditions.index'))
->assertSessionHasNoErrors()
->assertSessionHas('success', 'Audition created successfully');
$checkAudition = Audition::latest()->first();
expect($checkAudition->event_id)->toBe($newEvent->id)
->and($checkAudition->name)->toBe($changes['name'])
->and($checkAudition->entry_deadline)->toBe($changes['entry_deadline'])
->and($checkAudition->entry_fee)->toBe($changes['entry_fee'] * 100)
->and($checkAudition->minimum_grade)->toBe($changes['minimum_grade'])
->and($checkAudition->maximum_grade)->toBe($changes['maximum_grade'])
->and($checkAudition->for_seating)->toBe(0)
->and($checkAudition->for_advancement)->toBe(1);
});
it('does not allow a normal user or guest to create an audition', function () {
// Arrange
$precount = Audition::count();
$newEvent = Event::factory()->create();
$changes = [
'event_id' => $newEvent->id,
'name' => 'New Name',
'entry_deadline' => '1978-01-01',
'entry_fee' => 10000,
'minimum_grade' => 3,
'maximum_grade' => 8,
'for_advancement' => 'on',
];
// Act & Assert
post(route('admin.auditions.store'), $changes)
->assertRedirect(route('home'));
actAsNormal();
post(route('admin.auditions.store'), $changes)
->assertRedirect('/dashboard')
->assertSessionHas('error', 'You are not authorized to perform this action');
expect(Audition::count())->toBe($precount);
});

View File

@ -0,0 +1,49 @@
<?php
use App\Models\Audition;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Sinnbeck\DomAssertions\Asserts\AssertElement;
use function Pest\Laravel\get;
uses(RefreshDatabase::class);
it('allows only an admin to manage auditions', function () {
get((route('admin.auditions.index')))
->assertRedirect(route('home'));
actAsNormal();
get((route('admin.auditions.index')))
->assertRedirect('/dashboard')
->assertSessionHas('error', 'You are not authorized to perform this action');
actasAdmin();
get((route('admin.auditions.index')))
->assertOk();
});
it('has a link to add a new audition', function () {
// Arrange
actAsAdmin();
// Act & Assert
get((route('admin.auditions.index')))
->assertOk()
->assertSee('New Audition')
->assertSee(route('admin.auditions.create'));
});
it('shows audition data', function () {
// Arrange
$auditions = Audition::factory()->count(10)->create();
actAsAdmin();
// Act & Assert
$response = get((route('admin.auditions.index')));
$response->assertOk();
foreach ($auditions as $audition) {
$response->assertElementExists('#auditionRow-'.$audition->id,
function (AssertElement $element) use ($audition) {
$element->containsText($audition->event->name)
->containsText($audition->name)
->containsText($audition->entry_deadline)
->containsText($audition->display_fee())
->containsText($audition->minimum_grade.' - '.$audition->maximum_grade)
->containsText($audition->entries->count());
});
}
});