158 lines
5.5 KiB
PHP
158 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Apoloz\VideoExtractor\Tests\Feature;
|
|
|
|
use Apoloz\VideoExtractor\Dto\VideoRef;
|
|
use Apoloz\VideoExtractor\Exceptions\VideoNotFoundException;
|
|
use Apoloz\VideoExtractor\Http\HttpClient;
|
|
use Apoloz\VideoExtractor\Platform\Platform;
|
|
use Apoloz\VideoExtractor\Strategies\Vk\AlVideoStrategy;
|
|
use Apoloz\VideoExtractor\Strategies\Vk\VideoExtStrategy;
|
|
use Apoloz\VideoExtractor\Tests\TestCase;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
class VkExtractionTest extends TestCase
|
|
{
|
|
private function ref(): VideoRef
|
|
{
|
|
return new VideoRef(
|
|
platform: Platform::VK,
|
|
id: '-18403220_456239696',
|
|
oid: '-18403220',
|
|
type: 'video',
|
|
);
|
|
}
|
|
|
|
public function test_video_ext_strategy_extracts_full_info(): void
|
|
{
|
|
Http::fake([
|
|
'vk.com/video_ext.php*' => Http::response(
|
|
$this->fixture('vk/video_ext_success.html'),
|
|
200,
|
|
['Content-Type' => 'text/html; charset=windows-1251'],
|
|
),
|
|
]);
|
|
|
|
$strategy = new VideoExtStrategy($this->app->make(HttpClient::class));
|
|
$info = $strategy->extract($this->ref());
|
|
|
|
self::assertSame('-18403220_456239696', $info->id);
|
|
self::assertSame('Trump cancels grants // DeepSeek revolution', $info->title);
|
|
self::assertSame(1983, $info->duration);
|
|
self::assertSame(1738252883, $info->timestamp);
|
|
self::assertSame(699108, $info->viewCount);
|
|
self::assertSame(4320, $info->likeCount);
|
|
self::assertSame(213, $info->commentCount);
|
|
self::assertSame('Ruslan Usachev', $info->uploader);
|
|
|
|
// Thumbnails: multiple resolutions; best should be 1920x1080.
|
|
self::assertNotEmpty($info->thumbnails);
|
|
self::assertSame(1920, $info->bestThumbnail()?->width);
|
|
self::assertStringContainsString('video_thumb', (string) $info->thumbnailUrl());
|
|
}
|
|
|
|
public function test_video_ext_strategy_extracts_only_thumbnail(): void
|
|
{
|
|
Http::fake([
|
|
'vk.com/video_ext.php*' => Http::response(
|
|
$this->fixture('vk/video_ext_success.html'),
|
|
200,
|
|
['Content-Type' => 'text/html; charset=windows-1251'],
|
|
),
|
|
]);
|
|
|
|
$strategy = new VideoExtStrategy($this->app->make(HttpClient::class));
|
|
$url = $strategy->extractThumbnail($this->ref());
|
|
|
|
self::assertNotNull($url);
|
|
self::assertStringContainsString('video_thumb', $url);
|
|
}
|
|
|
|
public function test_video_ext_strategy_extracts_formats_with_expiry(): void
|
|
{
|
|
Http::fake([
|
|
'vk.com/video_ext.php*' => Http::response(
|
|
$this->fixture('vk/video_ext_success.html'),
|
|
200,
|
|
['Content-Type' => 'text/html; charset=windows-1251'],
|
|
),
|
|
]);
|
|
|
|
$strategy = new VideoExtStrategy($this->app->make(HttpClient::class));
|
|
$info = $strategy->extract($this->ref());
|
|
|
|
// 6 mp4 heights + hls + dash_sep = 8 formats.
|
|
self::assertCount(8, $info->formats);
|
|
|
|
$mp41080 = null;
|
|
foreach ($info->formats as $format) {
|
|
if ($format->formatId === 'mp4_1080') {
|
|
$mp41080 = $format;
|
|
}
|
|
}
|
|
self::assertNotNull($mp41080);
|
|
self::assertSame(1080, $mp41080->height);
|
|
// expires=1784467826444 is milliseconds -> 1784467826 seconds.
|
|
self::assertSame(1784467826, $mp41080->expiresAt);
|
|
}
|
|
|
|
public function test_video_ext_strategy_throws_when_video_not_found(): 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'],
|
|
),
|
|
]);
|
|
|
|
$strategy = new VideoExtStrategy($this->app->make(HttpClient::class));
|
|
|
|
$this->expectException(VideoNotFoundException::class);
|
|
$strategy->extract($this->ref());
|
|
}
|
|
|
|
public function test_al_video_strategy_extracts_info(): void
|
|
{
|
|
Http::fake([
|
|
'vk.com/al_video.php' => Http::response(
|
|
$this->fixture('vk/al_video_success.json'),
|
|
200,
|
|
['Content-Type' => 'application/json; charset=windows-1251'],
|
|
),
|
|
]);
|
|
|
|
$strategy = new AlVideoStrategy($this->app->make(HttpClient::class));
|
|
$info = $strategy->extract($this->ref());
|
|
|
|
self::assertSame('Trump cancels grants // DeepSeek revolution', $info->title);
|
|
self::assertSame(1983, $info->duration);
|
|
self::assertSame('Ruslan Usachev', $info->uploader);
|
|
self::assertSame(4320, $info->likeCount);
|
|
self::assertSame(213, $info->commentCount);
|
|
|
|
// AlVideo returns a single jpg thumbnail.
|
|
self::assertCount(1, $info->thumbnails);
|
|
self::assertStringContainsString('800x450', (string) $info->thumbnailUrl());
|
|
}
|
|
|
|
public function test_al_video_strategy_throws_for_deleted_video(): void
|
|
{
|
|
Http::fake([
|
|
'vk.com/al_video.php' => Http::response(
|
|
$this->fixture('vk/al_video_deleted.json'),
|
|
200,
|
|
['Content-Type' => 'application/json; charset=windows-1251'],
|
|
),
|
|
]);
|
|
|
|
$strategy = new AlVideoStrategy($this->app->make(HttpClient::class));
|
|
|
|
$this->expectException(VideoNotFoundException::class);
|
|
$this->expectExceptionMessage('Video has been deleted');
|
|
$strategy->extract($this->ref());
|
|
}
|
|
}
|