162 lines
5.8 KiB
PHP
162 lines
5.8 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace Tests\Feature\Artist;
|
||
|
||
use App\Models\Artist;
|
||
use App\Models\ArtistEngagement;
|
||
use App\Models\Event;
|
||
use App\Models\Genre;
|
||
use App\Models\Organisation;
|
||
use App\Models\Performance;
|
||
use App\Models\Scopes\OrganisationScope;
|
||
use App\Models\Stage;
|
||
use App\Models\StageDay;
|
||
use Database\Seeders\ArtistTimetableDevSeeder;
|
||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
use Tests\TestCase;
|
||
|
||
final class ArtistTimetableDevSeederTest extends TestCase
|
||
{
|
||
use RefreshDatabase;
|
||
|
||
public function test_organisation_pool_creates_125_artists_and_8_genres(): void
|
||
{
|
||
$org = Organisation::factory()->create();
|
||
|
||
$pool = ArtistTimetableDevSeeder::seedOrganisationPool($org, 125);
|
||
|
||
$this->assertSame(8, Genre::withoutGlobalScope(OrganisationScope::class)->count());
|
||
$this->assertSame(125, Artist::withoutGlobalScope(OrganisationScope::class)->count());
|
||
$this->assertCount(8, $pool['genres']);
|
||
$this->assertCount(125, $pool['artists']);
|
||
|
||
// Every artist belongs to the seeded organisation
|
||
$this->assertSame(
|
||
125,
|
||
Artist::withoutGlobalScope(OrganisationScope::class)
|
||
->where('organisation_id', $org->id)
|
||
->count(),
|
||
);
|
||
}
|
||
|
||
public function test_seed_for_festival_produces_stages_engagements_and_unscheduled(): void
|
||
{
|
||
$org = Organisation::factory()->create();
|
||
$pool = ArtistTimetableDevSeeder::seedOrganisationPool($org, 125);
|
||
|
||
/** @var Event $festival */
|
||
$festival = Event::factory()->for($org)->festival()->create([
|
||
'start_date' => '2026-07-10',
|
||
'end_date' => '2026-07-12',
|
||
]);
|
||
$vrijdag = Event::factory()->for($org)->subEvent($festival)->create([
|
||
'start_date' => '2026-07-10',
|
||
'end_date' => '2026-07-10',
|
||
]);
|
||
$zaterdag = Event::factory()->for($org)->subEvent($festival)->create([
|
||
'start_date' => '2026-07-11',
|
||
'end_date' => '2026-07-11',
|
||
]);
|
||
$zondag = Event::factory()->for($org)->subEvent($festival)->create([
|
||
'start_date' => '2026-07-12',
|
||
'end_date' => '2026-07-12',
|
||
]);
|
||
|
||
$result = ArtistTimetableDevSeeder::seedForFestival(
|
||
$org,
|
||
$festival,
|
||
[$vrijdag, $zaterdag, $zondag],
|
||
$pool,
|
||
);
|
||
|
||
// 5 stages, each linked to all 3 sub-events via stage_days
|
||
$this->assertSame(5, Stage::withoutGlobalScope(OrganisationScope::class)->count());
|
||
$this->assertSame(15, StageDay::withoutGlobalScope(OrganisationScope::class)->count());
|
||
|
||
// Engagement / performance counts (deterministic from the loop structure)
|
||
$this->assertSame(45, $result['engagements']);
|
||
$this->assertSame(12, $result['unscheduled']);
|
||
$this->assertGreaterThanOrEqual(35, $result['performances']);
|
||
|
||
// At least one parked performance for the wachtrij UI
|
||
$this->assertGreaterThanOrEqual(
|
||
1,
|
||
Performance::withoutGlobalScope(OrganisationScope::class)->whereNull('stage_id')->count(),
|
||
);
|
||
|
||
// Unscheduled engagements really have no performances
|
||
$unscheduledQuery = ArtistEngagement::withoutGlobalScope(OrganisationScope::class)
|
||
->doesntHave('performances');
|
||
$this->assertSame(12, $unscheduledQuery->count());
|
||
}
|
||
|
||
public function test_seed_for_flat_event_creates_stages_and_mixed_engagements(): void
|
||
{
|
||
$org = Organisation::factory()->create();
|
||
$pool = ArtistTimetableDevSeeder::seedOrganisationPool($org, 125);
|
||
|
||
/** @var Event $event */
|
||
$event = Event::factory()->for($org)->create([
|
||
'event_type' => 'event',
|
||
'start_date' => '2026-04-27',
|
||
'end_date' => '2026-04-27',
|
||
]);
|
||
|
||
$result = ArtistTimetableDevSeeder::seedForFlatEvent($org, $event, $pool, [
|
||
'scheduled' => 6,
|
||
'unscheduled' => 3,
|
||
'pool_offset' => 0,
|
||
]);
|
||
|
||
$this->assertSame(2, $result['stages']);
|
||
$this->assertSame(9, $result['engagements']);
|
||
$this->assertSame(3, $result['unscheduled']);
|
||
$this->assertSame(6, $result['performances']);
|
||
|
||
// Stage days for the flat event (1 day × 2 stages = 2 rows)
|
||
$this->assertSame(
|
||
2,
|
||
StageDay::withoutGlobalScope(OrganisationScope::class)
|
||
->where('event_id', $event->id)
|
||
->count(),
|
||
);
|
||
}
|
||
|
||
public function test_seed_for_series_creates_stages_with_stage_days_per_sub_event(): void
|
||
{
|
||
$org = Organisation::factory()->create();
|
||
$pool = ArtistTimetableDevSeeder::seedOrganisationPool($org, 125);
|
||
|
||
/** @var Event $parent */
|
||
$parent = Event::factory()->for($org)->create([
|
||
'event_type' => 'series',
|
||
'start_date' => '2026-12-05',
|
||
'end_date' => '2027-01-25',
|
||
]);
|
||
$subs = [];
|
||
foreach (['2026-12-06', '2026-12-20', '2027-01-04', '2027-01-25'] as $date) {
|
||
$subs[] = Event::factory()->for($org)->subEvent($parent)->create([
|
||
'start_date' => $date,
|
||
'end_date' => $date,
|
||
]);
|
||
}
|
||
|
||
$result = ArtistTimetableDevSeeder::seedForSeries($org, $parent, $subs, $pool, [
|
||
'per_week_scheduled' => 2,
|
||
'per_week_unscheduled' => 1,
|
||
'pool_offset' => 0,
|
||
]);
|
||
|
||
// 2 stages × 4 sub-events = 8 stage_days
|
||
$this->assertSame(2, $result['stages']);
|
||
$this->assertSame(8, StageDay::withoutGlobalScope(OrganisationScope::class)->count());
|
||
|
||
// 4 weeks × (2 scheduled + 1 unscheduled) = 12 engagements
|
||
$this->assertSame(12, $result['engagements']);
|
||
$this->assertSame(4, $result['unscheduled']);
|
||
$this->assertSame(8, $result['performances']);
|
||
}
|
||
}
|