diff options
Diffstat (limited to 'tests/lib/Updater')
-rw-r--r-- | tests/lib/Updater/ChangesCheckTest.php | 378 | ||||
-rw-r--r-- | tests/lib/Updater/ReleaseMetadataTest.php | 207 | ||||
-rw-r--r-- | tests/lib/Updater/VersionCheckTest.php | 378 |
3 files changed, 963 insertions, 0 deletions
diff --git a/tests/lib/Updater/ChangesCheckTest.php b/tests/lib/Updater/ChangesCheckTest.php new file mode 100644 index 00000000000..dd0d97a9e80 --- /dev/null +++ b/tests/lib/Updater/ChangesCheckTest.php @@ -0,0 +1,378 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace Test\Updater; + +use OC\Updater\Changes; +use OC\Updater\ChangesCheck; +use OC\Updater\ChangesMapper; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\Http\Client\IClient; +use OCP\Http\Client\IClientService; +use OCP\Http\Client\IResponse; +use Psr\Log\LoggerInterface; +use Test\TestCase; + +class ChangesCheckTest extends TestCase { + /** @var IClientService|\PHPUnit\Framework\MockObject\MockObject */ + protected $clientService; + + /** @var ChangesCheck */ + protected $checker; + + /** @var ChangesMapper|\PHPUnit\Framework\MockObject\MockObject */ + protected $mapper; + + /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ + protected $logger; + + protected function setUp(): void { + parent::setUp(); + + $this->clientService = $this->createMock(IClientService::class); + $this->mapper = $this->createMock(ChangesMapper::class); + $this->logger = $this->createMock(LoggerInterface::class); + + $this->checker = new ChangesCheck($this->clientService, $this->mapper, $this->logger); + } + + public static function statusCodeProvider(): array { + return [ + [200, ChangesCheck::RESPONSE_HAS_CONTENT], + [304, ChangesCheck::RESPONSE_USE_CACHE], + [404, ChangesCheck::RESPONSE_NO_CONTENT], + [418, ChangesCheck::RESPONSE_NO_CONTENT], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('statusCodeProvider')] + public function testEvaluateResponse(int $statusCode, int $expected): void { + $response = $this->createMock(IResponse::class); + $response->expects($this->atLeastOnce()) + ->method('getStatusCode') + ->willReturn($statusCode); + + if (!in_array($statusCode, [200, 304, 404])) { + $this->logger->expects($this->once()) + ->method('debug'); + } + + $evaluation = $this->invokePrivate($this->checker, 'evaluateResponse', [$response]); + $this->assertSame($expected, $evaluation); + } + + public function testCacheResultInsert(): void { + $version = '13.0.4'; + $entry = $this->createMock(Changes::class); + $entry->expects($this->exactly(2)) + ->method('__call') + ->willReturnMap([ + ['getVersion', [], ''], + ['setVersion', [$version], null], + ]); + + $this->mapper->expects($this->once()) + ->method('insert'); + $this->mapper->expects($this->never()) + ->method('update'); + + $this->invokePrivate($this->checker, 'cacheResult', [$entry, $version]); + } + + public function testCacheResultUpdate(): void { + $version = '13.0.4'; + $entry = $this->createMock(Changes::class); + $entry->expects($this->once()) + ->method('__call') + ->willReturn($version); + + $this->mapper->expects($this->never()) + ->method('insert'); + $this->mapper->expects($this->once()) + ->method('update'); + + $this->invokePrivate($this->checker, 'cacheResult', [$entry, $version]); + } + + public static function changesXMLProvider(): array { + return [ + [ # 0 - full example + '<?xml version="1.0" encoding="utf-8" ?> +<release xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://updates.nextcloud.com/changelog_server/schema.xsd" + version="13.0.0"> + <changelog href="https://nextcloud.com/changelog/#13-0-0"/> + <whatsNew lang="en"> + <regular> + <item>Refined user interface</item> + <item>End-to-end Encryption</item> + <item>Video and Text Chat</item> + </regular> + <admin> + <item>Changes to the Nginx configuration</item> + <item>Theming: CSS files were consolidated</item> + </admin> + </whatsNew> + <whatsNew lang="de"> + <regular> + <item>Überarbeitete Benutzerschnittstelle</item> + <item>Ende-zu-Ende Verschlüsselung</item> + <item>Video- und Text-Chat</item> + </regular> + <admin> + <item>Änderungen an der Nginx Konfiguration</item> + <item>Theming: CSS Dateien wurden konsolidiert</item> + </admin> + </whatsNew> +</release>', + [ + 'changelogURL' => 'https://nextcloud.com/changelog/#13-0-0', + 'whatsNew' => [ + 'en' => [ + 'regular' => [ + 'Refined user interface', + 'End-to-end Encryption', + 'Video and Text Chat' + ], + 'admin' => [ + 'Changes to the Nginx configuration', + 'Theming: CSS files were consolidated' + ], + ], + 'de' => [ + 'regular' => [ + 'Überarbeitete Benutzerschnittstelle', + 'Ende-zu-Ende Verschlüsselung', + 'Video- und Text-Chat' + ], + 'admin' => [ + 'Änderungen an der Nginx Konfiguration', + 'Theming: CSS Dateien wurden konsolidiert' + ], + ], + ], + ] + ], + [ # 1- admin part not translated + '<?xml version="1.0" encoding="utf-8" ?> +<release xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://updates.nextcloud.com/changelog_server/schema.xsd" + version="13.0.0"> + <changelog href="https://nextcloud.com/changelog/#13-0-0"/> + <whatsNew lang="en"> + <regular> + <item>Refined user interface</item> + <item>End-to-end Encryption</item> + <item>Video and Text Chat</item> + </regular> + <admin> + <item>Changes to the Nginx configuration</item> + <item>Theming: CSS files were consolidated</item> + </admin> + </whatsNew> + <whatsNew lang="de"> + <regular> + <item>Überarbeitete Benutzerschnittstelle</item> + <item>Ende-zu-Ende Verschlüsselung</item> + <item>Video- und Text-Chat</item> + </regular> + </whatsNew> +</release>', + [ + 'changelogURL' => 'https://nextcloud.com/changelog/#13-0-0', + 'whatsNew' => [ + 'en' => [ + 'regular' => [ + 'Refined user interface', + 'End-to-end Encryption', + 'Video and Text Chat' + ], + 'admin' => [ + 'Changes to the Nginx configuration', + 'Theming: CSS files were consolidated' + ], + ], + 'de' => [ + 'regular' => [ + 'Überarbeitete Benutzerschnittstelle', + 'Ende-zu-Ende Verschlüsselung', + 'Video- und Text-Chat' + ], + 'admin' => [ + ], + ], + ], + ] + ], + [ # 2 - minimal set + '<?xml version="1.0" encoding="utf-8" ?> +<release xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://updates.nextcloud.com/changelog_server/schema.xsd" + version="13.0.0"> + <changelog href="https://nextcloud.com/changelog/#13-0-0"/> + <whatsNew lang="en"> + <regular> + <item>Refined user interface</item> + <item>End-to-end Encryption</item> + <item>Video and Text Chat</item> + </regular> + </whatsNew> +</release>', + [ + 'changelogURL' => 'https://nextcloud.com/changelog/#13-0-0', + 'whatsNew' => [ + 'en' => [ + 'regular' => [ + 'Refined user interface', + 'End-to-end Encryption', + 'Video and Text Chat' + ], + 'admin' => [], + ], + ], + ] + ], + [ # 3 - minimal set (procrastinator edition) + '<?xml version="1.0" encoding="utf-8" ?> +<release xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://updates.nextcloud.com/changelog_server/schema.xsd" + version="13.0.0"> + <changelog href="https://nextcloud.com/changelog/#13-0-0"/> + <whatsNew lang="en"> + <regular> + <item>Write this tomorrow</item> + </regular> + </whatsNew> +</release>', + [ + 'changelogURL' => 'https://nextcloud.com/changelog/#13-0-0', + 'whatsNew' => [ + 'en' => [ + 'regular' => [ + 'Write this tomorrow', + ], + 'admin' => [], + ], + ], + ] + ], + [ # 4 - empty + '', + [] + ], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('changesXMLProvider')] + public function testExtractData(string $body, array $expected): void { + $actual = $this->invokePrivate($this->checker, 'extractData', [$body]); + $this->assertSame($expected, $actual); + } + + public static function etagProvider() { + return [ + [''], + ['a27aab83d8205d73978435076e53d143'] + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('etagProvider')] + public function testQueryChangesServer(string $etag): void { + $uri = 'https://changes.nextcloud.server/?13.0.5'; + $entry = $this->createMock(Changes::class); + $entry->expects($this->any()) + ->method('__call') + ->willReturn($etag); + + $expectedHeaders = $etag === '' ? [] : ['If-None-Match' => [$etag]]; + + $client = $this->createMock(IClient::class); + $client->expects($this->once()) + ->method('get') + ->with($uri, ['headers' => $expectedHeaders]) + ->willReturn($this->createMock(IResponse::class)); + + $this->clientService->expects($this->once()) + ->method('newClient') + ->willReturn($client); + + $response = $this->invokePrivate($this->checker, 'queryChangesServer', [$uri, $entry]); + $this->assertInstanceOf(IResponse::class, $response); + } + + public static function versionProvider(): array { + return [ + ['13.0.7', '13.0.7'], + ['13.0.7.3', '13.0.7'], + ['13.0.7.3.42', '13.0.7'], + ['13.0', '13.0.0'], + ['13', '13.0.0'], + ['', '0.0.0'], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('versionProvider')] + public function testNormalizeVersion(string $input, string $expected): void { + $normalized = $this->checker->normalizeVersion($input); + $this->assertSame($expected, $normalized); + } + + public static function changeDataProvider():array { + $testDataFound = $testDataNotFound = self::versionProvider(); + array_walk($testDataFound, static function (&$params): void { + $params[] = true; + }); + array_walk($testDataNotFound, static function (&$params): void { + $params[] = false; + }); + return array_merge($testDataFound, $testDataNotFound); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('changeDataProvider')] + public function testGetChangesForVersion(string $inputVersion, string $normalizedVersion, bool $isFound): void { + $mocker = $this->mapper->expects($this->once()) + ->method('getChanges') + ->with($normalizedVersion); + + if (!$isFound) { + $this->expectException(DoesNotExistException::class); + $mocker->willThrowException(new DoesNotExistException('Changes info is not present')); + } else { + $entry = $this->createMock(Changes::class); + $entry->expects($this->once()) + ->method('__call') + ->with('getData') + ->willReturn('{"changelogURL":"https:\/\/nextcloud.com\/changelog\/#13-0-0","whatsNew":{"en":{"regular":["Refined user interface","End-to-end Encryption","Video and Text Chat"],"admin":["Changes to the Nginx configuration","Theming: CSS files were consolidated"]},"de":{"regular":["\u00dcberarbeitete Benutzerschnittstelle","Ende-zu-Ende Verschl\u00fcsselung","Video- und Text-Chat"],"admin":["\u00c4nderungen an der Nginx Konfiguration","Theming: CSS Dateien wurden konsolidiert"]}}}'); + + $mocker->willReturn($entry); + } + + /** @noinspection PhpUnhandledExceptionInspection */ + $data = $this->checker->getChangesForVersion($inputVersion); + $this->assertTrue(isset($data['whatsNew']['en']['regular'])); + $this->assertTrue(isset($data['changelogURL'])); + } + + public function testGetChangesForVersionEmptyData(): void { + $entry = $this->createMock(Changes::class); + $entry->expects($this->once()) + ->method('__call') + ->with('getData') + ->willReturn(''); + + $this->mapper->expects($this->once()) + ->method('getChanges') + ->with('13.0.7') + ->willReturn($entry); + + $this->expectException(DoesNotExistException::class); + /** @noinspection PhpUnhandledExceptionInspection */ + $this->checker->getChangesForVersion('13.0.7'); + } +} diff --git a/tests/lib/Updater/ReleaseMetadataTest.php b/tests/lib/Updater/ReleaseMetadataTest.php new file mode 100644 index 00000000000..e93d9fe64be --- /dev/null +++ b/tests/lib/Updater/ReleaseMetadataTest.php @@ -0,0 +1,207 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace Test\Updater; + +use OC\Updater\ReleaseMetadata; +use OCP\Http\Client\IClient; +use OCP\Http\Client\IClientService; +use OCP\Http\Client\IResponse; +use PHPUnit\Framework\MockObject\MockObject; + +class ReleaseMetadataTest extends \Test\TestCase { + private IClientService|MockObject $clientService; + + protected function setUp(): void { + parent::setUp(); + $this->clientService = $this->createMock(IClientService::class); + } + + public function testDownloadMetadata(): void { + $client = $this->createMock(IClient::class); + $response = $this->createMock(IResponse::class); + $this->clientService->expects($this->once()) + ->method('newClient') + ->with() + ->willReturn($client); + $client->expects($this->once()) + ->method('get') + ->willReturn($response); + $response->expects($this->once()) + ->method('getBody') + ->with() + ->willReturn($this->resultRequest()); + + + $releaseMetadata = new ReleaseMetadata($this->clientService); + $this->assertSame(self::resultRequestArray(), $releaseMetadata->downloadMetadata('ouila')); + } + + /** + * + * @param string $version + * @param string $url + */ + #[\PHPUnit\Framework\Attributes\DataProvider('getMetadataUrlProvider')] + public function testGetMetadata(string $version, string $url): void { + $client = $this->createMock(IClient::class); + $response = $this->createMock(IResponse::class); + $this->clientService->expects($this->once()) + ->method('newClient') + ->with() + ->willReturn($client); + $client->expects($this->once()) + ->method('get') + ->with($url) + ->willReturn($response); + + $response->expects($this->once()) + ->method('getBody') + ->with() + ->willReturn('{}'); + + $releaseMetadata = new ReleaseMetadata($this->clientService); + $releaseMetadata->getMetadata($version); + } + + /** + * @return array + */ + public static function getMetadataUrlProvider(): array { + return [ + [ + '30.0.0', + 'https://download.nextcloud.com/server/releases/nextcloud-30.0.0.metadata' + ], + [ + '30.0.0-beta1', + 'https://download.nextcloud.com/server/prereleases/nextcloud-30.0.0-beta1.metadata' + ], + [ + '30', + 'https://download.nextcloud.com/server/releases/latest-30.metadata' + ] + ]; + } + + private static function resultRequest(): string { + return json_encode(self::resultRequestArray()); + } + + private static function resultRequestArray(): array { + return [ + 'migrations' => [ + 'core' => [], + 'apps' => [ + 'testing' => [ + '30000Date20240102030405' => [ + 'class' => 'OCP\\Migration\\Attributes\\DropTable', + 'table' => 'old_table', + 'description' => '', + 'notes' => [], + 'columns' => [] + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\CreateTable', + 'table' => 'new_table', + 'description' => 'Table is used to store things, but also to get more things', + 'notes' => [ + 'this is a notice', + 'and another one, if really needed' + ], + 'columns' => [] + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\AddColumn', + 'table' => 'my_table', + 'description' => '', + 'notes' => [], + 'name' => '', + 'type' => '' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\AddColumn', + 'table' => 'my_table', + 'description' => '', + 'notes' => [], + 'name' => 'another_field', + 'type' => '' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\AddColumn', + 'table' => 'other_table', + 'description' => '', + 'notes' => [], + 'name' => 'last_one', + 'type' => 'date' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\AddIndex', + 'table' => 'my_table', + 'description' => '', + 'notes' => [], + 'type' => '' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\AddIndex', + 'table' => 'my_table', + 'description' => '', + 'notes' => [], + 'type' => 'primary' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\DropColumn', + 'table' => 'other_table', + 'description' => '', + 'notes' => [], + 'name' => '', + 'type' => '' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\DropColumn', + 'table' => 'other_table', + 'description' => 'field is not used anymore and replaced by \'last_one\'', + 'notes' => [], + 'name' => 'old_column', + 'type' => '' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\DropIndex', + 'table' => 'other_table', + 'description' => '', + 'notes' => [], + 'type' => '' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\ModifyColumn', + 'table' => 'other_table', + 'description' => '', + 'notes' => [], + 'name' => '', + 'type' => '' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\ModifyColumn', + 'table' => 'other_table', + 'description' => '', + 'notes' => [], + 'name' => 'this_field', + 'type' => '' + ], + [ + 'class' => 'OCP\\Migration\\Attributes\\ModifyColumn', + 'table' => 'other_table', + 'description' => '', + 'notes' => [], + 'name' => 'this_field', + 'type' => 'bigint' + ] + ] + ] + ] + ]; + } +} diff --git a/tests/lib/Updater/VersionCheckTest.php b/tests/lib/Updater/VersionCheckTest.php new file mode 100644 index 00000000000..1936062a5d0 --- /dev/null +++ b/tests/lib/Updater/VersionCheckTest.php @@ -0,0 +1,378 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ + +namespace Test\Updater; + +use OC\Updater\VersionCheck; +use OCP\Http\Client\IClientService; +use OCP\IAppConfig; +use OCP\IConfig; +use OCP\IUserManager; +use OCP\Server; +use OCP\ServerVersion; +use OCP\Support\Subscription\IRegistry; +use Psr\Log\LoggerInterface; + +class VersionCheckTest extends \Test\TestCase { + /** @var ServerVersion|\PHPUnit\Framework\MockObject\MockObject */ + private $serverVersion; + /** @var IConfig| \PHPUnit\Framework\MockObject\MockObject */ + private $config; + /** @var IAppConfig| \PHPUnit\Framework\MockObject\MockObject */ + private $appConfig; + /** @var VersionCheck | \PHPUnit\Framework\MockObject\MockObject */ + private $updater; + /** @var IRegistry | \PHPUnit\Framework\Mo2ckObject\MockObject */ + private $registry; + /** @var LoggerInterface | \PHPUnit\Framework\Mo2ckObject\MockObject */ + private $logger; + + protected function setUp(): void { + parent::setUp(); + $this->serverVersion = $this->createMock(ServerVersion::class); + $this->config = $this->createMock(IConfig::class); + $this->appConfig = $this->createMock(IAppConfig::class); + $clientService = $this->createMock(IClientService::class); + + $this->serverVersion->method('getChannel')->willReturn('git'); + + $this->registry = $this->createMock(IRegistry::class); + $this->registry + ->method('delegateHasValidSubscription') + ->willReturn(false); + $this->logger = $this->createMock(LoggerInterface::class); + $this->updater = $this->getMockBuilder(VersionCheck::class) + ->onlyMethods(['getUrlContent']) + ->setConstructorArgs([ + $this->serverVersion, + $clientService, + $this->config, + $this->appConfig, + $this->createMock(IUserManager::class), + $this->registry, + $this->logger, + ]) + ->getMock(); + } + + /** + * @param string $baseUrl + * @return string + */ + private function buildUpdateUrl($baseUrl) { + $serverVersion = Server::get(ServerVersion::class); + return $baseUrl . '?version=' . implode('x', $serverVersion->getVersion()) . 'xinstalledatx' . time() . 'x' . $serverVersion->getChannel() . 'xxx' . PHP_MAJOR_VERSION . 'x' . PHP_MINOR_VERSION . 'x' . PHP_RELEASE_VERSION . 'x0x0'; + } + + public function testCheckInCache(): void { + $expectedResult = [ + 'version' => '8.0.4.2', + 'versionstring' => 'ownCloud 8.0.4', + 'url' => 'https://download.example.org/community/owncloud-8.0.4.zip', + 'web' => 'http://doc.example.org/server/8.0/admin_manual/maintenance/upgrade.html', + 'changes' => '', + ]; + + $this->config + ->expects($this->once()) + ->method('getSystemValueBool') + ->with('has_internet_connection', true) + ->willReturn(true); + $this->appConfig + ->expects($this->once()) + ->method('getValueInt') + ->with('core', 'lastupdatedat') + ->willReturn(time()); + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('core', 'lastupdateResult') + ->willReturn(json_encode($expectedResult)); + + $this->assertSame($expectedResult, $this->updater->check()); + } + + public function testCheckWithoutUpdateUrl(): void { + $expectedResult = [ + 'version' => '8.0.4.2', + 'versionstring' => 'ownCloud 8.0.4', + 'url' => 'https://download.example.org/community/owncloud-8.0.4.zip', + 'web' => 'http://doc.example.org/server/8.0/admin_manual/maintenance/upgrade.html', + 'changes' => '', + 'autoupdater' => '0', + 'eol' => '1', + ]; + + $this->config + ->expects($this->once()) + ->method('getSystemValueBool') + ->with('has_internet_connection', true) + ->willReturn(true); + $this->appConfig + ->expects($this->exactly(2)) + ->method('getValueInt') + ->with('core', 'lastupdatedat') + ->willReturnOnConsecutiveCalls( + 0, + time(), + ); + $this->config + ->expects($this->exactly(2)) + ->method('getAppValue') + ->with('core', 'installedat') + ->willReturn('installedat'); + $this->config + ->expects($this->once()) + ->method('getSystemValueString') + ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') + ->willReturnArgument(1); + $this->appConfig + ->expects($this->once()) + ->method('setValueInt') + ->with('core', 'lastupdatedat', time()); + $this->config + ->expects($this->once()) + ->method('setAppValue') + ->with('core', 'lastupdateResult', json_encode($expectedResult)); + + $updateXml = '<?xml version="1.0"?> +<owncloud> + <version>8.0.4.2</version> + <versionstring>ownCloud 8.0.4</versionstring> + <url>https://download.example.org/community/owncloud-8.0.4.zip</url> + <web>http://doc.example.org/server/8.0/admin_manual/maintenance/upgrade.html</web> + <autoupdater>0</autoupdater> + <eol>1</eol> +</owncloud>'; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.nextcloud.com/updater_server/')) + ->willReturn($updateXml); + + $this->assertSame($expectedResult, $this->updater->check()); + } + + public function testCheckWithInvalidXml(): void { + $this->config + ->expects($this->once()) + ->method('getSystemValueBool') + ->with('has_internet_connection', true) + ->willReturn(true); + $this->appConfig + ->expects($this->exactly(2)) + ->method('getValueInt') + ->with('core', 'lastupdatedat') + ->willReturnOnConsecutiveCalls( + 0, + time(), + ); + $this->config + ->expects($this->exactly(2)) + ->method('getAppValue') + ->with('core', 'installedat') + ->willReturn('installedat'); + $this->config + ->expects($this->once()) + ->method('getSystemValueString') + ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') + ->willReturnArgument(1); + $this->appConfig + ->expects($this->once()) + ->method('setValueInt') + ->with('core', 'lastupdatedat', time()); + $this->config + ->expects($this->once()) + ->method('setAppValue') + ->with('core', 'lastupdateResult', $this->isType('string')); + + $updateXml = 'Invalid XML Response!'; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.nextcloud.com/updater_server/')) + ->willReturn($updateXml); + + $this->assertSame([], $this->updater->check()); + } + + public function testCheckWithEmptyValidXmlResponse(): void { + $expectedResult = [ + 'version' => '', + 'versionstring' => '', + 'url' => '', + 'web' => '', + 'changes' => '', + 'autoupdater' => '', + 'eol' => '0', + ]; + + $this->config + ->expects($this->once()) + ->method('getSystemValueBool') + ->with('has_internet_connection', true) + ->willReturn(true); + $this->appConfig + ->expects($this->exactly(2)) + ->method('getValueInt') + ->with('core', 'lastupdatedat') + ->willReturnOnConsecutiveCalls( + 0, + time(), + ); + $this->config + ->expects($this->exactly(2)) + ->method('getAppValue') + ->with('core', 'installedat') + ->willReturn('installedat'); + $this->config + ->expects($this->once()) + ->method('getSystemValueString') + ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') + ->willReturnArgument(1); + $this->appConfig + ->expects($this->once()) + ->method('setValueInt') + ->with('core', 'lastupdatedat', time()); + $this->config + ->expects($this->once()) + ->method('setAppValue') + ->with('core', 'lastupdateResult', $this->isType('string')); + + $updateXml = '<?xml version="1.0"?> +<owncloud> + <version></version> + <versionstring></versionstring> + <url></url> + <web></web> + <autoupdater></autoupdater> +</owncloud>'; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.nextcloud.com/updater_server/')) + ->willReturn($updateXml); + + $this->assertSame($expectedResult, $this->updater->check()); + } + + public function testCheckWithEmptyInvalidXmlResponse(): void { + $expectedResult = []; + + $this->config + ->expects($this->once()) + ->method('getSystemValueBool') + ->with('has_internet_connection', true) + ->willReturn(true); + $this->appConfig + ->expects($this->exactly(2)) + ->method('getValueInt') + ->with('core', 'lastupdatedat') + ->willReturnOnConsecutiveCalls( + 0, + time(), + ); + $this->config + ->expects($this->exactly(2)) + ->method('getAppValue') + ->with('core', 'installedat') + ->willReturn('installedat'); + $this->config + ->expects($this->once()) + ->method('getSystemValueString') + ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') + ->willReturnArgument(1); + $this->appConfig + ->expects($this->once()) + ->method('setValueInt') + ->with('core', 'lastupdatedat', time()); + $this->config + ->expects($this->once()) + ->method('setAppValue') + ->with('core', 'lastupdateResult', $this->isType('string')); + + $updateXml = ''; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.nextcloud.com/updater_server/')) + ->willReturn($updateXml); + + $this->assertSame($expectedResult, $this->updater->check()); + } + + public function testCheckWithMissingAttributeXmlResponse(): void { + $expectedResult = [ + 'version' => '', + 'versionstring' => '', + 'url' => '', + 'web' => '', + 'changes' => '', + 'autoupdater' => '', + 'eol' => '0', + ]; + + $this->config + ->expects($this->once()) + ->method('getSystemValueBool') + ->with('has_internet_connection', true) + ->willReturn(true); + $this->appConfig + ->expects($this->exactly(2)) + ->method('getValueInt') + ->with('core', 'lastupdatedat') + ->willReturnOnConsecutiveCalls( + 0, + time(), + ); + $this->config + ->expects($this->exactly(2)) + ->method('getAppValue') + ->with('core', 'installedat') + ->willReturn('installedat'); + $this->config + ->expects($this->once()) + ->method('getSystemValueString') + ->with('updater.server.url', 'https://updates.nextcloud.com/updater_server/') + ->willReturnArgument(1); + $this->appConfig + ->expects($this->once()) + ->method('setValueInt') + ->with('core', 'lastupdatedat', time()); + $this->config + ->expects($this->once()) + ->method('setAppValue') + ->with('core', 'lastupdateResult', $this->isType('string')); + + // missing autoupdater element should still not fail + $updateXml = '<?xml version="1.0"?> +<owncloud> + <version></version> + <versionstring></versionstring> + <url></url> + <web></web> +</owncloud>'; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.nextcloud.com/updater_server/')) + ->willReturn($updateXml); + + $this->assertSame($expectedResult, $this->updater->check()); + } + + public function testNoInternet(): void { + $this->config + ->expects($this->once()) + ->method('getSystemValueBool') + ->with('has_internet_connection', true) + ->willReturn(false); + + $this->assertFalse($this->updater->check()); + } +} |