fedi-feed-router/tests/Unit/Services/ArticleFetcherTest.php

212 lines
6.8 KiB
PHP
Raw Normal View History

2025-08-02 03:48:06 +02:00
<?php
namespace Tests\Unit\Services;
use App\Models\Article;
use App\Models\Feed;
use App\Services\Article\ArticleFetcher;
2025-08-02 03:48:06 +02:00
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Collection;
2025-08-10 04:16:53 +02:00
use Illuminate\Support\Facades\Http;
2025-08-06 21:49:13 +02:00
use Mockery;
use Tests\TestCase;
use Tests\Traits\CreatesArticleFetcher;
2025-08-02 03:48:06 +02:00
class ArticleFetcherTest extends TestCase
{
use CreatesArticleFetcher, RefreshDatabase;
2025-08-02 03:48:06 +02:00
2025-08-10 04:16:53 +02:00
protected function setUp(): void
{
parent::setUp();
2025-08-11 18:26:00 +02:00
2025-08-10 04:16:53 +02:00
// Mock all HTTP requests by default to prevent external calls
Http::fake([
'*' => Http::response('<html><body>Mock HTML content</body></html>', 200),
2025-08-10 04:16:53 +02:00
]);
2025-08-15 02:50:42 +02:00
// Create ArticleFetcher only when needed - tests will create their own
2025-08-10 04:16:53 +02:00
}
2025-08-02 03:48:06 +02:00
public function test_get_articles_from_feed_returns_collection(): void
{
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
2025-08-02 03:48:06 +02:00
$feed = Feed::factory()->create([
'type' => 'rss',
'url' => 'https://example.com/feed.rss',
2025-08-02 03:48:06 +02:00
]);
2025-08-15 02:50:42 +02:00
$result = $articleFetcher->getArticlesFromFeed($feed);
2025-08-11 18:26:00 +02:00
$this->assertInstanceOf(Collection::class, $result);
2025-08-02 03:48:06 +02:00
}
public function test_get_articles_from_rss_feed_returns_empty_collection(): void
{
$feed = Feed::factory()->create([
'type' => 'rss',
'url' => 'https://example.com/feed.rss',
2025-08-02 03:48:06 +02:00
]);
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->getArticlesFromFeed($feed);
2025-08-11 18:26:00 +02:00
2025-08-02 03:48:06 +02:00
// RSS parsing is not implemented yet, should return empty collection
$this->assertEmpty($result);
}
public function test_get_articles_from_website_feed_handles_no_parser(): void
{
$feed = Feed::factory()->create([
'type' => 'website',
'url' => 'https://unsupported-site.com/',
2025-08-02 03:48:06 +02:00
]);
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->getArticlesFromFeed($feed);
2025-08-11 18:26:00 +02:00
2025-08-02 03:48:06 +02:00
// Should return empty collection when no parser is available
$this->assertInstanceOf(Collection::class, $result);
2025-08-02 03:48:06 +02:00
$this->assertEmpty($result);
}
public function test_get_articles_from_unsupported_feed_type(): void
{
$feed = Feed::factory()->create([
'type' => 'website', // Use valid type but with unsupported URL
'url' => 'https://unsupported-feed-type.com/feed',
2025-08-02 03:48:06 +02:00
]);
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->getArticlesFromFeed($feed);
2025-08-11 18:26:00 +02:00
$this->assertInstanceOf(Collection::class, $result);
2025-08-02 03:48:06 +02:00
$this->assertEmpty($result);
}
public function test_fetch_article_data_returns_array(): void
{
$article = Article::factory()->create([
'url' => 'https://example.com/article',
2025-08-02 03:48:06 +02:00
]);
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->fetchArticleData($article);
2025-08-11 18:26:00 +02:00
2025-08-02 03:48:06 +02:00
$this->assertIsArray($result);
// Will be empty array due to unsupported URL in test
$this->assertEmpty($result);
}
public function test_fetch_article_data_handles_invalid_url(): void
{
$article = Article::factory()->create([
'url' => 'invalid-url',
2025-08-02 03:48:06 +02:00
]);
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->fetchArticleData($article);
2025-08-11 18:26:00 +02:00
2025-08-02 03:48:06 +02:00
$this->assertIsArray($result);
$this->assertEmpty($result);
}
2025-08-06 21:49:13 +02:00
public function test_get_articles_from_feed_with_null_feed_type(): void
{
// Create feed with valid type first, then manually set to invalid value
$feed = Feed::factory()->create([
'type' => 'website',
'url' => 'https://example.com/feed',
2025-08-06 21:49:13 +02:00
]);
2025-08-11 18:26:00 +02:00
2025-08-06 21:49:13 +02:00
// Use reflection to set an invalid type that bypasses enum validation
$reflection = new \ReflectionClass($feed);
$property = $reflection->getProperty('attributes');
$property->setAccessible(true);
$attributes = $property->getValue($feed);
$attributes['type'] = 'invalid_type';
$property->setValue($feed, $attributes);
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->getArticlesFromFeed($feed);
2025-08-11 18:26:00 +02:00
$this->assertInstanceOf(Collection::class, $result);
2025-08-06 21:49:13 +02:00
$this->assertEmpty($result);
}
public function test_get_articles_from_website_feed_with_supported_parser(): void
{
2025-08-10 04:16:53 +02:00
// Mock successful HTTP response with sample HTML
Http::fake([
'https://www.vrt.be/vrtnws/nl/' => Http::response('<html><body>Sample VRT content</body></html>', 200),
2025-08-10 04:16:53 +02:00
]);
2025-08-06 21:49:13 +02:00
$feed = Feed::factory()->create([
'type' => 'website',
'url' => 'https://www.vrt.be/vrtnws/nl/',
2025-08-06 21:49:13 +02:00
]);
// Test actual behavior - VRT parser should be available
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->getArticlesFromFeed($feed);
2025-08-11 18:26:00 +02:00
$this->assertInstanceOf(Collection::class, $result);
2025-08-10 04:16:53 +02:00
// VRT parser will process the mocked HTML response
2025-08-06 21:49:13 +02:00
}
public function test_get_articles_from_website_feed_handles_invalid_url(): void
{
2025-08-11 18:26:00 +02:00
// HTTP mock already set in setUp() to return mock HTML for all requests
2025-08-06 21:49:13 +02:00
$feed = Feed::factory()->create([
'type' => 'website',
'url' => 'https://invalid-domain-that-does-not-exist-12345.com/',
2025-08-06 21:49:13 +02:00
]);
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->getArticlesFromFeed($feed);
2025-08-11 18:26:00 +02:00
$this->assertInstanceOf(Collection::class, $result);
2025-08-06 21:49:13 +02:00
$this->assertEmpty($result);
}
public function test_fetch_article_data_with_supported_parser(): void
{
2025-08-10 04:16:53 +02:00
// Mock successful HTTP response with sample HTML
Http::fake([
'https://www.vrt.be/vrtnws/nl/test-article' => Http::response('<html><body>Sample article content</body></html>', 200),
2025-08-10 04:16:53 +02:00
]);
2025-08-06 21:49:13 +02:00
$article = Article::factory()->create([
'url' => 'https://www.vrt.be/vrtnws/nl/test-article',
2025-08-06 21:49:13 +02:00
]);
// Test actual behavior - VRT parser should be available
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->fetchArticleData($article);
2025-08-11 18:26:00 +02:00
2025-08-06 21:49:13 +02:00
$this->assertIsArray($result);
2025-08-10 04:16:53 +02:00
// VRT parser will process the mocked HTML response
2025-08-06 21:49:13 +02:00
}
public function test_fetch_article_data_handles_unsupported_domain(): void
{
$article = Article::factory()->create([
'url' => 'https://unsupported-domain.com/article',
2025-08-06 21:49:13 +02:00
]);
2025-08-15 02:50:42 +02:00
$articleFetcher = $this->createArticleFetcher();
$result = $articleFetcher->fetchArticleData($article);
2025-08-11 18:26:00 +02:00
2025-08-06 21:49:13 +02:00
$this->assertIsArray($result);
$this->assertEmpty($result);
}
protected function tearDown(): void
{
Mockery::close();
parent::tearDown();
}
2025-08-11 18:26:00 +02:00
}