2026-07-18 17:22:16 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
use App\Models\Post;
|
|
|
|
|
use App\Models\Site;
|
|
|
|
|
use App\Models\SocialAccount;
|
|
|
|
|
|
|
|
|
|
test('it lists all posts', function () {
|
|
|
|
|
Post::factory()->count(3)->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/posts');
|
|
|
|
|
|
|
|
|
|
$response->assertOk()->assertJsonCount(3, 'data');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it filters posts by status', function () {
|
|
|
|
|
Post::factory()->create(['status' => 'draft']);
|
|
|
|
|
Post::factory()->create(['status' => 'published']);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/posts?status=published');
|
|
|
|
|
|
|
|
|
|
$response->assertOk()
|
|
|
|
|
->assertJsonCount(1, 'data')
|
|
|
|
|
->assertJsonPath('data.0.status', 'published');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it filters posts by site_id', function () {
|
|
|
|
|
$site = Site::factory()->create();
|
|
|
|
|
Post::factory()->create(['site_id' => $site->id]);
|
|
|
|
|
Post::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson("/api/posts?site_id={$site->id}");
|
|
|
|
|
|
|
|
|
|
$response->assertOk()->assertJsonCount(1, 'data');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it filters posts by social_account_id', function () {
|
|
|
|
|
$account = SocialAccount::factory()->create();
|
|
|
|
|
Post::factory()->create(['social_account_id' => $account->id]);
|
|
|
|
|
Post::factory()->create(['social_account_id' => null]);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson("/api/posts?social_account_id={$account->id}");
|
|
|
|
|
|
|
|
|
|
$response->assertOk()->assertJsonCount(1, 'data');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it filters posts that are due for publishing', function () {
|
|
|
|
|
Post::factory()->create(['status' => 'scheduled', 'scheduled_at' => now()->subHour()]);
|
|
|
|
|
Post::factory()->create(['status' => 'scheduled', 'scheduled_at' => now()->addDay()]);
|
|
|
|
|
Post::factory()->create(['status' => 'draft', 'scheduled_at' => now()->subHour()]);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson('/api/posts?due=1');
|
|
|
|
|
|
|
|
|
|
$response->assertOk()->assertJsonCount(1, 'data');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it shows a single post', function () {
|
|
|
|
|
$post = Post::factory()->create(['title' => 'Solo Post']);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson("/api/posts/{$post->id}");
|
|
|
|
|
|
|
|
|
|
$response->assertOk()->assertJsonPath('data.title', 'Solo Post');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it returns 404 for a missing post', function () {
|
|
|
|
|
$this->getJson('/api/posts/999')->assertNotFound();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it creates a post with required fields only', function () {
|
|
|
|
|
$site = Site::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/posts', [
|
|
|
|
|
'site_id' => $site->id,
|
|
|
|
|
'type' => 'blog',
|
|
|
|
|
'body' => 'New content',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertCreated()
|
|
|
|
|
->assertJsonPath('data.site_id', $site->id)
|
|
|
|
|
->assertJsonPath('data.type', 'blog')
|
|
|
|
|
->assertJsonPath('data.body', 'New content')
|
|
|
|
|
->assertJsonPath('data.status', 'draft');
|
|
|
|
|
|
|
|
|
|
expect(Post::where('body', 'New content')->exists())->toBeTrue();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it rejects creating a post without a valid site_id', function () {
|
|
|
|
|
$response = $this->postJson('/api/posts', [
|
|
|
|
|
'type' => 'blog',
|
|
|
|
|
'body' => 'New content',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertUnprocessable()->assertJsonValidationErrors(['site_id']);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it rejects creating a post without a valid type', function () {
|
|
|
|
|
$site = Site::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/posts', [
|
|
|
|
|
'site_id' => $site->id,
|
|
|
|
|
'type' => 'not-a-real-type',
|
|
|
|
|
'body' => 'New content',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertUnprocessable()->assertJsonValidationErrors(['type']);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it rejects creating a post without a body', function () {
|
|
|
|
|
$site = Site::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->postJson('/api/posts', [
|
|
|
|
|
'site_id' => $site->id,
|
|
|
|
|
'type' => 'blog',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertUnprocessable()->assertJsonValidationErrors(['body']);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it updates a post status', function () {
|
|
|
|
|
$post = Post::factory()->create(['status' => 'scheduled']);
|
|
|
|
|
|
|
|
|
|
$response = $this->patchJson("/api/posts/{$post->id}", [
|
|
|
|
|
'status' => 'published',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$response->assertOk()->assertJsonPath('data.status', 'published');
|
|
|
|
|
expect($post->fresh()->status)->toBe('published');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('it deletes a post', function () {
|
|
|
|
|
$post = Post::factory()->create();
|
|
|
|
|
|
|
|
|
|
$response = $this->deleteJson("/api/posts/{$post->id}");
|
|
|
|
|
|
|
|
|
|
$response->assertNoContent();
|
|
|
|
|
expect(Post::find($post->id))->toBeNull();
|
|
|
|
|
});
|
2026-07-19 16:51:15 +03:00
|
|
|
|
|
|
|
|
test('it includes published_url in the post response', function () {
|
|
|
|
|
$post = Post::factory()->create(['published_url' => 'https://example.com/my-post']);
|
|
|
|
|
|
|
|
|
|
$response = $this->getJson("/api/posts/{$post->id}");
|
|
|
|
|
|
|
|
|
|
$response->assertOk()->assertJsonPath('data.published_url', 'https://example.com/my-post');
|
|
|
|
|
});
|