From 3acc478143af44b07dc8ff6c4ca7758b16c288b6 Mon Sep 17 00:00:00 2001 From: Matt Young Date: Sun, 30 Jun 2024 22:14:17 -0500 Subject: [PATCH] Entry scope functions added --- app/Models/Entry.php | 24 ++++++++++- database/factories/EntryFactory.php | 25 +++++++++++- database/factories/StudentFactory.php | 3 ++ tests/Feature/Models/EntryTest.phpTest.php | 46 ++++++++++++++++++++++ 4 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 tests/Feature/Models/EntryTest.phpTest.php diff --git a/app/Models/Entry.php b/app/Models/Entry.php index 680a4f4..d48f760 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -69,7 +70,7 @@ class Entry extends Model } - public function addFlag($flag) + public function addFlag($flag): void { if ($this->hasFlag($flag)) { return; @@ -78,7 +79,7 @@ class Entry extends Model $this->flags()->create(['flag_name' => $flag]); } - public function removeFlag($flag) + public function removeFlag($flag): void { // remove related auditionFlag where flag_name = $flag $this->flags()->where('flag_name', $flag)->delete(); @@ -100,4 +101,23 @@ class Entry extends Model { return $this->hasOne(Seat::class); } + + public function scopeForSeating(Builder $query): void + { + $query->where('for_seating', 1); + } + + public function scopeForAdvancement(Builder $query): void + { + $query->where('for_advancement', 1); + } + + public function scopeAvailable(Builder $query): void + { + $query->whereDoesntHave('flags', function (Builder $query) { + $query->where('flag_name', 'declined') + ->orWhere('flag_name', 'no-show') + ->orWhere('flag_name', 'failed-prelim'); + }); + } } diff --git a/database/factories/EntryFactory.php b/database/factories/EntryFactory.php index ad03155..5ee40fa 100644 --- a/database/factories/EntryFactory.php +++ b/database/factories/EntryFactory.php @@ -2,6 +2,8 @@ namespace Database\Factories; +use App\Models\Audition; +use App\Models\Student; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -16,9 +18,28 @@ class EntryFactory extends Factory */ public function definition(): array { + $student = Student::factory()->create(); + $audition = Audition::factory()->create(); return [ - 'student_id' => 3, - 'audition_id' =>3 + 'student_id' => $student->id, + 'audition_id' => $audition->id, + 'draw_number' => null, + 'for_seating' => 1, + 'for_advancement' => 1, ]; } + + public function seatingOnly(): self + { + return $this->state( + fn (array $attributes) => ['for_advancement' => 0] + ); + } + + public function advanceOnly(): self + { + return $this->state( + fn (array $attributes) => ['for_seating' => 0] + ); + } } diff --git a/database/factories/StudentFactory.php b/database/factories/StudentFactory.php index 44ed7c1..99efec3 100644 --- a/database/factories/StudentFactory.php +++ b/database/factories/StudentFactory.php @@ -2,6 +2,7 @@ namespace Database\Factories; +use App\Models\School; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -16,7 +17,9 @@ class StudentFactory extends Factory */ public function definition(): array { + $school = School::factory()->create(); return [ + 'school_id' => $school->id, 'first_name' => fake()->firstName(), 'last_name' => fake()->lastName(), 'grade' => rand(7,12), diff --git a/tests/Feature/Models/EntryTest.phpTest.php b/tests/Feature/Models/EntryTest.phpTest.php new file mode 100644 index 0000000..a9bea2f --- /dev/null +++ b/tests/Feature/Models/EntryTest.phpTest.php @@ -0,0 +1,46 @@ +advanceOnly()->create(); + $seatingEntry = Entry::factory()->create(); + + // Act & Assert + expect(Entry::forSeating()->get()) + ->toHaveCount(1) + ->first()->id->toEqual($seatingEntry->id); +}); + +it('only returns entries for advancement with for forAdvancement scope', function () { + // Arrange + Entry::factory()->seatingOnly()->create(); + $advancementEntry = Entry::factory()->create(); + + // Act & Assert + expect(Entry::forAdvancement()->get()) + ->toHaveCount(1) + ->first()->id->toEqual($advancementEntry->id); +}); + +it('only returns entries that do not have a declined, no-show, or failed-prelim flag with available scope', + function () { + // Arrange + $availableEntry = Entry::factory()->create(); + $declinedEntry = Entry::factory()->create(); + $noShowEntry = Entry::factory()->create(); + $failedPrelimEntry = Entry::factory()->create(); + $declinedEntry->addFlag('declined'); + $noShowEntry->addFlag('no-show'); + $failedPrelimEntry->addFlag('failed-prelim'); + + // Act & Assert + expect(Entry::available()->get()) + ->toHaveCount(1) + ->first()->id->toEqual($availableEntry->id); + + });