Add scopes to models #10
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
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)) {
|
if ($this->hasFlag($flag)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -78,7 +79,7 @@ class Entry extends Model
|
||||||
$this->flags()->create(['flag_name' => $flag]);
|
$this->flags()->create(['flag_name' => $flag]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeFlag($flag)
|
public function removeFlag($flag): void
|
||||||
{
|
{
|
||||||
// remove related auditionFlag where flag_name = $flag
|
// remove related auditionFlag where flag_name = $flag
|
||||||
$this->flags()->where('flag_name', $flag)->delete();
|
$this->flags()->where('flag_name', $flag)->delete();
|
||||||
|
|
@ -100,4 +101,23 @@ class Entry extends Model
|
||||||
{
|
{
|
||||||
return $this->hasOne(Seat::class);
|
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');
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\Audition;
|
||||||
|
use App\Models\Student;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -16,9 +18,28 @@ class EntryFactory extends Factory
|
||||||
*/
|
*/
|
||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
|
$student = Student::factory()->create();
|
||||||
|
$audition = Audition::factory()->create();
|
||||||
return [
|
return [
|
||||||
'student_id' => 3,
|
'student_id' => $student->id,
|
||||||
'audition_id' =>3
|
'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]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\School;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -16,7 +17,9 @@ class StudentFactory extends Factory
|
||||||
*/
|
*/
|
||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
|
$school = School::factory()->create();
|
||||||
return [
|
return [
|
||||||
|
'school_id' => $school->id,
|
||||||
'first_name' => fake()->firstName(),
|
'first_name' => fake()->firstName(),
|
||||||
'last_name' => fake()->lastName(),
|
'last_name' => fake()->lastName(),
|
||||||
'grade' => rand(7,12),
|
'grade' => rand(7,12),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Entry;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('only returns entries for seating with forSeating scope', function () {
|
||||||
|
// Arrange
|
||||||
|
Entry::factory()->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);
|
||||||
|
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue