Add tests for the background job

This commit is contained in:
Joas Schilling 2016-05-09 12:04:32 +02:00
parent c34788918d
commit 96691138df
No known key found for this signature in database
GPG Key ID: 70A0B324C41C0946
4 changed files with 450 additions and 13 deletions

View File

@ -45,7 +45,8 @@ if(\OC::$server->getConfig()->getSystemValue('updatechecker', true) === true) {
$manager,
\OC::$server->getL10NFactory()
);
}, function() use ($l) {
}, function() {
$l = \OC::$server->getL10N('updatenotification');
return [
'id' => 'updatenotification',
'name' => $l->t('Update notifications'),

View File

@ -101,7 +101,7 @@ class AdminController extends Controller {
}
$updateState = $this->updateChecker->getUpdateState();
$notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'));
$notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'), true);
$params = [
'isNewVersionAvailable' => ($updateState === []) ? false : true,

View File

@ -82,15 +82,12 @@ class BackgroundJob extends TimedJob {
* Check for ownCloud update
*/
protected function checkCoreUpdate() {
if (in_array(\OC_Util::getChannel(), ['daily', 'git'])) {
if (in_array($this->getChannel(), ['daily', 'git'])) {
// "These aren't the update channels you're looking for." - Ben Obi-Wan Kenobi
return;
}
$updater = new VersionCheck(
$this->client,
$this->config
);
$updater = $this->createVersionCheck();
$status = $updater->check();
if (isset($status['version'])) {
@ -104,7 +101,7 @@ class BackgroundJob extends TimedJob {
protected function checkAppUpdates() {
$apps = $this->appManager->getInstalledApps();
foreach ($apps as $app) {
$update = Installer::isUpdateAvailable($app);
$update = $this->isUpdateAvailable($app);
if ($update !== false) {
$this->createNotifications($app, $update);
}
@ -134,8 +131,8 @@ class BackgroundJob extends TimedJob {
->setObject($app, $version)
->setSubject('update_available');
foreach ($this->getUsersToNotify() as $user) {
$notification->setUser($user->getUID());
foreach ($this->getUsersToNotify() as $uid) {
$notification->setUser($uid);
$this->notificationManager->notify($notification);
}
@ -143,21 +140,26 @@ class BackgroundJob extends TimedJob {
}
/**
* @return \OCP\IUser[]
* @return string[]
*/
protected function getUsersToNotify() {
if ($this->users !== null) {
return $this->users;
}
$notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'));
$notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'), true);
$this->users = [];
foreach ($notifyGroups as $group) {
$groupToNotify = $this->groupManager->get($group);
if ($groupToNotify instanceof IGroup) {
$this->users = array_merge($this->users, $groupToNotify->getUsers());
foreach ($groupToNotify->getUsers() as $user) {
$this->users[$user->getUID()] = true;
}
}
}
$this->users = array_keys($this->users);
return $this->users;
}
@ -173,4 +175,29 @@ class BackgroundJob extends TimedJob {
->setObject($app, $version);
$this->notificationManager->markProcessed($notification);
}
/**
* @return VersionCheck
*/
protected function createVersionCheck() {
return new VersionCheck(
$this->client,
$this->config
);
}
/**
* @return string
*/
protected function getChannel() {
return \OC_Util::getChannel();
}
/**
* @param string $app
* @return string|false
*/
protected function isUpdateAvailable($app) {
return Installer::isUpdateAvailable($app);
}
}

View File

@ -0,0 +1,409 @@
<?php
/**
* @author Joas Schilling <nickvergessen@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @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 OC\Installer;
use OC\Updater\VersionCheck;
use OCA\UpdateNotification\Notification\BackgroundJob;
use OCP\App\IAppManager;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
use OCP\IGroup;
use OCP\IGroupManager;
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;
public function setUp() {
parent::setUp();
$this->config = $this->getMock('OCP\IConfig');
$this->notificationManager = $this->getMock('OCP\Notification\IManager');
$this->groupManager = $this->getMock('OCP\IGroupManager');
$this->appManager = $this->getMock('OCP\App\IAppManager');
$this->client = $this->getMock('OCP\Http\Client\IClientService');
}
/**
* @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,
$this->client
);
} {
return $this->getMockBuilder('OCA\UpdateNotification\Notification\BackgroundJob')
->setConstructorArgs([
$this->config,
$this->notificationManager,
$this->groupManager,
$this->appManager,
$this->client,
])
->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 [
['daily', null, null],
['git', null, null],
['beta', false, null],
['beta', [
'version' => '9.2.0',
], '9.2.0'],
['stable', false, null],
['stable', [
'version' => '9.2.0',
], '9.2.0'],
['production', false, null],
['production', [
'version' => '9.2.0',
], '9.2.0'],
];
}
/**
* @dataProvider dataCheckCoreUpdate
*
* @param string $channel
* @param mixed $versionCheck
* @param null|string $notification
*/
public function testCheckCoreUpdate($channel, $versionCheck, $notification) {
$job = $this->getJob([
'getChannel',
'createVersionCheck',
'createNotifications',
]);
$job->expects($this->once())
->method('getChannel')
->willReturn($channel);
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) {
$job->expects($this->never())
->method('createNotifications');
} else {
$job->expects($this->once())
->method('createNotifications')
->willReturn('core', $notification);
}
$this->invokePrivate($job, 'checkCoreUpdate');
}
public function dataCheckAppUpdates() {
return [
[
['app1', 'app2'],
[
['app1', false],
['app2', '1.9.2'],
],
[
['app2', '1.9.2'],
],
],
];
}
/**
* @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);
$mockedMethod = $job->expects($this->exactly(sizeof($notifications)))
->method('createNotifications');
call_user_func_array([$mockedMethod, 'withConsecutive'], $notifications);
$this->invokePrivate($job, 'checkAppUpdates');
}
public function dataCreateNotifications() {
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']]],
];
}
/**
* @dataProvider dataCreateNotifications
*
* @param string $app
* @param string $version
* @param string|false $lastNotification
* @param string|false $callDelete
* @param bool $createNotification
* @param string[]|null $users
* @param array|null $userNotifications
*/
public function testCreateNotifications($app, $version, $lastNotification, $callDelete, $createNotification, $users, $userNotifications) {
$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) {
$notification = $this->getMock('OCP\Notification\INotification');
$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) {
$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');
}
$this->invokePrivate($job, 'createNotifications', [$app, $version]);
}
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) {
$notification = $this->getMock('OCP\Notification\INotification');
$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) {
$user = $this->getMock('OCP\IUser');
$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) {
$group = $this->getMock('OCP\IGroup');
$group->expects($this->any())
->method('getGID')
->willReturn($gid);
return $group;
}
}