Create tests for app/Models/Audition

This commit is contained in:
Matt Young 2025-07-03 03:07:45 -05:00
parent 0f1ed33216
commit c309c23ca6
3 changed files with 195 additions and 1 deletions

View File

@ -3,17 +3,21 @@
namespace App\Mail; namespace App\Mail;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable; use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content; use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope; use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
/**
* @codeCoverageIgnore
*/
// TODO: Figure out how to write tests for mailers
class NewUserPassword extends Mailable class NewUserPassword extends Mailable
{ {
use Queueable, SerializesModels; use Queueable, SerializesModels;
public $user; public $user;
public $password; public $password;
/** /**

View File

@ -142,8 +142,12 @@ class Audition extends Model
return $this->hasMany(Seat::class); return $this->hasMany(Seat::class);
} }
/**
* @codeCoverageIgnoreStart
*/
public function getDoublerEntries(): Collection public function getDoublerEntries(): Collection
{ {
// TODO: Remove if truly depricated
return $this->entries() return $this->entries()
->whereIn('student_id', function ($query) { ->whereIn('student_id', function ($query) {
$query->select('student_id') $query->select('student_id')
@ -153,6 +157,10 @@ class Audition extends Model
->get(); ->get();
} }
/**
* @codeCoverageIgnore
* TODO: Add Test Later
*/
public function scopeOpen(Builder $query): void public function scopeOpen(Builder $query): void
{ {
$currentDate = Carbon::now('America/Chicago'); $currentDate = Carbon::now('America/Chicago');
@ -160,11 +168,19 @@ class Audition extends Model
$query->where('entry_deadline', '>=', $currentDate); $query->where('entry_deadline', '>=', $currentDate);
} }
/**
* @codeCoverageIgnore
* TODO: Add Test Later
*/
public function scopeForSeating(Builder $query): void public function scopeForSeating(Builder $query): void
{ {
$query->where('for_seating', 1)->orderBy('score_order'); $query->where('for_seating', 1)->orderBy('score_order');
} }
/**
* @codeCoverageIgnore
* TODO: Add Test Later
*/
public function scopeForAdvancement(Builder $query): void public function scopeForAdvancement(Builder $query): void
{ {
$query->where('for_advancement', 1)->orderBy('score_order'); $query->where('for_advancement', 1)->orderBy('score_order');
@ -185,4 +201,7 @@ class Audition extends Model
}); });
} }
/**
* @codeCoverageIgnoreEnd
*/
} }

View File

