diff --git a/app/Http/Controllers/MonitorController.php b/app/Http/Controllers/MonitorController.php index b57a98a..68d93f6 100644 --- a/app/Http/Controllers/MonitorController.php +++ b/app/Http/Controllers/MonitorController.php @@ -9,9 +9,9 @@ class MonitorController extends Controller public function index() { if (! auth()->user()->hasFlag('monitor')) { - return redirect()->route('dashboard')->with('error', 'You are not assigned as a monitor'); + abort(403); } - $method = 'GET'; + $method = 'POST'; $formRoute = 'monitor.enterFlag'; $title = 'Flag Entry'; @@ -22,15 +22,17 @@ class MonitorController extends Controller public function flagForm() { if (! auth()->user()->hasFlag('monitor')) { - return redirect()->route('dashboard')->with('error', 'You are not assigned as a monitor'); + abort(403); } + $validData = request()->validate([ 'entry_id' => ['required', 'integer', 'exists:entries,id'], ]); + $entry = Entry::find($validData['entry_id']); // If the entries audition is published, bounce out - if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advance_published')) { + if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advancement_published')) { return redirect()->route('monitor.index')->with('error', 'Cannot set flags while results are published'); } @@ -45,11 +47,11 @@ class MonitorController extends Controller public function storeFlag(Entry $entry) { if (! auth()->user()->hasFlag('monitor')) { - return redirect()->route('dashboard')->with('error', 'You are not assigned as a monitor'); + abort(403); } // If the entries audition is published, bounce out - if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advance_published')) { + if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advancement_published')) { return redirect()->route('monitor.index')->with('error', 'Cannot set flags while results are published'); } @@ -65,9 +67,6 @@ class MonitorController extends Controller 'clear' => $this->setFlag($entry, 'clear'), default => redirect()->route('monitor.index')->with('error', 'Invalid action requested'), }; - if (! $result) { - return redirect()->route('monitor.index')->with('error', 'Failed to set flag'); - } return redirect()->route('monitor.index')->with('success', 'Flag set for entry #'.$entry->id); } @@ -93,6 +92,5 @@ class MonitorController extends Controller return true; } - return false; } } diff --git a/routes/web.php b/routes/web.php index 8221a7c..102f0e8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -31,7 +31,7 @@ Route::prefix('filters')->middleware(['auth', 'verified'])->controller(FilterCon // Monitor Related Routes Route::prefix('monitor')->middleware(['auth', 'verified'])->controller(MonitorController::class)->group(function () { Route::get('/', 'index')->name('monitor.index'); - Route::get('/enter_flag', 'flagForm')->name('monitor.enterFlag'); + Route::post('/enter_flag', 'flagForm')->name('monitor.enterFlag'); Route::post('enter_flag/{entry}', 'storeFlag')->name('monitor.storeFlag'); }); diff --git a/tests/Feature/app/Http/Controllers/MonitorControllerTest.php b/tests/Feature/app/Http/Controllers/MonitorControllerTest.php new file mode 100644 index 0000000..930401d --- /dev/null +++ b/tests/Feature/app/Http/Controllers/MonitorControllerTest.php @@ -0,0 +1,197 @@ +create(); + actingAs($user); + $response = $this->get(route('monitor.index')); + $response->assertForbidden(); + }); + + it('presents a form to choose an entry', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + actingAs($user); + $response = $this->get(route('monitor.index')); + $response->assertOk() + ->assertViewIs('tabulation.choose_entry'); + }); +}); + +describe('method flagForm is a form to decide what type of flag to put on an entry', function () { + it('only allows those assigned to monitor to access this page', function () { + $user = User::factory()->create(); + actingAs($user); + $response = $this->post(route('monitor.enterFlag')); + $response->assertStatus(403); + }); + it('wont add flags to an entry in an audition with published seats', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $entry->audition->addFlag('seats_published'); + $response = $this->post(route('monitor.enterFlag'), ['entry_id' => $entry->id]); + $response->assertRedirect(route('monitor.index')) + ->assertSessionHas('error'); + expect($response->getSession()->get('error'))->toBe('Cannot set flags while results are published'); + }); + + it('wont add flags to an entry in an audition with published advancement', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $entry->audition->addFlag('advancement_published'); + $response = $this->post(route('monitor.enterFlag'), ['entry_id' => $entry->id]); + $response->assertRedirect(route('monitor.index')) + ->assertSessionHas('error'); + expect($response->getSession()->get('error'))->toBe('Cannot set flags while results are published'); + }); + + it('wont add flags to an entry in an audition with scores', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + DB::table('score_sheets')->insert([ + 'user_id' => $user->id, + 'entry_id' => $entry->id, + 'subscores' => json_encode([12, 3, 5]), + 'seating_total' => 1, + 'advancement_total' => 1, + ]); + $response = $this->post(route('monitor.enterFlag'), ['entry_id' => $entry->id]); + $response->assertRedirect(route('monitor.index')) + ->assertSessionHas('error'); + expect($response->getSession()->get('error'))->toBe('That entry has existing scores'); + }); + + it('displays a form to choose a flag for the entry', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $response = $this->post(route('monitor.enterFlag'), ['entry_id' => $entry->id]); + $response->assertOk() + ->assertViewIs('monitor_entry_flag_form'); + }); +}); + +describe('method storeFlag stores the flag and returns to the select entry form', function () { + it('only allows those assigned to monitor to access this page', function () { + $user = User::factory()->create(); + $entry = Entry::factory()->create(); + actingAs($user); + $response = $this->post(route('monitor.storeFlag', $entry), ['flag' => 'no_show']); + $response->assertForbidden(); + }); + it('wont add flags to an entry in an audition with published seats', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $entry->audition->addFlag('seats_published'); + $response = $this->post(route('monitor.storeFlag', $entry), ['flag' => 'no_show']); + $response->assertRedirect(route('monitor.index')) + ->assertSessionHas('error'); + expect($response->getSession()->get('error'))->toBe('Cannot set flags while results are published'); + }); + + it('wont add flags to an entry in an audition with published advancement', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $entry->audition->addFlag('advancement_published'); + $response = $this->post(route('monitor.storeFlag', $entry), ['flag' => 'no_show']); + $response->assertRedirect(route('monitor.index')) + ->assertSessionHas('error'); + expect($response->getSession()->get('error'))->toBe('Cannot set flags while results are published'); + }); + + it('wont add flags to an entry in an audition with scores', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + DB::table('score_sheets')->insert([ + 'user_id' => $user->id, + 'entry_id' => $entry->id, + 'subscores' => json_encode([12, 3, 5]), + 'seating_total' => 1, + 'advancement_total' => 1, + ]); + $response = $this->post(route('monitor.storeFlag', $entry), ['flag' => 'no_show']); + $response->assertRedirect(route('monitor.index')) + ->assertSessionHas('error'); + expect($response->getSession()->get('error'))->toBe('That entry has existing scores'); + }); + + it('wont add a bogus flag', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $response = $this->post(route('monitor.storeFlag', $entry), ['action' => 'nonsense']); + $response->assertRedirect(route('monitor.index')) + ->assertSessionHas('error'); + expect($response->getSession()->get('error'))->toBe('Invalid action requested'); + }); + + it('can add a failed-prelim tag to an entry', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $response = $this->post(route('monitor.storeFlag', $entry), ['action' => 'failed-prelim']); + $response->assertRedirect(route('monitor.index')); + $entry->refresh(); + expect($entry->hasFlag('failed_prelim'))->toBeTrue(); + }); + + it('can add a no-show tag to an entry', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $response = $this->post(route('monitor.storeFlag', $entry), ['action' => 'no-show']); + $response->assertRedirect(route('monitor.index')); + $entry->refresh(); + expect($entry->hasFlag('no_show'))->toBeTrue(); + }); + + it('can clear flags', function () { + $user = User::factory()->create(); + $user->addFlag('monitor'); + $user->refresh(); + actingAs($user); + $entry = Entry::factory()->create(); + $entry->addFlag('no_show'); + $entry->refresh(); + expect($entry->hasFlag('no_show'))->toBeTrue(); + $response = $this->post(route('monitor.storeFlag', $entry), ['action' => 'clear']); + $response->assertRedirect(route('monitor.index')); + $entry->refresh(); + expect($entry->hasFlag('no_show'))->toBeFalse(); + }); + +});