Implement enum for audition flags

This commit is contained in:
Matt Young 2024-07-08 11:23:04 -05:00
parent 9b381ebbbc
commit 749af22aad
24 changed files with 74 additions and 43 deletions

View File

@ -0,0 +1,10 @@
<?php
namespace App\Enums;
enum AuditionFlags: string
{
case DRAWN = 'drawn';
case SEATS_PUBLISHED = 'seats_published';
case ADVANCEMENT_PUBLISHED = 'advancement_published';
}

View File

@ -5,12 +5,10 @@ namespace App\Http\Controllers;
use App\Models\Audition;
use App\Models\Entry;
use App\Models\JudgeAdvancementVote;
use App\Models\ScoreSheet;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use Tests\Feature\Models\ScoreSheet;
use function compact;
use function redirect;
use function url;

View File

@ -31,7 +31,7 @@ class EntryFlagController extends Controller
return to_route('entry-flags.noShowSelect')->with('error',
'Cannot enter a no-show for an entry in an audition where seats are published');
}
if ($entry->audition->hasFlag('advance_published')) {
if ($entry->audition->hasFlag('advancement_published')) {
return to_route('entry-flags.noShowSelect')->with('error',
'Cannot enter a no-show for an entry in an audition where advancement is published');
}
@ -71,7 +71,7 @@ class EntryFlagController extends Controller
return to_route('entry-flags.noShowSelect')->with('error',
'Cannot enter a no-show for an entry in an audition where seats are published');
}
if ($entry->audition->hasFlag('advance_published')) {
if ($entry->audition->hasFlag('advancement_published')) {
return to_route('entry-flags.noShowSelect')->with('error',
'Cannot enter a no-show for an entry in an audition where advancement is published');
}
@ -90,7 +90,7 @@ class EntryFlagController extends Controller
return to_route('entry-flags.noShowSelect')->with('error',
'Cannot undo a no-show for an entry in an audition where seats are published');
}
if ($entry->audition->hasFlag('advance_published')) {
if ($entry->audition->hasFlag('advancement_published')) {
return to_route('entry-flags.noShowSelect')->with('error',
'Cannot undo a no-show for an entry in an audition where advancement is published');
}

View File

@ -4,9 +4,9 @@ namespace App\Http\Controllers\Tabulation;
use App\Http\Controllers\Controller;
use App\Models\Entry;
use App\Models\ScoreSheet;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
use Tests\Feature\Models\ScoreSheet;
class ScoreController extends Controller
{

View File

@ -2,6 +2,7 @@
namespace App\Models;
use App\Enums\AuditionFlags;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -10,6 +11,8 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use function in_array;
class Audition extends Model
{
use HasFactory;
@ -75,8 +78,13 @@ class Audition extends Model
public function hasFlag($flag): bool
{
$flags = [];
foreach ($this->flags as $checkFlag) {
$flags[] = $checkFlag->flag_name->value;
}
// return true if any flag in $this->flags has a flag_name of declined without making another db query if flags are loaded
return $this->flags->contains('flag_name', $flag);
return in_array($flag, $flags);
}
public function addFlag($flag): void
@ -84,8 +92,12 @@ class Audition extends Model
if ($this->hasFlag($flag)) {
return;
}
$this->flags()->create(['flag_name' => $flag]);
$enum = match ($flag) {
'drawn' => AuditionFlags::DRAWN,
'seats_published' => AuditionFlags::SEATS_PUBLISHED,
'advancement_published' => AuditionFlags::ADVANCEMENT_PUBLISHED,
};
$this->flags()->create(['flag_name' => $enum]);
$this->load('flags');
}

View File

@ -2,7 +2,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use App\Enums\AuditionFlags;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -10,6 +10,10 @@ class AuditionFlag extends Model
{
protected $guarded = [];
protected $casts = [
'flag_name' => AuditionFlags::class,
];
public function audition(): BelongsTo
{
return $this->belongsTo(Audition::class);

View File

@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
use Tests\Feature\Models\ScoreSheet;
class Entry extends Model
{

View File

@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Collection;
use Tests\Feature\Models\ScoreSheet;
class User extends Authenticatable implements MustVerifyEmail
{

View File

@ -3,7 +3,7 @@
namespace App\Observers;
use App\Events\ScoreSheetChange;
use App\Models\ScoreSheet;
use Tests\Feature\Models\ScoreSheet;
class ScoreSheetObserver
{

View File

@ -3,9 +3,8 @@
namespace App\Policies;
use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Models\User;
use Illuminate\Auth\Access\Response;
use Tests\Feature\Models\ScoreSheet;
class ScoreSheetPolicy
{

View File

@ -17,7 +17,6 @@ use App\Models\Entry;
use App\Models\Room;
use App\Models\RoomUser;
use App\Models\School;
use App\Models\ScoreSheet;
use App\Models\ScoringGuide;
use App\Models\SeatingLimit;
use App\Models\Student;
@ -43,6 +42,7 @@ use App\Services\SeatingService;
use App\Services\TabulationService;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;
use Tests\Feature\Models\ScoreSheet;
class AppServiceProvider extends ServiceProvider

View File

@ -3,12 +3,11 @@
namespace App\Services;
use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Models\ScoringGuide;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Tests\Feature\Models\ScoreSheet;
use function array_unshift;
class ScoreService

View File

@ -2,9 +2,9 @@
namespace Database\Seeders;
use App\Models\ScoreSheet;
use App\Models\User;
use Illuminate\Database\Seeder;
use Tests\Feature\Models\ScoreSheet;
class ScoreAllAuditions extends Seeder
{

View File

@ -21,6 +21,7 @@
<div class="absolute left-1/2 z-10 mt-5 flex w-screen max-w-min -translate-x-1/2 px-4" x-show="open" x-cloak>
<div class="w-56 shrink rounded-xl bg-white p-4 text-sm font-semibold leading-6 text-gray-900 shadow-lg ring-1 ring-gray-900/5">
<a href="{{ route('scores.chooseEntry') }}" class="block p-2 hover:text-indigo-600">Enter Scores</a>
<a href="{{ route('entry-flags.noShowSelect') }}" class="block p-2 hover:text-indigo-600">Enter No-Shows</a>
<a href="{{ route('tabulation.status') }}" class="block p-2 hover:text-indigo-600">Audition Status</a>
<a href="{{ route('advancement.status') }}" class="block p-2 hover:text-indigo-600">{{ auditionSetting('advanceTo') }} Status</a>

View File

@ -1,14 +1,5 @@
@php use App\Models\Audition;
use App\Models\Entry;
use App\Models\School;
use App\Models\SchoolEmailDomain;
use App\Models\ScoreSheet;
use App\Models\ScoringGuide;
use App\Models\User;use App\Services\ScoreService;use App\Settings;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
@endphp
@php use App\Enums\AuditionFlags;use App\Models\Audition;use App\Models\AuditionFlag; @endphp
@php @endphp
@inject('scoreservice','App\Services\ScoreService');
@inject('auditionService','App\Services\AuditionService');
@inject('entryService','App\Services\EntryService')
@ -17,7 +8,8 @@
<x-layout.app>
<x-slot:page_title>Test Page</x-slot:page_title>
@php
$drawService->hello();
$audition = Audition::first();
$audition->addFlag('drawn');
@endphp

View File

@ -1,5 +1,6 @@
<?php
use App\Enums\AuditionFlags;
use App\Models\Audition;
use App\Models\AuditionFlag;
use Illuminate\Foundation\Testing\RefreshDatabase;
@ -12,7 +13,7 @@ test('has an audition', function () {
// Arrange
$flag = AuditionFlag::create([
'audition_id' => $audition->id,
'flag_name' => 'Test Flag',
'flag_name' => AuditionFlags::DRAWN,
]);
// Act and Assert

View File

@ -1,5 +1,6 @@
<?php
use App\Enums\AuditionFlags;
use App\Models\Audition;
use App\Models\AuditionFlag;
use App\Models\Entry;
@ -140,13 +141,13 @@ it('has a judges_count available', function () {
it('can have flags', function () {
// Arrange
$audition = Audition::factory()->create();
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'seats_published']);
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'advance_published']);
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => AuditionFlags::SEATS_PUBLISHED]);
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => AuditionFlags::ADVANCEMENT_PUBLISHED]);
// Act
// Assert
expect($audition->hasFlag('seats_published'))->toBeTrue();
expect($audition->hasFlag('notaflag'))->toBeFalse();
expect($audition->flags->count())->toEqual(2);
expect($audition->hasFlag('seats_published'))->toBeTrue()
->and($audition->hasFlag('notaflag'))->toBeFalse()
->and($audition->flags->count())->toEqual(2);
});
it('can add flags', function () {

View File

@ -6,11 +6,11 @@ use App\Models\Entry;
use App\Models\EntryFlag;
use App\Models\JudgeAdvancementVote;
use App\Models\School;
use App\Models\ScoreSheet;
use App\Models\Seat;
use App\Models\Student;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\Feature\Models\ScoreSheet;
uses(RefreshDatabase::class);

View File

@ -1,7 +1,10 @@
<?php
namespace App\Models;
namespace Tests\Feature\Models;
use App\Models\Audition;
use App\Models\Entry;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;

View File

@ -2,9 +2,9 @@
use App\Models\Audition;
use App\Models\Entry;
use App\Models\ScoreSheet;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\Feature\Models\ScoreSheet;
uses(RefreshDatabase::class);

View File

@ -3,7 +3,6 @@
use App\Models\Audition;
use App\Models\Entry;
use App\Models\Room;
use App\Models\ScoreSheet;
use App\Models\ScoringGuide;
use App\Models\SubscoreDefinition;
use App\Models\User;
@ -11,6 +10,7 @@ use App\Settings;
use Database\Seeders\ScoreAllAuditions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Artisan;
use Tests\Feature\Models\ScoreSheet;
uses(RefreshDatabase::class);
@ -108,3 +108,12 @@ test('it shows scores previously entered', function () {
]);
});
it('indicates when an audition has published seats or advancement', function () {
// Arrange
$seatsPublishedAudition = Audition::factory()->create();
$advancePublishedAudition = Audition::factory()->create();
$seatsPublishedAudition->addFlag('seats_published');
$advancePublishedAudition->addFlag('advancement_published');
// Act & Assert
});

View File

@ -33,7 +33,7 @@ it('will not work with an entry if it is in a published audition', function () {
$entry1 = Entry::factory()->create();
$entry2 = Entry::factory()->create();
$entry1->audition->addFlag('seats_published');
$entry2->audition->addFlag('advance_published');
$entry2->audition->addFlag('advancement_published');
actAsTab();
get(route('entry-flags.confirmNoShow', ['entry_id' => $entry1->id]))
->assertRedirect(route('entry-flags.noShowSelect'))

View File

@ -31,7 +31,7 @@ it('will not record an entry in a published audition as a no show', function ()
$entry1 = Entry::factory()->create();
$entry2 = Entry::factory()->create();
$entry1->audition->addFlag('seats_published');
$entry2->audition->addFlag('advance_published');
$entry2->audition->addFlag('advancement_published');
actAsAdmin();
post(route('entry-flags.enterNoShow', $entry1))
->assertRedirect(route('entry-flags.noShowSelect'))

View File

@ -33,7 +33,7 @@ it('will not undo a no-show flag for an entry in a published audition', function
$entry1->addFlag('no_show');
$entry2->addFlag('no_show');
$entry1->audition->addFlag('seats_published');
$entry2->audition->addFlag('advance_published');
$entry2->audition->addFlag('advancement_published');
actAsAdmin();
delete(route('entry-flags.undoNoShow', $entry1))
->assertRedirect(route('entry-flags.noShowSelect'))