diff --git a/lib/Controller/MailboxesApiController.php b/lib/Controller/MailboxesApiController.php new file mode 100644 index 0000000000..79a3a98934 --- /dev/null +++ b/lib/Controller/MailboxesApiController.php @@ -0,0 +1,120 @@ +, array{}>|DataResponse + * + * 200: Mailbox list + * 404: User was not logged in or account doesn't exist + */ + #[ApiRoute(verb: 'GET', url: 'ocs/mailboxes')] + #[NoAdminRequired] + #[NoCSRFRequired] + public function list(int $accountId): DataResponse { + $userId = $this->userId; + if ($userId === null) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + try { + $account = $this->accountService->find($userId, $accountId); + } catch (DoesNotExistException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + $mailboxes = $this->mailManager->getMailboxes($account); + return new DataResponse($mailboxes, Http::STATUS_OK); + } + + + + /** + * List the newest messages in a mailbox of the user which is currently logged-in + * + * @param int $mailboxId the mailbox id + * @param int $cursor the query cursor + * @param string $filter the query filter + * @param int|null $limit the number of messages to be returned, can be left ampty to get all messages + * @param string $view returns messages in requested view ('singleton' or 'threaded') + * @param string|null $v Cache buster version to guarantee unique urls (will trigger HTTP caching if set) + * @return DataResponse, array{}>|DataResponse|DataResponse + * + * 200: Message list + * 403: User cannot access this mailbox + * 404: User was not logged in + */ + #[ApiRoute(verb: 'GET', url: 'ocs/mailboxes/{mailboxId}/messages')] + #[NoAdminRequired] + #[NoCSRFRequired] + public function listMessages(int $mailboxId, + ?int $cursor = null, + ?string $filter = null, + ?int $limit = null, + ?string $view = null): DataResponse { + $userId = $this->userId; + if ($userId === null) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + try { + $mailbox = $this->mailManager->getMailbox($userId, $mailboxId); + $account = $this->accountService->find($userId, $mailbox->getAccountId()); + } catch (DoesNotExistException $e) { + return new DataResponse([], Http::STATUS_FORBIDDEN); + } + + $sort = IMailSearch::ORDER_NEWEST_FIRST; + + $view = $view === 'singleton' ? IMailSearch::VIEW_SINGLETON : IMailSearch::VIEW_THREADED; + + $messages = $this->mailSearch->findMessages( + $account, + $mailbox, + $sort, + $filter === '' ? null : $filter, + $cursor, + $limit, + $userId, + $view + ); + return new DataResponse($messages, Http::STATUS_OK); + } +} diff --git a/tests/Unit/Controller/MailboxesApiControllerTest.php b/tests/Unit/Controller/MailboxesApiControllerTest.php new file mode 100644 index 0000000000..9c0bdbbd21 --- /dev/null +++ b/tests/Unit/Controller/MailboxesApiControllerTest.php @@ -0,0 +1,175 @@ +request = $this->createMock(IRequest::class); + $this->accountService = $this->createMock(AccountService::class); + $this->mailManager = $this->createMock(IMailManager::class); + $this->mailSearch = $this->createMock(IMailSearch::class); + + $this->controller = new MailboxesApiController( + 'mail', + $this->request, + self::USER_ID, + $this->mailManager, + $this->accountService, + $this->mailSearch, + + ); + } + + public function testListMailboxesWithoutUser() { + $controller = new MailboxesApiController( + 'mail', + $this->request, + null, + $this->mailManager, + $this->accountService, + $this->mailSearch, + ); + + $this->accountService->expects(self::never()) + ->method('find'); + + $accountId = 28; + + $actual = $controller->list($accountId); + $this->assertEquals(Http::STATUS_NOT_FOUND, $actual->getStatus()); + } + + + public function testListMailboxes() { + $account = $this->createMock(Account::class); + $folder = $this->createMock(Folder::class); + $accountId = 42; + $this->accountService->expects($this->once()) + ->method('find') + ->with($this->equalTo(self::USER_ID), $this->equalTo($accountId)) + ->willReturn($account); + $this->mailManager->expects($this->once()) + ->method('getMailboxes') + ->with($this->equalTo($account)) + ->willReturn([ + $folder + ]); + $actual = $this->controller->list($accountId); + + $this->assertEquals(Http::STATUS_OK, $actual->getStatus()); + $this->assertEquals([$folder], $actual->getData()); + } + + public function testListMessagesWithoutUser() { + $controller = new MailboxesApiController( + 'mail', + $this->request, + null, + $this->mailManager, + $this->accountService, + $this->mailSearch, + ); + + $this->accountService->expects(self::never()) + ->method('find'); + + $accountId = 28; + + $actual = $controller->listMessages($accountId); + $this->assertEquals(Http::STATUS_NOT_FOUND, $actual->getStatus()); + } + + + public function testListMessages(): void { + $accountId = 100; + $mailboxId = 101; + $mailbox = new Mailbox(); + $mailbox->setAccountId($accountId); + $this->mailManager->expects(self::once()) + ->method('getMailbox') + ->with(SELF::USER_ID, $mailboxId) + ->willReturn($mailbox); + $mailAccount = new MailAccount(); + $account = new Account($mailAccount); + $this->accountService->expects(self::once()) + ->method('find') + ->with(SELF::USER_ID, $accountId) + ->willReturn($account); + + $messages = [ + new DbMessage(), + new DbMessage(), + ]; + $this->mailSearch->expects(self::once()) + ->method('findMessages') + ->with( + $account, + $mailbox, + 'DESC', + null, + null, + null, + SELF::USER_ID, + 'threaded', + )->willReturn($messages); + + $actual = $this->controller->listMessages($mailboxId); + + $this->assertEquals(Http::STATUS_OK, $actual->getStatus()); + $this->assertEquals($messages, $actual->getData()); + } + + public function testListMessagesInvalidMailbox(): void { + $accountId = 100; + $mailboxId = 101; + $mailbox = new Mailbox(); + $mailbox->setAccountId($accountId); + $this->mailManager->expects(self::once()) + ->method('getMailbox') + ->with(SELF::USER_ID, $mailboxId) + ->willThrowException(new DoesNotExistException('')); + $this->accountService->expects(self::never()) + ->method('find'); + + + $actual = $this->controller->listMessages($mailboxId); + + $this->assertEquals(Http::STATUS_FORBIDDEN, $actual->getStatus()); + } + + + +}