diff --git a/app/Console/Commands/DiscoverAgendaTypes.php b/app/Console/Commands/DiscoverAgendaTypes.php new file mode 100644 index 0000000..848a618 --- /dev/null +++ b/app/Console/Commands/DiscoverAgendaTypes.php @@ -0,0 +1,88 @@ +=', Carbon::today()) + ->orderBy('date') + ->first(); + + if (! $service) { + $this->info('Kein bevorstehender Service gefunden.'); + + return self::SUCCESS; + } + + $ctsEventId = (int) $service->cts_event_id; + $agenda = $churchToolsService->syncAgenda($ctsEventId); + + if (! $agenda) { + $this->info('Keine Agenda für diesen Service gefunden.'); + + return self::SUCCESS; + } + + $items = $agenda->getItems(); + + if (empty($items)) { + $this->info('Keine Agenda-Items gefunden.'); + + return self::SUCCESS; + } + + $headers = ['Position', 'Titel', 'Typ', 'Hat Song', 'Vor Event', 'Dauer']; + $rows = []; + $types = []; + + foreach ($items as $item) { + $position = $item->getPosition() ?? '-'; + $title = Str::limit($item->getTitle() ?? '', 40, '...'); + $type = $item->getType() ?? '-'; + $hasSong = $item->getSong() !== null ? 'Ja' : 'Nein'; + $isBeforeEvent = $item->getIsBeforeEvent() ? 'Ja' : 'Nein'; + $duration = $item->getDuration() ?? '-'; + + $rows[] = [ + $position, + $title, + $type, + $hasSong, + $isBeforeEvent, + $duration, + ]; + + if ($type !== '-' && ! in_array($type, $types)) { + $types[] = $type; + } + } + + $this->table($headers, $rows); + $this->newLine(); + $this->info('Unique Types:'); + foreach ($types as $type) { + $this->line(' - '.$type); + } + + return self::SUCCESS; + } catch (Throwable $exception) { + $this->error('Fehler beim Abrufen der Agenda: '.$exception->getMessage()); + + return self::FAILURE; + } + } +} diff --git a/tests/Feature/DiscoverAgendaTypesTest.php b/tests/Feature/DiscoverAgendaTypesTest.php new file mode 100644 index 0000000..d76ee47 --- /dev/null +++ b/tests/Feature/DiscoverAgendaTypesTest.php @@ -0,0 +1,157 @@ +artisan('cts:discover-agenda-types') + ->expectsOutput('Kein bevorstehender Service gefunden.') + ->assertExitCode(0); + } + + public function test_command_displays_agenda_items(): void + { + Carbon::setTestNow('2026-03-29 10:00:00'); + + Service::factory()->create([ + 'date' => Carbon::today(), + 'cts_event_id' => 123, + ]); + + $song = new Song; + $song->setId('song-1'); + + $item1 = new EventAgendaItem; + $item1->setPosition('1'); + $item1->setTitle('Welcome Song'); + $item1->setType('Song'); + $item1->setSong($song); + $item1->setIsBeforeEvent(false); + $item1->setDuration('5:00'); + + $item2 = new EventAgendaItem; + $item2->setPosition('2'); + $item2->setTitle('Announcement'); + $item2->setType('Default'); + $item2->setIsBeforeEvent(false); + $item2->setDuration(null); + + $item3 = new EventAgendaItem; + $item3->setPosition('3'); + $item3->setTitle('Sermon'); + $item3->setType('Sermon'); + $item3->setIsBeforeEvent(false); + $item3->setDuration('30:00'); + + $agenda = new EventAgenda; + $agenda->setItems([$item1, $item2, $item3]); + + $this->app->bind(ChurchToolsService::class, function () use ($agenda) { + return new ChurchToolsService( + agendaFetcher: fn ($id) => $agenda + ); + }); + + $this->artisan('cts:discover-agenda-types') + ->expectsTable( + ['Position', 'Titel', 'Typ', 'Hat Song', 'Vor Event', 'Dauer'], + [ + ['1', 'Welcome Song', 'Song', 'Ja', 'Nein', '5:00'], + ['2', 'Announcement', 'Default', 'Nein', 'Nein', '-'], + ['3', 'Sermon', 'Sermon', 'Nein', 'Nein', '30:00'], + ] + ) + ->expectsOutput('Unique Types:') + ->expectsOutput(' - Song') + ->expectsOutput(' - Default') + ->expectsOutput(' - Sermon') + ->assertExitCode(0); + } + + public function test_command_handles_missing_agenda(): void + { + Carbon::setTestNow('2026-03-29 10:00:00'); + + Service::factory()->create([ + 'date' => Carbon::today(), + 'cts_event_id' => 123, + ]); + + $this->app->bind(ChurchToolsService::class, function () { + return new ChurchToolsService( + agendaFetcher: fn ($id) => null + ); + }); + + $this->artisan('cts:discover-agenda-types') + ->expectsOutput('Keine Agenda für diesen Service gefunden.') + ->assertExitCode(0); + } + + public function test_command_handles_empty_items(): void + { + Carbon::setTestNow('2026-03-29 10:00:00'); + + Service::factory()->create([ + 'date' => Carbon::today(), + 'cts_event_id' => 123, + ]); + + $agenda = new EventAgenda; + $agenda->setItems([]); + + $this->app->bind(ChurchToolsService::class, function () use ($agenda) { + return new ChurchToolsService( + agendaFetcher: fn ($id) => $agenda + ); + }); + + $this->artisan('cts:discover-agenda-types') + ->expectsOutput('Keine Agenda-Items gefunden.') + ->assertExitCode(0); + } + + public function test_command_truncates_long_titles(): void + { + Carbon::setTestNow('2026-03-29 10:00:00'); + + Service::factory()->create([ + 'date' => Carbon::today(), + 'cts_event_id' => 123, + ]); + + $item = new EventAgendaItem; + $item->setPosition('1'); + $item->setTitle('This is a very long title that should be truncated to 40 characters'); + $item->setType('Song'); + $item->setIsBeforeEvent(false); + $item->setDuration('5:00'); + + $agenda = new EventAgenda; + $agenda->setItems([$item]); + + $this->app->bind(ChurchToolsService::class, function () use ($agenda) { + return new ChurchToolsService( + agendaFetcher: fn ($id) => $agenda + ); + }); + + $this->artisan('cts:discover-agenda-types') + ->expectsOutput('Unique Types:') + ->expectsOutput(' - Song') + ->assertExitCode(0); + } +}