123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755 |
- <?php
- /**
- * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-only
- */
- namespace OCA\DAV\Tests\unit\Comments;
- use OC\Comments\Comment;
- use OCA\DAV\Comments\CommentsPlugin as CommentsPluginImplementation;
- use OCA\DAV\Comments\EntityCollection;
- use OCP\Comments\IComment;
- use OCP\Comments\ICommentsManager;
- use OCP\IUser;
- use OCP\IUserSession;
- use Sabre\DAV\INode;
- use Sabre\DAV\Tree;
- use Sabre\HTTP\RequestInterface;
- use Sabre\HTTP\ResponseInterface;
- class CommentsPluginTest extends \Test\TestCase {
- /** @var \Sabre\DAV\Server */
- private $server;
- /** @var Tree */
- private $tree;
- /** @var ICommentsManager */
- private $commentsManager;
- /** @var IUserSession */
- private $userSession;
- /** @var CommentsPluginImplementation */
- private $plugin;
- protected function setUp(): void {
- parent::setUp();
- $this->tree = $this->getMockBuilder(Tree::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->server = $this->getMockBuilder('\Sabre\DAV\Server')
- ->setConstructorArgs([$this->tree])
- ->setMethods(['getRequestUri'])
- ->getMock();
- $this->commentsManager = $this->getMockBuilder(ICommentsManager::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->userSession = $this->getMockBuilder(IUserSession::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->plugin = new CommentsPluginImplementation($this->commentsManager, $this->userSession);
- }
- public function testCreateComment(): void {
- $commentData = [
- 'actorType' => 'users',
- 'verb' => 'comment',
- 'message' => 'my first comment',
- ];
- $comment = new Comment([
- 'objectType' => 'files',
- 'objectId' => '42',
- 'actorType' => 'users',
- 'actorId' => 'alice'
- ] + $commentData);
- $comment->setId('23');
- $path = 'comments/files/42';
- $requestData = json_encode($commentData);
- $user = $this->getMockBuilder(IUser::class)
- ->disableOriginalConstructor()
- ->getMock();
- $user->expects($this->once())
- ->method('getUID')
- ->willReturn('alice');
- $node = $this->getMockBuilder(EntityCollection::class)
- ->disableOriginalConstructor()
- ->getMock();
- $node->expects($this->once())
- ->method('getName')
- ->willReturn('files');
- $node->expects($this->once())
- ->method('getId')
- ->willReturn('42');
- $node->expects($this->once())
- ->method('setReadMarker')
- ->with(null);
- $this->commentsManager->expects($this->once())
- ->method('create')
- ->with('users', 'alice', 'files', '42')
- ->willReturn($comment);
- $this->userSession->expects($this->once())
- ->method('getUser')
- ->willReturn($user);
- // technically, this is a shortcut. Inbetween EntityTypeCollection would
- // be returned, but doing it exactly right would not be really
- // unit-testing like, as it would require to haul in a lot of other
- // things.
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn($node);
- $request = $this->getMockBuilder(RequestInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $response = $this->getMockBuilder(ResponseInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $request->expects($this->once())
- ->method('getPath')
- ->willReturn('/' . $path);
- $request->expects($this->once())
- ->method('getBodyAsString')
- ->willReturn($requestData);
- $request->expects($this->once())
- ->method('getHeader')
- ->with('Content-Type')
- ->willReturn('application/json');
- $request->expects($this->once())
- ->method('getUrl')
- ->willReturn('http://example.com/dav/' . $path);
- $response->expects($this->once())
- ->method('setHeader')
- ->with('Content-Location', 'http://example.com/dav/' . $path . '/23');
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->plugin->initialize($this->server);
- $this->plugin->httpPost($request, $response);
- }
-
- public function testCreateCommentInvalidObject(): void {
- $this->expectException(\Sabre\DAV\Exception\NotFound::class);
- $commentData = [
- 'actorType' => 'users',
- 'verb' => 'comment',
- 'message' => 'my first comment',
- ];
- $comment = new Comment([
- 'objectType' => 'files',
- 'objectId' => '666',
- 'actorType' => 'users',
- 'actorId' => 'alice'
- ] + $commentData);
- $comment->setId('23');
- $path = 'comments/files/666';
- $user = $this->getMockBuilder(IUser::class)
- ->disableOriginalConstructor()
- ->getMock();
- $user->expects($this->never())
- ->method('getUID');
- $node = $this->getMockBuilder(EntityCollection::class)
- ->disableOriginalConstructor()
- ->getMock();
- $node->expects($this->never())
- ->method('getName');
- $node->expects($this->never())
- ->method('getId');
- $this->commentsManager->expects($this->never())
- ->method('create');
- $this->userSession->expects($this->never())
- ->method('getUser');
- // technically, this is a shortcut. Inbetween EntityTypeCollection would
- // be returned, but doing it exactly right would not be really
- // unit-testing like, as it would require to haul in a lot of other
- // things.
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->will($this->throwException(new \Sabre\DAV\Exception\NotFound()));
- $request = $this->getMockBuilder(RequestInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $response = $this->getMockBuilder(ResponseInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $request->expects($this->once())
- ->method('getPath')
- ->willReturn('/' . $path);
- $request->expects($this->never())
- ->method('getBodyAsString');
- $request->expects($this->never())
- ->method('getHeader')
- ->with('Content-Type');
- $request->expects($this->never())
- ->method('getUrl');
- $response->expects($this->never())
- ->method('setHeader');
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->plugin->initialize($this->server);
- $this->plugin->httpPost($request, $response);
- }
-
- public function testCreateCommentInvalidActor(): void {
- $this->expectException(\Sabre\DAV\Exception\BadRequest::class);
- $commentData = [
- 'actorType' => 'robots',
- 'verb' => 'comment',
- 'message' => 'my first comment',
- ];
- $comment = new Comment([
- 'objectType' => 'files',
- 'objectId' => '42',
- 'actorType' => 'users',
- 'actorId' => 'alice'
- ] + $commentData);
- $comment->setId('23');
- $path = 'comments/files/42';
- $requestData = json_encode($commentData);
- $user = $this->getMockBuilder(IUser::class)
- ->disableOriginalConstructor()
- ->getMock();
- $user->expects($this->never())
- ->method('getUID');
- $node = $this->getMockBuilder(EntityCollection::class)
- ->disableOriginalConstructor()
- ->getMock();
- $node->expects($this->once())
- ->method('getName')
- ->willReturn('files');
- $node->expects($this->once())
- ->method('getId')
- ->willReturn('42');
- $this->commentsManager->expects($this->never())
- ->method('create');
- $this->userSession->expects($this->never())
- ->method('getUser');
- // technically, this is a shortcut. Inbetween EntityTypeCollection would
- // be returned, but doing it exactly right would not be really
- // unit-testing like, as it would require to haul in a lot of other
- // things.
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn($node);
- $request = $this->getMockBuilder(RequestInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $response = $this->getMockBuilder(ResponseInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $request->expects($this->once())
- ->method('getPath')
- ->willReturn('/' . $path);
- $request->expects($this->once())
- ->method('getBodyAsString')
- ->willReturn($requestData);
- $request->expects($this->once())
- ->method('getHeader')
- ->with('Content-Type')
- ->willReturn('application/json');
- $request->expects($this->never())
- ->method('getUrl');
- $response->expects($this->never())
- ->method('setHeader');
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->plugin->initialize($this->server);
- $this->plugin->httpPost($request, $response);
- }
-
- public function testCreateCommentUnsupportedMediaType(): void {
- $this->expectException(\Sabre\DAV\Exception\UnsupportedMediaType::class);
- $commentData = [
- 'actorType' => 'users',
- 'verb' => 'comment',
- 'message' => 'my first comment',
- ];
- $comment = new Comment([
- 'objectType' => 'files',
- 'objectId' => '42',
- 'actorType' => 'users',
- 'actorId' => 'alice'
- ] + $commentData);
- $comment->setId('23');
- $path = 'comments/files/42';
- $requestData = json_encode($commentData);
- $user = $this->getMockBuilder(IUser::class)
- ->disableOriginalConstructor()
- ->getMock();
- $user->expects($this->never())
- ->method('getUID');
- $node = $this->getMockBuilder(EntityCollection::class)
- ->disableOriginalConstructor()
- ->getMock();
- $node->expects($this->once())
- ->method('getName')
- ->willReturn('files');
- $node->expects($this->once())
- ->method('getId')
- ->willReturn('42');
- $this->commentsManager->expects($this->never())
- ->method('create');
- $this->userSession->expects($this->never())
- ->method('getUser');
- // technically, this is a shortcut. Inbetween EntityTypeCollection would
- // be returned, but doing it exactly right would not be really
- // unit-testing like, as it would require to haul in a lot of other
- // things.
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn($node);
- $request = $this->getMockBuilder(RequestInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $response = $this->getMockBuilder(ResponseInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $request->expects($this->once())
- ->method('getPath')
- ->willReturn('/' . $path);
- $request->expects($this->once())
- ->method('getBodyAsString')
- ->willReturn($requestData);
- $request->expects($this->once())
- ->method('getHeader')
- ->with('Content-Type')
- ->willReturn('application/trumpscript');
- $request->expects($this->never())
- ->method('getUrl');
- $response->expects($this->never())
- ->method('setHeader');
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->plugin->initialize($this->server);
- $this->plugin->httpPost($request, $response);
- }
-
- public function testCreateCommentInvalidPayload(): void {
- $this->expectException(\Sabre\DAV\Exception\BadRequest::class);
- $commentData = [
- 'actorType' => 'users',
- 'verb' => '',
- 'message' => '',
- ];
- $comment = new Comment([
- 'objectType' => 'files',
- 'objectId' => '42',
- 'actorType' => 'users',
- 'actorId' => 'alice',
- 'message' => 'dummy',
- 'verb' => 'dummy'
- ]);
- $comment->setId('23');
- $path = 'comments/files/42';
- $requestData = json_encode($commentData);
- $user = $this->getMockBuilder(IUser::class)
- ->disableOriginalConstructor()
- ->getMock();
- $user->expects($this->once())
- ->method('getUID')
- ->willReturn('alice');
- $node = $this->getMockBuilder(EntityCollection::class)
- ->disableOriginalConstructor()
- ->getMock();
- $node->expects($this->once())
- ->method('getName')
- ->willReturn('files');
- $node->expects($this->once())
- ->method('getId')
- ->willReturn('42');
- $this->commentsManager->expects($this->once())
- ->method('create')
- ->with('users', 'alice', 'files', '42')
- ->willReturn($comment);
- $this->userSession->expects($this->once())
- ->method('getUser')
- ->willReturn($user);
- // technically, this is a shortcut. Inbetween EntityTypeCollection would
- // be returned, but doing it exactly right would not be really
- // unit-testing like, as it would require to haul in a lot of other
- // things.
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn($node);
- $request = $this->getMockBuilder(RequestInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $response = $this->getMockBuilder(ResponseInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $request->expects($this->once())
- ->method('getPath')
- ->willReturn('/' . $path);
- $request->expects($this->once())
- ->method('getBodyAsString')
- ->willReturn($requestData);
- $request->expects($this->once())
- ->method('getHeader')
- ->with('Content-Type')
- ->willReturn('application/json');
- $request->expects($this->never())
- ->method('getUrl');
- $response->expects($this->never())
- ->method('setHeader');
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->plugin->initialize($this->server);
- $this->plugin->httpPost($request, $response);
- }
-
- public function testCreateCommentMessageTooLong(): void {
- $this->expectException(\Sabre\DAV\Exception\BadRequest::class);
- $this->expectExceptionMessage('Message exceeds allowed character limit of');
- $commentData = [
- 'actorType' => 'users',
- 'verb' => 'comment',
- 'message' => str_pad('', IComment::MAX_MESSAGE_LENGTH + 1, 'x'),
- ];
- $comment = new Comment([
- 'objectType' => 'files',
- 'objectId' => '42',
- 'actorType' => 'users',
- 'actorId' => 'alice',
- 'verb' => 'comment',
- ]);
- $comment->setId('23');
- $path = 'comments/files/42';
- $requestData = json_encode($commentData);
- $user = $this->getMockBuilder(IUser::class)
- ->disableOriginalConstructor()
- ->getMock();
- $user->expects($this->once())
- ->method('getUID')
- ->willReturn('alice');
- $node = $this->getMockBuilder(EntityCollection::class)
- ->disableOriginalConstructor()
- ->getMock();
- $node->expects($this->once())
- ->method('getName')
- ->willReturn('files');
- $node->expects($this->once())
- ->method('getId')
- ->willReturn('42');
- $node->expects($this->never())
- ->method('setReadMarker');
- $this->commentsManager->expects($this->once())
- ->method('create')
- ->with('users', 'alice', 'files', '42')
- ->willReturn($comment);
- $this->userSession->expects($this->once())
- ->method('getUser')
- ->willReturn($user);
- // technically, this is a shortcut. Inbetween EntityTypeCollection would
- // be returned, but doing it exactly right would not be really
- // unit-testing like, as it would require to haul in a lot of other
- // things.
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn($node);
- $request = $this->getMockBuilder(RequestInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $response = $this->getMockBuilder(ResponseInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $request->expects($this->once())
- ->method('getPath')
- ->willReturn('/' . $path);
- $request->expects($this->once())
- ->method('getBodyAsString')
- ->willReturn($requestData);
- $request->expects($this->once())
- ->method('getHeader')
- ->with('Content-Type')
- ->willReturn('application/json');
- $response->expects($this->never())
- ->method('setHeader');
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->plugin->initialize($this->server);
- $this->plugin->httpPost($request, $response);
- }
-
- public function testOnReportInvalidNode(): void {
- $this->expectException(\Sabre\DAV\Exception\ReportNotSupported::class);
- $path = 'totally/unrelated/13';
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn(
- $this->getMockBuilder(INode::class)
- ->disableOriginalConstructor()
- ->getMock()
- );
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->plugin->initialize($this->server);
- $this->plugin->onReport(CommentsPluginImplementation::REPORT_NAME, [], '/' . $path);
- }
-
- public function testOnReportInvalidReportName(): void {
- $this->expectException(\Sabre\DAV\Exception\ReportNotSupported::class);
- $path = 'comments/files/42';
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn(
- $this->getMockBuilder(INode::class)
- ->disableOriginalConstructor()
- ->getMock()
- );
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->plugin->initialize($this->server);
- $this->plugin->onReport('{whoever}whatever', [], '/' . $path);
- }
- public function testOnReportDateTimeEmpty(): void {
- $path = 'comments/files/42';
- $parameters = [
- [
- 'name' => '{http://owncloud.org/ns}limit',
- 'value' => 5,
- ],
- [
- 'name' => '{http://owncloud.org/ns}offset',
- 'value' => 10,
- ],
- [
- 'name' => '{http://owncloud.org/ns}datetime',
- 'value' => '',
- ]
- ];
- $node = $this->getMockBuilder(EntityCollection::class)
- ->disableOriginalConstructor()
- ->getMock();
- $node->expects($this->once())
- ->method('findChildren')
- ->with(5, 10, null)
- ->willReturn([]);
- $response = $this->getMockBuilder(ResponseInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $response->expects($this->once())
- ->method('setHeader')
- ->with('Content-Type', 'application/xml; charset=utf-8');
- $response->expects($this->once())
- ->method('setStatus')
- ->with(207);
- $response->expects($this->once())
- ->method('setBody');
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn($node);
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->server->httpResponse = $response;
- $this->plugin->initialize($this->server);
- $this->plugin->onReport(CommentsPluginImplementation::REPORT_NAME, $parameters, '/' . $path);
- }
- public function testOnReport(): void {
- $path = 'comments/files/42';
- $parameters = [
- [
- 'name' => '{http://owncloud.org/ns}limit',
- 'value' => 5,
- ],
- [
- 'name' => '{http://owncloud.org/ns}offset',
- 'value' => 10,
- ],
- [
- 'name' => '{http://owncloud.org/ns}datetime',
- 'value' => '2016-01-10 18:48:00',
- ]
- ];
- $node = $this->getMockBuilder(EntityCollection::class)
- ->disableOriginalConstructor()
- ->getMock();
- $node->expects($this->once())
- ->method('findChildren')
- ->with(5, 10, new \DateTime($parameters[2]['value']))
- ->willReturn([]);
- $response = $this->getMockBuilder(ResponseInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $response->expects($this->once())
- ->method('setHeader')
- ->with('Content-Type', 'application/xml; charset=utf-8');
- $response->expects($this->once())
- ->method('setStatus')
- ->with(207);
- $response->expects($this->once())
- ->method('setBody');
- $this->tree->expects($this->any())
- ->method('getNodeForPath')
- ->with('/' . $path)
- ->willReturn($node);
- $this->server->expects($this->any())
- ->method('getRequestUri')
- ->willReturn($path);
- $this->server->httpResponse = $response;
- $this->plugin->initialize($this->server);
- $this->plugin->onReport(CommentsPluginImplementation::REPORT_NAME, $parameters, '/' . $path);
- }
- }
|