Files
XC_VM/tests/Unit/StreamUtilsFirstSourceTest.php
T
obscuremindandClaude Opus 5.5 0861a7b0dc fix: harden the archive, timeshift and VOD source reads
Small fixes from a review of the archive, catch-up and VOD paths; each turns
a possible warning or TypeError into a clean step.

- archive: a segment pruned between the existence check and fopen() ended
  the archive with feof(false); it is skipped. The wait for the next segment
  polls every 50 ms, not 10 (about 200 stat calls a second per channel).
- timeshift (admin): a file removed since it was listed stops the answer
  instead of looping on feof(false).
- A stream's first source is read through StreamUtils::firstSource(): the
  TMDb refresh and a series' playlist read `json_decode(...)[0]` unguarded,
  and an empty source led to a TMDb search for an empty title.
- cron:servers reads a server's connection counts with a default.

Closes #353

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AneTzAHPPkYWPQjwyZ2td9
2026-10-11 14:59:33 +00:00

24 lines
1.0 KiB
PHP

<?php
use PHPUnit\Framework\TestCase;
use XcVm\Core\Util\StreamUtils;
/**
* `streams.stream_source` is a JSON list. Reading its first entry as
* `json_decode(...)[0]` warned on an empty list and failed on a source that
* does not parse; the TMDb refresh then searched for an empty title.
*/
final class StreamUtilsFirstSourceTest extends TestCase {
public function testTheFirstSourceOfAList(): void {
$this->assertSame('s:1:/vod/a.mkv', StreamUtils::firstSource('["s:1:/vod/a.mkv","http://b/c.mkv"]'));
$this->assertSame('http://b/c.mkv', StreamUtils::firstSource('{"x":"http://b/c.mkv"}'), 'a list stored with keys');
}
public function testNoSourceIsTheEmptyString(): void {
foreach (['', '[]', 'null', 'not json', '[null]', '[["nested"]]', '[42]', null, false, 7, []] as $rStored) {
$this->assertSame('', StreamUtils::firstSource($rStored), var_export($rStored, true));
}
$this->assertSame('', pathinfo(StreamUtils::firstSource('[]'))['filename'], 'what the TMDb refresh takes its title from');
}
}