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>
|
<licence>AGPL</licence>
|
||||||
<author>Joas Schilling</author>
|
<author>Joas Schilling</author>
|
||||||
<version>2.2.0</version>
|
<version>2.2.1</version>
|
||||||
|
|
||||||
<types>
|
<types>
|
||||||
<logging/>
|
<logging/>
|
||||||
|
@ -30,4 +30,8 @@
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<nextcloud min-version="14" max-version="14" />
|
<nextcloud min-version="14" max-version="14" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<commands>
|
||||||
|
<command>OCA\Notifications\Command\Generate</command>
|
||||||
|
</commands>
|
||||||
</info>
|
</info>
|
||||||
|
|
|
@ -27,5 +27,6 @@ return [
|
||||||
['name' => 'Endpoint#deleteAllNotifications', 'url' => '/api/{apiVersion}/notifications', 'verb' => 'DELETE', 'requirements' => ['apiVersion' => 'v(1|2)']],
|
['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#registerDevice', 'url' => '/api/{apiVersion}/push', 'verb' => 'POST', 'requirements' => ['apiVersion' => 'v2']],
|
||||||
['name' => 'Push#removeDevice', 'url' => '/api/{apiVersion}/push', 'verb' => 'DELETE', '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 OC\Authentication\Token\IProvider;
|
||||||
use OCA\Notifications\App;
|
use OCA\Notifications\App;
|
||||||
use OCA\Notifications\Capabilities;
|
use OCA\Notifications\Capabilities;
|
||||||
use OCA\Notifications\Controller\EndpointController;
|
use OCA\Notifications\Notifier\AdminNotifications;
|
||||||
use OCP\AppFramework\IAppContainer;
|
use OCP\AppFramework\IAppContainer;
|
||||||
use OCP\Util;
|
use OCP\Util;
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ class Application extends \OCP\AppFramework\App {
|
||||||
|
|
||||||
public function register() {
|
public function register() {
|
||||||
$this->registerNotificationApp();
|
$this->registerNotificationApp();
|
||||||
|
$this->registerAdminNotifications();
|
||||||
$this->registerUserInterface();
|
$this->registerUserInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +53,17 @@ class Application extends \OCP\AppFramework\App {
|
||||||
return $container->query(App::class);
|
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() {
|
protected function registerUserInterface() {
|
||||||
// Only display the app on index.php except for public shares
|
// 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::addScript('notifications', 'merged');
|
||||||
Util::addStyle('notifications', 'styles');
|
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->assertCount(1, $routes);
|
||||||
$this->assertArrayHasKey('ocs', $routes);
|
$this->assertArrayHasKey('ocs', $routes);
|
||||||
$this->assertInternalType('array', $routes['ocs']);
|
$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);
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче