Files
laravel-video-extractor/tests/Feature/OkRuExtractionTest.php
2026-07-16 21:56:58 +03:00

133 lines
4.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Apoloz\VideoExtractor\Tests\Feature;
use Apoloz\VideoExtractor\Dto\VideoRef;
use Apoloz\VideoExtractor\Exceptions\LoginRequiredException;
use Apoloz\VideoExtractor\Exceptions\VideoNotFoundException;
use Apoloz\VideoExtractor\Http\HttpClient;
use Apoloz\VideoExtractor\Platform\Platform;
use Apoloz\VideoExtractor\Strategies\OkRu\OkRuStrategy;
use Apoloz\VideoExtractor\Tests\TestCase;
use Illuminate\Support\Facades\Http;
class OkRuExtractionTest extends TestCase
{
private function ref(): VideoRef
{
return new VideoRef(platform: Platform::OK, id: '15019292494547');
}
public function test_extracts_full_info_from_data_options(): void
{
Http::fake([
'ok.ru/video/*' => Http::response($this->fixture('ok/video_success.html'), 200),
]);
$strategy = new OkRuStrategy($this->app->make(HttpClient::class));
$info = $strategy->extract($this->ref());
self::assertSame('15019292494547', $info->id);
self::assertSame('Falcon mystery in the hood', $info->title);
self::assertSame('A radical shift of optics.', $info->description);
self::assertSame(709, $info->duration);
self::assertSame('Egor Akimov', $info->uploader);
self::assertSame(45, $info->likeCount);
self::assertSame(3419, $info->viewCount);
self::assertSame(0, $info->ageLimit);
self::assertFalse($info->isLive);
self::assertSame(strtotime('2026-07-01T19:28:15+03:00'), $info->timestamp);
// Thumbnail from movie.poster with OG dimensions.
self::assertNotEmpty($info->thumbnails);
self::assertSame(720, $info->bestThumbnail()?->width);
self::assertStringContainsString('iv.okcdn.ru', (string) $info->thumbnailUrl());
// 6 mp4 + 1 hls = 7 formats.
self::assertCount(7, $info->formats);
$full = null;
foreach ($info->formats as $format) {
if ($format->formatId === 'full') {
$full = $format;
}
}
self::assertNotNull($full);
self::assertSame(1080, $full->height);
// expires=1784298004897 ms -> 1784298004 seconds.
self::assertSame(1784298004, $full->expiresAt);
self::assertSame(1784298004, $info->formatExpiresAt);
}
public function test_thumbnail_fast_path_uses_poster(): void
{
Http::fakeSequence()->push($this->fixture('ok/video_success.html'), 200);
$strategy = new OkRuStrategy($this->app->make(HttpClient::class));
$url = $strategy->extractThumbnail($this->ref());
self::assertNotNull($url);
self::assertStringContainsString('iv.okcdn.ru', $url);
}
public function test_falls_back_to_og_meta_when_no_data_options(): void
{
// Page without the inline player payload (external/restricted video).
Http::fake([
'ok.ru/video/*' => Http::response($this->fixture('ok/video_meta_only.html'), 200),
]);
$strategy = new OkRuStrategy($this->app->make(HttpClient::class));
$info = $strategy->extract($this->ref());
self::assertSame('External embed video', $info->title);
self::assertSame('Some Channel', $info->uploader);
self::assertSame(1529, $info->duration);
self::assertSame(12345, $info->viewCount);
// No formats available from the OG fallback.
self::assertSame([], $info->formats);
// Thumbnail still recovered from og:image.
self::assertStringContainsString('EXTERNAL', (string) $info->thumbnailUrl());
}
public function test_thumbnail_falls_back_to_og_image(): void
{
Http::fakeSequence()->push($this->fixture('ok/video_meta_only.html'), 200);
$strategy = new OkRuStrategy($this->app->make(HttpClient::class));
$url = $strategy->extractThumbnail($this->ref());
self::assertSame('https://iv.okcdn.ru/i?r=EXTERNAL&fn=external_8', $url);
}
public function test_throws_not_found_for_stub_error(): void
{
Http::fake([
'ok.ru/video/*' => Http::response($this->fixture('ok/video_not_found.html'), 200),
]);
$strategy = new OkRuStrategy($this->app->make(HttpClient::class));
$this->expectException(VideoNotFoundException::class);
$this->expectExceptionMessage('author of this video has not been found');
$strategy->extract($this->ref());
}
public function test_throws_login_required_for_restricted_video(): void
{
Http::fake([
'ok.ru/video/*' => Http::response(
'<html><body><div>Access to this video is restricted</div></body></html>',
200,
),
]);
$strategy = new OkRuStrategy($this->app->make(HttpClient::class));
$this->expectException(LoginRequiredException::class);
$strategy->extract($this->ref());
}
}