Fix test output

This commit is contained in:
myrmidex 2025-08-11 18:26:00 +02:00
parent 1c772e63cb
commit d59128871e
4 changed files with 45 additions and 51 deletions

View file

@ -325,7 +325,7 @@ public function test_create_route_validates_required_fields()
public function test_create_route_creates_route_successfully() public function test_create_route_creates_route_successfully()
{ {
$language = Language::first() ?? Language::factory()->create(); $language = Language::first();
$feed = Feed::factory()->language($language)->create(); $feed = Feed::factory()->language($language)->create();
$platformChannel = PlatformChannel::factory()->create(); $platformChannel = PlatformChannel::factory()->create();

View file

@ -3,10 +3,8 @@
namespace Tests\Unit\Modules\Lemmy\Services; namespace Tests\Unit\Modules\Lemmy\Services;
use App\Modules\Lemmy\Services\LemmyApiService; use App\Modules\Lemmy\Services\LemmyApiService;
use App\Modules\Lemmy\LemmyRequest;
use App\Models\PlatformChannelPost; use App\Models\PlatformChannelPost;
use App\Enums\PlatformEnum; use App\Enums\PlatformEnum;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Tests\TestCase; use Tests\TestCase;
@ -23,11 +21,11 @@ protected function tearDown(): void
public function test_constructor_sets_instance(): void public function test_constructor_sets_instance(): void
{ {
$service = new LemmyApiService('lemmy.world'); $service = new LemmyApiService('lemmy.world');
$reflection = new \ReflectionClass($service); $reflection = new \ReflectionClass($service);
$property = $reflection->getProperty('instance'); $property = $reflection->getProperty('instance');
$property->setAccessible(true); $property->setAccessible(true);
$this->assertEquals('lemmy.world', $property->getValue($service)); $this->assertEquals('lemmy.world', $property->getValue($service));
} }
@ -119,13 +117,13 @@ public function test_login_handles_rate_limit_error(): void
// Expecting 4 error logs: // Expecting 4 error logs:
// 1. 'Lemmy login failed' for HTTPS attempt // 1. 'Lemmy login failed' for HTTPS attempt
// 2. 'Lemmy login exception' for catching the rate limit exception on HTTPS // 2. 'Lemmy login exception' for catching the rate limit exception on HTTPS
// 3. 'Lemmy login failed' for HTTP attempt // 3. 'Lemmy login failed' for HTTP attempt
// 4. 'Lemmy login exception' for catching the rate limit exception on HTTP // 4. 'Lemmy login exception' for catching the rate limit exception on HTTP
Log::shouldReceive('error')->times(4); Log::shouldReceive('error')->times(4);
$service = new LemmyApiService('lemmy.world'); $service = new LemmyApiService('lemmy.world');
$result = $service->login('user', 'pass'); $result = $service->login('user', 'pass');
// Since the exception is caught and HTTP is tried, then that also fails, // Since the exception is caught and HTTP is tried, then that also fails,
// the method returns null instead of throwing // the method returns null instead of throwing
$this->assertNull($result); $this->assertNull($result);
@ -286,7 +284,7 @@ public function test_sync_channel_posts_handles_exception(): void
$service = new LemmyApiService('lemmy.world'); $service = new LemmyApiService('lemmy.world');
$service->syncChannelPosts('token', 42, 'test-community'); $service->syncChannelPosts('token', 42, 'test-community');
// Assert that the method completes without throwing // Assert that the method completes without throwing
$this->assertTrue(true); $this->assertTrue(true);
} }
@ -428,4 +426,4 @@ public function test_get_languages_returns_empty_when_all_languages_missing(): v
$this->assertEquals([], $languages); $this->assertEquals([], $languages);
} }
} }

View file

