pp-planer/tests/Feature/ServiceAgendaItemTest.php

162 lines
5.2 KiB
PHP

<?php
use App\Models\Service;
use App\Models\ServiceAgendaItem;
use App\Models\ServiceSong;
use App\Models\Slide;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Schema;
/*
|--------------------------------------------------------------------------
| ServiceAgendaItem Model & Migration Tests
|--------------------------------------------------------------------------
*/
test('migration creates service_agenda_items table with correct columns', function () {
expect(Schema::hasTable('service_agenda_items'))->toBeTrue();
$columns = [
'id',
'service_id',
'cts_agenda_item_id',
'position',
'title',
'type',
'note',
'duration',
'start',
'is_before_event',
'responsible',
'service_song_id',
'sort_order',
'created_at',
'updated_at',
];
foreach ($columns as $column) {
expect(Schema::hasColumn('service_agenda_items', $column))->toBeTrue();
}
});
test('factory creates valid service agenda item', function () {
$item = ServiceAgendaItem::factory()->create();
expect($item)->toBeInstanceOf(ServiceAgendaItem::class);
expect($item->id)->toBeGreaterThan(0);
expect($item->service_id)->toBeGreaterThan(0);
expect($item->title)->not->toBeNull();
expect($item->type)->toBeIn(['Song', 'Default', 'Header']);
expect($item->position)->not->toBeNull();
expect($item->is_before_event)->toBeFalse();
expect($item->sort_order)->toBeGreaterThan(0);
});
test('service relationship returns correct service', function () {
$service = Service::factory()->create();
$item = ServiceAgendaItem::factory()->create(['service_id' => $service->id]);
expect($item->service)->toBeInstanceOf(Service::class);
expect($item->service->id)->toBe($service->id);
});
test('serviceSong relationship is nullable', function () {
$item = ServiceAgendaItem::factory()->create(['service_song_id' => null]);
expect($item->serviceSong)->toBeNull();
});
test('serviceSong relationship returns correct service song', function () {
$song = ServiceSong::factory()->create();
$item = ServiceAgendaItem::factory()->create(['service_song_id' => $song->id]);
expect($item->serviceSong)->toBeInstanceOf(ServiceSong::class);
expect($item->serviceSong->id)->toBe($song->id);
});
test('slides relationship returns associated slides', function () {
$item = ServiceAgendaItem::factory()->create();
Slide::factory()->count(3)->create(['service_agenda_item_id' => $item->id]);
expect($item->slides)->toHaveCount(3);
expect($item->slides->first())->toBeInstanceOf(Slide::class);
});
test('scopeVisible excludes is_before_event true items', function () {
ServiceAgendaItem::factory()->count(2)->create(['is_before_event' => false]);
ServiceAgendaItem::factory()->count(3)->create(['is_before_event' => true]);
$visible = ServiceAgendaItem::visible()->get();
expect($visible)->toHaveCount(2);
$visible->each(fn ($item) => expect($item->is_before_event)->toBeFalse());
});
test('responsible is cast to array', function () {
$item = ServiceAgendaItem::factory()->create([
'responsible' => ['person1', 'person2'],
]);
expect($item->responsible)->toBeArray();
expect($item->responsible)->toHaveCount(2);
});
test('is_before_event is cast to boolean', function () {
$item = ServiceAgendaItem::factory()->create(['is_before_event' => true]);
expect($item->is_before_event)->toBeTrue();
expect(is_bool($item->is_before_event))->toBeTrue();
});
test('unique constraint on service_id and sort_order', function () {
$service = Service::factory()->create();
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'sort_order' => 1,
]);
expect(fn () => ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'sort_order' => 1,
]))->toThrow(QueryException::class);
});
test('withSong factory state', function () {
$song = ServiceSong::factory()->create();
$item = ServiceAgendaItem::factory()->withSong($song)->create();
expect($item->service_song_id)->toBe($song->id);
expect($item->service_id)->toBe($song->service_id);
expect($item->type)->toBe('Song');
});
test('nonSong factory state', function () {
$item = ServiceAgendaItem::factory()->nonSong()->create();
expect($item->service_song_id)->toBeNull();
expect($item->type)->toBeIn(['Default', 'Header']);
});
test('cascadeOnDelete removes agenda items when service deleted', function () {
$service = Service::factory()->create();
ServiceAgendaItem::factory()->count(3)->create(['service_id' => $service->id]);
expect(ServiceAgendaItem::where('service_id', $service->id)->count())->toBe(3);
$service->delete();
expect(ServiceAgendaItem::where('service_id', $service->id)->count())->toBe(0);
});
test('nullOnDelete nullifies service_song_id when song deleted', function () {
$song = ServiceSong::factory()->create();
$item = ServiceAgendaItem::factory()->create(['service_song_id' => $song->id]);
expect($item->service_song_id)->toBe($song->id);
$song->delete();
$item->refresh();
expect($item->service_song_id)->toBeNull();
});