aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Updater
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Updater')
-rw-r--r--tests/lib/Updater/ChangesCheckTest.php378
-rw-r--r--tests/lib/Updater/ReleaseMetadataTest.php207
-rw-r--r--tests/lib/Updater/VersionCheckTest.php378
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());
+ }
+}