diff --git a/app/Models/Entry.php b/app/Models/Entry.php index d48f760..9b08f7e 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -75,14 +75,15 @@ class Entry extends Model if ($this->hasFlag($flag)) { return; } - $this->flags()->create(['flag_name' => $flag]); + $this->load('flags'); } public function removeFlag($flag): void { // remove related auditionFlag where flag_name = $flag $this->flags()->where('flag_name', $flag)->delete(); + $this->load('flags'); } /** diff --git a/tests/Feature/Models/EntryTest.php b/tests/Feature/Models/EntryTest.php new file mode 100644 index 0000000..f0ba254 --- /dev/null +++ b/tests/Feature/Models/EntryTest.php @@ -0,0 +1,186 @@ +create(); + $entry = Entry::factory()->create(['student_id' => $student->id]); + // Act and Assert + expect($entry->student->first_name)->toBe($student->first_name) + ->and($entry->student)->toBeInstanceOf(Student::class); +}); + +test('has an audition', function () { + // Arrange + $audition = Audition::factory()->create(); + $entry = Entry::factory()->create(['audition_id' => $audition->id]); + // Act and Assert + expect($entry->audition)->toBeInstanceOf(Audition::class) + ->and($entry->audition->name)->toBe($audition->name); + +}); + +test('has a school', function () { + // Arrange + $student = Student::factory()->create(); + $school = $student->school; + $entry = Entry::factory()->create(['student_id' => $student->id]); + // Act and Assert + expect($entry->school->name)->toBe($school->name) + ->and($entry->school)->toBeInstanceOf(School::class); +}); + +test('has score sheets', function () { + // Arrange + $judge = User::factory()->create(); + $judge2 = User::factory()->create(); + $entry = Entry::factory()->create(); + $ss = ScoreSheet::create([ + 'entry_id' => $entry->id, + 'user_id' => $judge->id, + 'subscores' => json_encode(['subscore1' => 10, 'subscore2' => 20]), + ]); + $ss2 = ScoreSheet::create([ + 'entry_id' => $entry->id, + 'user_id' => $judge2->id, + 'subscores' => json_encode(['subscore1' => 10, 'subscore2' => 20]), + ]); + // Act and Assert + expect($entry->scoreSheets->count())->toBe(2) + ->and($entry->scoreSheets->first())->toBeInstanceOf(ScoreSheet::class); +}); + +test('has advancement votes', function () { + $entry = Entry::factory()->create(); + $judge = User::factory()->create(); + $judge2 = User::factory()->create(); + JudgeAdvancementVote::create(['user_id' => $judge->id, 'entry_id' => $entry->id, 'vote' => 'yes']); + JudgeAdvancementVote::create(['user_id' => $judge2->id, 'entry_id' => $entry->id, 'vote' => 'no']); + // Act and Assert + expect($entry->advancementVotes->count())->toBe(2) + ->and($entry->advancementVotes->first())->toBeInstanceOf(JudgeAdvancementVote::class); +}); + +it('can have flags and can check for a specific flag', function () { + // Arrange + $entry = Entry::factory()->create(); + EntryFlag::create(['entry_id' => $entry->id, 'flag_name' => 'declined']); + EntryFlag::create(['entry_id' => $entry->id, 'flag_name' => 'no-show']); + // Act & Assert + expect($entry->flags->count())->toBe(2) + ->and($entry->flags->first()->flag_name)->toBe('declined') + ->and($entry->hasFlag('declined'))->toBeTrue() + ->and($entry->hasFlag('random'))->toBeFalse(); +}); + +it('can set and remove a flag', function () { + // Arrange + $entry = Entry::factory()->create(); + // Act + $entry->addFlag('Test Flag'); + $entry->addFlag('Second Flag'); + // Assert + expect($entry->hasFlag('Test Flag'))->toBeTrue() + ->and($entry->hasFlag('Second Flag'))->toBeTrue() + ->and($entry->hasFlag('random'))->toBeFalse(); + $entry->removeFlag('Test Flag'); + expect($entry->hasFlag('Test Flag'))->toBeFalse() + ->and($entry->hasFlag('Second Flag'))->toBeTrue(); +}); + +it('always has a score sheet count available', function () { + // Arrange + // Arrange + $judge = User::factory()->create(); + $judge2 = User::factory()->create(); + $entry = Entry::factory()->create(); + $ss = ScoreSheet::create([ + 'entry_id' => $entry->id, + 'user_id' => $judge->id, + 'subscores' => json_encode(['subscore1' => 10, 'subscore2' => 20]), + ]); + $ss2 = ScoreSheet::create([ + 'entry_id' => $entry->id, + 'user_id' => $judge2->id, + 'subscores' => json_encode(['subscore1' => 10, 'subscore2' => 20]), + ]); + // Act & Assert + expect($entry->score_sheets_count)->toBe(2); +}); + +it('has a seat', function () { + // Arrange + $entry = Entry::factory()->create(); + $ensemble = Ensemble::factory()->create(); + $seat = Seat::create([ + 'ensemble_id' => $ensemble->id, + 'audition_id' => $entry->audition_id, + 'seat' => fake()->numberBetween(1, 15), + 'entry_id' => $entry->id, + ]); + // Act & Assert + expect($entry->seat->seat)->toBe($seat->seat) + ->and($entry->seat->ensemble_id)->toBe($ensemble->id) + ->and($entry->seat->audition_id)->toBe($entry->audition_id) + ->and($entry->seat)->toBeInstanceOf(Seat::class); + +}); + +it('has a forSeating scope that only returns those entries entered for seating', function () { + // Arrange + $noSeatStudent = Student::factory()->create(['first_name' => 'Advance Only']); + $noAdvanceStudent = Student::factory()->create(['first_name' => 'Seating Only']); + Entry::factory()->create(['student_id' => $noSeatStudent->id, 'for_seating' => false, 'for_advancement' => true]); + Entry::factory()->create([ + 'student_id' => $noAdvanceStudent->id, 'for_seating' => true, + 'for_advancement' => false, + ]); + Entry::factory()->count(10)->create(['for_seating' => true, 'for_advancement' => true]); + Entry::factory()->count(5)->create(['for_seating' => false, 'for_advancement' => true]); + // Act & Assert + expect(Entry::forSeating()->count())->toBe(11) + ->and(Entry::forSeating()->get()->first())->toBeInstanceOf(Entry::class) + ->and(Entry::forSeating()->get()->first()->student->first_name)->toBe('Seating Only'); +}); + +it('has a forAdvancement scope that only returns those entries entered for advancement', function () { + // Arrange + $noSeatStudent = Student::factory()->create(['first_name' => 'Advance Only']); + $noAdvanceStudent = Student::factory()->create(['first_name' => 'Seating Only']); + Entry::factory()->create(['student_id' => $noSeatStudent->id, 'for_seating' => false, 'for_advancement' => true]); + Entry::factory()->create([ + 'student_id' => $noAdvanceStudent->id, 'for_seating' => true, + 'for_advancement' => false, + ]); + Entry::factory()->count(10)->create(['for_seating' => true, 'for_advancement' => true]); + Entry::factory()->count(5)->create(['for_seating' => false, 'for_advancement' => true]); + // Act & Assert + expect(Entry::forAdvancement()->count())->toBe(16) + ->and(Entry::forAdvancement()->get()->first())->toBeInstanceOf(Entry::class) + ->and(Entry::forAdvancement()->get()->first()->student->first_name)->toBe('Advance Only'); +}); + +it('has an available scope that returns only auditions without a flag that would prevent seating', function () { + Entry::factory()->count(10)->create(); + Entry::factory()->create()->addFlag('declined'); + Entry::factory()->create()->addFlag('no-show'); + Entry::factory()->create()->addFlag('failed-prelim'); + // Act & Assert + expect(Entry::all()->count())->toBe(13) + ->and(Entry::available()->count())->toBe(10) + ->and(Entry::available()->get()->first())->toBeInstanceOf(Entry::class) + ->and(Entry::available()->get()->first()->flags->count())->toBe(0); +});