seed(RolesAndPermissionsSeeder::class); // In der Testumgebung ist die Queue `sync`; für die Queue-Metriken den // Produktions-Treiber (database) verwenden, der die jobs-Tabellen liest. config()->set('queue.default', 'database'); }); test('editor cannot open the system health report', function () { /** @var TestCase $this */ $editor = User::factory()->create(['is_active' => true]); $editor->assignRole('editor'); $this->actingAs($editor); $this->get('https://pressekonto.test/admin/reports/system-health')->assertForbidden(); }); test('admin can open the system health report', function () { /** @var TestCase $this */ $admin = User::factory()->create(['is_active' => true]); $admin->assignRole('admin'); $this->actingAs($admin); $this->get('https://pressekonto.test/admin/reports/system-health') ->assertSuccessful() ->assertSee('Betriebsüberwachung') ->assertSee('Queue-Worker'); }); test('the system health report shows the deployed version', function () { /** @var TestCase $this */ config()->set('app.version', 'v1.1.0'); $admin = User::factory()->create(['is_active' => true]); $admin->assignRole('admin'); $this->actingAs($admin); $this->get('https://pressekonto.test/admin/reports/system-health') ->assertSuccessful() ->assertSee('Version: v1.1.0'); }); test('snapshot reports an ok queue when there are no waiting jobs', function () { /** @var TestCase $this */ $snapshot = app(AdminSystemHealth::class)->snapshot(); expect($snapshot['queue']['pending'])->toBe(0) ->and($snapshot['queue']['worker_running'])->toBeTrue() ->and($snapshot['queue']['status'])->toBe('ok'); }); test('snapshot flags a stalled worker when a job has waited too long', function () { /** @var TestCase $this */ DB::table('jobs')->insert([ 'queue' => 'default', 'payload' => json_encode(['displayName' => 'App\\Jobs\\Example']), 'attempts' => 0, 'reserved_at' => null, 'available_at' => now()->subMinutes(10)->getTimestamp(), 'created_at' => now()->subMinutes(10)->getTimestamp(), ]); $snapshot = app(AdminSystemHealth::class)->snapshot(); expect($snapshot['queue']['status'])->toBe('critical') ->and($snapshot['queue']['worker_running'])->toBeFalse() ->and($snapshot['overall'])->toBe('critical'); }); test('snapshot surfaces recent failed jobs', function () { /** @var TestCase $this */ DB::table('failed_jobs')->insert([ 'uuid' => (string) Str::uuid(), 'connection' => 'database', 'queue' => 'default', 'payload' => json_encode(['displayName' => 'App\\Jobs\\Broken']), 'exception' => "RuntimeException: boom\nStack trace...", 'failed_at' => now(), ]); $snapshot = app(AdminSystemHealth::class)->snapshot(); expect($snapshot['queue']['failed_recent'])->toBe(1) ->and($snapshot['queue']['recent_failures'][0]['job'])->toBe('App\\Jobs\\Broken') ->and($snapshot['queue']['recent_failures'][0]['error'])->toContain('boom') ->and($snapshot['queue']['status'])->toBe('warn'); }); test('snapshot flags missing permissions as critical', function () { /** @var TestCase $this */ Permission::query()->where('name', 'billing:manage')->delete(); app(PermissionRegistrar::class)->forgetCachedPermissions(); $checks = collect(app(AdminSystemHealth::class)->snapshot()['checks']) ->keyBy('key'); expect($checks['permissions']['status'])->toBe('critical') ->and($checks['permissions']['detail'])->toContain('billing:manage'); }); test('snapshot flags pending media privatization', function () { /** @var TestCase $this */ $pr = PressRelease::factory()->forPortal(Portal::Presseecho)->create(); PressReleaseImage::query()->create([ 'press_release_id' => $pr->id, 'disk' => 'public', 'path' => 'press-releases/'.$pr->id.'/images/legacy.jpg', ]); $checks = collect(app(AdminSystemHealth::class)->snapshot()['checks'])->keyBy('key'); expect($checks['media_privatization']['status'])->toBe('warn') ->and($checks['media_privatization']['detail'])->toContain('1'); });