fedi-feed-router/backend/tests/Unit/Models/ArticleTest.php

213 lines
6.3 KiB
PHP
Raw Normal View History

2025-08-03 20:59:09 +02:00
<?php
namespace Tests\Unit\Models;
use App\Events\ArticleApproved;
use App\Events\NewArticleFetched;
use App\Models\Article;
use App\Models\Feed;
use App\Models\Setting;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
class ArticleTest extends TestCase
{
use RefreshDatabase;
public function test_is_valid_returns_false_when_validated_at_is_null(): void
{
$article = Article::factory()->make([
'validated_at' => null,
'is_valid' => true,
]);
$this->assertFalse($article->isValid());
}
public function test_is_valid_returns_false_when_is_valid_is_null(): void
{
$article = Article::factory()->make([
'validated_at' => now(),
'is_valid' => null,
]);
$this->assertFalse($article->isValid());
}
public function test_is_valid_returns_false_when_is_valid_is_false(): void
{
$article = Article::factory()->make([
'validated_at' => now(),
'is_valid' => false,
]);
$this->assertFalse($article->isValid());
}
public function test_is_valid_returns_true_when_validated_and_valid(): void
{
$article = Article::factory()->make([
'validated_at' => now(),
'is_valid' => true,
]);
$this->assertTrue($article->isValid());
}
public function test_is_approved_returns_true_for_approved_status(): void
{
$article = Article::factory()->make(['approval_status' => 'approved']);
$this->assertTrue($article->isApproved());
}
public function test_is_approved_returns_false_for_non_approved_status(): void
{
$article = Article::factory()->make(['approval_status' => 'pending']);
$this->assertFalse($article->isApproved());
}
public function test_is_pending_returns_true_for_pending_status(): void
{
$article = Article::factory()->make(['approval_status' => 'pending']);
$this->assertTrue($article->isPending());
}
public function test_is_rejected_returns_true_for_rejected_status(): void
{
$article = Article::factory()->make(['approval_status' => 'rejected']);
$this->assertTrue($article->isRejected());
}
public function test_approve_updates_status_and_timestamps(): void
{
$feed = Feed::factory()->create();
$article = Article::factory()->create([
'feed_id' => $feed->id,
'approval_status' => 'pending',
'approved_at' => null,
'approved_by' => null,
]);
Event::fake();
$article->approve('test_user');
$article->refresh();
$this->assertEquals('approved', $article->approval_status);
$this->assertNotNull($article->approved_at);
$this->assertEquals('test_user', $article->approved_by);
Event::assertDispatched(ArticleApproved::class, function ($event) use ($article) {
return $event->article->id === $article->id;
});
}
public function test_approve_without_approved_by_parameter(): void
{
$feed = Feed::factory()->create();
$article = Article::factory()->create([
'feed_id' => $feed->id,
'approval_status' => 'pending',
]);
Event::fake();
$article->approve();
$article->refresh();
$this->assertEquals('approved', $article->approval_status);
$this->assertNull($article->approved_by);
}
public function test_reject_updates_status_and_timestamps(): void
{
$feed = Feed::factory()->create();
$article = Article::factory()->create([
'feed_id' => $feed->id,
'approval_status' => 'pending',
'approved_at' => null,
'approved_by' => null,
]);
$article->reject('test_user');
$article->refresh();
$this->assertEquals('rejected', $article->approval_status);
$this->assertNotNull($article->approved_at);
$this->assertEquals('test_user', $article->approved_by);
}
public function test_can_be_published_returns_false_for_invalid_article(): void
{
$article = Article::factory()->make([
'is_valid' => false,
'validated_at' => now(),
'approval_status' => 'approved',
]);
$this->assertFalse($article->canBePublished());
}
public function test_can_be_published_requires_approval_when_approvals_enabled(): void
{
// Create a setting that enables approvals
Setting::create(['key' => 'enable_publishing_approvals', 'value' => '1']);
$validPendingArticle = Article::factory()->make([
'is_valid' => true,
'validated_at' => now(),
'approval_status' => 'pending',
]);
$validApprovedArticle = Article::factory()->make([
'is_valid' => true,
'validated_at' => now(),
'approval_status' => 'approved',
]);
$this->assertFalse($validPendingArticle->canBePublished());
$this->assertTrue($validApprovedArticle->canBePublished());
}
public function test_can_be_published_returns_true_when_approvals_disabled(): void
{
// Make sure approvals are disabled (default behavior)
Setting::where('key', 'enable_publishing_approvals')->delete();
$article = Article::factory()->make([
'is_valid' => true,
'validated_at' => now(),
'approval_status' => 'pending', // Even though pending, should be publishable
]);
$this->assertTrue($article->canBePublished());
}
public function test_feed_relationship(): void
{
$feed = Feed::factory()->create();
$article = Article::factory()->create(['feed_id' => $feed->id]);
$this->assertInstanceOf(Feed::class, $article->feed);
$this->assertEquals($feed->id, $article->feed->id);
}
public function test_article_creation_fires_new_article_fetched_event(): void
{
$eventFired = false;
Event::listen(NewArticleFetched::class, function ($event) use (&$eventFired) {
$eventFired = true;
});
$feed = Feed::factory()->create();
Article::factory()->create(['feed_id' => $feed->id]);
$this->assertTrue($eventFired);
}
}