diff --git a/tests/Unit/ModuleRegistriesTest.php b/tests/Unit/ModuleRegistriesTest.php new file mode 100644 index 00000000..5d4875eb --- /dev/null +++ b/tests/Unit/ModuleRegistriesTest.php @@ -0,0 +1,131 @@ +assertFalse(TableRegistry::has('watch_output')); + $this->assertNull(TableRegistry::get('watch_output')); + + $handler = static fn(array $r, int $s, int $l, bool $api): array => $r; + TableRegistry::register('watch_output', $handler); + + $this->assertTrue(TableRegistry::has('watch_output')); + $this->assertSame($handler, TableRegistry::get('watch_output')); + } + + public function testTableRegistryIsLastWinsPerId(): void { + $first = static fn(): array => ['first']; + $second = static fn(): array => ['second']; + TableRegistry::register('dup', $first); + TableRegistry::register('dup', $second); + + $this->assertSame($second, TableRegistry::get('dup')); + } + + public function testTableRegistryResetClearsHandlers(): void { + TableRegistry::register('x', static fn(): array => []); + TableRegistry::reset(); + $this->assertFalse(TableRegistry::has('x')); + } + + // ── TopbarRegistry ─────────────────────────────────────────────── + + public function testTopbarEntriesAreReturnedOrderedByOrder(): void { + TopbarRegistry::add('watch', 'Later', '/z', null, null, 200); + TopbarRegistry::add('watch', 'Sooner', '/a', 'adv', 'id="s"', 50); + + $page = TopbarRegistry::forPage('watch'); + + $this->assertSame(['Sooner', 'Later'], array_keys($page), 'ascending by order'); + $this->assertSame(['/a', 'adv', 'id="s"'], $page['Sooner'], 'spec = [url, permission, attr]'); + $this->assertSame(['/z', null, null], $page['Later']); + $this->assertSame(['watch'], TopbarRegistry::pages()); + } + + public function testTopbarAddIsLastWinsPerLabelOnAPage(): void { + TopbarRegistry::add('movies', 'Export', '/old'); + TopbarRegistry::add('movies', 'Export', '/new', null, null, 10); + + $page = TopbarRegistry::forPage('movies'); + $this->assertCount(1, $page); + $this->assertSame(['/new', null, null], $page['Export']); + } + + public function testTopbarForUnknownPageIsEmpty(): void { + $this->assertSame([], TopbarRegistry::forPage('nope')); + $this->assertSame([], TopbarRegistry::pages()); + } + + public function testTopbarExportPageAndLogTypeFlags(): void { + $this->assertFalse(TopbarRegistry::isExportPage('reports')); + $this->assertNull(TopbarRegistry::logType('reports')); + + TopbarRegistry::markExportPage('reports'); + TopbarRegistry::setLogType('reports', 'plex_logs'); + + $this->assertTrue(TopbarRegistry::isExportPage('reports')); + $this->assertSame('plex_logs', TopbarRegistry::logType('reports')); + $this->assertFalse(TopbarRegistry::isExportPage('other')); + } + + // ── QuickToolsRegistry ─────────────────────────────────────────── + + public function testQuickToolsGroupsCollectRowsAndHandlers(): void { + $clear = static function (): void {}; + $sync = static function (): void {}; + QuickToolsRegistry::add('cache', 'clear_cache', 'Clear cache', $clear); + QuickToolsRegistry::add('cache', 'sync_cache', 'Sync cache', $sync); + QuickToolsRegistry::add('epg', 'reload_epg', 'Reload EPG', static function (): void {}); + + $this->assertSame(['cache', 'epg'], QuickToolsRegistry::groups()); + $this->assertSame( + [['clear_cache', 'Clear cache'], ['sync_cache', 'Sync cache']], + QuickToolsRegistry::forGroup('cache') + ); + $this->assertSame(['clear_cache', 'sync_cache', 'reload_epg'], QuickToolsRegistry::keys()); + $this->assertSame($sync, QuickToolsRegistry::handler('sync_cache')); + $this->assertNull(QuickToolsRegistry::handler('missing')); + $this->assertSame([], QuickToolsRegistry::forGroup('missing')); + } + + // ── PermissionRegistry ─────────────────────────────────────────── + + public function testPermissionRegistryIsAnOrderedDedupedSet(): void { + $this->assertSame([], PermissionRegistry::keys()); + + PermissionRegistry::add('plex_manage'); + PermissionRegistry::add('watch_view'); + PermissionRegistry::add('plex_manage'); + + $this->assertSame(['plex_manage', 'watch_view'], PermissionRegistry::keys(), 'registration order, deduped'); + } +} diff --git a/tests/Unit/UpdateChannelsTest.php b/tests/Unit/UpdateChannelsTest.php new file mode 100644 index 00000000..7fa65bb5 --- /dev/null +++ b/tests/Unit/UpdateChannelsTest.php @@ -0,0 +1,91 @@ +assertSame('stable', UpdateChannels::main()); + $this->assertSame('stable', UpdateChannels::bin()); + $this->assertSame('stable', UpdateChannels::fanout()); + } + + public function testEachChannelReadsItsOwnSetting(): void { + SettingsManager::set([ + 'update_channel_main' => 'beta', + 'update_channel_bin' => 'stable', + 'update_channel_fanout' => 'beta', + ]); + + $this->assertSame('beta', UpdateChannels::main()); + $this->assertSame('stable', UpdateChannels::bin()); + $this->assertSame('beta', UpdateChannels::fanout()); + } + + public function testUnstableIsALegacyAliasForBeta(): void { + SettingsManager::set(['update_channel_main' => 'unstable']); + $this->assertSame('beta', UpdateChannels::main()); + } + + public function testUnknownOrEmptyValueFallsBackToStable(): void { + SettingsManager::set(['update_channel_bin' => 'nightly']); + $this->assertSame('stable', UpdateChannels::bin()); + + SettingsManager::set(['update_channel_bin' => '']); + $this->assertSame('stable', UpdateChannels::bin()); + } + + public function testForRepoDispatchesToTheOwningChannel(): void { + SettingsManager::set([ + 'update_channel_main' => 'stable', + 'update_channel_bin' => 'beta', + 'update_channel_fanout' => 'beta', + ]); + + $this->assertSame('beta', UpdateChannels::forRepo(GIT_REPO_BIN), 'BIN repo → bin channel'); + $this->assertSame('beta', UpdateChannels::forRepo(GIT_REPO_FANOUT), 'FANOUT repo → fanout channel'); + $this->assertSame('stable', UpdateChannels::forRepo(GIT_REPO_MAIN), 'MAIN repo → main channel'); + } + + public function testForRepoFollowsMainForUnknownRepos(): void { + SettingsManager::set([ + 'update_channel_main' => 'beta', + 'update_channel_bin' => 'stable', + ]); + + // UPDATE (GeoLite/ASN) and PROXY have no channel of their own → follow MAIN. + $this->assertSame('beta', UpdateChannels::forRepo('XC_VM_Data')); + $this->assertSame('beta', UpdateChannels::forRepo('some-unknown-repo')); + } +}