Merge admin notifications app
Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Родитель
fffb9ac5ca
Коммит
e80405d97b
|
@ -15,7 +15,7 @@
|
|||
|
||||
<licence>AGPL</licence>
|
||||
<author>Joas Schilling</author>
|
||||
<version>2.2.0</version>
|
||||
<version>2.2.1</version>
|
||||
|
||||
<types>
|
||||
<logging/>
|
||||
|
@ -30,4 +30,8 @@
|
|||
<dependencies>
|
||||
<nextcloud min-version="14" max-version="14" />
|
||||
</dependencies>
|
||||
|
||||
<commands>
|
||||
<command>OCA\Notifications\Command\Generate</command>
|
||||
</commands>
|
||||
</info>
|
||||
|
|
|
@ -27,5 +27,6 @@ return [
|
|||
['name' => 'Endpoint#deleteAllNotifications', 'url' => '/api/{apiVersion}/notifications', 'verb' => 'DELETE', 'requirements' => ['apiVersion' => 'v(1|2)']],
|
||||
['name' => 'Push#registerDevice', 'url' => '/api/{apiVersion}/push', 'verb' => 'POST', 'requirements' => ['apiVersion' => 'v2']],
|
||||
['name' => 'Push#removeDevice', 'url' => '/api/{apiVersion}/push', 'verb' => 'DELETE', 'requirements' => ['apiVersion' => 'v2']],
|
||||
['name' => 'API#generateNotification', 'url' => '/api/{apiVersion}/notifications/{userId}', 'verb' => 'POST', 'requirements' => ['apiVersion' => 'v(1|2)'], 'root' => '/apps/admin_notifications'],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
# Admin notifications
|
||||
|
||||
Allows admins to generate notifications for users via the console or an HTTP endpoint
|
||||
|
||||
## Console command
|
||||
|
||||
```
|
||||
$ sudo -u www-data ./occ notification:generate \
|
||||
admin "Short message up to 255 characters" \
|
||||
-l "Optional: longer message with more details, up to 4000 characters"
|
||||
```
|
||||
|
||||
### Help
|
||||
|
||||
```
|
||||
$ sudo -u www-data ./occ notification:generate --help
|
||||
Usage:
|
||||
notification:generate [options] [--] <user-id> <short-message>
|
||||
|
||||
Arguments:
|
||||
user-id User ID of the user to notify
|
||||
short-message Short message to be sent to the user (max. 255 characters)
|
||||
|
||||
Options:
|
||||
-l, --long-message=LONG-MESSAGE Long mesage to be sent to the user (max. 4000 characters) [default: ""]
|
||||
|
||||
```
|
||||
|
||||
## HTTP request
|
||||
|
||||
```
|
||||
curl -H "OCS-APIREQUEST: true" -X POST \
|
||||
https://admin:admin@localhost/ocs/v2.php/apps/admin_notifications/api/v1/notifications/admin \
|
||||
-d "shortMessage=Short message up to 255 characters" \
|
||||
-d "longMessage=Optional: longer message with more details, up to 4000 characters"
|
||||
```
|
||||
|
||||
### Help
|
||||
```
|
||||
curl -H "OCS-APIREQUEST: true" -X POST \
|
||||
https://<admin-user>:<admin-app-password-token>@<server-url>/ocs/v2.php/apps/admin_notifications/api/v1/notifications/<user-id> \
|
||||
-d "shortMessage=<short-message>" \
|
||||
-d "longMessage=<long-message>"
|
||||
|
||||
admin-user: User ID of a user with admin priviliges
|
||||
admin-app-password-token: Password or an "app password" of the "admin-user"
|
||||
server-url: URL with Webroot of your Nextcloud installation
|
||||
user-id: User ID of the user to notify
|
||||
short-message: Short message to be sent to the user (max. 255 characters)
|
||||
long-message: Long mesage to be sent to the user (max. 4000 characters)
|
||||
```
|
||||
|
||||
### Return codes
|
||||
|
||||
Status | Description
|
||||
------ | -----------
|
||||
200 | Notification was created successfully
|
||||
400 | Too long or empty `short-message`, too long `long-message`
|
||||
404 | Unknown user
|
||||
500 | Unexpected server error
|
||||
503 | Instance is in maintenance mode
|
||||
|
||||
## Screenshot
|
||||
|
||||
Both the occ command and the HTTP request generate the same notification
|
||||
|
||||
|
||||
![Admin notification triggered from console](docs/Screenshot.png)
|
|
@ -24,7 +24,7 @@ namespace OCA\Notifications\AppInfo;
|
|||
use OC\Authentication\Token\IProvider;
|
||||
use OCA\Notifications\App;
|
||||
use OCA\Notifications\Capabilities;
|
||||
use OCA\Notifications\Controller\EndpointController;
|
||||
use OCA\Notifications\Notifier\AdminNotifications;
|
||||
use OCP\AppFramework\IAppContainer;
|
||||
use OCP\Util;
|
||||
|
||||
|
@ -43,6 +43,7 @@ class Application extends \OCP\AppFramework\App {
|
|||
|
||||
public function register() {
|
||||
$this->registerNotificationApp();
|
||||
$this->registerAdminNotifications();
|
||||
$this->registerUserInterface();
|
||||
}
|
||||
|
||||
|
@ -52,6 +53,17 @@ class Application extends \OCP\AppFramework\App {
|
|||
return $container->query(App::class);
|
||||
});
|
||||
}
|
||||
protected function registerAdminNotifications() {
|
||||
$this->getContainer()->getServer()->getNotificationManager()->registerNotifier(function() {
|
||||
return $this->getContainer()->query(AdminNotifications::class);
|
||||
}, function() {
|
||||
$l = $this->getContainer()->getServer()->getL10NFactory()->get('notifications');
|
||||
return [
|
||||
'id' => 'admin_notifications',
|
||||
'name' => $l->t('Admin notifications'),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
protected function registerUserInterface() {
|
||||
// Only display the app on index.php except for public shares
|
||||
|
@ -66,6 +78,5 @@ class Application extends \OCP\AppFramework\App {
|
|||
Util::addScript('notifications', 'merged');
|
||||
Util::addStyle('notifications', 'styles');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Notifications\Command;
|
||||
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Notification\IManager;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Generate extends Command {
|
||||
|
||||
/** @var ITimeFactory */
|
||||
protected $timeFactory;
|
||||
|
||||
/** @var IUserManager */
|
||||
protected $userManager;
|
||||
|
||||
/** @var IManager */
|
||||
protected $notificationManager;
|
||||
|
||||
/**
|
||||
* @param ITimeFactory $timeFactory
|
||||
* @param IUserManager $userManager
|
||||
* @param IManager $notificationManager
|
||||
*/
|
||||
public function __construct(ITimeFactory $timeFactory, IUserManager $userManager, IManager $notificationManager) {
|
||||
parent::__construct();
|
||||
|
||||
$this->timeFactory = $timeFactory;
|
||||
$this->userManager = $userManager;
|
||||
$this->notificationManager = $notificationManager;
|
||||
}
|
||||
|
||||
protected function configure() {
|
||||
$this
|
||||
->setName('notification:generate')
|
||||
->setDescription('Generate a notification for the given user')
|
||||
->addArgument(
|
||||
'user-id',
|
||||
InputArgument::REQUIRED,
|
||||
'User ID of the user to notify'
|
||||
)
|
||||
->addArgument(
|
||||
'short-message',
|
||||
InputArgument::REQUIRED,
|
||||
'Short message to be sent to the user (max. 255 characters)'
|
||||
)
|
||||
->addOption(
|
||||
'long-message',
|
||||
'l',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'Long mesage to be sent to the user (max. 4000 characters)',
|
||||
''
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return int
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
|
||||
$userId = $input->getArgument('user-id');
|
||||
$subject = $input->getArgument('short-message');
|
||||
$message = $input->getOption('long-message');
|
||||
|
||||
$user = $this->userManager->get($userId);
|
||||
if (!$user instanceof IUser) {
|
||||
$output->writeln('Unknown user');
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($subject === '' || strlen($subject) > 255) {
|
||||
$output->writeln('Too long or empty short-message');
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($message !== '' && strlen($message) > 4000) {
|
||||
$output->writeln('Too long long-message');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$time = $this->timeFactory->getTime();
|
||||
$datetime = new \DateTime();
|
||||
$datetime->setTimestamp($time);
|
||||
|
||||
try {
|
||||
$notification->setApp('admin_notifications')
|
||||
->setUser($user->getUID())
|
||||
->setDateTime($datetime)
|
||||
->setObject('admin_notifications', dechex($time))
|
||||
->setSubject('cli', [$subject]);
|
||||
|
||||
if ($message !== '') {
|
||||
$notification->setMessage('cli', [$message]);
|
||||
}
|
||||
|
||||
$this->notificationManager->notify($notification);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
$output->writeln('Error while sending the notification');
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Notifications\Controller;
|
||||
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Notification\IManager;
|
||||
|
||||
class APIController extends OCSController {
|
||||
|
||||
/** @var ITimeFactory */
|
||||
protected $timeFactory;
|
||||
|
||||
/** @var IUserManager */
|
||||
protected $userManager;
|
||||
|
||||
/** @var IManager */
|
||||
protected $notificationManager;
|
||||
|
||||
/**
|
||||
* @param string $appName
|
||||
* @param IRequest $request
|
||||
* @param ITimeFactory $timeFactory
|
||||
* @param IUserManager $userManager
|
||||
* @param IManager $notificationManager
|
||||
*/
|
||||
public function __construct($appName, IRequest $request, ITimeFactory $timeFactory, IUserManager $userManager, IManager $notificationManager) {
|
||||
parent::__construct($appName, $request);
|
||||
|
||||
$this->timeFactory = $timeFactory;
|
||||
$this->userManager = $userManager;
|
||||
$this->notificationManager = $notificationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userId
|
||||
* @param string $shortMessage
|
||||
* @param string $longMessage
|
||||
* @return DataResponse
|
||||
*/
|
||||
public function generateNotification($userId, $shortMessage, $longMessage) {
|
||||
$shortMessage = (string) $shortMessage;
|
||||
$longMessage = (string) $longMessage;
|
||||
|
||||
$user = $this->userManager->get($userId);
|
||||
|
||||
if (!$user instanceof IUser) {
|
||||
return new DataResponse(null, Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($shortMessage === '' || strlen($shortMessage) > 255) {
|
||||
return new DataResponse(null, Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
if ($longMessage !== '' && strlen($longMessage) > 4000) {
|
||||
return new DataResponse(null, Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$time = $this->timeFactory->getTime();
|
||||
$datetime = new \DateTime();
|
||||
$datetime->setTimestamp($time);
|
||||
|
||||
try {
|
||||
$notification->setApp('admin_notifications')
|
||||
->setUser($user->getUID())
|
||||
->setDateTime($datetime)
|
||||
->setObject('admin_notifications', dechex($time))
|
||||
->setSubject('ocs', [$shortMessage]);
|
||||
|
||||
if ($longMessage !== '') {
|
||||
$notification->setMessage('ocs', [$longMessage]);
|
||||
}
|
||||
|
||||
$this->notificationManager->notify($notification);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return new DataResponse(null, Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
return new DataResponse();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Notifications\Notifier;
|
||||
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Notification\INotification;
|
||||
use OCP\Notification\INotifier;
|
||||
|
||||
class AdminNotifications implements INotifier {
|
||||
|
||||
/** @var IFactory */
|
||||
protected $l10nFactory;
|
||||
|
||||
/** @var IURLGenerator */
|
||||
protected $urlGenerator;
|
||||
|
||||
/**
|
||||
* @param IFactory $l10nFactory
|
||||
* @param IURLGenerator $urlGenerator
|
||||
*/
|
||||
public function __construct(IFactory $l10nFactory, IURLGenerator $urlGenerator) {
|
||||
$this->l10nFactory = $l10nFactory;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param INotification $notification
|
||||
* @param string $languageCode The code of the language that should be used to prepare the notification
|
||||
* @return INotification
|
||||
* @throws \InvalidArgumentException When the notification was not prepared by a notifier
|
||||
*/
|
||||
public function prepare(INotification $notification, $languageCode) {
|
||||
if ($notification->getApp() !== 'admin_notifications') {
|
||||
throw new \InvalidArgumentException('Unknown app');
|
||||
}
|
||||
|
||||
switch ($notification->getSubject()) {
|
||||
// Deal with known subjects
|
||||
case 'cli':
|
||||
case 'ocs':
|
||||
$subjectParams = $notification->getSubjectParameters();
|
||||
$notification->setParsedSubject($subjectParams[0]);
|
||||
$messageParams = $notification->getMessageParameters();
|
||||
if (isset($messageParams[0]) && $messageParams[0] !== '') {
|
||||
$notification->setParsedMessage($messageParams[0]);
|
||||
}
|
||||
|
||||
$notification->setIcon($this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('notifications', 'notifications-dark.svg')));
|
||||
return $notification;
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException('Unknown subject');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,6 @@ class RoutesTest extends TestCase {
|
|||
$this->assertCount(1, $routes);
|
||||
$this->assertArrayHasKey('ocs', $routes);
|
||||
$this->assertInternalType('array', $routes['ocs']);
|
||||
$this->assertCount(6, $routes['ocs']);
|
||||
$this->assertCount(7, $routes['ocs']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Notifications\Tests\Unit\Command;
|
||||
|
||||
use OCA\Notifications\Command\Generate;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class GenerateTest
|
||||
*
|
||||
* @package OCA\Notifications\Tests\Unit\Command
|
||||
* @group DB
|
||||
*/
|
||||
class GenerateTest extends \Test\TestCase {
|
||||
/** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $timeFactory;
|
||||
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $userManager;
|
||||
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $notificationManager;
|
||||
/** @var Generate */
|
||||
protected $command;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->notificationManager = $this->createMock(IManager::class);
|
||||
|
||||
$this->command = new Generate(
|
||||
$this->timeFactory,
|
||||
$this->userManager,
|
||||
$this->notificationManager
|
||||
);
|
||||
}
|
||||
|
||||
public function dataExecute() {
|
||||
return [
|
||||
['user', '', '', false, null, false, null, 123, null, 1],
|
||||
['user', '', '', false, null, false, 'user', 123, null, 1],
|
||||
['user', str_repeat('a', 256), '', false, null, false, 'user', 123, null, 1],
|
||||
['user', 'short', '', true, false, false, 'user', 123, '7b', 0],
|
||||
['user', 'short', str_repeat('a', 4001), false, null, false, 'user', 123, null, 1],
|
||||
['user', 'short', str_repeat('a', 4000), true, false, true, 'user', 123, '7b', 0],
|
||||
['user', 'short', 'long', true, true, true, 'user', 123, '7b', 1],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataExecute
|
||||
* @param string $userId
|
||||
* @param string $short
|
||||
* @param string $long
|
||||
* @param bool $createNotification
|
||||
* @param bool $notifyThrows
|
||||
* @param bool $validLong
|
||||
* @param string|null $user
|
||||
* @param int $time
|
||||
* @param string|null $hexTime
|
||||
* @param int $exitCode
|
||||
*/
|
||||
public function testExecute($userId, $short, $long, $createNotification, $notifyThrows, $validLong, $user, $time, $hexTime, $exitCode) {
|
||||
if ($user !== null) {
|
||||
$u = $this->createMock(IUser::class);
|
||||
$u->expects($createNotification ? $this->once() : $this->never())
|
||||
->method('getUID')
|
||||
->willReturn($user);
|
||||
} else {
|
||||
$u = null;
|
||||
}
|
||||
$this->userManager->expects($this->any())
|
||||
->method('get')
|
||||
->with($userId)
|
||||
->willReturn($u);
|
||||
|
||||
$this->timeFactory->expects($hexTime === null ? $this->never() : $this->once())
|
||||
->method('getTime')
|
||||
->willReturn($time);
|
||||
|
||||
if ($createNotification) {
|
||||
$n = $this->createMock(INotification::class);
|
||||
$n->expects($this->once())
|
||||
->method('setApp')
|
||||
->with('admin_notifications')
|
||||
->willReturnSelf();
|
||||
$n->expects($this->once())
|
||||
->method('setUser')
|
||||
->with($user)
|
||||
->willReturnSelf();
|
||||
$n->expects($this->once())
|
||||
->method('setDateTime')
|
||||
->willReturnSelf();
|
||||
$n->expects($this->once())
|
||||
->method('setObject')
|
||||
->with('admin_notifications', $hexTime)
|
||||
->willReturnSelf();
|
||||
$n->expects($this->once())
|
||||
->method('setSubject')
|
||||
->with('cli', [$short])
|
||||
->willReturnSelf();
|
||||
if ($validLong) {
|
||||
$n->expects($this->once())
|
||||
->method('setMessage')
|
||||
->with('cli', [$long])
|
||||
->willReturnSelf();
|
||||
} else {
|
||||
$n->expects($this->never())
|
||||
->method('setMessage');
|
||||
}
|
||||
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('createNotification')
|
||||
->willReturn($n);
|
||||
|
||||
if ($notifyThrows === null) {
|
||||
$this->notificationManager->expects($this->never())
|
||||
->method('notify');
|
||||
} else if ($notifyThrows === false) {
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('notify')
|
||||
->with($n);
|
||||
} else if ($notifyThrows === true) {
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('notify')
|
||||
->willThrowException(new \InvalidArgumentException());
|
||||
}
|
||||
}
|
||||
|
||||
$input = $this->createMock(InputInterface::class);
|
||||
$input->expects($this->exactly(2))
|
||||
->method('getArgument')
|
||||
->willReturnMap([
|
||||
['user-id', $userId],
|
||||
['short-message', $short],
|
||||
]);
|
||||
$input->expects($this->exactly(1))
|
||||
->method('getOption')
|
||||
->willReturnMap([
|
||||
['long-message', $long],
|
||||
]);
|
||||
$output = $this->createMock(OutputInterface::class);
|
||||
|
||||
$return = self::invokePrivate($this->command, 'execute', [$input, $output]);
|
||||
$this->assertSame($exitCode, $return);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Notifications\Tests\Unit\Controller;
|
||||
|
||||
use OCA\Notifications\Controller\APIController;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
|
||||
/**
|
||||
* Class APIControllerTest
|
||||
*
|
||||
* @package OCA\Notifications\Tests\Unit\Controller
|
||||
* @group DB
|
||||
*/
|
||||
class APIControllerTest extends \Test\TestCase {
|
||||
/** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $timeFactory;
|
||||
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $userManager;
|
||||
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $notificationManager;
|
||||
/** @var APIController */
|
||||
protected $controller;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */
|
||||
$request = $this->createMock(IRequest::class);
|
||||
$this->timeFactory = $this->createMock(ITimeFactory::class);
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->notificationManager = $this->createMock(IManager::class);
|
||||
|
||||
$this->controller = new APIController(
|
||||
'notifications',
|
||||
$request,
|
||||
$this->timeFactory,
|
||||
$this->userManager,
|
||||
$this->notificationManager
|
||||
);
|
||||
}
|
||||
|
||||
public function dataGenerateNotification() {
|
||||
return [
|
||||
['user', '', '', false, null, false, null, 123, null, Http::STATUS_NOT_FOUND],
|
||||
['user', '', '', false, null, false, 'user', 123, null, Http::STATUS_BAD_REQUEST],
|
||||
['user', null, '', false, null, false, 'user', 123, null, Http::STATUS_BAD_REQUEST],
|
||||
['user', str_repeat('a', 256), '', false, null, false, 'user', 123, null, Http::STATUS_BAD_REQUEST],
|
||||
['user', 'short', '', true, false, false, 'user', 123, '7b', Http::STATUS_OK],
|
||||
['user', 'short', str_repeat('a', 4001), false, null, false, 'user', 123, null, Http::STATUS_BAD_REQUEST],
|
||||
['user', 'short', str_repeat('a', 4000), true, false, true, 'user', 123, '7b', Http::STATUS_OK],
|
||||
['user', 'short', 'long', true, true, true, 'user', 123, '7b', Http::STATUS_INTERNAL_SERVER_ERROR],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGenerateNotification
|
||||
* @param string $userId
|
||||
* @param string $short
|
||||
* @param string $long
|
||||
* @param bool $createNotification
|
||||
* @param bool $notifyThrows
|
||||
* @param bool $validLong
|
||||
* @param string|null $user
|
||||
* @param int $time
|
||||
* @param string|null $hexTime
|
||||
* @param int $statusCode
|
||||
*/
|
||||
public function testGenerateNotification($userId, $short, $long, $createNotification, $notifyThrows, $validLong, $user, $time, $hexTime, $statusCode) {
|
||||
if ($user !== null) {
|
||||
$u = $this->createMock(IUser::class);
|
||||
$u->expects($createNotification ? $this->once() : $this->never())
|
||||
->method('getUID')
|
||||
->willReturn($user);
|
||||
} else {
|
||||
$u = null;
|
||||
}
|
||||
$this->userManager->expects($this->any())
|
||||
->method('get')
|
||||
->with($userId)
|
||||
->willReturn($u);
|
||||
|
||||
$this->timeFactory->expects($hexTime === null ? $this->never() : $this->once())
|
||||
->method('getTime')
|
||||
->willReturn($time);
|
||||
|
||||
if ($createNotification) {
|
||||
$n = $this->createMock(INotification::class);
|
||||
$n->expects($this->once())
|
||||
->method('setApp')
|
||||
->with('admin_notifications')
|
||||
->willReturnSelf();
|
||||
$n->expects($this->once())
|
||||
->method('setUser')
|
||||
->with($user)
|
||||
->willReturnSelf();
|
||||
$n->expects($this->once())
|
||||
->method('setDateTime')
|
||||
->willReturnSelf();
|
||||
$n->expects($this->once())
|
||||
->method('setObject')
|
||||
->with('admin_notifications', $hexTime)
|
||||
->willReturnSelf();
|
||||
$n->expects($this->once())
|
||||
->method('setSubject')
|
||||
->with('ocs', [$short])
|
||||
->willReturnSelf();
|
||||
if ($validLong) {
|
||||
$n->expects($this->once())
|
||||
->method('setMessage')
|
||||
->with('ocs', [$long])
|
||||
->willReturnSelf();
|
||||
} else {
|
||||
$n->expects($this->never())
|
||||
->method('setMessage');
|
||||
}
|
||||
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('createNotification')
|
||||
->willReturn($n);
|
||||
|
||||
if ($notifyThrows === null) {
|
||||
$this->notificationManager->expects($this->never())
|
||||
->method('notify');
|
||||
} else if ($notifyThrows === false) {
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('notify')
|
||||
->with($n);
|
||||
} else if ($notifyThrows === true) {
|
||||
$this->notificationManager->expects($this->once())
|
||||
->method('notify')
|
||||
->willThrowException(new \InvalidArgumentException());
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->controller->generateNotification($userId, $short, $long);
|
||||
|
||||
$this->assertInstanceOf(DataResponse::class, $response);
|
||||
$this->assertSame($statusCode, $response->getStatus());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Notifications\Tests\Unit\Notifier;
|
||||
|
||||
use OCA\Notifications\Notifier\AdminNotifications;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\L10N\IFactory;
|
||||
use OCP\Notification\INotification;
|
||||
|
||||
class NotifierTest extends \Test\TestCase {
|
||||
/** @var AdminNotifications */
|
||||
protected $notifier;
|
||||
|
||||
/** @var IFactory|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $factory;
|
||||
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $urlGenerator;
|
||||
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
|
||||
protected $l;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
||||
$this->l = $this->createMock(IL10N::class);
|
||||
$this->l->expects($this->any())
|
||||
->method('t')
|
||||
->willReturnCallback(function($string, $args) {
|
||||
return vsprintf($string, $args);
|
||||
});
|
||||
$this->factory = $this->createMock(IFactory::class);
|
||||
$this->factory->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn($this->l);
|
||||
|
||||
$this->notifier = new AdminNotifications(
|
||||
$this->factory,
|
||||
$this->urlGenerator
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Unknown app
|
||||
*/
|
||||
public function testPrepareWrongApp() {
|
||||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->createMock(INotification::class);
|
||||
|
||||
$notification->expects($this->once())
|
||||
->method('getApp')
|
||||
->willReturn('notifications');
|
||||
$notification->expects($this->never())
|
||||
->method('getSubject');
|
||||
|
||||
$this->notifier->prepare($notification, 'en');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Unknown subject
|
||||
*/
|
||||
public function testPrepareWrongSubject() {
|
||||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->createMock(INotification::class);
|
||||
|
||||
$notification->expects($this->once())
|
||||
->method('getApp')
|
||||
->willReturn('admin_notifications');
|
||||
$notification->expects($this->once())
|
||||
->method('getSubject')
|
||||
->willReturn('wrong subject');
|
||||
|
||||
$this->notifier->prepare($notification, 'en');
|
||||
}
|
||||
|
||||
public function dataPrepare() {
|
||||
return [
|
||||
['ocs', ['subject'], ['message'], true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataPrepare
|
||||
*
|
||||
* @param string $subject
|
||||
* @param array $subjectParams
|
||||
* @param array $messageParams
|
||||
* @param bool $setMessage
|
||||
*/
|
||||
public function testPrepare($subject, $subjectParams, $messageParams, $setMessage) {
|
||||
/** @var INotification|\PHPUnit_Framework_MockObject_MockObject $notification */
|
||||
$notification = $this->createMock(INotification::class);
|
||||
|
||||
$notification->expects($this->once())
|
||||
->method('getApp')
|
||||
->willReturn('admin_notifications');
|
||||
$notification->expects($this->once())
|
||||
->method('getSubject')
|
||||
->willReturn($subject);
|
||||
$notification->expects($this->once())
|
||||
->method('getSubjectParameters')
|
||||
->willReturn($subjectParams);
|
||||
$notification->expects($this->once())
|
||||
->method('getMessageParameters')
|
||||
->willReturn($messageParams);
|
||||
|
||||
$notification->expects($this->once())
|
||||
->method('setParsedSubject')
|
||||
->with($subjectParams[0])
|
||||
->willReturnSelf();
|
||||
|
||||
if ($setMessage) {
|
||||
$notification->expects($this->once())
|
||||
->method('setParsedMessage')
|
||||
->with($messageParams[0])
|
||||
->willReturnSelf();
|
||||
} else {
|
||||
$notification->expects($this->never())
|
||||
->method('setParsedMessage');
|
||||
}
|
||||
|
||||
$this->urlGenerator->expects($this->once())
|
||||
->method('imagePath')
|
||||
->with('notifications', 'notifications-dark.svg')
|
||||
->willReturn('icon-url');
|
||||
$this->urlGenerator->expects($this->once())
|
||||
->method('getAbsoluteURL')
|
||||
->with('icon-url')
|
||||
->willReturn('absolute-icon-url');
|
||||
$notification->expects($this->once())
|
||||
->method('setIcon')
|
||||
->with('absolute-icon-url')
|
||||
->willReturnSelf();
|
||||
|
||||
$return = $this->notifier->prepare($notification, 'en');
|
||||
|
||||
$this->assertEquals($notification, $return);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче