auditionadmin/tests/Feature/app/Http/Controllers/Tabulation/Seating/EnterDoublerDecisionControl...

202 lines
8.6 KiB
PHP

<?php
use App\Models\Audition;
use App\Models\Doubler;
use App\Models\Entry;
use App\Models\EntryTotalScore;
use App\Models\Event;
use App\Models\ScoringGuide;
use App\Models\Student;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->event = Event::factory()->create();
$this->ASaudition = Audition::factory()->create(['event_id' => $this->event->id, 'name' => 'Alto Sax']);
$this->TSaudition = Audition::factory()->create(['event_id' => $this->event->id, 'name' => 'Tenor Sax']);
$this->BSaudition = Audition::factory()->create(['event_id' => $this->event->id, 'name' => 'Bari Sax']);
$this->student = Student::factory()->create();
$this->ASentry = Entry::factory()->create([
'audition_id' => $this->ASaudition->id, 'student_id' => $this->student->id,
]);
$this->TSentry = Entry::factory()->create([
'audition_id' => $this->TSaudition->id, 'student_id' => $this->student->id,
]);
$this->BSentry = Entry::factory()->create([
'audition_id' => $this->BSaudition->id, 'student_id' => $this->student->id,
]);
DB::table('entry_total_scores')->insert([
'entry_id' => $this->ASentry->id,
'seating_total' => 34,
'advancement_total' => 4,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
DB::table('entry_total_scores')->insert([
'entry_id' => $this->TSentry->id,
'seating_total' => 34,
'advancement_total' => 4,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
// DB::table('entry_total_scores')->insert([
// 'entry_id' => $this->BSentry->id,
// 'seating_total' => 34,
// 'advancement_total' => 4,
// 'seating_subscore_totals' => json_encode([22, 2]),
// 'advancement_subscore_totals' => json_encode([22, 2]),
// ]);
});
it('can mark an entry as a no-show', function () {
actAsAdmin();
$response = $this->post(route('seating.audition.noshow', [$this->BSaudition->id, $this->BSentry->id]));
$response->assertRedirect()->assertSessionHas('success');
expect($this->BSentry->fresh()->hasFlag('no_show'))->toBeTrue();
$response->assertRedirect(route('seating.audition', [$this->BSaudition->id]));
});
it('passes exceptions from the enter noshow action', function () {
$this->BSaudition->addFlag('seats_published');
actAsAdmin();
$response = $this->post(route('seating.audition.noshow', [$this->BSaudition->id, $this->BSentry->id]));
$response->assertRedirect()->assertSessionHas('error');
expect($this->BSentry->fresh()->hasFlag('no_show'))->toBeFalse();
});
it('can decline an entry', function () {
actAsAdmin();
$response = $this->post(route('seating.audition.decline', [$this->TSaudition->id, $this->TSentry->id]));
$response->assertRedirect()->assertSessionHas('success');
expect($this->TSentry->fresh()->hasFlag('declined'))->toBeTrue();
$response->assertRedirect(route('seating.audition', [$this->TSaudition->id]));
});
it('passes exceptions from the enter decline action', function () {
actAsAdmin();
$response = $this->post(route('seating.audition.decline', [$this->BSaudition->id, $this->BSentry->id]));
$response->assertRedirect()->assertSessionHas('error');
expect($this->BSentry->fresh()->hasFlag('declined'))->toBeFalse();
});
it('can accept an entry', function () {
DB::table('entry_total_scores')->insert([
'entry_id' => $this->BSentry->id,
'seating_total' => 34,
'advancement_total' => 4,
'seating_subscore_totals' => json_encode([22, 2]),
'advancement_subscore_totals' => json_encode([22, 2]),
]);
actAsAdmin();
$response = $this->post(route('seating.audition.accept', [$this->BSaudition->id, $this->BSentry->id]));
$response->assertRedirect()->assertSessionHas('success');
$response->assertRedirect(route('seating.audition', [$this->BSaudition->id]));
expect($this->ASentry->fresh()->hasFlag('declined'))->toBeTrue()
->and($this->TSentry->fresh()->hasFlag('declined'))->toBeTrue()
->and(Doubler::findDoubler($this->student->id,
$this->event->id)->getAcceptedEntry()->id)->toEqual($this->BSentry->id);
});
it('passes exceptions from the enter accept action', function () {
actAsAdmin();
$response = $this->post(route('seating.audition.accept', [$this->BSaudition->id, $this->BSentry->id]));
$response->assertRedirect()->assertSessionHas('error');
expect($this->BSentry->fresh()->hasFlag('declined'))->toBeFalse();
expect($this->TSentry->fresh()->hasFlag('declined'))->toBeFalse();
expect($this->ASentry->fresh()->hasFlag('declined'))->toBeFalse()
->and(Doubler::findDoubler($this->student->id,
$this->event->id)->accepted_entry)->toBeNull();
});
it('can mass decline', function () {
$sg = ScoringGuide::factory()->create();
$audition = Audition::factory()->create(['event_id' => $this->event->id, 'scoring_guide_id' => $sg->id]);
$otherAudition = Audition::factory()->create(['event_id' => $this->event->id, 'scoring_guide_id' => $sg->id]);
// Scored entry that won't be declining
$entry1 = Entry::factory()->create(['audition_id' => $audition->id, 'student_id' => $this->student->id]);
$entry1Doubler = Entry::factory()->create([
'audition_id' => $otherAudition->id,
'student_id' => $entry1->student->id]);
EntryTotalScore::create([
'entry_id' => $entry1->id,
'seating_total' => 100,
'advancement_total' => 100,
'seating_subscore_totals' => json_encode([100, 100]),
'advancement_subscore_totals' => json_encode([100, 100]),
]);
// Create some space
$spacerEntries = Entry::factory()->count(5)->create(['audition_id' => $audition->id]);
foreach ($spacerEntries as $spacerEntry) {
EntryTotalScore::create([
'entry_id' => $spacerEntry->id,
'seating_total' => 95,
'advancement_total' => 95,
'seating_subscore_totals' => json_encode([95, 95]),
'advancement_subscore_totals' => json_encode([95, 95]),
]);
}
// Scored entry that will already be declined
$entry2 = Entry::factory()->create(['audition_id' => $audition->id]);
$entry2Doubler = Entry::factory()->create([
'audition_id' => $otherAudition->id,
'student_id' => $entry2->student->id]);
EntryTotalScore::create([
'entry_id' => $entry2->id,
'seating_total' => 90,
'advancement_total' => 90,
'seating_subscore_totals' => json_encode([90, 90]),
'advancement_subscore_totals' => json_encode([90, 90]),
]);
$entry2->addFlag('declined');
$entry2->refresh();
// Scored entry that is not a doubler
$entry3 = Entry::factory()->create(['audition_id' => $audition->id]);
EntryTotalScore::create([
'entry_id' => $entry3->id,
'seating_total' => 80,
'advancement_total' => 80,
'seating_subscore_totals' => json_encode([99, 99]),
'advancement_subscore_totals' => json_encode([99, 99]),
]);
// Scored entry that has accepted
$entry4 = Entry::factory()->create(['audition_id' => $audition->id]);
$entry4Doubler = Entry::factory()->create([
'audition_id' => $otherAudition->id,
'student_id' => $entry4->student->id]);
EntryTotalScore::create([
'entry_id' => $entry4->id,
'seating_total' => 75,
'advancement_total' => 75,
'seating_subscore_totals' => json_encode([75, 75]),
'advancement_subscore_totals' => json_encode([75, 75]),
]);
EntryTotalScore::create([
'entry_id' => $entry4Doubler->id,
'seating_total' => 75,
'advancement_total' => 75,
'seating_subscore_totals' => json_encode([75, 75]),
'advancement_subscore_totals' => json_encode([75, 75]),
]);
$doubler = Doubler::findDoubler($entry4->student->id, $audition->event_id);
$doubler->update(['accepted_entry' => $entry4->id]);
$entry4Doubler->addFlag('declined');
$entry4Doubler->refresh();
// ACT
actAsAdmin();
$response = $this->post(route('seating.audition.mass_decline', [$audition->id]), [
'decline-below' => 3,
]);
$response->assertRedirect(route('seating.audition', [$audition->id]));
expect($entry1->fresh()->hasFlag('declined'))->toBeFalse();
expect($entry2->fresh()->hasFlag('declined'))->toBeTrue();
expect($entry3->fresh()->hasFlag('declined'))->toBeFalse();
expect($entry4->fresh()->hasFlag('declined'))->toBeFalse();
});