Http::response( $this->fixture('vk/video_ext_success.html'), 200, ['Content-Type' => 'text/html; charset=windows-1251'], ), ]); $info = Video::extract('https://vkvideo.ru/video-18403220_456239696'); self::assertSame('Trump cancels grants // DeepSeek revolution', $info->title); self::assertSame(1920, $info->bestThumbnail()?->width); } public function test_facade_extracts_rutube_video_end_to_end(): void { Http::fake([ 'rutube.ru/api/video/*' => Http::response($this->fixture('rutube/video_meta.json'), 200), 'rutube.ru/api/play/options/*' => Http::response($this->fixture('rutube/play_options.json'), 200), ]); $info = Video::extract('https://rutube.ru/video/373ba417757981facf06c55ea5c46cb4/'); self::assertSame('First words of a toddler. Big collection.', $info->title); self::assertStringContainsString('pic.rtbcdn.ru', (string) $info->thumbnailUrl()); } public function test_thumbnail_shortcut_skips_format_fetch(): void { Http::fakeSequence() ->push($this->fixture('rutube/video_meta.json'), 200); $url = Video::thumbnail('https://rutube.ru/video/373ba417757981facf06c55ea5c46cb4/'); self::assertNotNull($url); self::assertStringContainsString('pic.rtbcdn.ru', $url); } public function test_vk_falls_back_to_al_video_when_embed_fails(): void { // Primary (video_ext) reports not found; fallback (al_video) succeeds. Http::fake([ 'vk.com/video_ext.php*' => Http::response( $this->fixture('vk/video_ext_not_found.html'), 200, ['Content-Type' => 'text/html; charset=windows-1251'], ), 'vk.com/al_video.php' => Http::response( $this->fixture('vk/al_video_success.json'), 200, ['Content-Type' => 'application/json; charset=windows-1251'], ), ]); $info = Video::extract('https://vkvideo.ru/video-18403220_456239696'); // Title now comes from the al_video fallback payload. self::assertSame('Trump cancels grants // DeepSeek revolution', $info->title); // AlVideo returns a single 800x450 thumbnail. self::assertCount(1, $info->thumbnails); } public function test_vk_raises_not_found_when_both_strategies_fail(): void { Http::fake([ 'vk.com/video_ext.php*' => Http::response( $this->fixture('vk/video_ext_not_found.html'), 200, ['Content-Type' => 'text/html; charset=windows-1251'], ), 'vk.com/al_video.php' => Http::response( $this->fixture('vk/al_video_deleted.json'), 200, ['Content-Type' => 'application/json; charset=windows-1251'], ), ]); $this->expectException(VideoNotFoundException::class); Video::extract('https://vkvideo.ru/video-18403220_456239696'); } }