nextcloud/apps/updatenotification/tests/BackgroundJob/UpdateAvailableNotificationsTest.php

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

443 lines
12 KiB
PHP
Raw Normal View History

2016-05-09 06:04:32 -04:00
<?php
declare(strict_types=1);
2016-05-09 06:04:32 -04:00
/**
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
2016-05-09 06:04:32 -04:00
*/
namespace OCA\UpdateNotification\Tests\BackgroundJob;
2016-05-09 06:04:32 -04:00
use OC\Installer;
use OC\Updater\VersionCheck;
use OCA\UpdateNotification\BackgroundJob\UpdateAvailableNotifications;
2016-05-09 06:04:32 -04:00
use OCP\App\IAppManager;
use OCP\AppFramework\Services\IAppConfig;
use OCP\AppFramework\Utility\ITimeFactory;
2016-05-09 06:04:32 -04:00
use OCP\IConfig;
use OCP\IGroup;
2016-05-09 06:04:32 -04:00
use OCP\IGroupManager;
use OCP\IUser;
use OCP\Notification\IManager;
use OCP\Notification\INotification;
use OCP\ServerVersion;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
2016-05-09 06:04:32 -04:00
class UpdateAvailableNotificationsTest extends TestCase {
private ServerVersion&MockObject $serverVersion;
private IConfig&MockObject $config;
private IManager&MockObject $notificationManager;
private IGroupManager&MockObject $groupManager;
private IAppManager&MockObject $appManager;
private IAppConfig&MockObject $appConfig;
private ITimeFactory&MockObject $timeFactory;
private Installer&MockObject $installer;
private VersionCheck&MockObject $versionCheck;
2016-05-09 06:04:32 -04:00
protected function setUp(): void {
2016-05-09 06:04:32 -04:00
parent::setUp();
$this->serverVersion = $this->createMock(ServerVersion::class);
$this->config = $this->createMock(IConfig::class);
$this->appConfig = $this->createMock(IAppConfig::class);
$this->notificationManager = $this->createMock(IManager::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
$this->installer = $this->createMock(Installer::class);
$this->versionCheck = $this->createMock(VersionCheck::class);
2016-05-09 06:04:32 -04:00
}
/**
* @return UpdateAvailableNotifications|MockObject
2016-05-09 06:04:32 -04:00
*/
protected function getJob(array $methods = []): UpdateAvailableNotifications {
2016-05-09 06:04:32 -04:00
if (empty($methods)) {
return new UpdateAvailableNotifications(
$this->timeFactory,
$this->serverVersion,
2016-05-09 06:04:32 -04:00
$this->config,
$this->appConfig,
2016-05-09 06:04:32 -04:00
$this->notificationManager,
$this->groupManager,
$this->appManager,
$this->installer,
$this->versionCheck,
2016-05-09 06:04:32 -04:00
);
}
{
return $this->getMockBuilder(UpdateAvailableNotifications::class)
2016-05-09 06:04:32 -04:00
->setConstructorArgs([
$this->timeFactory,
$this->serverVersion,
2016-05-09 06:04:32 -04:00
$this->config,
$this->appConfig,
2016-05-09 06:04:32 -04:00
$this->notificationManager,
$this->groupManager,
$this->appManager,
$this->installer,
$this->versionCheck,
2016-05-09 06:04:32 -04:00
])
->onlyMethods($methods)
2016-05-09 06:04:32 -04:00
->getMock();
}
}
public function testRun(): void {
$job = $this->getJob([
'checkCoreUpdate',
'checkAppUpdates',
]);
$job->expects($this->once())
->method('checkCoreUpdate');
$job->expects($this->once())
->method('checkAppUpdates');
$this->config->expects(self::exactly(2))
->method('getSystemValueBool')
->willReturnMap([
['debug', false, true],
['has_internet_connection', true, true],
]);
self::invokePrivate($job, 'run', [null]);
}
public function testRunNoInternet(): void {
$job = $this->getJob([
'checkCoreUpdate',
'checkAppUpdates',
]);
$job->expects($this->never())
->method('checkCoreUpdate');
$job->expects($this->never())
->method('checkAppUpdates');
$this->config
->expects(self::once())
->method('getSystemValueBool')
->with('has_internet_connection', true)
->willReturn(false);
self::invokePrivate($job, 'run', [null]);
2016-05-09 06:04:32 -04:00
}
public static function dataCheckCoreUpdate(): array {
2016-05-09 06:04:32 -04:00
return [
['daily', null, null, null, null],
['git', null, null, null, null],
['beta', [], null, null, null],
['beta', false, false, null, null],
['beta', false, false, null, 13],
2016-05-09 06:04:32 -04:00
['beta', [
'version' => '9.2.0',
'versionstring' => 'Nextcloud 11.0.0',
], '9.2.0', 'Nextcloud 11.0.0', null],
['stable', [], null, null, null],
['stable', false, false, null, null],
['stable', false, false, null, 6],
2016-05-09 06:04:32 -04:00
['stable', [
'version' => '9.2.0',
'versionstring' => 'Nextcloud 11.0.0',
], '9.2.0', 'Nextcloud 11.0.0', null],
['production', [], null, null, null],
['production', false, false, null, null],
['production', false, false, null, 2],
2016-05-09 06:04:32 -04:00
['production', [
'version' => '9.2.0',
'versionstring' => 'Nextcloud 11.0.0',
], '9.2.0', 'Nextcloud 11.0.0', null],
2016-05-09 06:04:32 -04:00
];
}
#[\PHPUnit\Framework\Attributes\DataProvider('dataCheckCoreUpdate')]
public function testCheckCoreUpdate(string $channel, mixed $versionCheck, mixed $version, ?string $readableVersion, ?int $errorDays): void {
2016-05-09 06:04:32 -04:00
$job = $this->getJob([
'createNotifications',
'clearErrorNotifications',
'sendErrorNotifications',
2016-05-09 06:04:32 -04:00
]);
$this->serverVersion->expects($this->once())
2016-05-09 06:04:32 -04:00
->method('getChannel')
->willReturn($channel);
2016-05-10 05:31:03 -04:00
2016-05-09 06:04:32 -04:00
if ($versionCheck === null) {
$this->versionCheck->expects($this->never())
->method('check');
2016-05-09 06:04:32 -04:00
} else {
$this->versionCheck->expects($this->once())
2016-05-09 06:04:32 -04:00
->method('check')
->willReturn($versionCheck);
}
if ($version === null) {
$job->expects($this->never())
->method('createNotifications');
$job->expects($versionCheck === null ? $this->never() : $this->once())
->method('clearErrorNotifications');
} elseif ($version === false) {
2016-05-09 06:04:32 -04:00
$job->expects($this->never())
->method('createNotifications');
$job->expects($this->never())
->method('clearErrorNotifications');
$this->appConfig->expects($this->once())
->method('getAppValueInt')
->willReturn($errorDays ?? 0);
$this->appConfig->expects($this->once())
->method('setAppValueInt')
->with('update_check_errors', $errorDays + 1);
$job->expects($errorDays !== null ? $this->once() : $this->never())
->method('sendErrorNotifications')
->with($errorDays + 1);
2016-05-09 06:04:32 -04:00
} else {
$this->appConfig->expects($this->once())
->method('setAppValueInt')
->with('update_check_errors', 0);
$job->expects($this->once())
->method('clearErrorNotifications');
2016-05-09 06:04:32 -04:00
$job->expects($this->once())
->method('createNotifications')
->with('core', $version, $readableVersion);
2016-05-09 06:04:32 -04:00
}
$this->config->expects(self::any())
->method('getSystemValueBool')
->willReturnMap([
['updatechecker', true, true],
['has_internet_connection', true, true],
]);
self::invokePrivate($job, 'checkCoreUpdate');
2016-05-09 06:04:32 -04:00
}
public static function dataCheckAppUpdates(): array {
2016-05-09 06:04:32 -04:00
return [
[
['app1', 'app2'],
[
['app1', false],
['app2', '1.9.2'],
],
[
['app2', '1.9.2', ''],
2016-05-09 06:04:32 -04:00
],
],
];
}
#[\PHPUnit\Framework\Attributes\DataProvider('dataCheckAppUpdates')]
2016-05-09 06:04:32 -04:00
public function testCheckAppUpdates(array $apps, array $isUpdateAvailable, array $notifications): void {
$job = $this->getJob([
'isUpdateAvailable',
'createNotifications',
]);
$this->appManager->expects($this->once())
->method('getEnabledApps')
2016-05-09 06:04:32 -04:00
->willReturn($apps);
$job->expects($this->exactly(\count($apps)))
2016-05-09 06:04:32 -04:00
->method('isUpdateAvailable')
->willReturnMap($isUpdateAvailable);
$i = 0;
$job->expects($this->exactly(\count($notifications)))
->method('createNotifications')
->willReturnCallback(function () use ($notifications, &$i): void {
$this->assertEquals($notifications[$i], func_get_args());
$i++;
});
2016-05-09 06:04:32 -04:00
self::invokePrivate($job, 'checkAppUpdates');
2016-05-09 06:04:32 -04:00
}
public static function dataCreateNotifications(): array {
2016-05-09 06:04:32 -04:00
return [
['app1', '1.0.0', '1.0.0', false, false, null, null],
['app2', '1.0.1', '1.0.0', '1.0.0', true, ['user1'], [['user1']]],
['app3', '1.0.1', false, false, true, ['user2', 'user3'], [['user2'], ['user3']]],
2016-05-09 06:04:32 -04:00
];
}
#[\PHPUnit\Framework\Attributes\DataProvider('dataCreateNotifications')]
public function testCreateNotifications(string $app, string $version, string|false $lastNotification, string|false $callDelete, bool $createNotification, ?array $users, ?array $userNotifications): void {
2016-05-09 06:04:32 -04:00
$job = $this->getJob([
'deleteOutdatedNotifications',
'getUsersToNotify',
]);
$this->appConfig->expects($this->once())
->method('getAppValueString')
->with($app, '')
->willReturn($lastNotification ?: '');
2016-05-09 06:04:32 -04:00
if ($lastNotification !== $version) {
$this->appConfig->expects($this->once())
->method('setAppValueString')
->with($app, $version);
2016-05-09 06:04:32 -04:00
}
if ($callDelete === false) {
$job->expects($this->never())
->method('deleteOutdatedNotifications');
} else {
$job->expects($this->once())
->method('deleteOutdatedNotifications')
->with($app, $callDelete);
}
if ($users === null) {
$job->expects($this->never())
->method('getUsersToNotify');
} else {
$job->expects($this->once())
->method('getUsersToNotify')
->willReturn($users);
}
if ($createNotification) {
$notification = $this->createMock(INotification::class);
2016-05-09 06:04:32 -04:00
$notification->expects($this->once())
->method('setApp')
->with('updatenotification')
->willReturnSelf();
$notification->expects($this->once())
->method('setDateTime')
->willReturnSelf();
$notification->expects($this->once())
->method('setObject')
->with($app, $version)
->willReturnSelf();
$notification->expects($this->once())
->method('setSubject')
->with('update_available')
->willReturnSelf();
if ($userNotifications !== null) {
$notification->expects($this->exactly(\count($userNotifications)))
2016-05-09 06:04:32 -04:00
->method('setUser')
->willReturnSelf();
$this->notificationManager->expects($this->exactly(\count($userNotifications)))
->method('notify');
2016-05-09 06:04:32 -04:00
}
$this->notificationManager->expects($this->once())
->method('createNotification')
->willReturn($notification);
} else {
$this->notificationManager->expects($this->never())
->method('createNotification');
}
self::invokePrivate($job, 'createNotifications', [$app, $version]);
2016-05-09 06:04:32 -04:00
}
public static function dataGetUsersToNotify(): array {
2016-05-09 06:04:32 -04:00
return [
[['g1', 'g2'], ['g1' => null, 'g2' => ['u1', 'u2']], ['u1', 'u2']],
[['g3', 'g4'], ['g3' => ['u1', 'u2'], 'g4' => ['u2', 'u3']], ['u1', 'u2', 'u3']],
];
}
#[\PHPUnit\Framework\Attributes\DataProvider('dataGetUsersToNotify')]
public function testGetUsersToNotify(array $groups, array $groupUsers, array $expected): void {
2016-05-09 06:04:32 -04:00
$job = $this->getJob();
$this->appConfig->expects($this->once())
->method('getAppValueArray')
->with('notify_groups', ['admin'])
->willReturn($groups);
2016-05-09 06:04:32 -04:00
$groupMap = [];
foreach ($groupUsers as $gid => $uids) {
if ($uids === null) {
$group = null;
} else {
$group = $this->getGroup($gid);
$group->expects($this->any())
->method('getUsers')
->willReturn($this->getUsers($uids));
}
$groupMap[] = [$gid, $group];
}
$this->groupManager->expects($this->exactly(\count($groups)))
2016-05-09 06:04:32 -04:00
->method('get')
->willReturnMap($groupMap);
$result = self::invokePrivate($job, 'getUsersToNotify');
2016-05-09 06:04:32 -04:00
$this->assertEquals($expected, $result);
// Test caching
$result = self::invokePrivate($job, 'getUsersToNotify');
2016-05-09 06:04:32 -04:00
$this->assertEquals($expected, $result);
}
public static function dataDeleteOutdatedNotifications(): array {
2016-05-09 06:04:32 -04:00
return [
['app1', '1.1.0'],
['app2', '1.2.0'],
];
}
/**
* @param string $app
* @param string $version
*/
#[\PHPUnit\Framework\Attributes\DataProvider('dataDeleteOutdatedNotifications')]
public function testDeleteOutdatedNotifications(string $app, string $version): void {
$notification = $this->createMock(INotification::class);
2016-05-09 06:04:32 -04:00
$notification->expects($this->once())
->method('setApp')
->with('updatenotification')
->willReturnSelf();
$notification->expects($this->once())
->method('setObject')
->with($app, $version)
->willReturnSelf();
$this->notificationManager->expects($this->once())
->method('createNotification')
->willReturn($notification);
$this->notificationManager->expects($this->once())
->method('markProcessed')
->with($notification);
$job = $this->getJob();
self::invokePrivate($job, 'deleteOutdatedNotifications', [$app, $version]);
2016-05-09 06:04:32 -04:00
}
/**
* @param string[] $userIds
* @return IUser[]|MockObject[]
2016-05-09 06:04:32 -04:00
*/
protected function getUsers(array $userIds): array {
2016-05-09 06:04:32 -04:00
$users = [];
foreach ($userIds as $uid) {
$user = $this->createMock(IUser::class);
2016-05-09 06:04:32 -04:00
$user->expects($this->any())
->method('getUID')
->willReturn($uid);
$users[] = $user;
}
return $users;
}
/**
* @param string $gid
* @return IGroup|MockObject
2016-05-09 06:04:32 -04:00
*/
protected function getGroup(string $gid) {
$group = $this->createMock(IGroup::class);
2016-05-09 06:04:32 -04:00
$group->expects($this->any())
->method('getGID')
->willReturn($gid);
return $group;
}
}