db = TestDatabase::getInstance(); $this->db->getPDO()->exec('DELETE FROM peertube_settings'); $this->db->getPDO()->exec('INSERT INTO peertube_settings (id) VALUES (1)'); // TestDatabase is a shared singleton — reset the feature flag we toggle. $this->db->getPDO() ->exec("DELETE FROM site_settings WHERE key = 'peertube_upload_enabled'"); $this->mock = new MockHandler(); $stack = HandlerStack::create($this->mock); PeerTubeService::setHttpClient(new Client([ 'handler' => $stack, 'http_errors' => false, 'allow_redirects' => false, ])); } protected function tearDown(): void { PeerTubeService::setHttpClient(null); $this->db->getPDO() ->exec("DELETE FROM site_settings WHERE key = 'peertube_upload_enabled'"); } /** Queue an OAuth client + token handshake, then return the request index. */ private function queueAuth(string $instanceUrl): void { $this->mock->append(new Response(200, [], json_encode([ 'client_id' => 'cid', 'client_secret' => 'csec', ]))); $this->mock->append(new Response(200, [], json_encode([ 'access_token' => 'tok', ]))); } /** * Settings are stored and read back verbatim — instance_url is absolute, * independent of any request context. */ public function testInstanceUrlStoredVerbatim(): void { PeerTubeService::updateSettings($this->db, [ 'instance_url' => 'https://video.erg.be/', 'channel_name' => 'tfe@video.erg.be', 'privacy' => 2, ]); $s = PeerTubeService::getSettings($this->db); $this->assertSame('https://video.erg.be', $s['instance_url'], 'trailing slash trimmed'); $this->assertSame('tfe@video.erg.be', $s['channel_name']); $this->assertSame(2, $s['privacy']); } /** * probeAuth() must hit the absolute instance_url, not a request-derived * host. Changing HTTPS detection must not alter these URLs. */ public function testProbeAuthUsesAbsoluteInstanceUrl(): void { $s = [ 'instance_url' => 'https://video.erg.be', 'username' => 'user', 'password' => 'pass', ]; $this->queueAuth('https://video.erg.be'); $result = PeerTubeService::probeAuth($s); $this->assertTrue($result['ok'], $result['error']); // Last request in the handshake is the token exchange; it must target // the absolute configured instance URL. $this->assertSame( 'https://video.erg.be/api/v1/users/token', (string) $this->mock->getLastRequest()->getUri() ); } /** * An HTTP instance_url must be preserved as-is. If URL handling ever * started "upgrading" to https based on request scheme, this fails. */ public function testHttpInstanceUrlPreservedWhenConfigured(): void { PeerTubeService::updateSettings($this->db, [ 'instance_url' => 'http://localhost:9000', 'channel_name' => 'chan', ]); $s = PeerTubeService::getSettings($this->db); $this->assertSame('http://localhost:9000', $s['instance_url']); } /** * isEnabled() is a pure feature-flag read and must not depend on request * scheme or HTTPS detection. */ public function testFeatureFlagIndependentOfRequestScheme(): void { $this->assertFalse(PeerTubeService::isEnabled($this->db)); $this->db->getPDO() ->prepare("INSERT OR REPLACE INTO site_settings (key, value) VALUES ('peertube_upload_enabled', '1')") ->execute(); $this->assertTrue(PeerTubeService::isEnabled($this->db)); } }