@ -0,0 +1,171 @@
<?php
use App\Models\Audition;
use App\Models\Ensemble;
use App\Models\Entry;
use App\Models\Room;
use App\Models\Seat;
use App\Models\SeatingLimit;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->audition = Audition::factory()->create(['entry_fee' => 2000]);
});
it('can return its event', function () {
expect($this->audition->event)->toBeInstanceOf(App\Models\Event::class);
});
it('can return its entries', function () {
Entry::factory()->count(5)->create(['audition_id' => $this->audition->id]);
expect($this->audition->entries)->toBeInstanceOf(Illuminate\Database\Eloquent\Collection::class)
->and($this->audition->entries->count())->toBeGreaterThan(0)
->and($this->audition->entries->first())->toBeInstanceOf(App\Models\Entry::class);
});
it('can return its unscored entries', function () {
$entries = Entry::factory()->count(25)->create(['audition_id' => $this->audition->id]);
DB::table('entry_total_scores')->insert([
'entry_id' => $entries[0]->id,
'seating_total' => 10,
'advancement_total' => 10,
'seating_subscore_totals' => json_encode([5, 5]),
'advancement_subscore_totals' => json_encode([5, 5]),
]);
$entries[1]->addFlag('no_show');
$entries[2]->addFlag('failed_prelim');
expect($this->audition->unscoredEntries)->toBeInstanceOf(Illuminate\Database\Eloquent\Collection::class)
->and($this->audition->unscoredEntries->count())->toBe(22)
->and($this->audition->unscoredEntries->first())->toBeInstanceOf(App\Models\Entry::class)
->and($this->audition->unscoredEntries->doesntContain($entries[0]))->toBeTrue()
->and($this->audition->unscoredEntries->doesntContain($entries[1]))->toBeTrue()
->and($this->audition->unscoredEntries->doesntContain($entries[2]))->toBeTrue()
->and($this->audition->unscoredEntries->contains($entries[12]))->toBeTrue()
->and($this->audition->unscoredEntries->contains($entries[8]))->toBeTrue();
});
it('can return its room if one is set', function () {
expect($this->audition->room)->toBeNull();
$room = Room::factory()->create();
$this->audition->room()->associate($room);
$this->audition->save();
expect($this->audition->room)->toBeInstanceOf(App\Models\Room::class);
});
it('can return its scoring guide if one is set', function () {
expect($this->audition->scoringGuide)->toBeNull();
$guide = App\Models\ScoringGuide::factory()->create();
$this->audition->scoringGuide()->associate($guide);
$this->audition->save();
expect($this->audition->scoringGuide)->toBeInstanceOf(App\Models\ScoringGuide::class);
});
it('can return its bonus score definition if one is set', function () {
expect($this->audition->bonusScore()->count())->toBe(0);
$definition = App\Models\BonusScoreDefinition::factory()->create();
$this->audition->bonusScore()->attach($definition);
$this->audition->save();
expect($this->audition->bonusScore->first())->toBeInstanceOf(App\Models\BonusScoreDefinition::class);
});
it('can return its seating limits if any are set', function () {
$we = Ensemble::create([
'code' => 'we',
'name' => 'Wind Ensemble',
'event_id' => $this->audition->event_id,
'rank' => 1,
]);
$alt = Ensemble::create([
'code' => 'alt',
'name' => 'Alternates',
'event_id' => $this->audition->event_id,
'rank' => 2,
]);
expect($this->audition->seatingLimits()->count())->toBe(0);
SeatingLimit::create(['ensemble_id' => $we->id, 'audition_id' => $this->audition->id, 'maximum_accepted' => 8]);
SeatingLimit::create(['ensemble_id' => $alt->id, 'audition_id' => $this->audition->id, 'maximum_accepted' => 2]);
expect($this->audition->seatingLimits()->count())->toBe(2)
->and($this->audition->seatingLimits->first())->toBeInstanceOf(App\Models\SeatingLimit::class)
->and($this->audition->seatingLimits->first()->maximum_accepted)->toBe(8)
->and($this->audition->seatingLimits->first()->ensemble->name)->toBe('Wind Ensemble');
});
it('returns entry fee in currency format', function () {
expect($this->audition->display_fee())->toBe('$20.00');
});
it('can return its judges', function () {
expect($this->audition->judges()->count())->toBe(0);
$room = Room::factory()->create();
$this->audition->room()->associate($room);
$this->audition->save();
$judge = App\Models\User::factory()->create();
$room->judges()->attach($judge);
expect($this->audition->judges()->count())->toBe(1)
->and($this->audition->judges->first())->toBeInstanceOf(App\Models\User::class);
});
it('can return a count of judges', function () {
expect($this->audition->judges()->count())->toBe(0);
$room = Room::factory()->create();
$this->audition->room()->associate($room);
$this->audition->save();
$judge = App\Models\User::factory()->create();
$room->judges()->attach($judge);
expect($this->audition->judges_count)->toBe(1);
});
it('can return all of its flags', function () {
expect($this->audition->flags()->count())->toBe(0);
$this->audition->addFlag('seats_published');
$this->audition->addFlag('advancement_published');
$this->audition->refresh();
expect($this->audition->flags()->count())->toBe(2);
});
it('can check for a specific flag', function () {
expect($this->audition->flags()->count())->toBe(0);
$this->audition->addFlag('seats_published');
$this->audition->refresh();
expect($this->audition->hasFlag('seats_published'))->toBeTrue()
->and($this->audition->hasFlag('advancement_published'))->toBeFalse();
});
it('can remove a flag', function () {
expect($this->audition->flags()->count())->toBe(0);
$this->audition->addFlag('seats_published');
$this->audition->refresh();
expect($this->audition->hasFlag('seats_published'))->toBeTrue();
$this->audition->removeFlag('seats_published');
$this->audition->refresh();
expect($this->audition->hasFlag('seats_published'))->toBeFalse();
});
it('will not add a flag that already exists', function () {
expect($this->audition->flags()->count())->toBe(0);
$this->audition->addFlag('seats_published');
$this->audition->refresh();
expect($this->audition->hasFlag('seats_published'))->toBeTrue();
$this->audition->addFlag('seats_published');
expect($this->audition->flags()->count())->toBe(1);
});
it('can return its seats if any exits', function () {
expect($this->audition->seats()->count())->toBe(0);
$ensemble = Ensemble::factory()->create();
$entries = Entry::factory()->count(5)->create(['audition_id' => $this->audition->id]);
$n = 1;
foreach ($entries as $entry) {
Seat::create([
'ensemble_id' => $ensemble->id,
'audition_id' => $this->audition->id,
'entry_id' => $entry->id,
'seat' => $n,
]);
$n++;
}
expect($this->audition->seats()->count())->toBe(5)
->and($this->audition->seats->first())->toBeInstanceOf(Seat::class);
});