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); } }