getJson('/api/v1/articles'); $response->assertStatus(200) ->assertJsonStructure([ 'success', 'data' => [ 'articles', 'pagination' => [ 'current_page', 'last_page', 'per_page', 'total', 'from', 'to', ], 'settings' => [ 'publishing_approvals_enabled', ], ], 'message' ]); } public function test_index_returns_articles_with_pagination(): void { $feed = Feed::factory()->create(); Article::factory()->count(25)->create(['feed_id' => $feed->id]); $response = $this->getJson('/api/v1/articles?per_page=10'); $response->assertStatus(200) ->assertJson([ 'success' => true, 'data' => [ 'pagination' => [ 'per_page' => 10, 'total' => 25, 'last_page' => 3, ], ] ]); $this->assertCount(10, $response->json('data.articles')); } public function test_index_respects_per_page_limit(): void { $feed = Feed::factory()->create(); Article::factory()->count(10)->create(['feed_id' => $feed->id]); // Test max limit of 100 $response = $this->getJson('/api/v1/articles?per_page=150'); $response->assertStatus(200) ->assertJson([ 'success' => true, 'data' => [ 'pagination' => [ 'per_page' => 100, // Should be capped at 100 ], ] ]); } public function test_index_orders_articles_by_created_at_desc(): void { $feed = Feed::factory()->create(); $firstArticle = Article::factory()->create([ 'feed_id' => $feed->id, 'created_at' => now()->subHours(2), 'title' => 'First Article' ]); $secondArticle = Article::factory()->create([ 'feed_id' => $feed->id, 'created_at' => now()->subHour(), 'title' => 'Second Article' ]); $response = $this->getJson('/api/v1/articles'); $response->assertStatus(200); $articles = $response->json('data.articles'); $this->assertEquals('Second Article', $articles[0]['title']); $this->assertEquals('First Article', $articles[1]['title']); } public function test_approve_article_successfully(): void { $feed = Feed::factory()->create(); $article = Article::factory()->create([ 'feed_id' => $feed->id, 'approval_status' => 'pending' ]); $response = $this->postJson("/api/v1/articles/{$article->id}/approve"); $response->assertStatus(200) ->assertJson([ 'success' => true, 'message' => 'Article approved and queued for publishing.' ]); $article->refresh(); $this->assertEquals('approved', $article->approval_status); } public function test_approve_nonexistent_article_returns_404(): void { $response = $this->postJson('/api/v1/articles/999/approve'); $response->assertStatus(404); } public function test_reject_article_successfully(): void { $feed = Feed::factory()->create(); $article = Article::factory()->create([ 'feed_id' => $feed->id, 'approval_status' => 'pending' ]); $response = $this->postJson("/api/v1/articles/{$article->id}/reject"); $response->assertStatus(200) ->assertJson([ 'success' => true, 'message' => 'Article rejected.' ]); $article->refresh(); $this->assertEquals('rejected', $article->approval_status); } public function test_reject_nonexistent_article_returns_404(): void { $response = $this->postJson('/api/v1/articles/999/reject'); $response->assertStatus(404); } public function test_index_includes_settings(): void { $response = $this->getJson('/api/v1/articles'); $response->assertStatus(200) ->assertJsonStructure([ 'data' => [ 'settings' => [ 'publishing_approvals_enabled' ] ] ]); } }