mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-09-28 12:02:04 +02:00
refactor(user): consolidate getStreamingUserInfo/getUserInfo shared blocks
The two methods were ~90% duplicate, differing only in how they obtain
settings/cache/bouquets and in the divergent GeoIP + signal backends
(GeoIPService/file-signals vs GeoIP/Redis) that stay inline. Extract the
identical blocks into private helpers, called by both:
loadUserRow - credential resolution (token/cache file or DB),
resolving $rUserID by reference so the cached
re-verification keeps its exact behaviour
verifyCachedCredentials - cached access-token / username+password re-check
decodeUserFields - JSON line fields -> arrays
resolveOutputFormats - allowed output-format keys
aggregateBouquetIds - bouquet -> channel/series/vod/live/radio id lists
resolveCategoryIds - bouquet -> category ids
Also de-obfuscate the remaining `if (cond) {} else { body }` blocks in both
methods. Net -74 lines despite adding the shared helpers (~240 lines of
duplication removed). Behaviour preserved; the file-vs-Redis signal divergence
is intentionally left as-is (separate decision).
Tests: UserRepositoryTest covers the pure helpers (aggregate/category/decode/
verify), 12 tests total. Validated live: player_api/testxc returns auth=1,
Active, allowed_output_formats=[m3u8,ts,rtmp]; on-demand /live start still works.
Verified: php -l, phpunit (430 tests, 962 assertions), make gates.
This commit is contained in:
@@ -12,6 +12,13 @@ use XcVm\Domain\User\UserRepository;
|
||||
*/
|
||||
final class UserRepositoryTest extends TestCase {
|
||||
|
||||
/** Invoke a private static UserRepository method via reflection. */
|
||||
private function call(string $rMethod, ...$rArgs) {
|
||||
$rM = new ReflectionMethod(UserRepository::class, $rMethod);
|
||||
$rM->setAccessible(true);
|
||||
return $rM->invoke(null, ...$rArgs);
|
||||
}
|
||||
|
||||
public function testPersistsWhenIspDetectedAndChanged(): void {
|
||||
$this->assertTrue(UserRepository::ispChanged('Comcast', 0, 'Verizon'));
|
||||
}
|
||||
@@ -41,4 +48,67 @@ final class UserRepositoryTest extends TestCase {
|
||||
public function testViolationDoesNotPersist(): void {
|
||||
$this->assertFalse(UserRepository::ispChanged('Comcast', 1, 'Verizon'));
|
||||
}
|
||||
|
||||
// ── aggregateBouquetIds — locks the streams→channel_ids / channels→live_ids mapping ──
|
||||
|
||||
public function testAggregateBouquetIdsMapsAndDedupes(): void {
|
||||
$rBouquets = array(
|
||||
1 => array('streams' => array(10, 11), 'series' => array(20), 'channels' => array(30), 'movies' => array(40), 'radios' => array(50)),
|
||||
2 => array('streams' => array(11, 12)), // 11 shared across bouquets
|
||||
);
|
||||
$rOut = $this->call('aggregateBouquetIds', array(1, 2), $rBouquets);
|
||||
$this->assertSame(array(10, 11, 12), array_values($rOut['channel_ids']), 'streams -> channel_ids, unique');
|
||||
$this->assertSame(array(20), array_values($rOut['series_ids']));
|
||||
$this->assertSame(array(30), array_values($rOut['live_ids']), 'channels -> live_ids');
|
||||
$this->assertSame(array(40), array_values($rOut['vod_ids']), 'movies -> vod_ids');
|
||||
$this->assertSame(array(50), array_values($rOut['radio_ids']));
|
||||
}
|
||||
|
||||
public function testAggregateBouquetIdsIgnoresMissingKeys(): void {
|
||||
$rOut = $this->call('aggregateBouquetIds', array(1), array(1 => array('streams' => array(7))));
|
||||
$this->assertSame(array(7), array_values($rOut['channel_ids']));
|
||||
$this->assertSame(array(), $rOut['series_ids']);
|
||||
$this->assertSame(array(), $rOut['radio_ids']);
|
||||
}
|
||||
|
||||
// ── resolveCategoryIds ──
|
||||
|
||||
public function testResolveCategoryIdsUniqueAcrossBouquets(): void {
|
||||
$rMap = array(1 => array(100, 101), 2 => array(101, 102));
|
||||
$this->assertSame(array(100, 101, 102), $this->call('resolveCategoryIds', array(1, 2), $rMap));
|
||||
}
|
||||
|
||||
// ── decodeUserFields ──
|
||||
|
||||
public function testDecodeUserFieldsNormalises(): void {
|
||||
$rOut = $this->call('decodeUserFields', array(
|
||||
'allowed_ips' => '["1.2.3.4"," 5.6.7.8 "]',
|
||||
'allowed_ua' => 'null',
|
||||
'bouquet' => '[1,2,3]',
|
||||
'allowed_outputs' => '["1","2"]',
|
||||
));
|
||||
$this->assertSame(array(1, 2, 3), $rOut['bouquet']);
|
||||
$this->assertSame(array('1.2.3.4', '5.6.7.8'), array_values($rOut['allowed_ips']), 'trimmed');
|
||||
$this->assertSame(array(), $rOut['allowed_ua'], 'non-array json -> []');
|
||||
$this->assertSame(array(1, 2), $rOut['allowed_outputs'], 'intval-mapped');
|
||||
}
|
||||
|
||||
// ── verifyCachedCredentials ──
|
||||
|
||||
public function testVerifyTokenLookup(): void {
|
||||
$rToken = str_repeat('a', 32);
|
||||
$this->assertTrue($this->call('verifyCachedCredentials', array('access_token' => $rToken), null, $rToken, null));
|
||||
$this->assertFalse($this->call('verifyCachedCredentials', array('access_token' => 'other'), null, $rToken, null));
|
||||
}
|
||||
|
||||
public function testVerifyCredentialLookup(): void {
|
||||
$rRow = array('username' => 'u', 'password' => 'p');
|
||||
$this->assertTrue($this->call('verifyCachedCredentials', $rRow, null, 'u', 'p'));
|
||||
$this->assertFalse($this->call('verifyCachedCredentials', $rRow, null, 'u', 'wrong'));
|
||||
}
|
||||
|
||||
public function testVerifyIdLookupSkipsCheck(): void {
|
||||
// An id-based lookup carries no username/password to re-verify.
|
||||
$this->assertTrue($this->call('verifyCachedCredentials', array(), 5, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user