auditionadmin/tests/Feature/app/Http/Controllers/Judging/JudgingControllerTest.php

301 lines
14 KiB
PHP

<?php
use App\Models\Audition;
use App\Models\BonusScoreDefinition;
use App\Models\Entry;
use App\Models\JudgeAdvancementVote;
use App\Models\PrelimDefinition;
use App\Models\Room;
use App\Models\ScoreSheet;
use App\Models\ScoringGuide;
use App\Models\SubscoreDefinition;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
describe('JudgingController::index', function () {
it('denies access to non-judges', function () {
actAsNormal();
$response = $this->get(route('judging.index'));
$response->assertRedirect(route('dashboard'));
$response->assertSessionHas('error', 'You are not assigned to judge.');
});
it('shows a dashboard showing rooms and bonus scores the user is assigned to judge', function () {
$judge = User::factory()->create();
$room = Room::factory()->create();
$room->judges()->attach($judge);
$bonusScoreDefinition = BonusScoreDefinition::factory()->create();
$bonusScoreDefinition->judges()->attach($judge);
$response = $this->actingAs($judge)->get(route('judging.index'));
$response->assertOk();
$response->assertSee($room->name);
$response->assertSee($bonusScoreDefinition->name);
});
it('shows prelim auditions the user is assigned to juge', function () {
$judge = User::factory()->create();
$room = Room::factory()->create();
$room->judges()->attach($judge);
$audition = Audition::factory()->create();
$prelimAudition = PrelimDefinition::create([
'audition_id' => $audition->id,
'room_id' => $room->id,
'passing_score' => 75,
]);
$response = $this->actingAs($judge)->get(route('judging.index'));
$response->assertOk();
$response->assertSee($room->name);
$response->assertSee($audition->name.' Prelims');
});
});
describe('JudgingController::auditionEntryList', function () {
it('denies access to non-judges', function () {
actAsNormal();
$audition = Audition::factory()->create();
$response = $this->get(route('judging.auditionEntryList', $audition->id));
$response->assertRedirect(route('dashboard'));
$response->assertSessionHas('error', 'You are not assigned to judge.');
});
it('denies access if were not assigned to the auditions room', function () {
$judge = User::factory()->create();
$room = Room::factory()->create();
$otherRoom = Room::factory()->create();
$otherRoom->judges()->attach($judge);
$audition = Audition::factory()->create(['room_id' => $room->id]);
$response = $this->actingAs($judge)->get(route('judging.auditionEntryList', $audition->id));
$response->assertRedirect(route('judging.index'));
$response->assertSessionHas('error', 'You are not assigned to judge that audition');
});
it('gives us an entry list from which we may select an entry to score', function () {
$scoringGuide = ScoringGuide::factory()->create();
$judge = User::factory()->create();
$room = Room::factory()->create();
$room->judges()->attach($judge);
$audition = Audition::factory()->create(['room_id' => $room->id, 'scoring_guide_id' => $scoringGuide->id]);
$entries = Entry::factory()->count(5)->forAudition($audition)->create();
$response = $this->actingAs($judge)->get(route('judging.auditionEntryList', $audition->id));
$response->assertOk();
$response->assertViewIs('judging.audition_entry_list');
$response->assertViewHas('audition', $audition);
$response->assertViewHas('entries', $entries);
foreach ($entries as $entry) {
$response->assertSee($entry->audition->name.' '.$entry->draw_number);
$response->assertDontSee($entry->student->full_name());
$response->assertDontSee($entry->student->full_name(true));
}
foreach (SubscoreDefinition::all() as $subscoreDefinition) {
$response->assertSee($subscoreDefinition->name);
}
});
});
describe('JudgingController::entryScoreSheet', function () {
it('denies access to non-judges', function () {
actAsNormal();
$entry = Entry::factory()->create();
$response = $this->get(route('judging.entryScoreSheet', $entry));
$response->assertRedirect(route('dashboard'));
$response->assertSessionHas('error', 'You are not assigned to judge.');
});
it('denies access if were not assigned to the auditions room', function () {
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$entry = Entry::factory()->create();
$this->actingAs($judge);
$response = $this->get(route('judging.entryScoreSheet', $entry));
$response->assertRedirect(route('judging.index'));
$response->assertSessionHas('error', 'You are not assigned to judge this entry');
});
it('denies access if the audition is published', function () {
$room = Room::factory()->create();
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$audition = Audition::factory()->create(['room_id' => $room->id]);
$entry = Entry::factory()->forAudition($audition)->create();
$audition->addFlag('seats_published');
$this->actingAs($judge);
$response = $this->get(route('judging.entryScoreSheet', $entry));
$response->assertRedirect(route('judging.auditionEntryList', $audition));
$response->assertSessionHas('error', 'Scores for entries in published auditions cannot be modified');
});
it('denies access if the entry is flagged as a no-show', function () {
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$audition = Audition::factory()->create(['room_id' => $room->id]);
$entry = Entry::factory()->forAudition($audition)->create();
$entry->addFlag('no_show');
$this->actingAs($judge);
$response = $this->get(route('judging.entryScoreSheet', $entry));
$response->assertRedirect(route('judging.auditionEntryList', $audition));
$response->assertSessionHas('error', 'The requested entry is marked as a no-show. Scores cannot be entered.');
});
it('denies access if the entry is flagged as a failed-prelim', function () {
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$audition = Audition::factory()->create(['room_id' => $room->id]);
$entry = Entry::factory()->forAudition($audition)->create();
$entry->addFlag('failed_prelim');
$this->actingAs($judge);
$response = $this->get(route('judging.entryScoreSheet', $entry));
$response->assertRedirect(route('judging.auditionEntryList', $audition));
$response->assertSessionHas('error',
'The requested entry is marked as having failed a prelim. Scores cannot be entered.');
});
it('gives us a form to enter a score for an entry', function () {
$scoringGuide = ScoringGuide::factory()->create();
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$audition = Audition::factory()->create(['room_id' => $room->id, 'scoring_guide_id' => $scoringGuide->id]);
$entry = Entry::factory()->forAudition($audition)->create();
$this->actingAs($judge);
$response = $this->get(route('judging.entryScoreSheet', $entry));
$response->assertOk();
$response->assertViewIs('judging.entry_score_sheet');
$response->assertDontSee($entry->student->full_name());
foreach (SubscoreDefinition::all() as $subscoreDefinition) {
$response->assertSee($subscoreDefinition->name);
$response->assertSee('score['.$subscoreDefinition->id.']');
$response->assertSee('max: '.$subscoreDefinition->maximum_score);
}
});
});
describe('JudgingController::saveScoreSheet', function () {
it('denies access to non-judges', function () {
actAsNormal();
$audition = Audition::factory()->create();
$entry = Entry::factory()->forAudition($audition)->create();
$response = $this->post(route('judging.saveScoreSheet', $entry));
$response->assertRedirect(route('dashboard'));
$response->assertSessionHas('error', 'You are not assigned to judge.');
});
it('denies access to judges not assigned to the audition', function () {
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$audition = Audition::factory()->create();
$entry = Entry::factory()->forAudition($audition)->create();
$this->actingAs($judge);
$response = $this->post(route('judging.saveScoreSheet', $entry));
$response->assertRedirect(route('judging.index'));
$response->assertSessionHas('error', 'You are not assigned to judge this entry');
});
it('saves a score sheet', function () {
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$scoringGuide = ScoringGuide::factory()->create();
$audition = Audition::factory()->create(['room_id' => $room->id, 'scoring_guide_id' => $scoringGuide->id]);
$subscoreIds = SubscoreDefinition::all()->pluck('id');
$entry = Entry::factory()->forAudition($audition)->create();
$submitData = [
'score' => [
$subscoreIds[0] => 10,
$subscoreIds[1] => 20,
$subscoreIds[2] => 30,
$subscoreIds[3] => 40,
$subscoreIds[4] => 50,
],
'advancement-vote' => 'yes',
];
$this->actingAs($judge);
$response = $this->post(route('judging.saveScoreSheet', $entry), $submitData);
$response->assertRedirect(route('judging.auditionEntryList', $audition));
$response->assertSessionHas('success');
expect(ScoreSheet::where('entry_id', $entry->id)->first())->toBeInstanceOf(ScoreSheet::class)
->and(JudgeAdvancementVote::where('entry_id',
$entry->id)->first())->toBeInstanceOf(JudgeAdvancementVote::class)
->and(JudgeAdvancementVote::first()->vote)->toBe('yes');
});
});
describe('JudgingController::updateScoreSheet', function () {
it('denies access to non-judges', function () {
actAsNormal();
$audition = Audition::factory()->create();
$entry = Entry::factory()->forAudition($audition)->create();
$response = $this->patch(route('judging.updateScoreSheet', $entry));
$response->assertRedirect(route('dashboard'));
$response->assertSessionHas('error', 'You are not assigned to judge.');
});
it('denies access to judges not assigned to the audition', function () {
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$audition = Audition::factory()->create();
$entry = Entry::factory()->forAudition($audition)->create();
$this->actingAs($judge);
$response = $this->patch(route('judging.updateScoreSheet', $entry));
$response->assertRedirect(route('judging.index'));
$response->assertSessionHas('error', 'You are not assigned to judge this entry');
});
it('will not update a non-existent score sheet', function () {
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$audition = Audition::factory()->create(['room_id' => $room->id]);
$entry = Entry::factory()->forAudition($audition)->create();
$this->actingAs($judge);
$response = $this->patch(route('judging.updateScoreSheet', $entry));
$response->assertRedirect()->assertSessionHas('error', 'Attempt to edit non existent score sheet');
});
it('will update a score sheet', function () {
$room = Room::factory()->create();
$judge = User::factory()->create();
$room->addJudge($judge);
$scoringGuide = ScoringGuide::factory()->create();
$audition = Audition::factory()->create(['room_id' => $room->id, 'scoring_guide_id' => $scoringGuide->id]);
$subscoreIds = SubscoreDefinition::all()->pluck('id');
$entry = Entry::factory()->forAudition($audition)->create();
$submitData = [
'score' => [
$subscoreIds[0] => 10,
$subscoreIds[1] => 20,
$subscoreIds[2] => 30,
$subscoreIds[3] => 40,
$subscoreIds[4] => 50,
],
'advancement-vote' => 'yes',
];
$this->actingAs($judge);
$this->post(route('judging.saveScoreSheet', $entry), $submitData);
$newSubmitData = [
'score' => [
$subscoreIds[0] => 5,
$subscoreIds[1] => 15,
$subscoreIds[2] => 25,
$subscoreIds[3] => 35,
$subscoreIds[4] => 45,
],
'advancement-vote' => 'no',
];
$response = $this->patch(route('judging.updateScoreSheet', $entry), $newSubmitData);
$response->assertRedirect(route('judging.auditionEntryList', $audition))
->assertSessionHas('success');
expect(ScoreSheet::count())->toEqual(1);
$ss = ScoreSheet::first();
expect($ss->getSubscore($subscoreIds[0]))->toEqual(5);
expect($ss->getSubscore($subscoreIds[1]))->toEqual(15);
expect($ss->getSubscore($subscoreIds[2]))->toEqual(25);
expect($ss->getSubscore($subscoreIds[3]))->toEqual(35);
expect($ss->getSubscore($subscoreIds[4]))->toEqual(45);
expect(JudgeAdvancementVote::count())->toEqual(1);
$vote = JudgeAdvancementVote::first();
expect($vote->vote)->toEqual('no');
});
});