diff --git a/app/Models/HistoricalSeat.php b/app/Models/HistoricalSeat.php index 916ea6d..6c9e440 100644 --- a/app/Models/HistoricalSeat.php +++ b/app/Models/HistoricalSeat.php @@ -2,11 +2,14 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class HistoricalSeat extends Model { + use hasFactory; + protected $guarded = []; public function student(): BelongsTo diff --git a/app/Models/NominationEnsemble.php b/app/Models/NominationEnsemble.php index 2829e4a..a6fe671 100644 --- a/app/Models/NominationEnsemble.php +++ b/app/Models/NominationEnsemble.php @@ -2,11 +2,14 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class NominationEnsemble extends Model { + use HasFactory; + protected $guarded = []; protected function casts(): array diff --git a/app/Models/Student.php b/app/Models/Student.php index f68c4b4..0b3cd73 100644 --- a/app/Models/Student.php +++ b/app/Models/Student.php @@ -13,7 +13,7 @@ class Student extends Model { use HasFactory; - public static $shirtSizes = [ + public static array $shirtSizes = [ 'none' => '---', 'YS' => 'Youth Small', 'YM' => 'Youth Medium', @@ -68,7 +68,7 @@ class Student extends Model /** * Returns the directors at this student's school. - * Alias of users()) + * Alias of users() * ' */ public function directors(): HasManyThrough @@ -116,8 +116,8 @@ class Student extends Model return Entry::query() ->where('student_id', $this->id) - ->whereHas('audition', function ($query) use ($event) { - $query->where('event_id', $event); + ->whereHas('audition', function ($query) use ($eventId) { + $query->where('event_id', $eventId); }) ->with('audition.SeatingLimits') // Eager load the audition relation if needed ->with('totalScore') diff --git a/database/factories/AuditionFactory.php b/database/factories/AuditionFactory.php index 8366d9c..e221203 100644 --- a/database/factories/AuditionFactory.php +++ b/database/factories/AuditionFactory.php @@ -74,4 +74,13 @@ class AuditionFactory extends Factory fn (array $attributes) => ['for_seating' => 0] ); } + + public function forEvent(Event $event): self + { + return $this->state(function (array $attributes) use ($event) { + return [ + 'event_id' => $event->id, + ]; + }); + } } diff --git a/database/factories/DoublerRequestFactory.php b/database/factories/DoublerRequestFactory.php new file mode 100644 index 0000000..65e6f82 --- /dev/null +++ b/database/factories/DoublerRequestFactory.php @@ -0,0 +1,43 @@ + $this->faker->word(), + 'created_at' => Carbon::now(), + 'updated_at' => Carbon::now(), + 'event_id' => Event::factory(), + 'student_id' => Student::factory(), + ]; + } + + public function forStudent(Student $student): self + { + return $this->state(function (array $attributes) use ($student) { + return [ + 'student_id' => $student->id, + ]; + }); + } + + public function forEvent(Event $event): self + { + return $this->state(function (array $attributes) use ($event) { + return [ + 'event_id' => $event->id, + ]; + }); + } +} diff --git a/database/factories/EntryFactory.php b/database/factories/EntryFactory.php index 80cec5c..ae99121 100644 --- a/database/factories/EntryFactory.php +++ b/database/factories/EntryFactory.php @@ -18,11 +18,9 @@ class EntryFactory extends Factory */ public function definition(): array { - $student = Student::factory()->create(); - $audition = Audition::factory()->create(); return [ - 'student_id' => $student->id, - 'audition_id' => $audition->id, + 'student_id' => Student::factory(), + 'audition_id' => Audition::factory(), 'draw_number' => null, 'for_seating' => 1, 'for_advancement' => 1, @@ -43,4 +41,22 @@ class EntryFactory extends Factory fn (array $attributes) => ['for_seating' => 0] ); } + + public function forStudent(Student $student): self + { + return $this->state(function (array $attributes) use ($student) { + return [ + 'student_id' => $student->id, + ]; + }); + } + + public function forAudition(Audition $audition): self + { + return $this->state(function (array $attributes) use ($audition) { + return [ + 'audition_id' => $audition->id, + ]; + }); + } } diff --git a/database/factories/HistoricalSeatFactory.php b/database/factories/HistoricalSeatFactory.php new file mode 100644 index 0000000..50896a8 --- /dev/null +++ b/database/factories/HistoricalSeatFactory.php @@ -0,0 +1,33 @@ + Carbon::now(), + 'updated_at' => Carbon::now(), + 'year' => $this->faker->randomNumber(), + 'seat_description' => $this->faker->text(), + 'student_id' => Student::factory(), + ]; + } + + public function forStudent(Student $student): self + { + return $this->state(function (array $attributes) use ($student) { + return [ + 'student_id' => $student->id, + ]; + }); + } +} diff --git a/database/factories/NominationEnsembleEntryFactory.php b/database/factories/NominationEnsembleEntryFactory.php index 1f04ba9..f9cc49d 100644 --- a/database/factories/NominationEnsembleEntryFactory.php +++ b/database/factories/NominationEnsembleEntryFactory.php @@ -2,7 +2,9 @@ namespace Database\Factories; +use App\Models\NominationEnsemble; use App\Models\NominationEnsembleEntry; +use App\Models\Student; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Carbon; @@ -13,11 +15,29 @@ class NominationEnsembleEntryFactory extends Factory public function definition(): array { return [ - 'student_id' => $this->faker->randomNumber(), - 'nomination_ensemble_id' => $this->faker->randomNumber(), - 'data' => $this->faker->words(), + 'student_id' => Student::factory(), + 'nomination_ensemble_id' => NominationEnsemble::factory(), + 'data' => json_encode([5, 2, 4]), 'created_at' => Carbon::now(), 'updated_at' => Carbon::now(), ]; } + + public function forEnsemble(NominationEnsemble $ensemble): self + { + return $this->state(function (array $attributes) use ($ensemble) { + return [ + 'nomination_ensemble_id' => $ensemble->id, + ]; + }); + } + + public function forStudent(Student $student): self + { + return $this->state(function (array $attributes) use ($student) { + return [ + 'student_id' => $student->id, + ]; + }); + } } diff --git a/database/factories/NominationEnsembleFactory.php b/database/factories/NominationEnsembleFactory.php new file mode 100644 index 0000000..70cc6f4 --- /dev/null +++ b/database/factories/NominationEnsembleFactory.php @@ -0,0 +1,25 @@ + $this->faker->name(), + 'entry_deadline' => Carbon::now(), + 'minimum_grade' => 1, + 'maximum_grade' => 15, + 'data' => json_encode([2, 5, 3]), + 'created_at' => Carbon::now(), + 'updated_at' => Carbon::now(), + ]; + } +} diff --git a/tests/Feature/app/Models/StudentTest.php b/tests/Feature/app/Models/StudentTest.php new file mode 100644 index 0000000..6571922 --- /dev/null +++ b/tests/Feature/app/Models/StudentTest.php @@ -0,0 +1,102 @@ +student = Student::factory()->create(); +}); + +it('can return its nominations', function () { + NominationEnsembleEntry::factory() + ->forStudent($this->student)->create(); + expect($this->student->nominations()->count())->toEqual(1) + ->and($this->student->nominations()->first())->toBeInstanceOf(NominationEnsembleEntry::class); +}); + +it('can return its school', function () { + expect($this->student->school->id)->toEqual(1) + ->and($this->student->school)->toBeInstanceOf(School::class); +}); + +it('can return its historical seats', function () { + HistoricalSeat::factory() + ->forStudent($this->student)->create(); + expect($this->student->historicalSeats->count())->toEqual(1) + ->and($this->student->historicalSeats()->first())->toBeInstanceOf(HistoricalSeat::class); +}); + +it('can return the students directors using either director or user', function () { + User::factory()->count(2)->create(['school_id' => $this->student->school_id]); + expect($this->student->directors()->count())->toEqual(2) + ->and($this->student->directors()->first())->toBeInstanceOf(User::class); +}); + +it('can return its entries)', function () { + Entry::factory()->count(3)->forStudent($this->student)->create(); + expect($this->student->entries()->count())->toEqual(3) + ->and($this->student->entries()->first())->toBeInstanceOf(Entry::class); +}); + +it('can return its full name', function () { + expect($this->student->full_name())->toEqual($this->student->first_name.' '.$this->student->last_name) + ->and($this->student->full_name(true))->toEqual($this->student->last_name.', '.$this->student->first_name); +}); + +it('can return its doubler requests', function () { + DoublerRequest::factory()->forStudent($this->student)->create(); + DoublerRequest::factory()->forStudent($this->student)->create(); + expect($this->student->doublerRequests()->count())->toEqual(2) + ->and($this->student->doublerRequests()->first())->toBeInstanceOf(DoublerRequest::class); +}); + +it('can return its doublers', function () { + $event = Event::factory()->create(); + DB::table('doublers')->insert([ + 'student_id' => $this->student->id, + 'event_id' => $event->id, + 'entries' => json_encode([1, 2, 3]), + 'accepted_entry' => null, + ]); + expect($this->student->doublers()->count())->toEqual(1) + ->and($this->student->doublers()->first())->toBeInstanceOf(Doubler::class); +}); + +it('can check if it is a doubler in a given event', function () { + $event = Event::factory()->create(); + expect($this->student->isDoublerInEvent($event))->toBeFalse(); + DB::table('doublers')->insert([ + 'student_id' => $this->student->id, + 'event_id' => $event->id, + 'entries' => json_encode([1, 2, 3]), + 'accepted_entry' => null, + ]); + expect($this->student->isDoublerInEvent($event))->toBeTrue(); +}); + +it('can return its entries for a given event', function () { + $event1 = Event::factory()->create(); + $event2 = Event::factory()->create(); + $audition1 = Audition::factory()->forEvent($event1)->create(); + $audition2 = Audition::factory()->forEvent($event2)->create(); + $audition3 = Audition::factory()->forEvent($event2)->create(); + Entry::factory()->forStudent($this->student)->forAudition($audition1)->create(); + Entry::factory()->forStudent($this->student)->forAudition($audition2)->create(); + Entry::factory()->forStudent($this->student)->forAudition($audition3)->create(); + expect($this->student->entries()->count())->toEqual(3) + ->and($this->student->entriesForEvent($event1->id)->count())->toEqual(1) + ->and($this->student->entriesForEvent($event1->id)->first())->toBeInstanceOf(Entry::class) + ->and($this->student->entriesForEvent($event2)->count())->toEqual(2) + ->and($this->student->entriesForEvent($event2)->first())->toBeInstanceOf(Entry::class); +});