81 lines
2.6 KiB
PHP
81 lines
2.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Apoloz\VideoExtractor\Tests\Unit;
|
|
|
|
use Apoloz\VideoExtractor\Exceptions\ParseFailedException;
|
|
use Apoloz\VideoExtractor\Parsing\EmbeddedJsonExtractor;
|
|
use Apoloz\VideoExtractor\Tests\TestCase;
|
|
|
|
class EmbeddedJsonExtractorTest extends TestCase
|
|
{
|
|
private EmbeddedJsonExtractor $extractor;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->extractor = new EmbeddedJsonExtractor();
|
|
}
|
|
|
|
public function test_extracts_flat_object(): void
|
|
{
|
|
$html = 'prefix window.cur = Object.assign(window.cur || {}, {"a":1,"b":"x"}); suffix';
|
|
|
|
$result = $this->extractor->extractAfterMarker($html, 'window.cur = Object.assign(');
|
|
|
|
self::assertSame(['a' => 1, 'b' => 'x'], $result);
|
|
}
|
|
|
|
public function test_extracts_deeply_nested_structure(): void
|
|
{
|
|
$html = 'x = Object.assign({}, {"apiPrefetchCache":[{"response":{"items":[{"id":1,"files":{"hls":"u"}}]}}]});';
|
|
|
|
$result = $this->extractor->extractAfterMarker($html, 'Object.assign(');
|
|
|
|
self::assertSame(1, $result['apiPrefetchCache'][0]['response']['items'][0]['id']);
|
|
self::assertSame('u', $result['apiPrefetchCache'][0]['response']['items'][0]['files']['hls']);
|
|
}
|
|
|
|
public function test_ignores_braces_inside_strings(): void
|
|
{
|
|
// A brace and quote inside a string must not unbalance the count.
|
|
$html = 'm({"msg":"has } and \" escaped","n":2});';
|
|
|
|
$result = $this->extractor->extractAfterMarker($html, 'm(');
|
|
|
|
self::assertSame('has } and " escaped', $result['msg']);
|
|
self::assertSame(2, $result['n']);
|
|
}
|
|
|
|
public function test_extracts_array_root(): void
|
|
{
|
|
$html = 'data = assign([], [1, [2, 3], {"k": "v"}]);';
|
|
|
|
$result = $this->extractor->extractAfterMarker($html, 'assign([], ');
|
|
|
|
self::assertSame([1, [2, 3], ['k' => 'v']], $result);
|
|
}
|
|
|
|
public function test_throws_when_marker_missing(): void
|
|
{
|
|
$this->expectException(ParseFailedException::class);
|
|
$this->extractor->extractAfterMarker('no marker here', 'window.cur');
|
|
}
|
|
|
|
public function test_throws_on_unbalanced_json(): void
|
|
{
|
|
$this->expectException(ParseFailedException::class);
|
|
$this->extractor->extractAfterMarker('m({"a":1', 'm(');
|
|
}
|
|
|
|
public function test_handles_cyrillic_content(): void
|
|
{
|
|
$html = 'window.cur = Object.assign(window.cur || {}, {"title":"Трамп отменяет гранты"});';
|
|
|
|
$result = $this->extractor->extractAfterMarker($html, 'window.cur = Object.assign(');
|
|
|
|
self::assertSame('Трамп отменяет гранты', $result['title']);
|
|
}
|
|
}
|