@ -5,10 +5,6 @@
use App\Services\Article\ArticleFetcher; use App\Services\Article\ArticleFetcher;
use App\Models\Feed; use App\Models\Feed;
use App\Models\Article; use App\Models\Article;
use App\Services\Http\HttpFetcher;
use App\Services\Factories\HomepageParserFactory;
use App\Services\Factories\ArticleParserFactory;
use App\Services\Log\LogSaver;
use Tests\TestCase; use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
@ -21,10 +17,10 @@ class ArticleFetcherTest extends TestCase
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
// Mock all HTTP requests by default to prevent external calls // Mock all HTTP requests by default to prevent external calls
Http::fake([ Http::fake([
'*' => Http::response('', 500) '*' => Http::response('<html><body>Mock HTML content</body></html>', 200)
]); ]);
} }
@ -36,7 +32,7 @@ public function test_get_articles_from_feed_returns_collection(): void
]); ]);
$result = ArticleFetcher::getArticlesFromFeed($feed); $result = ArticleFetcher::getArticlesFromFeed($feed);
$this->assertInstanceOf(\Illuminate\Support\Collection::class, $result); $this->assertInstanceOf(\Illuminate\Support\Collection::class, $result);
} }
@ -48,7 +44,7 @@ public function test_get_articles_from_rss_feed_returns_empty_collection(): void
]); ]);
$result = ArticleFetcher::getArticlesFromFeed($feed); $result = ArticleFetcher::getArticlesFromFeed($feed);
// RSS parsing is not implemented yet, should return empty collection // RSS parsing is not implemented yet, should return empty collection
$this->assertEmpty($result); $this->assertEmpty($result);
} }
@ -61,7 +57,7 @@ public function test_get_articles_from_website_feed_handles_no_parser(): void
]); ]);
$result = ArticleFetcher::getArticlesFromFeed($feed); $result = ArticleFetcher::getArticlesFromFeed($feed);
// Should return empty collection when no parser is available // Should return empty collection when no parser is available
$this->assertInstanceOf(\Illuminate\Support\Collection::class, $result); $this->assertInstanceOf(\Illuminate\Support\Collection::class, $result);
$this->assertEmpty($result); $this->assertEmpty($result);
@ -75,7 +71,7 @@ public function test_get_articles_from_unsupported_feed_type(): void
]); ]);
$result = ArticleFetcher::getArticlesFromFeed($feed); $result = ArticleFetcher::getArticlesFromFeed($feed);
$this->assertInstanceOf(\Illuminate\Support\Collection::class, $result); $this->assertInstanceOf(\Illuminate\Support\Collection::class, $result);
$this->assertEmpty($result); $this->assertEmpty($result);
} }
@ -87,7 +83,7 @@ public function test_fetch_article_data_returns_array(): void
]); ]);
$result = ArticleFetcher::fetchArticleData($article); $result = ArticleFetcher::fetchArticleData($article);
$this->assertIsArray($result); $this->assertIsArray($result);
// Will be empty array due to unsupported URL in test // Will be empty array due to unsupported URL in test
$this->assertEmpty($result); $this->assertEmpty($result);
@ -100,7 +96,7 @@ public function test_fetch_article_data_handles_invalid_url(): void
]); ]);
$result = ArticleFetcher::fetchArticleData($article); $result = ArticleFetcher::fetchArticleData($article);
$this->assertIsArray($result); $this->assertIsArray($result);
$this->assertEmpty($result); $this->assertEmpty($result);
} }
@ -112,7 +108,7 @@ public function test_get_articles_from_feed_with_null_feed_type(): void
'type' => 'website', 'type' => 'website',
'url' => 'https://example.com/feed' 'url' => 'https://example.com/feed'
]); ]);
// Use reflection to set an invalid type that bypasses enum validation // Use reflection to set an invalid type that bypasses enum validation
$reflection = new \ReflectionClass($feed); $reflection = new \ReflectionClass($feed);
$property = $reflection->getProperty('attributes'); $property = $reflection->getProperty('attributes');
@ -122,7 +118,7 @@ public function test_get_articles_from_feed_with_null_feed_type(): void
$property->setValue($feed, $attributes); $property->setValue($feed, $attributes);
$result = ArticleFetcher::getArticlesFromFeed($feed); $result = ArticleFetcher::getArticlesFromFeed($feed);
$this->assertInstanceOf(\Illuminate\Support\Collection::class, $result); $this->assertInstanceOf(\Illuminate\Support\Collection::class, $result);
$this->assertEmpty($result); $this->assertEmpty($result);
} }
@ -141,22 +137,22 @@ public function test_get_articles_from_website_feed_with_supported_parser(): voi
// Test actual behavior - VRT parser should be available // Test actual behavior - VRT parser should be available
$result = ArticleFetcher::getArticlesFromFeed($feed); $result = ArticleFetcher::getArticlesFromFeed($feed);
$this->assertInstanceOf(\Illuminate\Support\Collection::class, $result); $this->assertInstanceOf(\Illuminate\Support\Collection::class, $result);
// VRT parser will process the mocked HTML response // VRT parser will process the mocked HTML response
} }
public function test_get_articles_from_website_feed_handles_invalid_url(): void public function test_get_articles_from_website_feed_handles_invalid_url(): void
{ {
// HTTP mock already set in setUp() to return 500 for all requests // HTTP mock already set in setUp() to return mock HTML for all requests
$feed = Feed::factory()->create([ $feed = Feed::factory()->create([
'type' => 'website', 'type' => 'website',
'url' => 'https://invalid-domain-that-does-not-exist-12345.com/' 'url' => 'https://invalid-domain-that-does-not-exist-12345.com/'
]); ]);
$result = ArticleFetcher::getArticlesFromFeed($feed); $result = ArticleFetcher::getArticlesFromFeed($feed);
$this->assertInstanceOf(\Illuminate\Support\Collection::class, $result); $this->assertInstanceOf(\Illuminate\Support\Collection::class, $result);
$this->assertEmpty($result); $this->assertEmpty($result);
} }
@ -174,7 +170,7 @@ public function test_fetch_article_data_with_supported_parser(): void
// Test actual behavior - VRT parser should be available // Test actual behavior - VRT parser should be available
$result = ArticleFetcher::fetchArticleData($article); $result = ArticleFetcher::fetchArticleData($article);
$this->assertIsArray($result); $this->assertIsArray($result);
// VRT parser will process the mocked HTML response // VRT parser will process the mocked HTML response
} }
@ -186,7 +182,7 @@ public function test_fetch_article_data_handles_unsupported_domain(): void
]); ]);
$result = ArticleFetcher::fetchArticleData($article); $result = ArticleFetcher::fetchArticleData($article);
$this->assertIsArray($result); $this->assertIsArray($result);
$this->assertEmpty($result); $this->assertEmpty($result);
} }
@ -195,17 +191,17 @@ public function test_save_article_creates_new_article_when_not_exists(): void
{ {
$feed = Feed::factory()->create(); $feed = Feed::factory()->create();
$url = 'https://example.com/unique-article'; $url = 'https://example.com/unique-article';
// Ensure article doesn't exist // Ensure article doesn't exist
$this->assertDatabaseMissing('articles', ['url' => $url]); $this->assertDatabaseMissing('articles', ['url' => $url]);
// Use reflection to access private method for testing // Use reflection to access private method for testing
$reflection = new \ReflectionClass(ArticleFetcher::class); $reflection = new \ReflectionClass(ArticleFetcher::class);
$saveArticleMethod = $reflection->getMethod('saveArticle'); $saveArticleMethod = $reflection->getMethod('saveArticle');
$saveArticleMethod->setAccessible(true); $saveArticleMethod->setAccessible(true);
$article = $saveArticleMethod->invoke(null, $url, $feed->id); $article = $saveArticleMethod->invoke(null, $url, $feed->id);
$this->assertInstanceOf(Article::class, $article); $this->assertInstanceOf(Article::class, $article);
$this->assertEquals($url, $article->url); $this->assertEquals($url, $article->url);
$this->assertEquals($feed->id, $article->feed_id); $this->assertEquals($feed->id, $article->feed_id);
@ -219,17 +215,17 @@ public function test_save_article_returns_existing_article_when_exists(): void
'url' => 'https://example.com/existing-article', 'url' => 'https://example.com/existing-article',
'feed_id' => $feed->id 'feed_id' => $feed->id
]); ]);
// Use reflection to access private method for testing // Use reflection to access private method for testing
$reflection = new \ReflectionClass(ArticleFetcher::class); $reflection = new \ReflectionClass(ArticleFetcher::class);
$saveArticleMethod = $reflection->getMethod('saveArticle'); $saveArticleMethod = $reflection->getMethod('saveArticle');
$saveArticleMethod->setAccessible(true); $saveArticleMethod->setAccessible(true);
$article = $saveArticleMethod->invoke(null, $existingArticle->url, $feed->id); $article = $saveArticleMethod->invoke(null, $existingArticle->url, $feed->id);
$this->assertEquals($existingArticle->id, $article->id); $this->assertEquals($existingArticle->id, $article->id);
$this->assertEquals($existingArticle->url, $article->url); $this->assertEquals($existingArticle->url, $article->url);
// Ensure no duplicate was created // Ensure no duplicate was created
$this->assertEquals(1, Article::where('url', $existingArticle->url)->count()); $this->assertEquals(1, Article::where('url', $existingArticle->url)->count());
} }
@ -237,14 +233,14 @@ public function test_save_article_returns_existing_article_when_exists(): void
public function test_save_article_without_feed_id(): void public function test_save_article_without_feed_id(): void
{ {
$url = 'https://example.com/article-without-feed'; $url = 'https://example.com/article-without-feed';
// Use reflection to access private method for testing // Use reflection to access private method for testing
$reflection = new \ReflectionClass(ArticleFetcher::class); $reflection = new \ReflectionClass(ArticleFetcher::class);
$saveArticleMethod = $reflection->getMethod('saveArticle'); $saveArticleMethod = $reflection->getMethod('saveArticle');
$saveArticleMethod->setAccessible(true); $saveArticleMethod->setAccessible(true);
$article = $saveArticleMethod->invoke(null, $url, null); $article = $saveArticleMethod->invoke(null, $url, null);
$this->assertInstanceOf(Article::class, $article); $this->assertInstanceOf(Article::class, $article);
$this->assertEquals($url, $article->url); $this->assertEquals($url, $article->url);
$this->assertNull($article->feed_id); $this->assertNull($article->feed_id);
@ -256,4 +252,4 @@ protected function tearDown(): void
Mockery::close(); Mockery::close();
parent::tearDown(); parent::tearDown();
} }
} }

