Files
XC_VM/tests/Unit/PlaylistGeneratorEncryptedUrlTest.php
T
AbdoAhmedElbanaaandDivarion_D cf471013b9 feat(stream): implement Encrypt Playlists across live and VOD
Port of Rosmi720/XC_VM@4e91fb68. Encrypted playlist entries carried the output
extension as a URL fragment (play/<token>#.<ext>), which the client strips and
nginx never sees, so every encrypted stream fell back to .ts — VOD/HLS were
effectively broken. Encode the extension in the path instead:

- PlaylistGenerator emits play/<token>.<ext> for live and VOD (Cloudflare TS
  keeps the bare token). The live/VOD suffix is a small pure helper
  (encryptedPlaySuffix, unit-tested) so generate() stays within its ceiling.
- nginx rewrites play/<token>.<ext> to the auth handler, keeping the legacy
  play/<token>/<ext> and bare-token rules for already-saved playlists.
- stream/auth.php splits a <token>.<ext> token and fills the extension when
  nginx did not.
- settings label uses the new encrypt_playlists key (en.ini).

Adapted to this tree: ar.ini is absent here, so only en.ini was updated.
2026-09-21 19:11:10 +03:00

34 lines
1.4 KiB
PHP

<?php
use PHPUnit\Framework\TestCase;
use XcVm\Domain\Stream\PlaylistGenerator;
/**
* Coverage for PlaylistGenerator::encryptedPlaySuffix — the /play/<token> URL
* suffix used by the Encrypt Playlists feature. A VOD entry keeps its
* container extension; a live entry keeps its output extension, except the
* Cloudflare TS case which stays a bare token (rewritten to .ts by nginx).
*/
final class PlaylistGeneratorEncryptedUrlTest extends TestCase {
private function suffix(array $rChannelInfo, array $rSettings, string $rOutputExt): string {
$rM = new ReflectionMethod(PlaylistGenerator::class, 'encryptedPlaySuffix');
$rM->setAccessible(true);
return $rM->invoke(null, $rChannelInfo, $rSettings, $rOutputExt);
}
public function testVodKeepsContainerExtension(): void {
$this->assertSame('.mp4', $this->suffix(['live' => 0, 'target_container' => 'mp4'], ['cloudflare' => 0], 'ts'));
}
public function testLiveKeepsOutputExtension(): void {
$this->assertSame('.m3u8', $this->suffix(['live' => 1, 'target_container' => 'ts'], ['cloudflare' => 0], 'm3u8'));
// Cloudflare set but a non-ts output still keeps its extension.
$this->assertSame('.m3u8', $this->suffix(['live' => 1, 'target_container' => 'ts'], ['cloudflare' => 1], 'm3u8'));
}
public function testCloudflareTsLiveStaysBareToken(): void {
$this->assertSame('', $this->suffix(['live' => 1, 'target_container' => 'ts'], ['cloudflare' => 1], 'ts'));
}
}