appConfig = $this->createMock(IAppConfig::class); $this->config = $this->createMock(IConfig::class); $this->logger = $this->createMock(LoggerInterface::class); $cache = $this->createMock(ICache::class); $cacheFactory = $this->createMock(ICacheFactory::class); $cacheFactory->method("createLocal")->willReturn($cache); $this->subject = new AppConfig( $this->appName, $this->appConfig, $this->config, $this->logger, $cacheFactory, ); } /** * Reads directly from the root system config when $system=true, bypassing the app-specific section. */ public function testGetSystemValueFromRootConfig(): void { $this->config->method("getSystemValue") ->with("somekey") ->willReturn("rootvalue"); $result = $this->subject->getSystemValue("somekey", true); $this->assertSame("rootvalue", $result); } /** * Reads from the app-specific section of the system config when $system is not set and the key exists there. */ public function testGetSystemValueFromAppSection(): void { $this->config->method("getSystemValue") ->with($this->appName) ->willReturn(["somekey" => "appvalue"]); $result = $this->subject->getSystemValue("somekey"); $this->assertSame("appvalue", $result); } /** * Returns null when the requested key is absent from the app-specific config section. */ public function testGetSystemValueReturnsNullWhenKeyMissing(): void { $this->config->method("getSystemValue") ->with($this->appName) ->willReturn(["otherkey" => "value"]); $result = $this->subject->getSystemValue("somekey"); $this->assertNull($result); } /** * Returns available=true and enabled=false when no demo data has been stored yet. */ public function testGetDemoDataReturnsDefaultsWhenNoneStored(): void { $this->appConfig->method("getValueString")->willReturn(""); $data = $this->subject->getDemoData(); $this->assertTrue($data["available"]); $this->assertFalse($data["enabled"]); } /** * Reports the demo as available and enabled when the trial start date is within the 30-day window. */ public function testGetDemoDataReturnsAvailableWhenWithinTrialPeriod(): void { $start = new DateTime(); $start->sub(new DateInterval("P5D")); $stored = json_encode(["start" => $start, "enabled" => true]); $this->appConfig->method("getValueString")->willReturn($stored); $data = $this->subject->getDemoData(); $this->assertTrue($data["available"]); $this->assertTrue($data["enabled"]); } /** * Marks the demo as unavailable and forcibly disabled once the 30-day trial period has elapsed. */ public function testGetDemoDataReturnsUnavailableWhenTrialExpired(): void { $start = new DateTime(); $start->sub(new DateInterval("P31D")); $stored = json_encode(["start" => $start, "enabled" => true]); $this->appConfig->method("getValueString")->willReturn($stored); $data = $this->subject->getDemoData(); $this->assertFalse($data["available"]); $this->assertFalse($data["enabled"]); } /** * Prefixes a URL that has no scheme with http:// before storing it. */ public function testSetDocumentServerUrlAddsHttpSchemeWhenMissing(): void { $this->appConfig->expects($this->once()) ->method("setValueString") ->with($this->appName, "DocumentServerUrl", "http://example.com/"); $this->subject->setDocumentServerUrl("example.com"); } /** * Preserves an existing https:// scheme unchanged when storing the URL. */ public function testSetDocumentServerUrlKeepsHttpsScheme(): void { $this->appConfig->expects($this->once()) ->method("setValueString") ->with($this->appName, "DocumentServerUrl", "https://example.com/"); $this->subject->setDocumentServerUrl("https://example.com"); } /** * Ensures a trailing slash is always present on the stored URL, normalising URLs that already include one. */ public function testSetDocumentServerUrlAddsTrailingSlash(): void { $this->appConfig->expects($this->once()) ->method("setValueString") ->with($this->appName, "DocumentServerUrl", "https://example.com/"); $this->subject->setDocumentServerUrl("https://example.com/"); } /** * Strips leading and trailing whitespace from the URL before normalisation and storage. */ public function testSetDocumentServerUrlTrimsWhitespace(): void { $this->appConfig->expects($this->once()) ->method("setValueString") ->with($this->appName, "DocumentServerUrl", "https://example.com/"); $this->subject->setDocumentServerUrl(" https://example.com "); } /** * Stores an empty string as-is, allowing the server URL to be cleared without triggering normalisation. */ public function testSetDocumentServerUrlStoresEmptyStringAsIs(): void { $this->appConfig->expects($this->once()) ->method("setValueString") ->with($this->appName, "DocumentServerUrl", ""); $this->subject->setDocumentServerUrl(""); } /** * Returns the hardcoded demo server address instead of the configured URL when demo mode is active. */ public function testGetDocumentServerUrlReturnsDemoUrlWhenDemoEnabled(): void { $start = new DateTime(); $start->sub(new DateInterval("P5D")); $stored = json_encode(["start" => $start, "enabled" => true]); $this->appConfig->method("getValueString") ->willReturnCallback(fn($app, $key, $default) => $key === "demo" ? $stored : ""); $url = $this->subject->getDocumentServerUrl(); $this->assertSame("https://onlinedocs.docs.onlyoffice.com/", $url); } /** * Returns the administrator-configured server URL when demo mode is not active. */ public function testGetDocumentServerUrlReturnsConfiguredUrlWhenDemoDisabled(): void { $this->appConfig->method("getValueString") ->willReturnCallback(fn($app, $key, $default) => $key === "DocumentServerUrl" ? "https://myserver.com/" : ""); $url = $this->subject->getDocumentServerUrl(); $this->assertSame("https://myserver.com/", $url); } }