2016-05-09 13:04:32 +03:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
2016-07-21 17:49:16 +03:00
|
|
|
*
|
|
|
|
* @author Joas Schilling <coding@schilljs.com>
|
|
|
|
*
|
2016-05-09 13:04:32 +03:00
|
|
|
* @license AGPL-3.0
|
|
|
|
*
|
|
|
|
* This code is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
|
|
* as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace OCA\UpdateNotification\Tests\Notification;
|
|
|
|
|
|
|
|
|
|
|
|
use OCA\UpdateNotification\Notification\BackgroundJob;
|
|
|
|
use OCP\App\IAppManager;
|
|
|
|
use OCP\Http\Client\IClientService;
|
|
|
|
use OCP\IConfig;
|
|
|
|
use OCP\IGroupManager;
|
2016-05-10 12:31:03 +03:00
|
|
|
use OCP\IURLGenerator;
|
2016-05-09 13:04:32 +03:00
|
|
|
use OCP\IUser;
|
|
|
|
use OCP\Notification\IManager;
|
|
|
|
use Test\TestCase;
|
|
|
|
|
|
|
|
class BackgroundJobTest extends TestCase {
|
|
|
|
|
|
|
|
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
|
|
|
|
protected $config;
|
|
|
|
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
|
|
|
|
protected $notificationManager;
|
|
|
|
/** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
|
|
|
|
protected $groupManager;
|
|
|
|
/** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */
|
|
|
|
protected $appManager;
|
|
|
|
/** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */
|
|
|
|
protected $client;
|
2016-05-10 12:31:03 +03:00
|
|
|
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
|
|
|
|
protected $urlGenerator;
|
2016-05-09 13:04:32 +03:00
|
|
|
|
|
|
|
public function setUp() {
|
|
|
|
parent::setUp();
|
|
|
|
|
2016-08-14 16:45:45 +03:00
|
|
|
$this->config = $this->getMockBuilder('OCP\IConfig')->getMock();
|
|
|
|
$this->notificationManager = $this->getMockBuilder('OCP\Notification\IManager')->getMock();
|
|
|
|
$this->groupManager = $this->getMockBuilder('OCP\IGroupManager')->getMock();
|
|
|
|
$this->appManager = $this->getMockBuilder('OCP\App\IAppManager')->getMock();
|
|
|
|
$this->client = $this->getMockBuilder('OCP\Http\Client\IClientService')->getMock();
|
|
|
|
$this->urlGenerator = $this->getMockBuilder('OCP\IURLGenerator')->getMock();
|
2016-05-09 13:04:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $methods
|
|
|
|
* @return BackgroundJob|\PHPUnit_Framework_MockObject_MockObject
|
|
|
|
*/
|
|
|
|
protected function getJob(array $methods = []) {
|
|
|
|
if (empty($methods)) {
|
|
|
|
return new BackgroundJob(
|
|
|
|
$this->config,
|
|
|
|
$this->notificationManager,
|
|
|
|
$this->groupManager,
|
|
|
|
$this->appManager,
|
2016-05-10 12:31:03 +03:00
|
|
|
$this->client,
|
|
|
|
$this->urlGenerator
|
2016-05-09 13:04:32 +03:00
|
|
|
);
|
|
|
|
} {
|
|
|
|
return $this->getMockBuilder('OCA\UpdateNotification\Notification\BackgroundJob')
|
|
|
|
->setConstructorArgs([
|
|
|
|
$this->config,
|
|
|
|
$this->notificationManager,
|
|
|
|
$this->groupManager,
|
|
|
|
$this->appManager,
|
|
|
|
$this->client,
|
2016-05-10 12:31:03 +03:00
|
|
|
$this->urlGenerator,
|
2016-05-09 13:04:32 +03:00
|
|
|
])
|
|
|
|
->setMethods($methods)
|
|
|
|
->getMock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRun() {
|
|
|
|
$job = $this->getJob([
|
|
|
|
'checkCoreUpdate',
|
|
|
|
'checkAppUpdates',
|
|
|
|
]);
|
|
|
|
|
|
|
|
$job->expects($this->once())
|
|
|
|
->method('checkCoreUpdate');
|
|
|
|
$job->expects($this->once())
|
|
|
|
->method('checkAppUpdates');
|
|
|
|
|
|
|
|
$this->invokePrivate($job, 'run', [null]);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function dataCheckCoreUpdate() {
|
|
|
|
return [
|
2016-10-04 13:48:17 +03:00
|
|
|
['daily', null, null, null],
|
|
|
|
['git', null, null, null],
|
|
|
|
['beta', false, null, null],
|
2016-05-09 13:04:32 +03:00
|
|
|
['beta', [
|
|
|
|
'version' => '9.2.0',
|
2016-10-04 13:48:17 +03:00
|
|
|
'versionstring' => 'Nextcloud 11.0.0',
|
|
|
|
], '9.2.0', 'Nextcloud 11.0.0'],
|
|
|
|
['stable', false, null, null],
|
2016-05-09 13:04:32 +03:00
|
|
|
['stable', [
|
|
|
|
'version' => '9.2.0',
|
2016-10-04 13:48:17 +03:00
|
|
|
'versionstring' => 'Nextcloud 11.0.0',
|
|
|
|
], '9.2.0', 'Nextcloud 11.0.0'],
|
|
|
|
['production', false, null, null],
|
2016-05-09 13:04:32 +03:00
|
|
|
['production', [
|
|
|
|
'version' => '9.2.0',
|
2016-10-04 13:48:17 +03:00
|
|
|
'versionstring' => 'Nextcloud 11.0.0',
|
|
|
|
], '9.2.0', 'Nextcloud 11.0.0'],
|
2016-05-09 13:04:32 +03:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataCheckCoreUpdate
|
|
|
|
*
|
|
|
|
* @param string $channel
|
|
|
|
* @param mixed $versionCheck
|
|
|
|
* @param null|string $notification
|
2016-10-04 13:48:17 +03:00
|
|
|
* @param null|string $readableVersion
|
2016-05-09 13:04:32 +03:00
|
|
|
*/
|
2016-10-04 13:48:17 +03:00
|
|
|
public function testCheckCoreUpdate($channel, $versionCheck, $notification, $readableVersion) {
|
2016-05-09 13:04:32 +03:00
|
|
|
$job = $this->getJob([
|
|
|
|
'getChannel',
|
|
|
|
'createVersionCheck',
|
|
|
|
'createNotifications',
|
|
|
|
]);
|
|
|
|
|
|
|
|
$job->expects($this->once())
|
|
|
|
->method('getChannel')
|
|
|
|
->willReturn($channel);
|
2016-05-10 12:31:03 +03:00
|
|
|
|
2016-05-09 13:04:32 +03:00
|
|
|
if ($versionCheck === null) {
|
|
|
|
$job->expects($this->never())
|
|
|
|
->method('createVersionCheck');
|
|
|
|
} else {
|
|
|
|
$check = $this->getMockBuilder('OC\Updater\VersionCheck')
|
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
|
|
|
$check->expects($this->once())
|
|
|
|
->method('check')
|
|
|
|
->willReturn($versionCheck);
|
|
|
|
|
|
|
|
$job->expects($this->once())
|
|
|
|
->method('createVersionCheck')
|
|
|
|
->willReturn($check);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($notification === null) {
|
2016-05-10 12:31:03 +03:00
|
|
|
$this->urlGenerator->expects($this->never())
|
|
|
|
->method('linkToRouteAbsolute');
|
|
|
|
|
2016-05-09 13:04:32 +03:00
|
|
|
$job->expects($this->never())
|
|
|
|
->method('createNotifications');
|
|
|
|
} else {
|
2016-05-10 12:31:03 +03:00
|
|
|
$this->urlGenerator->expects($this->once())
|
|
|
|
->method('linkToRouteAbsolute')
|
2016-10-04 13:49:55 +03:00
|
|
|
->with('settings.AdminSettings.index')
|
2016-05-10 12:31:03 +03:00
|
|
|
->willReturn('admin-url');
|
|
|
|
|
2016-05-09 13:04:32 +03:00
|
|
|
$job->expects($this->once())
|
|
|
|
->method('createNotifications')
|
2016-10-04 13:48:17 +03:00
|
|
|
->willReturn('core', $notification, 'admin-url#updater', $readableVersion);
|
2016-05-09 13:04:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->invokePrivate($job, 'checkCoreUpdate');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function dataCheckAppUpdates() {
|
|
|
|
return [
|
|
|
|
[
|
|
|
|
['app1', 'app2'],
|
|
|
|
[
|
|
|
|
['app1', false],
|
|
|
|
['app2', '1.9.2'],
|
|
|
|
],
|
|
|
|
[
|
2016-05-10 12:31:03 +03:00
|
|
|
['app2', '1.9.2', 'apps-url#app-app2'],
|
2016-05-09 13:04:32 +03:00
|
|
|
],
|
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataCheckAppUpdates
|
|
|
|
*
|
|
|
|
* @param string[] $apps
|
|
|
|
* @param array $isUpdateAvailable
|
|
|
|
* @param array $notifications
|
|
|
|
*/
|
|
|
|
public function testCheckAppUpdates(array $apps, array $isUpdateAvailable, array $notifications) {
|
|
|
|
$job = $this->getJob([
|
|
|
|
'isUpdateAvailable',
|
|
|
|
'createNotifications',
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->appManager->expects($this->once())
|
|
|
|
->method('getInstalledApps')
|
|
|
|
->willReturn($apps);
|
|
|
|
|
|
|
|
$job->expects($this->exactly(sizeof($apps)))
|
|
|
|
->method('isUpdateAvailable')
|
|
|
|
->willReturnMap($isUpdateAvailable);
|
|
|
|
|
2016-05-10 12:31:03 +03:00
|
|
|
$this->urlGenerator->expects($this->exactly(sizeof($notifications)))
|
|
|
|
->method('linkToRouteAbsolute')
|
|
|
|
->with('settings.AppSettings.viewApps')
|
|
|
|
->willReturn('apps-url');
|
|
|
|
|
2016-05-09 13:04:32 +03:00
|
|
|
$mockedMethod = $job->expects($this->exactly(sizeof($notifications)))
|
|
|
|
->method('createNotifications');
|
|
|
|
call_user_func_array([$mockedMethod, 'withConsecutive'], $notifications);
|
|
|
|
|
|
|
|
$this->invokePrivate($job, 'checkAppUpdates');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function dataCreateNotifications() {
|
|
|
|
return [
|
2016-05-10 12:31:03 +03:00
|
|
|
['app1', '1.0.0', 'link1', '1.0.0', false, false, null, null],
|
|
|
|
['app2', '1.0.1', 'link2', '1.0.0', '1.0.0', true, ['user1'], [['user1']]],
|
|
|
|
['app3', '1.0.1', 'link3', false, false, true, ['user2', 'user3'], [['user2'], ['user3']]],
|
2016-05-09 13:04:32 +03:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataCreateNotifications
|
|
|
|
*
|
|
|
|
* @param string $app
|
|
|
|
* @param string $version
|
2016-05-10 12:31:03 +03:00
|
|
|
* @param string $url
|
2016-05-09 13:04:32 +03:00
|
|
|
* @param string|false $lastNotification
|
|
|
|
* @param string|false $callDelete
|
|
|
|
* @param bool $createNotification
|
|
|
|
* @param string[]|null $users
|
|
|
|
* @param array|null $userNotifications
|
|
|
|
*/
|
2016-05-10 12:31:03 +03:00
|
|
|
public function testCreateNotifications($app, $version, $url, $lastNotification, $callDelete, $createNotification, $users, $userNotifications) {
|
2016-05-09 13:04:32 +03:00
|
|
|
$job = $this->getJob([
|
|
|
|
'deleteOutdatedNotifications',
|
|
|
|
'getUsersToNotify',
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->config->expects($this->once())
|
|
|
|
->method('getAppValue')
|
|
|
|
->with('updatenotification', $app, false)
|
|
|
|
->willReturn($lastNotification);
|
|
|
|
|
|
|
|
if ($lastNotification !== $version) {
|
|
|
|
$this->config->expects($this->once())
|
|
|
|
->method('setAppValue')
|
|
|
|
->with('updatenotification', $app, $version);
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2016-08-14 16:45:45 +03:00
|
|
|
$notification = $this->getMockBuilder('OCP\Notification\INotification')->getMock();
|
2016-05-09 13:04:32 +03: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();
|
2016-05-10 12:31:03 +03:00
|
|
|
$notification->expects($this->once())
|
|
|
|
->method('setLink')
|
|
|
|
->with($url)
|
|
|
|
->willReturnSelf();
|
2016-05-09 13:04:32 +03:00
|
|
|
|
|
|
|
if ($userNotifications !== null) {
|
|
|
|
$mockedMethod = $notification->expects($this->exactly(sizeof($userNotifications)))
|
|
|
|
->method('setUser')
|
|
|
|
->willReturnSelf();
|
|
|
|
call_user_func_array([$mockedMethod, 'withConsecutive'], $userNotifications);
|
|
|
|
|
|
|
|
$this->notificationManager->expects($this->exactly(sizeof($userNotifications)))
|
|
|
|
->method('notify')
|
|
|
|
->willReturn($notification);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->notificationManager->expects($this->once())
|
|
|
|
->method('createNotification')
|
|
|
|
->willReturn($notification);
|
|
|
|
} else {
|
|
|
|
$this->notificationManager->expects($this->never())
|
|
|
|
->method('createNotification');
|
|
|
|
}
|
|
|
|
|
2016-05-10 12:31:03 +03:00
|
|
|
$this->invokePrivate($job, 'createNotifications', [$app, $version, $url]);
|
2016-05-09 13:04:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function dataGetUsersToNotify() {
|
|
|
|
return [
|
|
|
|
[['g1', 'g2'], ['g1' => null, 'g2' => ['u1', 'u2']], ['u1', 'u2']],
|
|
|
|
[['g3', 'g4'], ['g3' => ['u1', 'u2'], 'g4' => ['u2', 'u3']], ['u1', 'u2', 'u3']],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataGetUsersToNotify
|
|
|
|
* @param string[] $groups
|
|
|
|
* @param array $groupUsers
|
|
|
|
* @param string[] $expected
|
|
|
|
*/
|
|
|
|
public function testGetUsersToNotify($groups, array $groupUsers, array $expected) {
|
|
|
|
$job = $this->getJob();
|
|
|
|
|
|
|
|
$this->config->expects($this->once())
|
|
|
|
->method('getAppValue')
|
|
|
|
->with('updatenotification', 'notify_groups', '["admin"]')
|
|
|
|
->willReturn(json_encode($groups));
|
|
|
|
|
|
|
|
$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(sizeof($groups)))
|
|
|
|
->method('get')
|
|
|
|
->willReturnMap($groupMap);
|
|
|
|
|
|
|
|
$result = $this->invokePrivate($job, 'getUsersToNotify');
|
|
|
|
$this->assertEquals($expected, $result);
|
|
|
|
|
|
|
|
// Test caching
|
|
|
|
$result = $this->invokePrivate($job, 'getUsersToNotify');
|
|
|
|
$this->assertEquals($expected, $result);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function dataDeleteOutdatedNotifications() {
|
|
|
|
return [
|
|
|
|
['app1', '1.1.0'],
|
|
|
|
['app2', '1.2.0'],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider dataDeleteOutdatedNotifications
|
|
|
|
* @param string $app
|
|
|
|
* @param string $version
|
|
|
|
*/
|
|
|
|
public function testDeleteOutdatedNotifications($app, $version) {
|
2016-08-14 16:45:45 +03:00
|
|
|
$notification = $this->getMockBuilder('OCP\Notification\INotification')->getMock();
|
2016-05-09 13:04:32 +03: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();
|
|
|
|
$this->invokePrivate($job, 'deleteOutdatedNotifications', [$app, $version]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string[] $userIds
|
|
|
|
* @return IUser[]|\PHPUnit_Framework_MockObject_MockObject[]
|
|
|
|
*/
|
|
|
|
protected function getUsers(array $userIds) {
|
|
|
|
$users = [];
|
|
|
|
foreach ($userIds as $uid) {
|
2016-08-14 16:45:45 +03:00
|
|
|
$user = $this->getMockBuilder('OCP\IUser')->getMock();
|
2016-05-09 13:04:32 +03:00
|
|
|
$user->expects($this->any())
|
|
|
|
->method('getUID')
|
|
|
|
->willReturn($uid);
|
|
|
|
$users[] = $user;
|
|
|
|
}
|
|
|
|
return $users;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $gid
|
|
|
|
* @return \OCP\IGroup|\PHPUnit_Framework_MockObject_MockObject
|
|
|
|
*/
|
|
|
|
protected function getGroup($gid) {
|
2016-08-14 16:45:45 +03:00
|
|
|
$group = $this->getMockBuilder('OCP\IGroup')->getMock();
|
2016-05-09 13:04:32 +03:00
|
|
|
$group->expects($this->any())
|
|
|
|
->method('getGID')
|
|
|
|
->willReturn($gid);
|
|
|
|
return $group;
|
|
|
|
}
|
|
|
|
}
|