add test for admin EntryController

This commit is contained in:
Matt Young 2025-07-08 23:07:28 -05:00
parent 4963124d22
commit fa25e76c5b
5 changed files with 207 additions and 69 deletions

View File

@ -4,17 +4,13 @@ namespace App\Http\Controllers\Admin;
use App\Actions\Entries\CreateEntry; use App\Actions\Entries\CreateEntry;
use App\Actions\Entries\UpdateEntry; use App\Actions\Entries\UpdateEntry;
use App\Exceptions\AuditionAdminException;
use App\Exceptions\ManageEntryException;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests\EntryStoreRequest; use App\Http\Requests\EntryStoreRequest;
use App\Models\Audition; use App\Models\Audition;
use App\Models\AuditLogEntry;
use App\Models\Entry; use App\Models\Entry;
use App\Models\School; use App\Models\School;
use App\Models\Seat; use App\Models\Seat;
use App\Models\Student; use App\Models\Student;
use App\Services\ScoreService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use function auditionSetting; use function auditionSetting;
@ -68,7 +64,6 @@ class EntryController extends Controller
if (isset($filters['entry_type']) && $filters['entry_type']) { if (isset($filters['entry_type']) && $filters['entry_type']) {
// TODO define actions for each possible type filter from index.blade.php of the admin entry // TODO define actions for each possible type filter from index.blade.php of the admin entry
match ($filters['entry_type']) { match ($filters['entry_type']) {
'all' => null,
'seats' => $entries->where('for_seating', true), 'seats' => $entries->where('for_seating', true),
'advancement' => $entries->where('for_advancement', true), 'advancement' => $entries->where('for_advancement', true),
'seatsOnly' => $entries->where('for_seating', true)->where('for_advancement', false), 'seatsOnly' => $entries->where('for_seating', true)->where('for_advancement', false),
@ -110,11 +105,16 @@ class EntryController extends Controller
public function store(EntryStoreRequest $request, CreateEntry $creator) public function store(EntryStoreRequest $request, CreateEntry $creator)
{ {
$validData = $request->validatedWithEnterFor(); $validData = $request->validatedWithEnterFor();
try {
$entry = $creator($validData['student_id'], $validData['audition_id'], $enter_for); /** @noinspection PhpUnhandledExceptionInspection */
} catch (ManageEntryException $ex) { $entry = $creator(
return redirect()->route('admin.entries.index')->with('error', $ex->getMessage()); student: $validData['student_id'],
} audition: $validData['audition_id'],
for_seating: $validData['for_seating'],
for_advancement: $validData['for_advancement'],
late_fee_waived: $validData['late_fee_waived'],
);
if ($validData['late_fee_waived']) { if ($validData['late_fee_waived']) {
$entry->addFlag('late_fee_waived'); $entry->addFlag('late_fee_waived');
} }
@ -122,7 +122,7 @@ class EntryController extends Controller
return redirect(route('admin.entries.index'))->with('success', 'The entry has been added.'); return redirect(route('admin.entries.index'))->with('success', 'The entry has been added.');
} }
public function edit(Entry $entry, ScoreService $scoreService) public function edit(Entry $entry)
{ {
if ($entry->audition->hasFlag('seats_published')) { if ($entry->audition->hasFlag('seats_published')) {
return to_route('admin.entries.index')->with('error', return to_route('admin.entries.index')->with('error',
@ -136,31 +136,33 @@ class EntryController extends Controller
$students = Student::with('school')->orderBy('last_name')->orderBy('first_name')->get(); $students = Student::with('school')->orderBy('last_name')->orderBy('first_name')->get();
$auditions = Audition::orderBy('score_order')->get(); $auditions = Audition::orderBy('score_order')->get();
$scores = $entry->scoreSheets()->with('audition', 'judge')->get(); // TODO: When updating Laravel, can we use the chaperone method I heard about ot load the entry back into the score
foreach ($scores as $score) { $scores = $entry->scoreSheets()->with('audition', 'judge', 'entry')->get();
$score->entry = $entry;
$score->valid = $scoreService->isScoreSheetValid($score);
$score->seating_total_score = $score->seating_total ?? 0;
$score->advancement_total_score = $score->advancement_total ?? 0;
}
return view('admin.entries.edit', compact('entry', 'students', 'auditions', 'scores')); return view('admin.entries.edit', compact('entry', 'students', 'auditions', 'scores'));
} }
public function update(Request $request, Entry $entry, UpdateEntry $updater) public function update(Request $request, Entry $entry, UpdateEntry $updater)
{ {
if ($entry->audition->hasFlag('seats_published')) { // If the entry's current audition is published, we can't change it
if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advancement_published')) {
return to_route('admin.entries.index')->with('error', return to_route('admin.entries.index')->with('error',
'Entries in auditions with seats published cannot be modified'); 'Entries in published auditions cannot be modified');
} }
if ($entry->audition->hasFlag('advancement_published')) {
return to_route('admin.entries.index')->with('error',
'Entries in auditions with advancement results published cannot be modified');
}
$validData = request()->validate([ $validData = request()->validate([
'audition_id' => ['required', 'exists:auditions,id'], 'audition_id' => ['required', 'exists:auditions,id'],
'late_fee_waived' => ['sometimes'],
'for_seating' => ['sometimes'],
'for_advancement' => ['sometimes'],
]); ]);
$proposedAudition = Audition::find($validData['audition_id']);
// If the entry's new audition is published, we can't change it
if ($proposedAudition->hasFlag('seats_published') || $proposedAudition->hasFlag('advancement_published')) {
return to_route('admin.entries.index')->with('error',
'Entries cannot be moved to published auditions');
}
$validData['for_seating'] = $request->get('for_seating') ? 1 : 0; $validData['for_seating'] = $request->get('for_seating') ? 1 : 0;
$validData['for_advancement'] = $request->get('for_advancement') ? 1 : 0; $validData['for_advancement'] = $request->get('for_advancement') ? 1 : 0;
@ -170,11 +172,10 @@ class EntryController extends Controller
if (! auditionSetting('advanceTo')) { if (! auditionSetting('advanceTo')) {
$validData['for_seating'] = 1; $validData['for_seating'] = 1;
} }
try {
$updater($entry, $validData); /** @noinspection PhpUnhandledExceptionInspection */
} catch (AuditionAdminException $e) { $updater($entry, $validData);
return redirect()->route('admin.entries.index')->with('error', $e->getMessage());
}
if ($validData['late_fee_waived']) { if ($validData['late_fee_waived']) {
$entry->addFlag('late_fee_waived'); $entry->addFlag('late_fee_waived');
} else { } else {
@ -184,17 +185,13 @@ class EntryController extends Controller
return to_route('admin.entries.index')->with('success', 'Entry updated successfully'); return to_route('admin.entries.index')->with('success', 'Entry updated successfully');
} }
public function destroy(Request $request, Entry $entry) public function destroy(Entry $entry)
{ {
if ($entry->audition->hasFlag('seats_published')) { if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advancement_published')) {
return to_route('admin.entries.index')->with('error', return to_route('admin.entries.index')->with('error',
'Entries in auditions with seats published cannot be deleted'); 'Entries in published auditions cannot be deleted');
} }
if ($entry->audition->hasFlag('advancement_published')) {
return to_route('admin.entries.index')->with('error',
'Entries in auditions with advancement results published cannot be deleted');
}
if (Seat::where('entry_id', $entry->id)->exists()) { if (Seat::where('entry_id', $entry->id)->exists()) {
return redirect()->route('admin.entries.index')->with('error', 'Cannot delete an entry that is seated'); return redirect()->route('admin.entries.index')->with('error', 'Cannot delete an entry that is seated');
} }
@ -203,21 +200,7 @@ class EntryController extends Controller
return redirect()->route('admin.entries.index')->with('error', return redirect()->route('admin.entries.index')->with('error',
'Cannot delete an entry that has been scored'); 'Cannot delete an entry that has been scored');
} }
if (auth()->user()) {
$message = 'Deleted entry '.$entry->id;
$affected = [
'entries' => [$entry->id],
'auditions' => [$entry->audition_id],
'schools' => [$entry->student->school_id],
'students' => [$entry->student_id],
];
AuditLogEntry::create([
'user' => auth()->user()->email,
'ip_address' => request()->ip(),
'message' => $message,
'affected' => $affected,
]);
}
$entry->delete(); $entry->delete();
return redirect()->route('admin.entries.index')->with('success', 'Entry Deleted'); return redirect()->route('admin.entries.index')->with('success', 'Entry Deleted');

View File

@ -49,7 +49,7 @@ class ScoreSheet extends Model
// this function is used at resources/views/tabulation/entry_score_sheet.blade.php // this function is used at resources/views/tabulation/entry_score_sheet.blade.php
} }
public function testValidity() public function testValidity(): bool
{ {
return $this->audition->judges->contains('id', $this->user_id); return $this->audition->judges->contains('id', $this->user_id);
} }

View File

@ -88,12 +88,14 @@
<div class="grid grid-cols-2 border-b"> <div class="grid grid-cols-2 border-b">
<span class="font-semibold text-sm">{{ $score->judge->full_name() }}</span> <span class="font-semibold text-sm">{{ $score->judge->full_name() }}</span>
<span class="text-right mb-2"> <span class="text-right mb-2">
<x-delete-resource-modal @if(! $score->entry->audition->hasFlag('seats_published') && ! $score->entry->audition->hasFlag('advancement_published'))
size="15" <x-delete-resource-modal
action="{{route('scores.destroy',$score->id)}}" size="15"
title="Delete score"> action="{{route('scores.destroy',$score->id)}}"
title="Delete score">
Confirm you would like to delete the {{ $score->entry->audition->name }} score for {{ $score->entry->student->full_name() }} by {{ $score->judge->full_name() }}. Confirm you would like to delete the {{ $score->entry->audition->name }} score for {{ $score->entry->student->full_name() }} by {{ $score->judge->full_name() }}.
</x-delete-resource-modal> </x-delete-resource-modal>
@endif
</span> </span>
</div> </div>
@foreach($score->subscores as $subscore) @foreach($score->subscores as $subscore)
@ -105,16 +107,16 @@
<p class="grid grid-cols-2 border-b"> <p class="grid grid-cols-2 border-b">
<span <span
class="font-semibold text-sm">{{ auditionSetting('auditionAbbreviation') }} Total</span> class="font-semibold text-sm">{{ auditionSetting('auditionAbbreviation') }} Total</span>
<span class="text-right font-semibold">{{ $score->seating_total_score }}</span> <span class="text-right font-semibold">{{ $score->seating_total }}</span>
</p> </p>
@if( auditionSetting('advanceTo')) @if( auditionSetting('advanceTo'))
<p class="grid grid-cols-2 border-b"> <p class="grid grid-cols-2 border-b">
<span class="font-semibold text-sm">{{ auditionSetting('advanceTo') }} Total</span> <span class="font-semibold text-sm">{{ auditionSetting('advanceTo') }} Total</span>
<span class="text-right font-semibold">{{ $score->advancement_total_score }}</span> <span class="text-right font-semibold">{{ $score->advancement_total }}</span>
</p> </p>
@endif @endif
@if(! $score->valid)) @if(! $score->testValidity())
<div class="bg-red-500 text-white p-2 rounded mt-2"> <div class="bg-red-500 text-white p-2 rounded mt-2">
<p class="text-sm">This score is invalid</p> <p class="text-sm">This score is invalid</p>
</div> </div>

View File

@ -1,11 +1,16 @@
<?php <?php
use App\Models\Audition; use App\Models\Audition;
use App\Models\Ensemble;
use App\Models\Entry; use App\Models\Entry;
use App\Models\Event; use App\Models\Event;
use App\Models\Student; use App\Models\Student;
use App\Models\User;
use App\Settings;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\assertDatabaseMissing;
uses(RefreshDatabase::class); uses(RefreshDatabase::class);
beforeEach(function () { beforeEach(function () {
@ -57,7 +62,6 @@ describe('EntryController::index', function () {
'id' => $this->entry4->id, 'id' => $this->entry4->id,
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$response->assertSee($this->entry4->student->full_name()) $response->assertSee($this->entry4->student->full_name())
->assertDontSee($this->entry2->student->full_name()); ->assertDontSee($this->entry2->student->full_name());
}); });
@ -68,7 +72,6 @@ describe('EntryController::index', function () {
'first_name' => $this->entry4->student->first_name, 'first_name' => $this->entry4->student->first_name,
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$response->assertSee($this->entry4->student->full_name()) $response->assertSee($this->entry4->student->full_name())
->assertDontSee($this->entry2->student->full_name()); ->assertDontSee($this->entry2->student->full_name());
}); });
@ -79,7 +82,6 @@ describe('EntryController::index', function () {
'last_name' => $this->entry4->student->last_name, 'last_name' => $this->entry4->student->last_name,
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$response->assertSee($this->entry4->student->full_name()) $response->assertSee($this->entry4->student->full_name())
->assertDontSee($this->entry2->student->full_name()); ->assertDontSee($this->entry2->student->full_name());
}); });
@ -90,7 +92,6 @@ describe('EntryController::index', function () {
'audition' => $this->entry1->audition_id, 'audition' => $this->entry1->audition_id,
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$returnedEntries = $response->viewData('entries'); $returnedEntries = $response->viewData('entries');
expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue() expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue()
->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse() ->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse()
@ -104,7 +105,6 @@ describe('EntryController::index', function () {
'school' => $this->entry1->student->school_id, 'school' => $this->entry1->student->school_id,
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$returnedEntries = $response->viewData('entries'); $returnedEntries = $response->viewData('entries');
expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue() expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue()
->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse() ->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse()
@ -118,7 +118,6 @@ describe('EntryController::index', function () {
'grade' => 9, 'grade' => 9,
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$returnedEntries = $response->viewData('entries'); $returnedEntries = $response->viewData('entries');
expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue() expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue()
->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse() ->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse()
@ -132,7 +131,6 @@ describe('EntryController::index', function () {
'entry_type' => 'seats', 'entry_type' => 'seats',
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$returnedEntries = $response->viewData('entries'); $returnedEntries = $response->viewData('entries');
expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue() expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue()
->and($returnedEntries->contains('id', $this->entry2->id))->toBeTrue() ->and($returnedEntries->contains('id', $this->entry2->id))->toBeTrue()
@ -146,7 +144,6 @@ describe('EntryController::index', function () {
'entry_type' => 'advancement', 'entry_type' => 'advancement',
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$returnedEntries = $response->viewData('entries'); $returnedEntries = $response->viewData('entries');
expect($returnedEntries->contains('id', $this->entry1->id))->toBeFalse() expect($returnedEntries->contains('id', $this->entry1->id))->toBeFalse()
->and($returnedEntries->contains('id', $this->entry2->id))->toBeTrue() ->and($returnedEntries->contains('id', $this->entry2->id))->toBeTrue()
@ -160,7 +157,6 @@ describe('EntryController::index', function () {
'entry_type' => 'seatsOnly', 'entry_type' => 'seatsOnly',
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$returnedEntries = $response->viewData('entries'); $returnedEntries = $response->viewData('entries');
expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue() expect($returnedEntries->contains('id', $this->entry1->id))->toBeTrue()
->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse() ->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse()
@ -174,7 +170,6 @@ describe('EntryController::index', function () {
'entry_type' => 'advancementOnly', 'entry_type' => 'advancementOnly',
], ],
])->get(route('admin.entries.index'))->assertOk(); ])->get(route('admin.entries.index'))->assertOk();
saveContentLocally($response->getContent());
$returnedEntries = $response->viewData('entries'); $returnedEntries = $response->viewData('entries');
expect($returnedEntries->contains('id', $this->entry1->id))->toBeFalse() expect($returnedEntries->contains('id', $this->entry1->id))->toBeFalse()
->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse() ->and($returnedEntries->contains('id', $this->entry2->id))->toBeFalse()
@ -254,7 +249,163 @@ describe('EntryController::store', function () {
$this->post(route('admin.entries.store'), $this->testSubmitData)->assertRedirect(route('dashboard')); $this->post(route('admin.entries.store'), $this->testSubmitData)->assertRedirect(route('dashboard'));
}); });
it('creates an entry', function () { it('creates an entry', function () {
$startingEntryCount = Entry::count();
actAsAdmin(); actAsAdmin();
$this->post(route('admin.entries.store'), $this->testSubmitData); $this->post(route('admin.entries.store'), $this->testSubmitData);
expect(Entry::count())->toEqual($startingEntryCount + 1);
});
});
describe('EntryController::edit', function () {
it('denies access to non-admins', function () {
$this->get(route('admin.entries.edit', $this->entry1))->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.entries.edit', $this->entry1))->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.entries.edit', $this->entry1))->assertRedirect(route('dashboard'));
});
it('will not edit a published audition', function () {
actAsAdmin();
$this->entry1->audition->addFlag('seats_published');
$this->entry1->refresh();
$this->get(route('admin.entries.edit', $this->entry1))->assertRedirect(route('admin.entries.index'))
->assertSessionHas('error', 'Entries in auditions with seats published cannot be modified');
$this->entry2->audition->addFlag('advancement_published');
$this->entry2->refresh();
$this->get(route('admin.entries.edit', $this->entry2))->assertRedirect(route('admin.entries.index'))
->assertSessionHas('error', 'Entries in auditions with advancement results published cannot be modified');
});
it('presents a form to edit an entry', function () {
actAsAdmin();
$this->get(route('admin.entries.edit', $this->entry1))->assertOk()
->assertViewIs('admin.entries.edit');
});
});
describe('EntryController::update', function () {
it('denies access to non-admins', function () {
$this->patch(route('admin.entries.update', $this->entry1))->assertRedirect(route('home'));
actAsNormal();
$this->patch(route('admin.entries.update', $this->entry1))->assertRedirect(route('dashboard'));
actAsTab();
$this->patch(route('admin.entries.update', $this->entry1))->assertRedirect(route('dashboard'));
});
it('will not update an entry whose current audition has published seats', function () {
actAsAdmin();
$this->auditions[0]->addFlag('seats_published');
$response = $this->patch(route('admin.entries.update', $this->entry1), [
'audition_id' => $this->auditions[1]->id,
]);
$response->assertRedirect(route('admin.entries.index'))->assertSessionHas('error',
'Entries in published auditions cannot be modified');
});
it('will not update an entry whose current audition has published advancement', function () {
actAsAdmin();
$this->auditions[0]->addFlag('advancement_published');
$response = $this->patch(route('admin.entries.update', $this->entry1), [
'audition_id' => $this->auditions[1]->id,
]);
$response->assertRedirect(route('admin.entries.index'))->assertSessionHas('error',
'Entries in published auditions cannot be modified');
});
it('will not update an entry whose proposed audition has published seats', function () {
actAsAdmin();
$this->auditions[1]->addFlag('seats_published');
$response = $this->patch(route('admin.entries.update', $this->entry1), [
'audition_id' => $this->auditions[1]->id,
]);
$response->assertRedirect(route('admin.entries.index'))->assertSessionHas('error',
'Entries cannot be moved to published auditions');
});
it('will not update an entry whose proposed audition has published advancement', function () {
actAsAdmin();
$this->auditions[1]->addFlag('advancement_published');
$response = $this->patch(route('admin.entries.update', $this->entry1), [
'audition_id' => $this->auditions[1]->id,
]);
$response->assertRedirect(route('admin.entries.index'))->assertSessionHas('error',
'Entries cannot be moved to published auditions');
});
it('chan change entry type', function () {
actAsAdmin();
$response = $this->patch(route('admin.entries.update', $this->entry1), [
'audition_id' => $this->auditions[0]->id,
'for_advancement' => 'on',
]);
$response->assertRedirect(route('admin.entries.index'));
$this->entry1->refresh();
expect($this->entry1->for_seating)->toBeFalsy()
->and($this->entry1->for_advancement)->toBeTruthy();
});
it('can waive late fees', function () {
actAsAdmin();
$response = $this->patch(route('admin.entries.update', $this->entry1), [
'audition_id' => $this->auditions[0]->id,
'for_advancement' => 'on',
'late_fee_waived' => 'on',
]);
$response->assertRedirect(route('admin.entries.index'));
$this->entry1->refresh();
expect($this->entry1->hasFlag('late_fee_waived'))->toBeTruthy();
});
it('if we dont have advancement, for_seating must be true', function () {
actAsAdmin();
Settings::set('advanceTo', '');
$response = $this->patch(route('admin.entries.update', $this->entry1), [
'audition_id' => $this->auditions[0]->id,
]);
$response->assertRedirect(route('admin.entries.index'));
$this->entry1->refresh();
expect($this->entry1->for_seating)->toBeTruthy()
->and($this->entry1->for_advancement)->toBeFalsy();
});
});
describe('EntryController::destroy', function () {
it('denies access to non-admins', function () {
$this->delete(route('admin.entries.destroy', $this->entry1))->assertRedirect(route('home'));
actAsNormal();
$this->delete(route('admin.entries.destroy', $this->entry1))->assertRedirect(route('dashboard'));
actAsTab();
$this->delete(route('admin.entries.destroy', $this->entry1))->assertRedirect(route('dashboard'));
});
it('will not delete an entry with a published audition', function () {
actAsAdmin();
$this->auditions[0]->addFlag('seats_published');
$this->auditions[1]->addFlag('advancement_published');
$this->delete(route('admin.entries.destroy', $this->entry1))->assertRedirect(route('admin.entries.index'))
->assertSessionHas('error', 'Entries in published auditions cannot be deleted');
$this->delete(route('admin.entries.destroy', $this->entry2))->assertRedirect(route('admin.entries.index'))
->assertSessionHas('error', 'Entries in published auditions cannot be deleted');
});
it('will not delete an entry that is seated', function () {
actAsAdmin();
$ensemble = Ensemble::factory()->create();
DB::table('seats')->insert([
'ensemble_id' => $ensemble->id,
'audition_id' => $this->entry1->audition_id,
'seat' => 1,
'entry_id' => $this->entry1->id,
]);
$this->delete(route('admin.entries.destroy', $this->entry1))->assertRedirect(route('admin.entries.index'))
->assertSessionHas('error', 'Cannot delete an entry that is seated');
});
it('will not delete an entry that is scored', function () {
actAsAdmin();
DB::table('score_sheets')->insert([
'user_id' => User::factory()->create()->id,
'entry_id' => $this->entry1->id,
'subscores' => json_encode([3, 5, 6]),
'seating_total' => 44,
'advancement_total' => 55,
]);
$this->delete(route('admin.entries.destroy', $this->entry1))->assertRedirect(route('admin.entries.index'))
->assertSessionHas('error', 'Cannot delete an entry that has been scored');
});
it('can delete an entry', function () {
actAsAdmin();
$this->delete(route('admin.entries.destroy', $this->entry1))->assertRedirect(route('admin.entries.index'))
->assertSessionHas('success', 'Entry Deleted');
assertDatabaseMissing('entries', ['id' => $this->entry1->id]);
}); });
}); });

View File

@ -1,5 +1,7 @@
<?php <?php
/** @noinspection PhpUndefinedFieldInspection */
use App\Models\Audition; use App\Models\Audition;
use App\Models\Entry; use App\Models\Entry;
use App\Models\Room; use App\Models\Room;