| <?php |
|
|
| namespace Tests\Feature; |
|
|
| use App\Models\User; |
| use App\Services\FreepikStockContentService; |
| use App\Services\SocialMediaStudioService; |
| use Illuminate\Foundation\Testing\DatabaseTransactions; |
| use Mockery\MockInterface; |
| use Tests\TestCase; |
|
|
| class ToolsViewTest extends TestCase |
| { |
| use DatabaseTransactions; |
|
|
| public function test_tools_page_displays_freepik_asset_explorer_results(): void |
| { |
| $user = User::factory()->create(); |
| $hfOnly = in_array(strtolower((string) env('TOOLS_HF_ONLY', 'false')), ['1', 'true', 'yes', 'on'], true); |
|
|
| if (! $hfOnly) { |
| $this->mock(FreepikStockContentService::class, function (MockInterface $mock): void { |
| $mock->shouldReceive('search') |
| ->once() |
| ->with('nature', 'all', 'relevance', 1) |
| ->andReturn([ |
| 'results' => [ |
| 'images' => [[ |
| 'id' => 10, |
| 'kind' => 'image', |
| 'title' => 'Waterfall hero', |
| 'url' => 'https://www.freepik.com/asset/10', |
| 'thumb' => 'https://img.example.com/resource.jpg', |
| 'subtitle' => 'PHOTO • Vertical • Freepik Author', |
| 'badge' => 'PHOTO', |
| 'meta_line' => 'Likes 9', |
| ]], |
| 'videos' => [[ |
| 'id' => 20, |
| 'kind' => 'video', |
| 'title' => 'Forest Walk', |
| 'url' => 'https://www.freepik.com/video/20', |
| 'thumb' => 'https://img.example.com/video-thumb.jpg', |
| 'preview_url' => 'https://img.example.com/video-preview.mp4', |
| 'subtitle' => '4K • 00:00:10 • Video Author', |
| 'badge' => 'VIDEO', |
| 'meta_line' => '16:9 • footage', |
| ]], |
| 'icons' => [[ |
| 'id' => 30, |
| 'kind' => 'icon', |
| 'title' => 'Nature icon', |
| 'url' => 'https://www.freepik.com/icon/nature-icon_30', |
| 'thumb' => 'https://img.example.com/icon.png', |
| 'subtitle' => 'Outline • Icon Author', |
| 'badge' => 'ICON', |
| 'meta_line' => 'leaf • tree', |
| ]], |
| 'audio' => [[ |
| 'id' => 40, |
| 'kind' => 'audio', |
| 'title' => 'Soft Seasons', |
| 'url' => 'https://img.example.com/music.mp3', |
| 'thumb' => 'https://img.example.com/music.jpg', |
| 'subtitle' => '3:05 • MudiG', |
| 'badge' => 'AUDIO', |
| 'meta_line' => 'Pop • Acoustic • Free', |
| ]], |
| ], |
| 'errors' => [], |
| 'summary' => [ |
| 'images' => 1, |
| 'videos' => 1, |
| 'icons' => 1, |
| 'audio' => 1, |
| ], |
| ]); |
| }); |
| } |
|
|
| $response = $this->actingAs($user) |
| ->get(route('tools.index', [ |
| 'stock_q' => 'nature', |
| 'stock_type' => 'all', |
| 'stock_order' => 'relevance', |
| ])) |
| ->assertOk(); |
|
|
| if ($hfOnly) { |
| $response |
| ->assertSeeText('Hugging Face Mode') |
| ->assertSeeText('HF-only workspace is active.') |
| ->assertSeeText('Image Generator') |
| ->assertSeeText('Remix Lab'); |
|
|
| return; |
| } |
|
|
| $response |
| ->assertSeeText('Freepik Asset Explorer') |
| ->assertSeeText('Images & Templates') |
| ->assertSeeText('Videos') |
| ->assertSeeText('Audio') |
| ->assertSeeText('Icons') |
| ->assertSeeText('Waterfall hero') |
| ->assertSeeText('Forest Walk') |
| ->assertSeeText('Soft Seasons') |
| ->assertSeeText('Nature icon') |
| ->assertSeeText('Click to edit or download') |
| ->assertSeeText('Use Asset') |
| ->assertSeeText('Edit image') |
| ->assertSeeText('Create video'); |
| } |
|
|
| public function test_app_page_displays_template_launcher_and_defaults_video_lab_to_replicate(): void |
| { |
| $user = User::factory()->create(); |
|
|
| $this->actingAs($user) |
| ->get(route('app.index')) |
| ->assertOk() |
| ->assertSee('id="video-provider-input" name="video_provider" value="replicate"', false) |
| ->assertSee('id="video-quality-input" name="video_quality" value="720p"', false) |
| ->assertSee('id="video-duration-input" name="video_duration" value="4s"', false) |
| ->assertSeeText('Movie Poster') |
| ->assertSeeText('Create a Movie Poster') |
| ->assertSeeText('Portrait in, poster out') |
| ->assertSeeText('Generate poster') |
| ->assertSeeText('Replicate WAN 2.1') |
| ->assertSeeText('Sora 2') |
| ->assertSeeText('Default') |
| ->assertSeeText('Alt') |
| ->assertSeeText('Generate Video memakai WaveSpeed WAN 2.1 I2V 480p di Replicate sebagai default service.'); |
| } |
|
|
| public function test_video_generation_defaults_to_replicate_when_video_provider_is_missing(): void |
| { |
| $user = User::factory()->create(); |
|
|
| $this->mock(SocialMediaStudioService::class, function (MockInterface $mock): void { |
| $mock->shouldReceive('generateVideo') |
| ->once() |
| ->with('Animate a clean product reveal', \Mockery::on(function (array $options): bool { |
| return ($options['video_provider'] ?? null) === 'replicate' |
| && ($options['video_model'] ?? null) === 'minimax' |
| && ($options['aspect_ratio'] ?? null) === '16:9' |
| && ($options['video_quality'] ?? null) === '720p' |
| && ($options['video_duration'] ?? null) === '4s'; |
| })) |
| ->andReturn([ |
| 'url' => 'https://cdn.example.com/generated-video.mp4', |
| 'provider' => 'replicate', |
| 'prompt' => 'Animate a clean product reveal', |
| 'aspect' => '16:9', |
| 'duration_seconds' => 5, |
| 'source_image_url' => 'https://cdn.example.com/generated-video-thumb.jpg', |
| ]); |
| }); |
|
|
| $this->actingAs($user) |
| ->postJson(route('tools.video'), [ |
| 'prompt' => 'Animate a clean product reveal', |
| ]) |
| ->assertOk() |
| ->assertJsonPath('status', 'succeeded') |
| ->assertJsonPath('provider', 'replicate') |
| ->assertJsonPath('effective_settings.aspect_ratio', '16:9') |
| ->assertJsonPath('effective_settings.video_quality', '720p') |
| ->assertJsonPath('effective_settings.video_duration', '4s'); |
| } |
| } |
|
|