diff --git a/app/Http/Controllers/SyncController.php b/app/Http/Controllers/SyncController.php index efba901..4d09965 100644 --- a/app/Http/Controllers/SyncController.php +++ b/app/Http/Controllers/SyncController.php @@ -2,19 +2,19 @@ namespace App\Http\Controllers; +use App\Services\ChurchToolsService; use Illuminate\Http\RedirectResponse; -use Illuminate\Support\Facades\Artisan; class SyncController extends Controller { - public function sync(): RedirectResponse + public function sync(ChurchToolsService $service): RedirectResponse { - $exitCode = Artisan::call('cts:sync'); + try { + $service->sync(); - if ($exitCode === 0) { return back()->with('success', 'Daten wurden aktualisiert'); + } catch (\Throwable $e) { + return back()->with('error', 'Sync fehlgeschlagen: ' . $e->getMessage()); } - - return back()->with('error', 'Fehler beim Synchronisieren'); } } diff --git a/tests/Feature/SyncControllerTest.php b/tests/Feature/SyncControllerTest.php new file mode 100644 index 0000000..b98640d --- /dev/null +++ b/tests/Feature/SyncControllerTest.php @@ -0,0 +1,108 @@ +create(); + $this->actingAs($user); + + // Mock ChurchToolsService to throw exception + $mockService = Mockery::mock(ChurchToolsService::class); + $mockService->shouldReceive('sync') + ->once() + ->andThrow(new \Exception('Agenda for event [823] not found.')); + + app()->instance(ChurchToolsService::class, $mockService); + + // Call sync endpoint + $response = $this->post(route('sync')); + + // Verify error message is propagated + $response->assertSessionHas('error', 'Sync fehlgeschlagen: Agenda for event [823] not found.'); +}); + +test('sync controller zeigt Erfolgsmeldung bei erfolgreichem Sync', function () { + // Create and authenticate user + $user = \App\Models\User::factory()->create(); + $this->actingAs($user); + + // Mock ChurchToolsService to return success + $mockService = Mockery::mock(ChurchToolsService::class); + $mockService->shouldReceive('sync') + ->once() + ->andReturn([ + 'services_count' => 1, + 'songs_count' => 2, + 'matched_songs_count' => 1, + 'unmatched_songs_count' => 1, + 'catalog_songs_count' => 5, + ]); + + app()->instance(ChurchToolsService::class, $mockService); + + // Call sync endpoint + $response = $this->post(route('sync')); + + // Verify success message + $response->assertSessionHas('success', 'Daten wurden aktualisiert'); +}); + +function ensureSyncControllerTables(): void +{ + if (! Schema::hasTable('services')) { + Schema::create('services', function (Blueprint $table) { + $table->id(); + $table->string('cts_event_id')->unique(); + $table->string('title'); + $table->date('date')->nullable(); + $table->string('preacher_name')->nullable(); + $table->string('beamer_tech_name')->nullable(); + $table->timestamp('last_synced_at')->nullable(); + $table->json('cts_data')->nullable(); + $table->timestamps(); + }); + } + + if (! Schema::hasTable('songs')) { + Schema::create('songs', function (Blueprint $table) { + $table->id(); + $table->string('title'); + $table->string('ccli_id')->nullable()->unique(); + $table->timestamps(); + }); + } + + if (! Schema::hasTable('service_songs')) { + Schema::create('service_songs', function (Blueprint $table) { + $table->id(); + $table->foreignId('service_id')->constrained('services')->cascadeOnDelete(); + $table->foreignId('song_id')->nullable()->constrained('songs')->nullOnDelete(); + $table->string('cts_song_name'); + $table->string('cts_ccli_id')->nullable(); + $table->unsignedInteger('order')->default(0); + $table->timestamp('matched_at')->nullable(); + $table->timestamps(); + $table->unique(['service_id', 'order']); + }); + } + + if (! Schema::hasTable('cts_sync_log')) { + Schema::create('cts_sync_log', function (Blueprint $table) { + $table->id(); + $table->timestamp('synced_at')->nullable(); + $table->unsignedInteger('events_count')->default(0); + $table->unsignedInteger('songs_count')->default(0); + $table->string('status'); + $table->text('error')->nullable(); + $table->timestamps(); + }); + } +}