teknolis / tests /Feature /SocialAutomationTest.php.bak-20260329-setup-modal
OpenAI Codex
Fix storage symlink and adapt cron status for Spaces
1501522
Raw
History Blame Contribute Delete
6.98 kB
<?php
namespace Tests\Feature;
use App\Models\SocialPlatformCredential;
use App\Models\SocialPost;
use App\Models\User;
use App\Services\SocialContentGeneratorService;
use App\Services\SocialPublisherService;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Mockery\MockInterface;
use RuntimeException;
use Tests\TestCase;
class SocialAutomationTest extends TestCase
{
use DatabaseTransactions;
public function test_generate_failures_are_returned_as_flash_error(): void
{
$user = User::factory()->create();
$this->mock(SocialContentGeneratorService::class, function (MockInterface $mock): void {
$mock->shouldReceive('generate')
->once()
->andThrow(new RuntimeException('OpenAI unavailable'));
});
$response = $this
->actingAs($user)
->from(route('social.index'))
->post(route('social.generate'), [
'topic' => 'Promo hosting ramadhan',
'tone' => 'friendly-professional',
'platform_hint' => 'facebook, instagram',
]);
$response
->assertRedirect(route('social.index'))
->assertSessionHas('social_error', 'OpenAI unavailable');
}
public function test_instagram_posts_require_an_image_url(): void
{
$user = User::factory()->create();
$response = $this
->actingAs($user)
->from(route('social.index'))
->post(route('social.store'), [
'platforms' => ['instagram'],
'title' => 'Promo baru',
'caption' => 'Caption promo',
'hashtags' => 'promo,bisnis',
'scheduled_at' => now()->addHour()->toDateTimeString(),
'status' => 'scheduled',
]);
$response
->assertRedirect(route('social.index'))
->assertSessionHas('social_error', 'Instagram membutuhkan image_url publik sebelum post bisa dibuat.');
$this->assertDatabaseCount('social_posts', 0);
}
public function test_tiktok_posts_require_a_video_url(): void
{
$user = User::factory()->create();
$response = $this
->actingAs($user)
->from(route('social.index'))
->post(route('social.store'), [
'platforms' => ['tiktok'],
'title' => 'Promo video',
'caption' => 'Caption tiktok',
'hashtags' => 'promo,video',
'scheduled_at' => now()->addHour()->toDateTimeString(),
'status' => 'scheduled',
]);
$response
->assertRedirect(route('social.index'))
->assertSessionHas('social_error', 'TikTok membutuhkan video_url publik sebelum post bisa dibuat.');
$this->assertDatabaseCount('social_posts', 0);
}
public function test_credential_settings_page_is_displayed(): void
{
$user = User::factory()->create();
$this->actingAs($user)
->get(route('social.credentials.index'))
->assertOk()
->assertSeeText('Setting Credential');
}
public function test_saving_credentials_preserves_existing_token_and_meta_when_left_blank(): void
{
$user = User::factory()->create();
$credential = SocialPlatformCredential::create([
'user_id' => $user->id,
'platform' => 'facebook',
'account_label' => 'Main page',
'account_id' => 'page-1',
'access_token' => 'token-lama',
'meta' => [
'client_id' => 'client-lama',
'client_secret' => 'secret-lama',
],
]);
$response = $this
->actingAs($user)
->from(route('social.credentials.index'))
->post(route('social.credentials.store'), [
'platform' => 'facebook',
'account_label' => 'Main page updated',
'account_id' => 'page-2',
'access_token' => '',
'meta_client_id' => '',
'meta_client_secret' => '',
]);
$response
->assertRedirect(route('social.credentials.index').'#platform-facebook')
->assertSessionHasNoErrors();
$credential->refresh();
$this->assertSame('Main page updated', $credential->account_label);
$this->assertSame('page-2', $credential->account_id);
$this->assertSame('token-lama', $credential->access_token);
$this->assertSame([
'client_id' => 'client-lama',
'client_secret' => 'secret-lama',
], $credential->meta);
}
public function test_publish_now_rejects_posts_that_are_already_posted(): void
{
$user = User::factory()->create();
$post = SocialPost::create([
'user_id' => $user->id,
'platform' => 'x',
'status' => 'posted',
'requires_approval' => false,
'caption' => 'Sudah terbit',
'scheduled_at' => now()->subHour(),
'posted_at' => now()->subMinutes(10),
]);
$response = $this
->actingAs($user)
->post(route('social.publish-now', $post));
$response
->assertRedirect(route('social.index'))
->assertSessionHas('social_error', 'Post ini sudah pernah dipublish.');
}
public function test_publish_now_clears_retry_metadata_after_success(): void
{
$user = User::factory()->create();
SocialPlatformCredential::create([
'user_id' => $user->id,
'platform' => 'x',
'access_token' => 'token-x',
]);
$post = SocialPost::create([
'user_id' => $user->id,
'platform' => 'x',
'status' => 'failed',
'requires_approval' => false,
'caption' => 'Coba kirim ulang',
'scheduled_at' => now()->subHour(),
'attempt_count' => 2,
'next_retry_at' => now()->addMinutes(15),
]);
$this->mock(SocialPublisherService::class, function (MockInterface $mock): void {
$mock->shouldReceive('publish')
->once()
->andReturn([
'external_post_id' => 'tweet-123',
'payload' => ['ok' => true],
]);
});
$response = $this
->actingAs($user)
->post(route('social.publish-now', $post));
$response
->assertRedirect(route('social.index'))
->assertSessionHas('social_success', 'Post berhasil dipublish ke x.');
$post->refresh();
$this->assertSame('posted', $post->status);
$this->assertNull($post->next_retry_at);
$this->assertNotNull($post->approved_at);
$this->assertSame('tweet-123', $post->external_post_id);
}
}