From fb1e51361fd72e3d9a1c1fd38adea5a241e70b4a Mon Sep 17 00:00:00 2001 From: Thorsten Bus Date: Sun, 29 Mar 2026 12:26:05 +0200 Subject: [PATCH] test(php): update existing tests for agenda model - Fix uploaded_at in InformationBlockTest and ServiceControllerTest (Faker ignores Carbon::setTestNow, generating future dates that fail the uploaded_at <= service.date filter) - Add agenda item association tests to ModerationBlockTest (3 new tests) - Add agenda item association tests to SermonBlockTest (3 new tests) - Verify legacy slides without agenda item still work Test results: 12 failures (down from 14 baseline), all pre-existing (ProPresenter parser path issues + suite ordering flake) --- tests/Feature/InformationBlockTest.php | 9 +++ tests/Feature/ModerationBlockTest.php | 82 +++++++++++++++++++++++++ tests/Feature/SermonBlockTest.php | 82 +++++++++++++++++++++++++ tests/Feature/ServiceControllerTest.php | 1 + 4 files changed, 174 insertions(+) diff --git a/tests/Feature/InformationBlockTest.php b/tests/Feature/InformationBlockTest.php index ce0b4dd..e84380a 100644 --- a/tests/Feature/InformationBlockTest.php +++ b/tests/Feature/InformationBlockTest.php @@ -27,6 +27,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-03-16', + 'uploaded_at' => '2026-03-14 10:00:00', ]); // Slide expired yesterday (should NOT show) @@ -34,6 +35,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-03-14', + 'uploaded_at' => '2026-03-14 10:00:00', ]); $response = $this->get(route('services.edit', $service)); @@ -57,6 +59,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-04-10', + 'uploaded_at' => '2026-03-30 10:00:00', ]); // Slide expires one day before service (should NOT show) @@ -64,6 +67,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-04-09', + 'uploaded_at' => '2026-03-30 10:00:00', ]); $response = $this->get(route('services.edit', $service)); @@ -87,6 +91,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-03-15', + 'uploaded_at' => '2026-02-28 10:00:00', ]); // Global slide expiring 2026-03-25 — should appear in BOTH services @@ -94,6 +99,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-03-25', + 'uploaded_at' => '2026-02-28 10:00:00', ]); // Service A: both slides should appear (both expire_date >= 2026-03-10) @@ -124,6 +130,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-03-20', + 'uploaded_at' => '2026-02-28 10:00:00', ]); // Soft-deleted slide @@ -131,6 +138,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-03-20', + 'uploaded_at' => '2026-02-28 10:00:00', ]); $deletedSlide->delete(); @@ -154,6 +162,7 @@ 'type' => 'information', 'service_id' => null, 'expire_date' => '2026-03-20', + 'uploaded_at' => '2026-02-28 10:00:00', ]); // Moderation slide (should NOT show) diff --git a/tests/Feature/ModerationBlockTest.php b/tests/Feature/ModerationBlockTest.php index f1aa80f..4d8314b 100644 --- a/tests/Feature/ModerationBlockTest.php +++ b/tests/Feature/ModerationBlockTest.php @@ -1,6 +1,7 @@ expire_date)->toBeNull(); }); + +/* +|-------------------------------------------------------------------------- +| Moderation Slides — Agenda Item Association +|-------------------------------------------------------------------------- +*/ + +test('moderation slides can be linked to agenda items', function () { + $service = Service::factory()->create(); + $agendaItem = ServiceAgendaItem::factory()->create([ + 'service_id' => $service->id, + 'title' => 'Hinweise', + 'sort_order' => 1, + 'is_before_event' => false, + ]); + + $slide = Slide::factory()->create([ + 'type' => 'moderation', + 'service_id' => $service->id, + 'service_agenda_item_id' => $agendaItem->id, + ]); + + expect($slide->serviceAgendaItem)->not->toBeNull(); + expect($slide->serviceAgendaItem->id)->toBe($agendaItem->id); + expect($agendaItem->slides)->toHaveCount(1); + expect($agendaItem->slides->first()->id)->toBe($slide->id); +}); + +test('moderation slides on agenda items are scoped per item', function () { + $service = Service::factory()->create(); + $item1 = ServiceAgendaItem::factory()->create([ + 'service_id' => $service->id, + 'title' => 'Hinweise', + 'sort_order' => 1, + 'is_before_event' => false, + ]); + $item2 = ServiceAgendaItem::factory()->create([ + 'service_id' => $service->id, + 'title' => 'Begrüßung', + 'sort_order' => 2, + 'is_before_event' => false, + ]); + + $slide1 = Slide::factory()->create([ + 'type' => 'moderation', + 'service_id' => $service->id, + 'service_agenda_item_id' => $item1->id, + ]); + $slide2 = Slide::factory()->create([ + 'type' => 'moderation', + 'service_id' => $service->id, + 'service_agenda_item_id' => $item2->id, + ]); + + expect($item1->slides)->toHaveCount(1); + expect($item1->slides->first()->id)->toBe($slide1->id); + expect($item2->slides)->toHaveCount(1); + expect($item2->slides->first()->id)->toBe($slide2->id); +}); + +test('legacy moderation slides without agenda item still work', function () { + $service = Service::factory()->create(); + + // Legacy slide: service_id set, no agenda item link + $slide = Slide::factory()->create([ + 'type' => 'moderation', + 'service_id' => $service->id, + 'service_agenda_item_id' => null, + ]); + + expect($slide->service_agenda_item_id)->toBeNull(); + expect($slide->serviceAgendaItem)->toBeNull(); + + // Still queryable via legacy filter + $legacySlides = Slide::where('type', 'moderation') + ->where('service_id', $service->id) + ->get(); + + expect($legacySlides)->toHaveCount(1); + expect($legacySlides->first()->id)->toBe($slide->id); +}); diff --git a/tests/Feature/SermonBlockTest.php b/tests/Feature/SermonBlockTest.php index 1e738fa..adc14bf 100644 --- a/tests/Feature/SermonBlockTest.php +++ b/tests/Feature/SermonBlockTest.php @@ -1,6 +1,7 @@ expire_date)->toBeNull(); }); + +/* +|-------------------------------------------------------------------------- +| Sermon Slides — Agenda Item Association +|-------------------------------------------------------------------------- +*/ + +test('sermon slides can be linked to agenda items', function () { + $service = Service::factory()->create(); + $agendaItem = ServiceAgendaItem::factory()->create([ + 'service_id' => $service->id, + 'title' => 'Predigt: Hoffnung', + 'sort_order' => 1, + 'is_before_event' => false, + ]); + + $slide = Slide::factory()->create([ + 'type' => 'sermon', + 'service_id' => $service->id, + 'service_agenda_item_id' => $agendaItem->id, + ]); + + expect($slide->serviceAgendaItem)->not->toBeNull(); + expect($slide->serviceAgendaItem->id)->toBe($agendaItem->id); + expect($agendaItem->slides)->toHaveCount(1); + expect($agendaItem->slides->first()->id)->toBe($slide->id); +}); + +test('sermon slides on agenda items are scoped per item', function () { + $service = Service::factory()->create(); + $item1 = ServiceAgendaItem::factory()->create([ + 'service_id' => $service->id, + 'title' => 'Predigt Teil 1', + 'sort_order' => 1, + 'is_before_event' => false, + ]); + $item2 = ServiceAgendaItem::factory()->create([ + 'service_id' => $service->id, + 'title' => 'Predigt Teil 2', + 'sort_order' => 2, + 'is_before_event' => false, + ]); + + $slide1 = Slide::factory()->create([ + 'type' => 'sermon', + 'service_id' => $service->id, + 'service_agenda_item_id' => $item1->id, + ]); + $slide2 = Slide::factory()->create([ + 'type' => 'sermon', + 'service_id' => $service->id, + 'service_agenda_item_id' => $item2->id, + ]); + + expect($item1->slides)->toHaveCount(1); + expect($item1->slides->first()->id)->toBe($slide1->id); + expect($item2->slides)->toHaveCount(1); + expect($item2->slides->first()->id)->toBe($slide2->id); +}); + +test('legacy sermon slides without agenda item still work', function () { + $service = Service::factory()->create(); + + // Legacy slide: service_id set, no agenda item link + $slide = Slide::factory()->create([ + 'type' => 'sermon', + 'service_id' => $service->id, + 'service_agenda_item_id' => null, + ]); + + expect($slide->service_agenda_item_id)->toBeNull(); + expect($slide->serviceAgendaItem)->toBeNull(); + + // Still queryable via legacy filter + $legacySlides = Slide::where('type', 'sermon') + ->where('service_id', $service->id) + ->get(); + + expect($legacySlides)->toHaveCount(1); + expect($legacySlides->first()->id)->toBe($slide->id); +}); diff --git a/tests/Feature/ServiceControllerTest.php b/tests/Feature/ServiceControllerTest.php index 34ab5dc..a5d8775 100644 --- a/tests/Feature/ServiceControllerTest.php +++ b/tests/Feature/ServiceControllerTest.php @@ -248,6 +248,7 @@ public function test_service_edit_seite_zeigt_service_mit_songs_und_slides(): vo 'service_id' => null, 'type' => 'information', 'expire_date' => Carbon::today()->addDays(14), + 'uploaded_at' => Carbon::today()->subDays(2), ]); $response = $this->actingAs($user)->get(route('services.edit', $service));