auditionadmin/tests/Feature/app/Http/Controllers/Tabulation/AdvancementControllerTest.php

214 lines
9.5 KiB
PHP

<?php
use App\Models\Audition;
use App\Models\Entry;
use App\Models\EntryTotalScore;
use App\Models\ScoringGuide;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
afterEach(function () {
\Illuminate\Support\Facades\Cache::flush();
});
describe('AdvancementController::status', function () {
beforeEach(function () {
$sg = ScoringGuide::factory()->create();
$this->audition1 = Audition::factory()->create(['scoring_guide_id' => $sg->id, 'score_order' => 1]);
$this->audition2 = Audition::factory()->create(['scoring_guide_id' => $sg->id, 'score_order' => 2]);
// Create 15 entries for audition 1 and score them all
$a1Entries = Entry::factory()->count(15)->create(['audition_id' => $this->audition1->id]);
foreach ($a1Entries as $entry) {
EntryTotalScore::create([
'entry_id' => $entry->id,
'seating_total' => 34,
'advancement_total' => 4,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
}
// Create 10 entries for audition2 and score one of them
$a2Entries = Entry::factory()->count(10)->create(['audition_id' => $this->audition2->id]);
EntryTotalScore::create([
'entry_id' => $a2Entries->first()->id,
'seating_total' => 34,
'advancement_total' => 4,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
});
it('denies access to regular users and guests', function () {
$this->get(route('advancement.status'))->assertRedirect(route('home'));
actAsNormal();
$this->get(route('advancement.status'))->assertRedirect(route('dashboard'));
});
it('returns the correct status', function () {
actAsAdmin();
$response = $this->get(route('advancement.status'));
$response->assertOk()->assertViewIs('tabulation.advancement.status');
$data = $response->viewData('auditionData');
expect($data)->toHaveCount(2)
->and($data[0]['name'])->toEqual($this->audition1->name)
->and($data[0]['entries_count'])->toEqual(15)
->and($data[0]['unscored_entries_count'])->toEqual(0)
->and($data[0]['scored_entries_count'])->toEqual(15)
->and($data[0]['scored_percentage'])->toEqual(100)
->and($data[0]['scoring_complete'])->toBeTruthy()
->and($data[0]['published'])->toBeFalsy()
->and($data[1]['name'])->toEqual($this->audition2->name)
->and($data[1]['entries_count'])->toEqual(10)
->and($data[1]['unscored_entries_count'])->toEqual(9)
->and($data[1]['scored_entries_count'])->toEqual(1)
->and($data[1]['scored_percentage'])->toEqual(10)
->and($data[1]['scoring_complete'])->toBeFalsy()
->and($data[1]['published'])->toBeFalsy();
});
});
describe('AdvancementController::ranking', function () {
beforeEach(function () {
$this->audition = Audition::factory()->create();
$this->entries = Entry::factory()->count(3)->create(['audition_id' => $this->audition->id]);
EntryTotalScore::create([
'entry_id' => $this->entries[0]->id,
'seating_total' => 34,
'advancement_total' => 20,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
EntryTotalScore::create([
'entry_id' => $this->entries[1]->id,
'seating_total' => 34,
'advancement_total' => 10,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
EntryTotalScore::create([
'entry_id' => $this->entries[2]->id,
'seating_total' => 34,
'advancement_total' => 30,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
});
it('denies access to regular users and guests', function () {
$this->get(route('advancement.ranking', $this->audition))->assertRedirect(route('home'));
actAsNormal();
$this->get(route('advancement.ranking', $this->audition))->assertRedirect(route('dashboard'));
});
it('returns a list of entries', function () {
actAsAdmin();
$response = $this->get(route('advancement.ranking', $this->audition));
$response->assertOk()->assertViewIs('tabulation.advancement.ranking');
$response->assertSeeInOrder([
$this->entries[2]->student->full_name(),
$this->entries[0]->student->full_name(),
$this->entries[1]->student->full_name(),
]);
});
it('shows a form to set accepted entries if scoring is complete', function () {
actAsAdmin();
$response = $this->get(route('advancement.ranking', $this->audition));
$response->assertOk()->assertViewIs('tabulation.advancement.ranking');
$response->assertSee('Mark entries ranked');
});
it('does not show the form if there are unseated entries', function () {
actAsAdmin();
$newEntry = Entry::factory()->create(['audition_id' => $this->audition->id]);
$response = $this->get(route('advancement.ranking', $this->audition));
$response->assertOk()->assertViewIs('tabulation.advancement.ranking');
$response->assertDontSee('Mark entries ranked');
});
});
describe('AdvancementController::setAuditionPassers', function () {
beforeEach(function () {
$this->audition = Audition::factory()->create();
$this->entries = Entry::factory()->count(3)->create(['audition_id' => $this->audition->id]);
EntryTotalScore::create([
'entry_id' => $this->entries[0]->id,
'seating_total' => 34,
'advancement_total' => 20,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
EntryTotalScore::create([
'entry_id' => $this->entries[1]->id,
'seating_total' => 34,
'advancement_total' => 10,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
EntryTotalScore::create([
'entry_id' => $this->entries[2]->id,
'seating_total' => 34,
'advancement_total' => 30,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
});
it('will not publish advancement with no advancing students', function () {
actAsAdmin();
$response = $this->post(route('advancement.setAuditionPassers', $this->audition));
$response->assertRedirect(route('advancement.ranking', $this->audition));
$response->assertSessionHas('error', 'Cannot publish advancement if no entries advance');
});
it('adds appropriate flags to the audition and passing entries', function () {
actAsAdmin();
$response = $this->post(route('advancement.setAuditionPassers', $this->audition),
[
'pass' => [
$this->entries[0]->id => 'on',
],
],
);
expect($this->audition->fresh()->hasFlag('advancement_published'))->toBeTrue();
expect($this->entries[0]->fresh()->hasFlag('will_advance'))->toBeTrue();
expect($this->entries[1]->fresh()->hasFlag('will_advance'))->toBeFalse();
expect($this->entries[2]->fresh()->hasFlag('will_advance'))->toBeFalse();
});
});
describe('AdvancementController::clearAuditionPassers', function () {
beforeEach(function () {
$this->audition = Audition::factory()->create();
$this->entries = Entry::factory()->count(3)->create(['audition_id' => $this->audition->id]);
EntryTotalScore::create([
'entry_id' => $this->entries[0]->id,
'seating_total' => 34,
'advancement_total' => 20,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
EntryTotalScore::create([
'entry_id' => $this->entries[1]->id,
'seating_total' => 34,
'advancement_total' => 10,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
EntryTotalScore::create([
'entry_id' => $this->entries[2]->id,
'seating_total' => 34,
'advancement_total' => 30,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
});
it('clears passers', function () {
$this->audition->addFlag('advancement_published');
$this->entries[0]->addFlag('will_advance');
$this->entries[1]->addFlag('will_advance');
actAsAdmin();
$response = $this->delete(route('advancement.clearAuditionPassers', $this->audition));
expect($this->audition->fresh()->hasFlag('advancement_published'))->toBeFalse();
expect($this->entries[0]->fresh()->hasFlag('will_advance'))->toBeFalse();
expect($this->entries[1]->fresh()->hasFlag('will_advance'))->toBeFalse();
expect($this->entries[2]->fresh()->hasFlag('will_advance'))->toBeFalse();
});
});