View file

@ -28,7 +28,7 @@ public function test_validate_returns_article_with_validation_status(): void
]); ]);
$result = ValidationService::validate($article); $result = ValidationService::validate($article);
$this->assertInstanceOf(Article::class, $result); $this->assertInstanceOf(Article::class, $result);
$this->assertContains($result->approval_status, ['pending', 'approved', 'rejected']); $this->assertContains($result->approval_status, ['pending', 'approved', 'rejected']);
} }
@ -48,7 +48,7 @@ public function test_validate_marks_article_invalid_when_missing_data(): void
]); ]);
$result = ValidationService::validate($article); $result = ValidationService::validate($article);
$this->assertEquals('rejected', $result->approval_status); $this->assertEquals('rejected', $result->approval_status);
} }
@ -67,7 +67,7 @@ public function test_validate_with_supported_article_content(): void
]); ]);
$result = ValidationService::validate($article); $result = ValidationService::validate($article);
// Since we can't fetch real content in tests, it should be marked rejected // Since we can't fetch real content in tests, it should be marked rejected
$this->assertEquals('rejected', $result->approval_status); $this->assertEquals('rejected', $result->approval_status);
} }
@ -87,9 +87,9 @@ public function test_validate_updates_article_in_database(): void
]); ]);
$originalId = $article->id; $originalId = $article->id;
ValidationService::validate($article); ValidationService::validate($article);
// Check that the article was updated in the database // Check that the article was updated in the database
$updatedArticle = Article::find($originalId); $updatedArticle = Article::find($originalId);
$this->assertContains($updatedArticle->approval_status, ['pending', 'approved', 'rejected']); $this->assertContains($updatedArticle->approval_status, ['pending', 'approved', 'rejected']);
@ -110,9 +110,9 @@ public function test_validate_handles_article_with_existing_validation(): void
]); ]);
$originalApprovalStatus = $article->approval_status; $originalApprovalStatus = $article->approval_status;
$result = ValidationService::validate($article); $result = ValidationService::validate($article);
// Should re-validate - status may change based on content validation // Should re-validate - status may change based on content validation
$this->assertContains($result->approval_status, ['pending', 'approved', 'rejected']); $this->assertContains($result->approval_status, ['pending', 'approved', 'rejected']);
} }
@ -128,7 +128,7 @@ public function test_validate_keyword_checking_logic(): void
]); ]);
$feed = Feed::factory()->create(); $feed = Feed::factory()->create();
// Create an article that would match the validation keywords if content was available // Create an article that would match the validation keywords if content was available
$article = Article::factory()->create([ $article = Article::factory()->create([
'feed_id' => $feed->id, 'feed_id' => $feed->id,
@ -137,9 +137,9 @@ public function test_validate_keyword_checking_logic(): void
]); ]);
$result = ValidationService::validate($article); $result = ValidationService::validate($article);
// The service looks for keywords in the full_article content // The service looks for keywords in the full_article content
// Since we can't fetch real content, it will be marked rejected // Since we can't fetch real content, it will be marked rejected
$this->assertEquals('rejected', $result->approval_status); $this->assertEquals('rejected', $result->approval_status);
} }
} }