From cca0a12379c0a3e61199d98e8ab170d1e7a75338 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Jan 2021 23:52:59 +0100 Subject: [PATCH] Cleanup duplicate API methods Signed-off-by: Joas Schilling --- appinfo/routes.php | 5 - lib/Controller/APIController.php | 26 +- lib/Controller/PageController.php | 206 +----------- tests/Controller/APIControllerTest.php | 425 ++++++++++++++++++++++++ tests/Controller/PageControllerTest.php | 400 +--------------------- 5 files changed, 451 insertions(+), 611 deletions(-) create mode 100644 tests/Controller/APIControllerTest.php diff --git a/appinfo/routes.php b/appinfo/routes.php index 8631411f..e20204c5 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -24,11 +24,6 @@ return [ 'routes' => [ ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], - ['name' => 'page#get', 'url' => '/announcement', 'verb' => 'GET'], - ['name' => 'page#add', 'url' => '/announcement', 'verb' => 'POST'], - ['name' => 'page#delete', 'url' => '/announcement/{id}', 'verb' => 'DELETE'], - ['name' => 'page#removeNotifications', 'url' => '/announcement/{id}/notifications', 'verb' => 'DELETE'], - ['name' => 'page#searchGroups', 'url' => '/groups', 'verb' => 'GET'], ], 'ocs' => [ ['name' => 'API#get', 'url' => '/api/v1/announcements', 'verb' => 'GET'], diff --git a/lib/Controller/APIController.php b/lib/Controller/APIController.php index 55dec526..4c287893 100644 --- a/lib/Controller/APIController.php +++ b/lib/Controller/APIController.php @@ -25,19 +25,16 @@ namespace OCA\AnnouncementCenter\Controller; +use InvalidArgumentException; use OCA\AnnouncementCenter\Manager; use OCA\AnnouncementCenter\Model\Announcement; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Http\Response; use OCP\AppFramework\OCSController; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; -use OCP\IConfig; -use OCP\IDBConnection; use OCP\IGroup; use OCP\IGroupManager; -use OCP\IInitialStateService; use OCP\IL10N; use OCP\IRequest; use OCP\IUser; @@ -50,9 +47,6 @@ class APIController extends OCSController { /** @var IJobList */ protected $jobList; - /** @var IDBConnection */ - protected $connection; - /** @var IGroupManager */ protected $groupManager; @@ -65,42 +59,30 @@ class APIController extends OCSController { /** @var Manager */ protected $manager; - /** @var IConfig */ - protected $config; - /** @var ITimeFactory */ protected $timeFactory; /** @var IUserSession */ protected $userSession; - /** @var IInitialStateService */ - protected $initialState; - public function __construct(string $appName, IRequest $request, - IDBConnection $connection, IGroupManager $groupManager, IUserManager $userManager, IJobList $jobList, IL10N $l, Manager $manager, - IConfig $config, ITimeFactory $timeFactory, - IUserSession $userSession, - IInitialStateService $initialState) { + IUserSession $userSession) { parent::__construct($appName, $request); - $this->connection = $connection; $this->groupManager = $groupManager; $this->userManager = $userManager; $this->jobList = $jobList; $this->l = $l; $this->manager = $manager; - $this->config = $config; $this->timeFactory = $timeFactory; $this->userSession = $userSession; - $this->initialState = $initialState; } /** @@ -139,7 +121,7 @@ public function add(string $subject, string $message, array $groups, bool $activ try { $announcement = $this->manager->announce($subject, $message, $userId, $this->timeFactory->getTime(), $groups, $comments); - } catch (\InvalidArgumentException $e) { + } catch (InvalidArgumentException $e) { return new DataResponse( ['error' => $this->l->t('The subject is too long or empty')], Http::STATUS_BAD_REQUEST @@ -226,7 +208,7 @@ public function delete(int $id): DataResponse { * @NoAdminRequired * * @param int $id - * @return Response + * @return DataResponse */ public function removeNotifications(int $id): DataResponse { if (!$this->manager->checkIsAdmin()) { diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 00a8b5ef..b1f89437 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -27,41 +27,14 @@ use OCA\AnnouncementCenter\AppInfo\Application; use OCA\AnnouncementCenter\Manager; -use OCA\AnnouncementCenter\Model\Announcement; -use OCP\AppFramework\Http; -use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; -use OCP\AppFramework\Http\Response; use OCP\AppFramework\Controller; -use OCP\AppFramework\Utility\ITimeFactory; -use OCP\BackgroundJob\IJobList; +use OCP\AppFramework\Services\IInitialState; use OCP\IConfig; -use OCP\IDBConnection; -use OCP\IGroupManager; -use OCP\IInitialStateService; -use OCP\IL10N; use OCP\IRequest; -use OCP\IUser; -use OCP\IUserManager; -use OCP\IUserSession; -use OCA\AnnouncementCenter\BackgroundJob; class PageController extends Controller { - /** @var IJobList */ - protected $jobList; - - /** @var IDBConnection */ - protected $connection; - - /** @var IGroupManager */ - protected $groupManager; - - /** @var IUserManager */ - protected $userManager; - - /** @var IL10N */ - protected $l; /** @var Manager */ protected $manager; @@ -69,159 +42,21 @@ class PageController extends Controller { /** @var IConfig */ protected $config; - /** @var ITimeFactory */ - protected $timeFactory; - - /** @var IUserSession */ - protected $userSession; - - /** @var IInitialStateService */ + /** @var IInitialState */ protected $initialState; public function __construct(string $AppName, IRequest $request, - IDBConnection $connection, - IGroupManager $groupManager, - IUserManager $userManager, - IJobList $jobList, - IL10N $l, Manager $manager, IConfig $config, - ITimeFactory $timeFactory, - IUserSession $userSession, - IInitialStateService $initialState) { + IInitialState $initialState) { parent::__construct($AppName, $request); - $this->connection = $connection; - $this->groupManager = $groupManager; - $this->userManager = $userManager; - $this->jobList = $jobList; - $this->l = $l; $this->manager = $manager; $this->config = $config; - $this->timeFactory = $timeFactory; - $this->userSession = $userSession; $this->initialState = $initialState; } - /** - * @NoAdminRequired - * @NoCSRFRequired - * - * @param int $offset - * @return JSONResponse - */ - public function get($offset = 0): JSONResponse { - $announcements = $this->manager->getAnnouncements($offset); - $data = array_map([$this, 'renderAnnouncement'], $announcements); - return new JSONResponse($data); - } - - /** - * @NoAdminRequired - * - * @param string $subject - * @param string $message - * @param string[] $groups, - * @param bool $activities - * @param bool $notifications - * @param bool $comments - * @return JSONResponse - */ - public function add($subject, $message, array $groups, $activities, $notifications, $comments): JSONResponse { - if (!$this->manager->checkIsAdmin()) { - return new JSONResponse( - ['message' => 'Logged in user must be an admin'], - Http::STATUS_FORBIDDEN - ); - } - $user = $this->userSession->getUser(); - $userId = $user instanceof IUser ? $user->getUID() : ''; - - try { - $announcement = $this->manager->announce($subject, $message, $userId, $this->timeFactory->getTime(), $groups, $comments); - } catch (\InvalidArgumentException $e) { - return new JSONResponse( - ['error' => $this->l->t('The subject is too long or empty')], - Http::STATUS_BAD_REQUEST - ); - } - - if ($activities || $notifications) { - $this->jobList->add(BackgroundJob::class, [ - 'id' => $announcement->getId(), - 'activities' => $activities, - 'notifications' => $notifications, - ]); - } - - return new JSONResponse($this->renderAnnouncement($announcement)); - } - - protected function renderAnnouncement(Announcement $announcement): array { - $displayName = $announcement->getUser(); - $user = $this->userManager->get($announcement->getUser()); - if ($user instanceof IUser) { - $displayName = $user->getDisplayName(); - } - - $result = [ - 'id' => $announcement->getId(), - 'author_id' => $announcement->getUser(), - 'author' => $displayName, - 'time' => $announcement->getTime(), - 'subject' => $announcement->getSubject(), - 'message' => $announcement->getParsedMessage(), - 'groups' => null, - 'comments' => $announcement->getAllowComments() ? $this->manager->getNumberOfComments($announcement) : false, - ]; - - if ($this->manager->checkIsAdmin()) { - $result['groups'] = $this->manager->getGroups($announcement); - $result['notifications'] = $this->manager->hasNotifications($announcement); - } - - return $result; - } - - /** - * @NoAdminRequired - * - * @param int $id - * @return Response - */ - public function delete($id): Response { - if (!$this->manager->checkIsAdmin()) { - return new JSONResponse( - ['message' => 'Logged in user must be an admin'], - Http::STATUS_FORBIDDEN - ); - } - - $this->manager->delete($id); - - return new Response(); - } - - /** - * @NoAdminRequired - * - * @param int $id - * @return Response - */ - public function removeNotifications($id): Response { - if (!$this->manager->checkIsAdmin()) { - return new JSONResponse( - ['message' => 'Logged in user must be an admin'], - Http::STATUS_FORBIDDEN - ); - } - - $this->manager->removeNotifications($id); - - return new Response(); - } - /** * @NoAdminRequired * @NoCSRFRequired @@ -235,49 +70,22 @@ public function index($announcement = 0): TemplateResponse { } $this->initialState->provideInitialState( - Application::APP_ID, 'isAdmin', $this->manager->checkIsAdmin() ); $this->initialState->provideInitialState( - Application::APP_ID, 'createActivities', - $this->config->getAppValue('announcementcenter', 'create_activities', 'yes') === 'yes' + $this->config->getAppValue(Application::APP_ID, 'create_activities', 'yes') === 'yes' ); $this->initialState->provideInitialState( - Application::APP_ID, 'createNotifications', - $this->config->getAppValue('announcementcenter', 'create_notifications', 'yes') === 'yes' + $this->config->getAppValue(Application::APP_ID, 'create_notifications', 'yes') === 'yes' ); $this->initialState->provideInitialState( - Application::APP_ID, 'allowComments', - $this->config->getAppValue('announcementcenter', 'allow_comments', 'yes') === 'yes' + $this->config->getAppValue(Application::APP_ID, 'allow_comments', 'yes') === 'yes' ); - return new TemplateResponse('announcementcenter', 'main'); - } - - /** - * @NoAdminRequired - * - * @param string $pattern - * @return JSONResponse - */ - public function searchGroups($pattern): JSONResponse { - if (!$this->manager->checkIsAdmin()) { - return new JSONResponse( - ['message' => 'Logged in user must be an admin'], - Http::STATUS_FORBIDDEN - ); - } - - $groups = $this->groupManager->search($pattern, 10); - $gids = []; - foreach ($groups as $group) { - $gids[] = $group->getGID(); - } - - return new JSONResponse($gids); + return new TemplateResponse(Application::APP_ID, 'main'); } } diff --git a/tests/Controller/APIControllerTest.php b/tests/Controller/APIControllerTest.php new file mode 100644 index 00000000..1386d397 --- /dev/null +++ b/tests/Controller/APIControllerTest.php @@ -0,0 +1,425 @@ + + * + * @author Joas Schilling + * + * @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 . + * + */ + +namespace OCA\AnnouncementCenter\Tests\Controller; + +use OCA\AnnouncementCenter\Controller\APIController; +use OCA\AnnouncementCenter\Manager; +use OCA\AnnouncementCenter\Model\Announcement; +use OCA\AnnouncementCenter\Tests\TestCase; +use OCP\AppFramework\Http; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use OCP\IConfig; +use OCP\IGroupManager; +use OCP\IInitialStateService; +use OCP\IL10N; +use OCP\IRequest; +use OCP\IUserManager; +use OCP\IUserSession; +use OCP\IUser; +use OCP\AppFramework\Http\DataResponse; +use OCP\IGroup; +use PHPUnit\Framework\MockObject\MockBuilder; +use PHPUnit\Framework\MockObject\MockObject; + +/** + * @package OCA\AnnouncementCenter\Tests\Controller + */ +class APIControllerTest extends TestCase { + /** @var IRequest|MockObject */ + protected $request; + /** @var IGroupManager|MockObject */ + protected $groupManager; + /** @var IUserManager|MockObject */ + protected $userManager; + /** @var IJobList|MockObject */ + protected $jobList; + /** @var IL10N|MockObject */ + protected $l; + /** @var Manager|MockObject */ + protected $manager; + /** @var IConfig|MockObject */ + protected $config; + /** @var ITimeFactory|MockObject */ + protected $timeFactory; + /** @var IUserSession|MockObject */ + protected $userSession; + /** @var IInitialStateService|MockObject */ + protected $initialStateService; + + protected function setUp(): void { + parent::setUp(); + + $this->request = $this->createMock(IRequest::class); + $this->groupManager = $this->createMock(IGroupManager::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->jobList = $this->createMock(IJobList::class); + $this->l = $this->createMock(IL10N::class); + $this->manager = $this->createMock(Manager::class); + $this->timeFactory = $this->createMock(ITimeFactory::class); + $this->userSession = $this->createMock(IUserSession::class); + + $this->l + ->method('t') + ->willReturnCallback(function ($string, $args) { + return vsprintf($string, $args); + }); + } + + protected function getController(array $methods = []): APIController { + if (empty($methods)) { + return new APIController( + 'announcementcenter', + $this->request, + $this->groupManager, + $this->userManager, + $this->jobList, + $this->l, + $this->manager, + $this->timeFactory, + $this->userSession, + ); + } + + /** @var APIController|MockBuilder $mock */ + $mock = $this->getMockBuilder(APIController::class); + return $mock->setConstructorArgs([ + 'announcementcenter', + $this->request, + $this->groupManager, + $this->userManager, + $this->jobList, + $this->l, + $this->manager, + $this->timeFactory, + $this->userSession, + ]) + ->setMethods($methods) + ->getMock(); + } + + protected function getUserMock(string $uid, string $displayName): IUser { + /** @var IUser|MockObject $user */ + $user = $this->createMock(IUser::class); + $user + ->method('getUID') + ->willReturn($uid); + $user + ->method('getDisplayName') + ->willReturn($displayName); + return $user; + } + + public function dataGet(): array { + return [ + [0, [], [], []], + [1, [], [], []], + [2, [], [], []], + [ + 1, + [ + ['id' => 1337, 'author' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message #1', 'time' => 1440672792, 'groups' => ['gid1'], 'comments' => false], + ], [], + [ + ['id' => 1337, 'author' => 'author1', 'author_id' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message #1', 'time' => 1440672792, 'groups' => ['gid1'], 'comments' => false], + ], + ], + [ + 1, + [ + ['id' => 23, 'author' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message #1', 'time' => 1440672792, 'groups' => ['gid1'], 'comments' => false], + ], + [ + ['author1', $this->getUserMock('author1', 'Author One')], + ], + [ + ['id' => 23, 'author' => 'Author One', 'author_id' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message #1', 'time' => 1440672792, 'groups' => ['gid1'], 'comments' => false], + ], + ], + [ + 1, + [ + ['id' => 42, 'author' => 'author1', 'subject' => "Subject\n#1", 'message' => "Message\n#1", 'time' => 1440672792, 'groups' => null, 'comments' => 31], + ], + [], + [ + ['id' => 42, 'author' => 'author1', 'author_id' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message
<html>#1</html>', 'time' => 1440672792, 'groups' => null, 'comments' => 31], + ], + ], + ]; + } + + /** + * @dataProvider dataGet + * @param int $offset + * @param array $announcements + * @param array $userMap + * @param array $expected + */ + public function legacyTestGet($offset, $announcements, $userMap, $expected) { + $this->userManager + ->method('get') + ->willReturnMap($userMap); + + $comments = []; + $announcements = array_map(function (array $data) use (&$comments) { + $announcement = new Announcement(); + $announcement->setId($data['id']); + $announcement->setUser($data['author']); + $announcement->setSubject($data['subject']); + $announcement->setMessage($data['message']); + $announcement->setTime($data['time']); + $announcement->setAllowComments($data['comments'] === false ? 0 : 1); + + if ($data['comments'] !== false) { + $comments[] = [$announcement, $data['comments']]; + } + + return $announcement; + }, $announcements); + + $this->manager + ->method('getAnnouncements') + ->with($offset) + ->willReturn($announcements); + + $this->manager->expects(self::exactly(count($comments))) + ->method('getNumberOfComments') + ->willReturnMap($comments); + + $controller = $this->getController(); + $jsonResponse = $controller->get($offset); + + self::assertEquals($expected, $jsonResponse->getData()); + } + + public function dataDelete(): array { + return [ + [42, true, Http::STATUS_OK], + [1337, false, Http::STATUS_FORBIDDEN], + ]; + } + + /** + * @dataProvider dataDelete + * @param int $id + * @param bool $isAdmin + * @param int $statusCode + */ + public function testDelete($id, $isAdmin, $statusCode) { + $this->manager->expects(self::once()) + ->method('checkIsAdmin') + ->willReturn($isAdmin); + + if ($isAdmin) { + $this->manager->expects(self::once()) + ->method('delete') + ->with($id); + } else { + $this->manager->expects(self::never()) + ->method('delete'); + } + + $controller = $this->getController(); + $response = $controller->delete($id); + + self::assertEquals($statusCode, $response->getStatus()); + } + + public function dataAddThrows() { + return [ + ['', ['error' => 'The subject is too long or empty']], + [str_repeat('a', 513), ['error' => 'The subject is too long or empty']], + ]; + } + + /** + * @dataProvider dataAddThrows + * @param string $subject + * @param array $expectedData + */ + public function testAddThrows($subject, array $expectedData) { + $this->manager->expects(self::once()) + ->method('checkIsAdmin') + ->willReturn(true); + $this->userSession->expects(self::once()) + ->method('getUser') + ->willReturn($this->getUserMock('author', 'author')); + + $this->manager->expects(self::once()) + ->method('announce') + ->with($subject, '', 'author', self::anything()) + ->willThrowException(new \InvalidArgumentException()); + + $controller = $this->getController(['createPublicity']); + $controller->expects(self::never()) + ->method('createPublicity'); + + $response = $controller->add($subject, '', [], true, true, true); + + self::assertInstanceOf(DataResponse::class, $response); + self::assertSame($expectedData, $response->getData()); + } + + public function testAddNoAdmin() { + $this->manager->expects(self::once()) + ->method('checkIsAdmin') + ->willReturn(false); + + $this->manager->expects(self::never()) + ->method('announce'); + $this->jobList->expects(self::never()) + ->method('add'); + + $controller = $this->getController(['createPublicity']); + $controller->expects(self::never()) + ->method('createPublicity'); + + $response = $controller->add('subject', '', [], true, true, true); + + self::assertInstanceOf(DataResponse::class, $response); + self::assertSame(Http::STATUS_FORBIDDEN, $response->getStatus()); + } + + public function dataAdd() { + return [ + ['subject1', 'message1', ['gid1'], true, true, false], + ['subject2', 'message2', ['gid2'], true, false, false], + ['subject3', 'message3', ['gid3'], false, true, false], + ['subject4', 'message4', ['gid4'], false, false, false], + ['subject4', 'message4', ['gid4'], false, false, true], + ]; + } + + /** + * @dataProvider dataAdd + * + * @param string $subject + * @param string $message + * @param array $groups + * @param bool $activities + * @param bool $notifications + * @param bool $comments + */ + public function legacyTestAdd($subject, $message, array $groups, $activities, $notifications, $comments) { + $this->manager->expects(self::once()) + ->method('checkIsAdmin') + ->willReturn(true); + $this->userSession->expects(self::once()) + ->method('getUser') + ->willReturn($this->getUserMock('author', 'author')); + + $this->manager->expects(self::once()) + ->method('announce') + ->with($subject, $message, 'author', self::anything(), $groups, $comments) + ->willReturn([ + 'author' => 'author', + 'subject' => $subject, + 'message' => $message, + 'time' => time(), + 'id' => 10, + 'comments' => $comments, + ]); + $this->userManager->expects(self::once()) + ->method('get') + ->with('author') + ->willReturn($this->getUserMock('author', 'Author')); + $this->jobList->expects(($activities || $notifications) ? self::once() : self::never()) + ->method('add') + ->with('OCA\AnnouncementCenter\BackgroundJob', [ + 'id' => 10, + 'activities' => $activities, + 'notifications' => $notifications, + ]); + + $controller = $this->getController(); + + $response = $controller->add($subject, $message, $groups, $activities, $notifications, $comments); + + self::assertInstanceOf(DataResponse::class, $response); + $data = $response->getData(); + self::assertArrayHasKey('time', $data); + self::assertInternalType('int', $data['time']); + unset($data['time']); + self::assertEquals([ + 'author' => 'Author', + 'author_id' => 'author', + 'subject' => $subject, + 'message' => $message, + 'id' => 10, + 'comments' => $comments, + 'notifications' => $notifications, + ], $data); + } + + protected function getGroupMock(string $gid): IGroup { + /** @var IGroup|MockObject $group */ + $group = $this->createMock(IGroup::class); + + $group + ->method('getGID') + ->willReturn($gid); + $group + ->method('getDisplayName') + ->willReturn($gid . '-displayname'); + + return $group; + } + + public function dataSearchGroup(): array { + return [ + [true, 'gid', [], [], Http::STATUS_OK], + [true, 'gid', [$this->getGroupMock('gid1'), $this->getGroupMock('gid2')], [['id' => 'gid1', 'label' => 'gid1-displayname'], ['id' => 'gid2', 'label' => 'gid2-displayname']], Http::STATUS_OK], + [false, '', null, ['message' => 'Logged in user must be an admin'], Http::STATUS_FORBIDDEN], + ]; + } + + /** + * @dataProvider dataSearchGroup + * @param bool $isAdmin + * @param string $pattern + * @param array|null $groupSearch + * @param string $expected + * @param int $code + */ + public function testSearchGroup(bool $isAdmin, string $pattern, $groupSearch, array $expected, int $code) { + $this->manager->expects(self::once()) + ->method('checkIsAdmin') + ->willReturn($isAdmin); + + if ($groupSearch !== null) { + $this->groupManager->expects(self::once()) + ->method('search') + ->willReturn($groupSearch); + } else { + $this->groupManager->expects(self::never()) + ->method('search'); + } + + $controller = $this->getController(); + $response = $controller->searchGroups($pattern); + self::assertSame($code, $response->getStatus()); + self::assertSame($expected, $response->getData()); + } +} diff --git a/tests/Controller/PageControllerTest.php b/tests/Controller/PageControllerTest.php index d4755c5f..5725da78 100644 --- a/tests/Controller/PageControllerTest.php +++ b/tests/Controller/PageControllerTest.php @@ -23,366 +23,44 @@ namespace OCA\AnnouncementCenter\Tests\Controller; -use OCA\AnnouncementCenter\AppInfo\Application; use OCA\AnnouncementCenter\Controller\PageController; use OCA\AnnouncementCenter\Manager; -use OCA\AnnouncementCenter\Model\Announcement; use OCA\AnnouncementCenter\Tests\TestCase; -use OCP\AppFramework\Http; -use OCP\AppFramework\Utility\ITimeFactory; -use OCP\BackgroundJob\IJobList; +use OCP\AppFramework\Services\IInitialState; use OCP\IConfig; -use OCP\IGroupManager; -use OCP\IInitialStateService; -use OCP\IL10N; use OCP\IRequest; -use OCP\IUserManager; -use OCP\IUserSession; -use OCP\IUser; -use OCP\AppFramework\Http\JSONResponse; -use OCP\IGroup; -use PHPUnit\Framework\MockObject\MockBuilder; use PHPUnit\Framework\MockObject\MockObject; /** - * Class PageController - * * @package OCA\AnnouncementCenter\Tests\Controller - * @group DB */ class PageControllerTest extends TestCase { /** @var IRequest|MockObject */ protected $request; - /** @var IGroupManager|MockObject */ - protected $groupManager; - /** @var IUserManager|MockObject */ - protected $userManager; - /** @var IJobList|MockObject */ - protected $jobList; - /** @var IL10N|MockObject */ - protected $l; /** @var Manager|MockObject */ protected $manager; /** @var IConfig|MockObject */ protected $config; - /** @var ITimeFactory|MockObject */ - protected $timeFactory; - /** @var IUserSession|MockObject */ - protected $userSession; - /** @var IInitialStateService|MockObject */ - protected $initialStateService; + /** @var IInitialState|MockObject */ + protected $initialState; protected function setUp(): void { parent::setUp(); $this->request = $this->createMock(IRequest::class); - $this->groupManager = $this->createMock(IGroupManager::class); - $this->userManager = $this->createMock(IUserManager::class); - $this->l = $this->createMock(IL10N::class); - $this->jobList = $this->createMock(IJobList::class); $this->manager = $this->createMock(Manager::class); $this->config = $this->createMock(IConfig::class); - $this->timeFactory = $this->createMock(ITimeFactory::class); - $this->userSession = $this->createMock(IUserSession::class); - $this->initialStateService = $this->createMock(IInitialStateService::class); - - $this->l - ->method('t') - ->willReturnCallback(function ($string, $args) { - return vsprintf($string, $args); - }); + $this->initialState = $this->createMock(IInitialState::class); } - protected function getController(array $methods = []): PageController { - if (empty($methods)) { - return new PageController( - 'announcementcenter', - $this->request, - \OC::$server->getDatabaseConnection(), - $this->groupManager, - $this->userManager, - $this->jobList, - $this->l, - $this->manager, - $this->config, - $this->timeFactory, - $this->userSession, - $this->initialStateService - ); - } - - /** @var PageController|MockBuilder $mock */ - $mock = $this->getMockBuilder(PageController::class); - return $mock->setConstructorArgs([ + protected function getController(): PageController { + return new PageController( 'announcementcenter', $this->request, - \OC::$server->getDatabaseConnection(), - $this->groupManager, - $this->userManager, - $this->jobList, - $this->l, $this->manager, $this->config, - $this->timeFactory, - $this->userSession, - $this->initialStateService, - ]) - ->setMethods($methods) - ->getMock(); - } - - protected function getUserMock(string $uid, string $displayName): IUser { - /** @var IUser|MockObject $user */ - $user = $this->createMock(IUser::class); - $user - ->method('getUID') - ->willReturn($uid); - $user - ->method('getDisplayName') - ->willReturn($displayName); - return $user; - } - - public function dataGet(): array { - return [ - [0, [], [], []], - [1, [], [], []], - [2, [], [], []], - [ - 1, - [ - ['id' => 1337, 'author' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message #1', 'time' => 1440672792, 'groups' => ['gid1'], 'comments' => false], - ], [], - [ - ['id' => 1337, 'author' => 'author1', 'author_id' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message #1', 'time' => 1440672792, 'groups' => ['gid1'], 'comments' => false], - ], - ], - [ - 1, - [ - ['id' => 23, 'author' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message #1', 'time' => 1440672792, 'groups' => ['gid1'], 'comments' => false], - ], - [ - ['author1', $this->getUserMock('author1', 'Author One')], - ], - [ - ['id' => 23, 'author' => 'Author One', 'author_id' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message #1', 'time' => 1440672792, 'groups' => ['gid1'], 'comments' => false], - ], - ], - [ - 1, - [ - ['id' => 42, 'author' => 'author1', 'subject' => "Subject\n#1", 'message' => "Message\n#1", 'time' => 1440672792, 'groups' => null, 'comments' => 31], - ], - [], - [ - ['id' => 42, 'author' => 'author1', 'author_id' => 'author1', 'subject' => 'Subject #1', 'message' => 'Message
<html>#1</html>', 'time' => 1440672792, 'groups' => null, 'comments' => 31], - ], - ], - ]; - } - - /** - * @dataProvider dataGet - * @param int $offset - * @param array $announcements - * @param array $userMap - * @param array $expected - */ - public function legacyTestGet($offset, $announcements, $userMap, $expected) { - $this->userManager - ->method('get') - ->willReturnMap($userMap); - - $comments = []; - $announcements = array_map(function (array $data) use (&$comments) { - $announcement = new Announcement(); - $announcement->setId($data['id']); - $announcement->setUser($data['author']); - $announcement->setSubject($data['subject']); - $announcement->setMessage($data['message']); - $announcement->setTime($data['time']); - $announcement->setAllowComments($data['comments'] === false ? 0 : 1); - - if ($data['comments'] !== false) { - $comments[] = [$announcement, $data['comments']]; - } - - return $announcement; - }, $announcements); - - $this->manager - ->method('getAnnouncements') - ->with($offset) - ->willReturn($announcements); - - $this->manager->expects(self::exactly(count($comments))) - ->method('getNumberOfComments') - ->willReturnMap($comments); - - $controller = $this->getController(); - $jsonResponse = $controller->get($offset); - - self::assertEquals($expected, $jsonResponse->getData()); - } - - public function dataDelete(): array { - return [ - [42, true, Http::STATUS_OK], - [1337, false, Http::STATUS_FORBIDDEN], - ]; - } - - /** - * @dataProvider dataDelete - * @param int $id - * @param bool $isAdmin - * @param int $statusCode - */ - public function testDelete($id, $isAdmin, $statusCode) { - $this->manager->expects(self::once()) - ->method('checkIsAdmin') - ->willReturn($isAdmin); - - if ($isAdmin) { - $this->manager->expects(self::once()) - ->method('delete') - ->with($id); - } else { - $this->manager->expects(self::never()) - ->method('delete'); - } - - $controller = $this->getController(); - $response = $controller->delete($id); - - self::assertEquals($statusCode, $response->getStatus()); - } - - public function dataAddThrows() { - return [ - ['', ['error' => 'The subject is too long or empty']], - [str_repeat('a', 513), ['error' => 'The subject is too long or empty']], - ]; - } - - /** - * @dataProvider dataAddThrows - * @param string $subject - * @param array $expectedData - */ - public function testAddThrows($subject, array $expectedData) { - $this->manager->expects(self::once()) - ->method('checkIsAdmin') - ->willReturn(true); - $this->userSession->expects(self::once()) - ->method('getUser') - ->willReturn($this->getUserMock('author', 'author')); - - $this->manager->expects(self::once()) - ->method('announce') - ->with($subject, '', 'author', self::anything()) - ->willThrowException(new \InvalidArgumentException()); - - $controller = $this->getController(['createPublicity']); - $controller->expects(self::never()) - ->method('createPublicity'); - - $response = $controller->add($subject, '', [], true, true, true); - - self::assertInstanceOf(JSONResponse::class, $response); - self::assertSame($expectedData, $response->getData()); - } - - public function testAddNoAdmin() { - $this->manager->expects(self::once()) - ->method('checkIsAdmin') - ->willReturn(false); - - $this->manager->expects(self::never()) - ->method('announce'); - $this->jobList->expects(self::never()) - ->method('add'); - - $controller = $this->getController(['createPublicity']); - $controller->expects(self::never()) - ->method('createPublicity'); - - $response = $controller->add('subject', '', [], true, true, true); - - self::assertInstanceOf(JSONResponse::class, $response); - self::assertSame(Http::STATUS_FORBIDDEN, $response->getStatus()); - } - - public function dataAdd() { - return [ - ['subject1', 'message1', ['gid1'], true, true, false], - ['subject2', 'message2', ['gid2'], true, false, false], - ['subject3', 'message3', ['gid3'], false, true, false], - ['subject4', 'message4', ['gid4'], false, false, false], - ['subject4', 'message4', ['gid4'], false, false, true], - ]; - } - - /** - * @dataProvider dataAdd - * - * @param string $subject - * @param string $message - * @param array $groups - * @param bool $activities - * @param bool $notifications - * @param bool $comments - */ - public function legacyTestAdd($subject, $message, array $groups, $activities, $notifications, $comments) { - $this->manager->expects(self::once()) - ->method('checkIsAdmin') - ->willReturn(true); - $this->userSession->expects(self::once()) - ->method('getUser') - ->willReturn($this->getUserMock('author', 'author')); - - $this->manager->expects(self::once()) - ->method('announce') - ->with($subject, $message, 'author', self::anything(), $groups, $comments) - ->willReturn([ - 'author' => 'author', - 'subject' => $subject, - 'message' => $message, - 'time' => time(), - 'id' => 10, - 'comments' => $comments, - ]); - $this->userManager->expects(self::once()) - ->method('get') - ->with('author') - ->willReturn($this->getUserMock('author', 'Author')); - $this->jobList->expects(($activities || $notifications) ? self::once() : self::never()) - ->method('add') - ->with('OCA\AnnouncementCenter\BackgroundJob', [ - 'id' => 10, - 'activities' => $activities, - 'notifications' => $notifications, - ]); - - $controller = $this->getController(); - - $response = $controller->add($subject, $message, $groups, $activities, $notifications, $comments); - - self::assertInstanceOf(JSONResponse::class, $response); - $data = $response->getData(); - self::assertArrayHasKey('time', $data); - self::assertInternalType('int', $data['time']); - unset($data['time']); - self::assertEquals([ - 'author' => 'Author', - 'author_id' => 'author', - 'subject' => $subject, - 'message' => $message, - 'id' => 10, - 'comments' => $comments, - 'notifications' => $notifications, - ], $data); + $this->initialState + ); } public function dataIndex(): array { @@ -404,23 +82,21 @@ public function dataIndex(): array { * @param bool $allowComments */ public function testIndex(bool $isAdmin, string $createActivitiesConfig, bool $createActivities, string $createNotificationsConfig, bool $createNotifications, string $allowCommentsConfig, bool $allowComments) { - $this->manager->expects(self::once()) - ->method('checkIsAdmin') + $this->manager->method('checkIsAdmin') ->willReturn($isAdmin); - $this->config->expects(self::exactly(3)) - ->method('getAppValue') + $this->config->method('getAppValue') ->willReturnMap([ ['announcementcenter', 'create_activities', 'yes', $createActivitiesConfig], ['announcementcenter', 'create_notifications', 'yes', $createNotificationsConfig], ['announcementcenter', 'allow_comments', 'yes', $allowCommentsConfig], ]); - $this->initialStateService->method('provideInitialState') + $this->initialState->method('provideInitialState') ->withConsecutive( - [Application::APP_ID, 'isAdmin', $isAdmin], - [Application::APP_ID, 'createActivities', $createActivities], - [Application::APP_ID, 'createNotifications', $createNotifications], - [Application::APP_ID, 'allowComments', $allowComments] + ['isAdmin', $isAdmin], + ['createActivities', $createActivities], + ['createNotifications', $createNotifications], + ['allowComments', $allowComments] ); $controller = $this->getController(); @@ -430,50 +106,4 @@ public function testIndex(bool $isAdmin, string $createActivitiesConfig, bool $c self::assertSame('main', $response->getTemplateName()); } - protected function getGroupMock(string $gid): IGroup { - /** @var IGroup|MockObject $group */ - $group = $this->createMock(IGroup::class); - - $group - ->method('getGID') - ->willReturn($gid); - - return $group; - } - - public function dataSearchGroup(): array { - return [ - [true, 'gid', [], [], Http::STATUS_OK], - [true, 'gid', [$this->getGroupMock('gid1'), $this->getGroupMock('gid2')], ['gid1', 'gid2'], Http::STATUS_OK], - [false, '', null, ['message' => 'Logged in user must be an admin'], Http::STATUS_FORBIDDEN], - ]; - } - - /** - * @dataProvider dataSearchGroup - * @param bool $isAdmin - * @param string $pattern - * @param array|null $groupSearch - * @param string $expected - * @param int $code - */ - public function testSearchGroup(bool $isAdmin, string $pattern, $groupSearch, array $expected, int $code) { - $this->manager->expects(self::once()) - ->method('checkIsAdmin') - ->willReturn($isAdmin); - - if ($groupSearch !== null) { - $this->groupManager->expects(self::once()) - ->method('search') - ->willReturn($groupSearch); - } else { - $this->groupManager->expects(self::never()) - ->method('search'); - } - - $controller = $this->getController(); - $response = $controller->searchGroups($pattern); - self::assertSame($code, $response->getStatus()); - self::assertSame($expected, $response->getData()); - } }