fedi-feed-router/backend/tests/Unit/Services/SystemStatusServiceTest.php

302 lines
No EOL
12 KiB
PHP

<?php
namespace Tests\Unit\Services;
use App\Models\Feed;
use App\Models\PlatformChannel;
use App\Models\Route;
use App\Models\Setting;
use App\Services\SystemStatusService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class SystemStatusServiceTest extends TestCase
{
use RefreshDatabase;
protected SystemStatusService $service;
protected function setUp(): void
{
parent::setUp();
$this->service = new SystemStatusService();
}
public function test_get_system_status_returns_enabled_when_all_conditions_met(): void
{
// Enable article processing
Setting::setArticleProcessingEnabled(true);
// Create active entities
Feed::factory()->create(['is_active' => true]);
PlatformChannel::factory()->create(['is_active' => true]);
Route::factory()->create(['is_active' => true]);
$status = $this->service->getSystemStatus();
$this->assertIsArray($status);
$this->assertArrayHasKey('is_enabled', $status);
$this->assertArrayHasKey('status', $status);
$this->assertArrayHasKey('status_class', $status);
$this->assertArrayHasKey('reasons', $status);
$this->assertTrue($status['is_enabled']);
$this->assertEquals('Enabled', $status['status']);
$this->assertEquals('text-green-600', $status['status_class']);
$this->assertEmpty($status['reasons']);
}
public function test_get_system_status_returns_disabled_when_manually_disabled(): void
{
// Manually disable article processing
Setting::setArticleProcessingEnabled(false);
// Create active entities
Feed::factory()->create(['is_active' => true]);
PlatformChannel::factory()->create(['is_active' => true]);
Route::factory()->create(['is_active' => true]);
$status = $this->service->getSystemStatus();
$this->assertFalse($status['is_enabled']);
$this->assertEquals('Disabled', $status['status']);
$this->assertEquals('text-red-600', $status['status_class']);
$this->assertContains('Manually disabled by user', $status['reasons']);
}
public function test_get_system_status_returns_disabled_when_no_active_feeds(): void
{
// Enable article processing
Setting::setArticleProcessingEnabled(true);
// Create only inactive feeds
Feed::factory()->create(['is_active' => false]);
PlatformChannel::factory()->create(['is_active' => true]);
Route::factory()->create(['is_active' => true]);
// Ensure no active feeds exist due to factory relationship side effects
Feed::where('is_active', true)->update(['is_active' => false]);
$status = $this->service->getSystemStatus();
$this->assertFalse($status['is_enabled']);
$this->assertEquals('Disabled', $status['status']);
$this->assertEquals('text-red-600', $status['status_class']);
$this->assertContains('No active feeds configured', $status['reasons']);
}
public function test_get_system_status_returns_disabled_when_no_active_platform_channels(): void
{
// Enable article processing
Setting::setArticleProcessingEnabled(true);
Feed::factory()->create(['is_active' => true]);
// Create only inactive platform channels
PlatformChannel::factory()->create(['is_active' => false]);
Route::factory()->create(['is_active' => true]);
// Ensure no active platform channels exist due to factory relationship side effects
PlatformChannel::where('is_active', true)->update(['is_active' => false]);
$status = $this->service->getSystemStatus();
$this->assertFalse($status['is_enabled']);
$this->assertEquals('Disabled', $status['status']);
$this->assertEquals('text-red-600', $status['status_class']);
$this->assertContains('No active platform channels configured', $status['reasons']);
}
public function test_get_system_status_returns_disabled_when_no_active_routes(): void
{
// Enable article processing
Setting::setArticleProcessingEnabled(true);
Feed::factory()->create(['is_active' => true]);
PlatformChannel::factory()->create(['is_active' => true]);
// Create only inactive routes
Route::factory()->create(['is_active' => false]);
$status = $this->service->getSystemStatus();
$this->assertFalse($status['is_enabled']);
$this->assertEquals('Disabled', $status['status']);
$this->assertEquals('text-red-600', $status['status_class']);
$this->assertContains('No active feed-to-channel routes configured', $status['reasons']);
}
public function test_get_system_status_accumulates_multiple_reasons_when_multiple_conditions_fail(): void
{
// Disable article processing first
Setting::setArticleProcessingEnabled(false);
// Force all existing active records to inactive, and repeat after any factory creates
// to handle cascade relationship issues
do {
$updated = Feed::where('is_active', true)->update(['is_active' => false]);
$updated += PlatformChannel::where('is_active', true)->update(['is_active' => false]);
$updated += Route::where('is_active', true)->update(['is_active' => false]);
} while ($updated > 0);
// Create some inactive entities to ensure they exist but are not active
Feed::factory()->create(['is_active' => false]);
PlatformChannel::factory()->create(['is_active' => false]);
Route::factory()->create(['is_active' => false]);
// Force deactivation again after factory creation in case of relationship side-effects
do {
$updated = Feed::where('is_active', true)->update(['is_active' => false]);
$updated += PlatformChannel::where('is_active', true)->update(['is_active' => false]);
$updated += Route::where('is_active', true)->update(['is_active' => false]);
} while ($updated > 0);
$status = $this->service->getSystemStatus();
$this->assertFalse($status['is_enabled']);
$this->assertEquals('Disabled', $status['status']);
$this->assertEquals('text-red-600', $status['status_class']);
$expectedReasons = [
'Manually disabled by user',
'No active feeds configured',
'No active platform channels configured',
'No active feed-to-channel routes configured'
];
$this->assertCount(4, $status['reasons']);
foreach ($expectedReasons as $reason) {
$this->assertContains($reason, $status['reasons']);
}
}
public function test_get_system_status_handles_completely_empty_database(): void
{
// Enable article processing
Setting::setArticleProcessingEnabled(true);
// Don't create any entities at all
$status = $this->service->getSystemStatus();
$this->assertFalse($status['is_enabled']);
$this->assertEquals('Disabled', $status['status']);
$this->assertEquals('text-red-600', $status['status_class']);
$expectedReasons = [
'No active feeds configured',
'No active platform channels configured',
'No active feed-to-channel routes configured'
];
$this->assertCount(3, $status['reasons']);
foreach ($expectedReasons as $reason) {
$this->assertContains($reason, $status['reasons']);
}
}
public function test_get_system_status_ignores_inactive_entities(): void
{
// Enable article processing
Setting::setArticleProcessingEnabled(true);
// Create both active and inactive entities
Feed::factory()->create(['is_active' => true]);
Feed::factory()->create(['is_active' => false]);
PlatformChannel::factory()->create(['is_active' => true]);
PlatformChannel::factory()->create(['is_active' => false]);
Route::factory()->create(['is_active' => true]);
Route::factory()->create(['is_active' => false]);
$status = $this->service->getSystemStatus();
// Should be enabled because we have at least one active entity of each type
$this->assertTrue($status['is_enabled']);
$this->assertEquals('Enabled', $status['status']);
$this->assertEquals('text-green-600', $status['status_class']);
$this->assertEmpty($status['reasons']);
}
public function test_can_process_articles_returns_true_when_system_enabled(): void
{
// Enable article processing
Setting::setArticleProcessingEnabled(true);
// Create active entities
Feed::factory()->create(['is_active' => true]);
PlatformChannel::factory()->create(['is_active' => true]);
Route::factory()->create(['is_active' => true]);
$result = $this->service->canProcessArticles();
$this->assertTrue($result);
}
public function test_can_process_articles_returns_false_when_system_disabled(): void
{
// Disable article processing
Setting::setArticleProcessingEnabled(false);
// Create active entities
Feed::factory()->create(['is_active' => true]);
PlatformChannel::factory()->create(['is_active' => true]);
Route::factory()->create(['is_active' => true]);
$result = $this->service->canProcessArticles();
$this->assertFalse($result);
}
public function test_can_process_articles_delegates_to_get_system_status(): void
{
// Enable article processing
Setting::setArticleProcessingEnabled(true);
// Create active entities
Feed::factory()->create(['is_active' => true]);
PlatformChannel::factory()->create(['is_active' => true]);
Route::factory()->create(['is_active' => true]);
$systemStatus = $this->service->getSystemStatus();
$canProcess = $this->service->canProcessArticles();
// Both methods should return the same result
$this->assertEquals($systemStatus['is_enabled'], $canProcess);
}
public function test_get_system_status_partial_failures(): void
{
// Test with only feeds and channels active, but no routes
Setting::setArticleProcessingEnabled(true);
Feed::factory()->create(['is_active' => true]);
PlatformChannel::factory()->create(['is_active' => true]);
// No routes created
$status = $this->service->getSystemStatus();
$this->assertFalse($status['is_enabled']);
$this->assertCount(1, $status['reasons']);
$this->assertContains('No active feed-to-channel routes configured', $status['reasons']);
}
public function test_get_system_status_mixed_active_inactive_entities(): void
{
// Create multiple entities of each type with mixed active status
Setting::setArticleProcessingEnabled(true);
Feed::factory()->count(3)->create(['is_active' => false]);
Feed::factory()->create(['is_active' => true]); // At least one active
PlatformChannel::factory()->count(2)->create(['is_active' => false]);
PlatformChannel::factory()->create(['is_active' => true]); // At least one active
Route::factory()->count(4)->create(['is_active' => false]);
Route::factory()->create(['is_active' => true]); // At least one active
$status = $this->service->getSystemStatus();
$this->assertTrue($status['is_enabled']);
$this->assertEquals('Enabled', $status['status']);
$this->assertEmpty($status['reasons']);
}
}