add test for admin DrawController. Work on deprecating DrawService
This commit is contained in:
parent
e1d72ee040
commit
7efe029ff9
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Draw;
|
||||||
|
|
||||||
|
use App\Models\Audition;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
use function auditionLog;
|
||||||
|
|
||||||
|
class ClearDraw
|
||||||
|
{
|
||||||
|
public function __invoke(Audition|collection $auditions): void
|
||||||
|
{
|
||||||
|
if ($auditions instanceof Audition) {
|
||||||
|
$this->clearDraw($auditions);
|
||||||
|
}
|
||||||
|
if ($auditions instanceof Collection) {
|
||||||
|
$this->clearDraws($auditions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearDraw(Audition $audition): void
|
||||||
|
{
|
||||||
|
$audition->removeFlag('drawn');
|
||||||
|
DB::table('entries')->where('audition_id', $audition->id)->update(['draw_number' => null]);
|
||||||
|
$message = 'Cleared draw for audition #'.$audition->id.' '.$audition->name;
|
||||||
|
$affected['auditions'] = [$audition->id];
|
||||||
|
auditionLog($message, $affected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearDraws(Collection $auditions): void
|
||||||
|
{
|
||||||
|
foreach ($auditions as $audition) {
|
||||||
|
$this->clearDraw($audition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Draw;
|
||||||
|
|
||||||
|
use App\Models\Audition;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class RunDraw
|
||||||
|
{
|
||||||
|
public function __invoke(Audition|Collection $auditions): void
|
||||||
|
{
|
||||||
|
if ($auditions instanceof Audition) {
|
||||||
|
// Single audition, run draw directly
|
||||||
|
$this->runDraw($auditions);
|
||||||
|
|
||||||
|
return;
|
||||||
|
} elseif ($auditions instanceof Collection) {
|
||||||
|
$this->runDrawMultiple($auditions);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runDraw(Audition $audition): void
|
||||||
|
{
|
||||||
|
// start off by clearing any existing draw numbers in the audition
|
||||||
|
DB::table('entries')->where('audition_id', $audition->id)->update(['draw_number' => null]);
|
||||||
|
|
||||||
|
$randomizedEntries = $audition->entries->shuffle();
|
||||||
|
|
||||||
|
// Move entries flagged as no show to the end
|
||||||
|
[$noShowEntries, $otherEntries] = $randomizedEntries->partition(function ($entry) {
|
||||||
|
return $entry->hasFlag('no_show');
|
||||||
|
});
|
||||||
|
$randomizedEntries = $otherEntries->merge($noShowEntries);
|
||||||
|
|
||||||
|
// Save draw numbers back to the entries\
|
||||||
|
$nextNumber = 1;
|
||||||
|
foreach ($randomizedEntries as $index => $entry) {
|
||||||
|
$entry->update(['draw_number' => $nextNumber]);
|
||||||
|
$nextNumber++;
|
||||||
|
}
|
||||||
|
$audition->addFlag('drawn');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runDrawMultiple(Collection $auditions): void
|
||||||
|
{
|
||||||
|
// Eager load the 'entries' relationship on all auditions if not already loaded
|
||||||
|
$auditions->loadMissing('entries');
|
||||||
|
|
||||||
|
$auditions->each(fn ($audition) => $this->runDraw($audition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Actions\Draw\RunDraw;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\ClearDrawRequest;
|
use App\Http\Requests\ClearDrawRequest;
|
||||||
use App\Http\Requests\RunDrawRequest;
|
use App\Http\Requests\RunDrawRequest;
|
||||||
|
|
@ -10,7 +11,6 @@ use App\Models\Event;
|
||||||
use App\Services\DrawService;
|
use App\Services\DrawService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use function array_keys;
|
use function array_keys;
|
||||||
use function to_route;
|
use function to_route;
|
||||||
|
|
||||||
|
|
@ -26,6 +26,7 @@ class DrawController extends Controller
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$events = Event::with('auditions.flags')->get();
|
$events = Event::with('auditions.flags')->get();
|
||||||
|
|
||||||
// $drawnAuditionsExist is true if any audition->hasFlag('drawn') is true
|
// $drawnAuditionsExist is true if any audition->hasFlag('drawn') is true
|
||||||
$drawnAuditionsExist = Audition::whereHas('flags', function ($query) {
|
$drawnAuditionsExist = Audition::whereHas('flags', function ($query) {
|
||||||
$query->where('flag_name', 'drawn');
|
$query->where('flag_name', 'drawn');
|
||||||
|
|
@ -36,18 +37,23 @@ class DrawController extends Controller
|
||||||
|
|
||||||
public function store(RunDrawRequest $request)
|
public function store(RunDrawRequest $request)
|
||||||
{
|
{
|
||||||
|
// Request will contain audition which is an array of audition IDs all with a value of 1
|
||||||
|
// Code below results in a collection of auditions that were checked on the form
|
||||||
$auditions = Audition::with('flags')->findMany(array_keys($request->input('audition', [])));
|
$auditions = Audition::with('flags')->findMany(array_keys($request->input('audition', [])));
|
||||||
|
|
||||||
if ($this->drawService->checkCollectionForDrawnAuditions($auditions)) {
|
if ($this->drawService->checkCollectionForDrawnAuditions($auditions)) {
|
||||||
return to_route('admin.draw.index')->with('error',
|
return to_route('admin.draw.index')->with('error',
|
||||||
'Invalid attempt to draw an audition that has already been drawn');
|
'Cannot run draw. Some auditions have already been drawn.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->drawService->runDrawsOnCollection($auditions);
|
app(RunDraw::class)($auditions);
|
||||||
|
|
||||||
return to_route('admin.draw.index')->with('status', 'Draw completed successfully');
|
return to_route('admin.draw.index')->with('success', 'Draw completed successfully');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generates the page with checkboxes for each drawn audition with an intent to clear them
|
||||||
|
*/
|
||||||
public function edit(Request $request)
|
public function edit(Request $request)
|
||||||
{
|
{
|
||||||
$drawnAuditions = Audition::whereHas('flags', function ($query) {
|
$drawnAuditions = Audition::whereHas('flags', function ($query) {
|
||||||
|
|
@ -57,12 +63,17 @@ class DrawController extends Controller
|
||||||
return view('admin.draw.edit', compact('drawnAuditions'));
|
return view('admin.draw.edit', compact('drawnAuditions'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the draw for auditions
|
||||||
|
*/
|
||||||
public function destroy(ClearDrawRequest $request)
|
public function destroy(ClearDrawRequest $request)
|
||||||
{
|
{
|
||||||
|
// Request will contain audition which is an array of audition IDs all with a value of 1
|
||||||
|
// Code below results in a collection of auditions that were checked on the form
|
||||||
$auditions = Audition::with('flags')->findMany(array_keys($request->input('audition', [])));
|
$auditions = Audition::with('flags')->findMany(array_keys($request->input('audition', [])));
|
||||||
$this->drawService->clearDrawsOnCollection($auditions);
|
$this->drawService->clearDrawsOnCollection($auditions);
|
||||||
|
|
||||||
return to_route('admin.draw.index')->with('status', 'Draw completed successfully');
|
return to_route('admin.draw.index')->with('success', 'Draws cleared successfully');
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Observers;
|
||||||
|
|
||||||
|
use App\Models\Audition;
|
||||||
|
use App\Models\Event;
|
||||||
|
|
||||||
|
class AuditionObserver
|
||||||
|
{
|
||||||
|
public function created(Audition $audition): void
|
||||||
|
{
|
||||||
|
$message = 'Added audition #'.$audition->id.' '.$audition->name.' to event '.$audition->event->name;
|
||||||
|
$message .= '<br>Deadline: '.$audition->entry_deadline->format('m/d/Y');
|
||||||
|
$message .= '<br>Entry Fee: '.$audition->display_fee();
|
||||||
|
$message .= '<br>Grade Range: '.$audition->minimum_grade.' - '.$audition->maximum_grade;
|
||||||
|
$affected = ['auditions' => [$audition->id], 'events' => [$audition->event_id]];
|
||||||
|
auditionLog($message, $affected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updated(Audition $audition): void
|
||||||
|
{
|
||||||
|
$message = 'Updated audition #'.$audition->getOriginal('name').' '.$audition->name;
|
||||||
|
if ($audition->event_id !== $audition->getOriginal('event_id')) {
|
||||||
|
$message .= '<br>Event: '.Event::find($audition->getOriginal('event_id'))->name.' -> '.Event::find($audition->event_id)->name;
|
||||||
|
$affected['events'] = [$audition->event_id, $audition->getOriginal('event_id')];
|
||||||
|
} else {
|
||||||
|
$affected['auditions'] = [$audition->id];
|
||||||
|
}
|
||||||
|
if ($audition->entry_deadline !== $audition->getOriginal('entry_deadline')) {
|
||||||
|
$message .= '<br>Deadline: '.$audition->entry_deadline->format('m/d/Y');
|
||||||
|
}
|
||||||
|
if ($audition->entryFee !== $audition->getOriginal('entryFee')) {
|
||||||
|
$message .= '<br>Entry Fee: '.$audition->display_fee();
|
||||||
|
}
|
||||||
|
if ($audition->minimum_grade !== $audition->getOriginal('minimum_grade') || $audition->maximum_grade !== $audition->getOriginal('maximum_grade')) {
|
||||||
|
$message .= '<br>Grade Range: '.$audition->minimum_grade.' - '.$audition->maximum_grade;
|
||||||
|
}
|
||||||
|
$affected['auditions'] = [$audition->id];
|
||||||
|
auditionLog($message, $affected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleted(Audition $audition): void
|
||||||
|
{
|
||||||
|
$message = 'Deleted audition #'.$audition->id.' '.$audition->name;
|
||||||
|
$affected = ['auditions' => [$audition->id]];
|
||||||
|
auditionLog($message, $affected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,8 @@ use App\Models\Audition;
|
||||||
use App\Models\Doubler;
|
use App\Models\Doubler;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
|
|
||||||
|
use function auditionSetting;
|
||||||
|
|
||||||
class EntryObserver
|
class EntryObserver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -30,6 +32,9 @@ class EntryObserver
|
||||||
$message .= '<br>Student: '.$entry->student->full_name();
|
$message .= '<br>Student: '.$entry->student->full_name();
|
||||||
$message .= '<br>Grade: '.$entry->student->grade;
|
$message .= '<br>Grade: '.$entry->student->grade;
|
||||||
$message .= '<br>School: '.$entry->student->school->name;
|
$message .= '<br>School: '.$entry->student->school->name;
|
||||||
|
if ($entry->draw_number) {
|
||||||
|
$message .= '<br>Draw Number: '.$entry->draw_number;
|
||||||
|
}
|
||||||
|
|
||||||
$affected = [
|
$affected = [
|
||||||
'students' => [$entry->student_id],
|
'students' => [$entry->student_id],
|
||||||
|
|
@ -48,6 +53,46 @@ class EntryObserver
|
||||||
$syncer = app(DoublerSync::class);
|
$syncer = app(DoublerSync::class);
|
||||||
// Update doubler table when an entry is updated
|
// Update doubler table when an entry is updated
|
||||||
$syncer();
|
$syncer();
|
||||||
|
|
||||||
|
// Log entry changes
|
||||||
|
$message = 'Updated Entry #'.$entry->id;
|
||||||
|
$affected['entries'] = [$entry->id];
|
||||||
|
$affected['auditions'] = [$entry->audition_id];
|
||||||
|
$affected['students'] = [$entry->student_id];
|
||||||
|
$shouldLog = false;
|
||||||
|
if ($entry->wasChanged('audition_id')) {
|
||||||
|
$originalAuditionName = Audition::find($entry->getOriginal('audition_id'))->name;
|
||||||
|
$message .= '<br>Audition: '.$originalAuditionName.' -> '.$entry->audition->name;
|
||||||
|
$affected['auditions'][] = $entry->getOriginal('audition_id');
|
||||||
|
$shouldLog = true;
|
||||||
|
}
|
||||||
|
if ($entry->wasChanged('student_id')) {
|
||||||
|
$originalStudentName = $entry->getOriginal('student')->full_name();
|
||||||
|
$message .= '<br>Student: '.$originalStudentName.' -> '.$entry->student->full_name();
|
||||||
|
$affected['students'][] = $entry->getOriginal('student_id');
|
||||||
|
$shouldLog = true;
|
||||||
|
}
|
||||||
|
if ($entry->wasChanged('for_advancement' && auditionSetting('advanceTo'))) {
|
||||||
|
$message .= '<br>Entered for '.auditionSetting('advanceTo');
|
||||||
|
$shouldLog = true;
|
||||||
|
}
|
||||||
|
if ($entry->wasChanged('for_seating')) {
|
||||||
|
$message .= '<br>Entered for seating';
|
||||||
|
$shouldLog = true;
|
||||||
|
}
|
||||||
|
if ($shouldLog) {
|
||||||
|
auditionLog($message, $affected);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($entry->wasChanged('draw_number')) {
|
||||||
|
$message = 'Assigned Entry #'.$entry->id.' draw number '.$entry->draw_number;
|
||||||
|
$message .= '<br>Audition: '.$entry->audition->name;
|
||||||
|
$message .= '<br>Student: '.$entry->student->full_name();
|
||||||
|
$affected['students'] = [$entry->student_id];
|
||||||
|
$affected['auditions'] = [$entry->audition_id];
|
||||||
|
$affected['entries'] = [$entry->id];
|
||||||
|
auditionLog($message, $affected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use App\Actions\Entries\UpdateEntry;
|
||||||
use App\Actions\Schools\SetHeadDirector;
|
use App\Actions\Schools\SetHeadDirector;
|
||||||
use App\Actions\Tabulation\CalculateAuditionScores;
|
use App\Actions\Tabulation\CalculateAuditionScores;
|
||||||
use App\Actions\Tabulation\TotalEntryScores;
|
use App\Actions\Tabulation\TotalEntryScores;
|
||||||
|
use App\Models\Audition;
|
||||||
use App\Models\BonusScore;
|
use App\Models\BonusScore;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
use App\Models\EntryFlag;
|
use App\Models\EntryFlag;
|
||||||
|
|
@ -17,6 +18,7 @@ use App\Models\ScoreSheet;
|
||||||
use App\Models\ScoringGuide;
|
use App\Models\ScoringGuide;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Observers\AuditionObserver;
|
||||||
use App\Observers\BonusScoreObserver;
|
use App\Observers\BonusScoreObserver;
|
||||||
use App\Observers\EntryFlagObserver;
|
use App\Observers\EntryFlagObserver;
|
||||||
use App\Observers\EntryObserver;
|
use App\Observers\EntryObserver;
|
||||||
|
|
@ -61,6 +63,7 @@ class AppServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
|
Audition::observe(AuditionObserver::class);
|
||||||
BonusScore::observe(BonusScoreObserver::class);
|
BonusScore::observe(BonusScoreObserver::class);
|
||||||
Entry::observe(EntryObserver::class);
|
Entry::observe(EntryObserver::class);
|
||||||
EntryFlag::observe(EntryFlagObserver::class);
|
EntryFlag::observe(EntryFlagObserver::class);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Actions\Draw\RunDraw;
|
||||||
|
use App\Models\Audition;
|
||||||
|
use App\Models\Entry;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('assigns sequential draw numbers with no_show entries at the end', function () {
|
||||||
|
// Create an audition with entries
|
||||||
|
$audition = Audition::factory()->create();
|
||||||
|
|
||||||
|
// Create entries: some flagged as no_show, some not
|
||||||
|
$entries = Entry::factory()
|
||||||
|
->count(5)
|
||||||
|
->for($audition)
|
||||||
|
->create();
|
||||||
|
|
||||||
|
// Flag two entries as no_show
|
||||||
|
$noShowEntries = $entries->take(2);
|
||||||
|
foreach ($noShowEntries as $entry) {
|
||||||
|
$entry->addFlag('no_show');
|
||||||
|
$entry->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally, assign some existing draw numbers to test clearing
|
||||||
|
// foreach ($entries as $entry) {
|
||||||
|
// $entry->draw_number = 99;
|
||||||
|
// $entry->save();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Run the draw
|
||||||
|
app(RunDraw::class)($audition);
|
||||||
|
|
||||||
|
// Reload entries from DB to get fresh data
|
||||||
|
$entries = $audition->entries()->orderBy('draw_number')->get();
|
||||||
|
|
||||||
|
// Assert all draw_numbers are sequential starting at 1
|
||||||
|
$drawNumbers = $entries->pluck('draw_number')->all();
|
||||||
|
expect($drawNumbers)->toEqual(range(1, $entries->count()));
|
||||||
|
|
||||||
|
// Assert entries without no_show flag come first
|
||||||
|
$entriesWithoutNoShow = $entries->filter(fn ($e) => ! $e->hasFlag('no_show'));
|
||||||
|
$entriesWithNoShow = $entries->filter(fn ($e) => $e->hasFlag('no_show'));
|
||||||
|
|
||||||
|
// The max draw_number of entries without no_show should be less than min draw_number of no_show entries
|
||||||
|
if ($entriesWithNoShow->isNotEmpty()) {
|
||||||
|
expect($entriesWithoutNoShow->max('draw_number'))->toBeLessThan($entriesWithNoShow->min('draw_number'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert the audition has the 'drawn' flag
|
||||||
|
expect($audition->hasFlag('drawn'))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('runs draw on multiple auditions correctly', function () {
|
||||||
|
// Create multiple auditions
|
||||||
|
$auditions = Audition::factory()->count(3)->create();
|
||||||
|
|
||||||
|
// For each audition, create entries with some flagged as no_show
|
||||||
|
foreach ($auditions as $audition) {
|
||||||
|
$entries = Entry::factory()->count(4)->for($audition)->create();
|
||||||
|
|
||||||
|
// Flag one entry as no_show per audition
|
||||||
|
$entries->first()->addFlag('no_show');
|
||||||
|
$entries->first()->save();
|
||||||
|
|
||||||
|
// // Assign dummy draw numbers to test clearing
|
||||||
|
// foreach ($entries as $entry) {
|
||||||
|
// $entry->draw_number = 99;
|
||||||
|
// $entry->save();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the draw on all auditions
|
||||||
|
app(RunDraw::class)($auditions);
|
||||||
|
|
||||||
|
// Reload auditions with entries
|
||||||
|
$auditions = $auditions->load('entries');
|
||||||
|
|
||||||
|
foreach ($auditions as $audition) {
|
||||||
|
$entries = $audition->entries->sortBy('draw_number')->values();
|
||||||
|
|
||||||
|
// Assert draw numbers are sequential starting at 1
|
||||||
|
$drawNumbers = $entries->pluck('draw_number')->all();
|
||||||
|
expect($drawNumbers)->toEqual(range(1, $entries->count()));
|
||||||
|
|
||||||
|
// Separate no_show and other entries
|
||||||
|
$entriesWithoutNoShow = $entries->filter(fn ($e) => ! $e->hasFlag('no_show'));
|
||||||
|
$entriesWithNoShow = $entries->filter(fn ($e) => $e->hasFlag('no_show'));
|
||||||
|
|
||||||
|
if ($entriesWithNoShow->isNotEmpty()) {
|
||||||
|
expect($entriesWithoutNoShow->max('draw_number'))->toBeLessThan($entriesWithNoShow->min('draw_number'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert the audition has the 'drawn' flag
|
||||||
|
expect($audition->hasFlag('drawn'))->toBeTrue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Audition;
|
||||||
|
use App\Models\Entry;
|
||||||
|
use App\Models\Event;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
describe('DrawController::index', function () {
|
||||||
|
it('denies access to a non-admin user', function () {
|
||||||
|
$this->get(route('admin.draw.index'))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->get(route('admin.draw.index'))->assertRedirect(route('dashboard'));
|
||||||
|
actAsTab();
|
||||||
|
$this->get(route('admin.draw.index'))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('returns a page to select auditions to draw, including a section for each event that has entries', function () {
|
||||||
|
$events = Event::factory()->count(3)->create();
|
||||||
|
foreach ($events as $event) {
|
||||||
|
Audition::factory()->forEvent($event)->count(3)->create();
|
||||||
|
}
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->get(route('admin.draw.index'));
|
||||||
|
$response->assertOk()
|
||||||
|
->assertViewIs('admin.draw.index')
|
||||||
|
->assertSee('events');
|
||||||
|
foreach ($events as $event) {
|
||||||
|
$response->assertSee($event->name, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it('tells the view if any auditions are drawn', function () {
|
||||||
|
$events = Event::factory()->count(3)->create();
|
||||||
|
foreach ($events as $event) {
|
||||||
|
Audition::factory()->forEvent($event)->count(3)->create();
|
||||||
|
}
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->get(route('admin.draw.index'));
|
||||||
|
$response->assertOk();
|
||||||
|
expect($response->viewData('drawnAuditionsExist'))->toBeFalse();
|
||||||
|
foreach (Audition::all() as $audition) {
|
||||||
|
$response->assertSee($audition->name, false);
|
||||||
|
}
|
||||||
|
$testCase = Audition::first();
|
||||||
|
$testCase->addFlag('drawn');
|
||||||
|
$response = $this->get(route('admin.draw.index'));
|
||||||
|
$response->assertOk();
|
||||||
|
expect($response->viewData('drawnAuditionsExist'))->toBeTrue();
|
||||||
|
$response->assertDontSee($testCase->name, false);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DrawController::store', function () {
|
||||||
|
it('denies access to a non-admin user', function () {
|
||||||
|
$this->post(route('admin.draw.store'))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->post(route('admin.draw.store'))->assertRedirect(route('dashboard'));
|
||||||
|
actAsTab();
|
||||||
|
$this->post(route('admin.draw.store'))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('draws selected auditions', function () {
|
||||||
|
$auditions = Audition::factory()->count(5)->create();
|
||||||
|
$testCase1 = $auditions[0];
|
||||||
|
$testCase2 = $auditions[1];
|
||||||
|
$input = ['audition' => [$testCase1->id => 1, $testCase2->id => 1]];
|
||||||
|
actAsAdmin();
|
||||||
|
$this->post(route('admin.draw.store'), $input)
|
||||||
|
->assertRedirect(route('admin.draw.index'))
|
||||||
|
->assertSessionHas('success');
|
||||||
|
$testCase1->refresh();
|
||||||
|
$testCase2->refresh();
|
||||||
|
expect($testCase1->hasFlag('drawn'))->toBeTrue();
|
||||||
|
expect($testCase2->hasFlag('drawn'))->toBeTrue();
|
||||||
|
});
|
||||||
|
it('will not draw an audition if it is already drawn', function () {
|
||||||
|
$auditions = Audition::factory()->count(5)->create();
|
||||||
|
$testCase = $auditions[0];
|
||||||
|
$testCase->addFlag('drawn');
|
||||||
|
$input = ['audition' => [$testCase->id => 1]];
|
||||||
|
actAsAdmin();
|
||||||
|
$this->post(route('admin.draw.store'), $input)
|
||||||
|
->assertRedirect(route('admin.draw.index'))
|
||||||
|
->assertSessionHas('error', 'Cannot run draw. Some auditions have already been drawn.');
|
||||||
|
$testCase->refresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DrawController::edit', function () {
|
||||||
|
it('denies access to a non-admin user', function () {
|
||||||
|
$this->get(route('admin.draw.edit'))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->get(route('admin.draw.edit'))->assertRedirect(route('dashboard'));
|
||||||
|
actAsTab();
|
||||||
|
$this->get(route('admin.draw.edit'))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('returns a page to select drawn auditions to be cleared. Includes all drawn auditions', function () {
|
||||||
|
$auditions = Audition::factory()->count(5)->create();
|
||||||
|
$testCase1 = $auditions[0];
|
||||||
|
$testCase2 = $auditions[1];
|
||||||
|
$testCase1->addFlag('drawn');
|
||||||
|
$testCase2->addFlag('drawn');
|
||||||
|
actAsAdmin();
|
||||||
|
$response = $this->get(route('admin.draw.edit'), ['audition' => [$testCase1->id => 1, $testCase2->id => 1]]);
|
||||||
|
$response->assertOk()
|
||||||
|
->assertViewIs('admin.draw.edit');
|
||||||
|
expect($response->viewData('drawnAuditions')->contains('id', $testCase1->id))->toBeTrue();
|
||||||
|
expect($response->viewData('drawnAuditions')->contains('id', $testCase2->id))->toBeTrue();
|
||||||
|
expect($response->viewData('drawnAuditions')->contains('id', $auditions[2]->id))->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DrawController::destroy', function () {
|
||||||
|
it('denies access to a non-admin user', function () {
|
||||||
|
$this->delete(route('admin.draw.destroy'))->assertRedirect(route('home'));
|
||||||
|
actAsNormal();
|
||||||
|
$this->delete(route('admin.draw.destroy'))->assertRedirect(route('dashboard'));
|
||||||
|
actAsTab();
|
||||||
|
$this->delete(route('admin.draw.destroy'))->assertRedirect(route('dashboard'));
|
||||||
|
});
|
||||||
|
it('clears selected drawn auditions', function () {
|
||||||
|
$auditions = Audition::factory()->count(5)->create();
|
||||||
|
$testCase1 = $auditions[0];
|
||||||
|
$testCase2 = $auditions[1];
|
||||||
|
$testCase3 = $auditions[2];
|
||||||
|
foreach (Audition::all() as $audition) {
|
||||||
|
Entry::factory()->forAudition($audition)->count(5)->create();
|
||||||
|
}
|
||||||
|
actAsAdmin();
|
||||||
|
expect(Entry::where('audition_id', $testCase1->id)->first()->draw_number)->toBeNull();
|
||||||
|
// First off, get the draws run
|
||||||
|
$this->post(route('admin.draw.store'), [
|
||||||
|
'audition' => [
|
||||||
|
$testCase1->id => 1,
|
||||||
|
$testCase2->id => 1,
|
||||||
|
$testCase3->id => 1,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$testCase1->refresh();
|
||||||
|
$testCase2->refresh();
|
||||||
|
$testCase3->refresh();
|
||||||
|
expect($testCase1->hasFlag('drawn'))->toBeTrue()
|
||||||
|
->and(Entry::where('audition_id', $testCase1->id)->first()->draw_number)->not()->toBeNull();
|
||||||
|
|
||||||
|
$this->delete(route('admin.draw.destroy'), ['audition' => [$testCase1->id => 1, $testCase2->id => 1]])
|
||||||
|
->assertRedirect(route('admin.draw.index'))
|
||||||
|
->assertSessionHas('success');
|
||||||
|
$testCase1->refresh();
|
||||||
|
$testCase2->refresh();
|
||||||
|
$testCase3->refresh();
|
||||||
|
expect($testCase1->hasFlag('drawn'))->toBeFalse()
|
||||||
|
->and($testCase2->hasFlag('drawn'))->toBeFalse()
|
||||||
|
->and($testCase3->hasFlag('drawn'))->toBeTrue();
|
||||||
|
expect(Entry::where('audition_id', $testCase1->id)->first()->draw_number)->toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue