CommentsNodeTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. * @author Joas Schilling <coding@schilljs.com>
  7. * @author Morris Jobke <hey@morrisjobke.de>
  8. * @author Roeland Jago Douma <roeland@famdouma.nl>
  9. * @author Vincent Petry <pvince81@owncloud.com>
  10. *
  11. * @license AGPL-3.0
  12. *
  13. * This code is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License, version 3,
  15. * as published by the Free Software Foundation.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Affero General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Affero General Public License, version 3,
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>
  24. *
  25. */
  26. namespace OCA\DAV\Tests\unit\Comments;
  27. use OCA\DAV\Comments\CommentNode;
  28. use OCP\Comments\IComment;
  29. use OCP\Comments\ICommentsManager;
  30. use OCP\Comments\MessageTooLongException;
  31. use OCP\ILogger;
  32. use OCP\IUser;
  33. use OCP\IUserManager;
  34. use OCP\IUserSession;
  35. use Sabre\DAV\PropPatch;
  36. class CommentsNodeTest extends \Test\TestCase {
  37. /** @var ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */
  38. protected $commentsManager;
  39. protected $comment;
  40. protected $node;
  41. protected $userManager;
  42. protected $logger;
  43. protected $userSession;
  44. public function setUp() {
  45. parent::setUp();
  46. $this->commentsManager = $this->getMockBuilder(ICommentsManager::class)
  47. ->disableOriginalConstructor()
  48. ->getMock();
  49. $this->comment = $this->getMockBuilder(IComment::class)
  50. ->disableOriginalConstructor()
  51. ->getMock();
  52. $this->userManager = $this->getMockBuilder(IUserManager::class)
  53. ->disableOriginalConstructor()
  54. ->getMock();
  55. $this->userSession = $this->getMockBuilder(IUserSession::class)
  56. ->disableOriginalConstructor()
  57. ->getMock();
  58. $this->logger = $this->getMockBuilder(ILogger::class)
  59. ->disableOriginalConstructor()
  60. ->getMock();
  61. $this->node = new CommentNode(
  62. $this->commentsManager,
  63. $this->comment,
  64. $this->userManager,
  65. $this->userSession,
  66. $this->logger
  67. );
  68. }
  69. public function testDelete() {
  70. $user = $this->getMockBuilder(IUser::class)
  71. ->disableOriginalConstructor()
  72. ->getMock();
  73. $user->expects($this->once())
  74. ->method('getUID')
  75. ->will($this->returnValue('alice'));
  76. $this->userSession->expects($this->once())
  77. ->method('getUser')
  78. ->will($this->returnValue($user));
  79. $this->comment->expects($this->once())
  80. ->method('getId')
  81. ->will($this->returnValue('19'));
  82. $this->comment->expects($this->any())
  83. ->method('getActorType')
  84. ->will($this->returnValue('users'));
  85. $this->comment->expects($this->any())
  86. ->method('getActorId')
  87. ->will($this->returnValue('alice'));
  88. $this->commentsManager->expects($this->once())
  89. ->method('delete')
  90. ->with('19');
  91. $this->node->delete();
  92. }
  93. /**
  94. * @expectedException \Sabre\DAV\Exception\Forbidden
  95. */
  96. public function testDeleteForbidden() {
  97. $user = $this->getMockBuilder(IUser::class)
  98. ->disableOriginalConstructor()
  99. ->getMock();
  100. $user->expects($this->once())
  101. ->method('getUID')
  102. ->will($this->returnValue('mallory'));
  103. $this->userSession->expects($this->once())
  104. ->method('getUser')
  105. ->will($this->returnValue($user));
  106. $this->comment->expects($this->never())
  107. ->method('getId');
  108. $this->comment->expects($this->any())
  109. ->method('getActorType')
  110. ->will($this->returnValue('users'));
  111. $this->comment->expects($this->any())
  112. ->method('getActorId')
  113. ->will($this->returnValue('alice'));
  114. $this->commentsManager->expects($this->never())
  115. ->method('delete');
  116. $this->node->delete();
  117. }
  118. public function testGetName() {
  119. $id = '19';
  120. $this->comment->expects($this->once())
  121. ->method('getId')
  122. ->will($this->returnValue($id));
  123. $this->assertSame($this->node->getName(), $id);
  124. }
  125. /**
  126. * @expectedException \Sabre\DAV\Exception\MethodNotAllowed
  127. */
  128. public function testSetName() {
  129. $this->node->setName('666');
  130. }
  131. public function testGetLastModified() {
  132. $this->assertSame($this->node->getLastModified(), null);
  133. }
  134. public function testUpdateComment() {
  135. $msg = 'Hello Earth';
  136. $user = $this->getMockBuilder(IUser::class)
  137. ->disableOriginalConstructor()
  138. ->getMock();
  139. $user->expects($this->once())
  140. ->method('getUID')
  141. ->will($this->returnValue('alice'));
  142. $this->userSession->expects($this->once())
  143. ->method('getUser')
  144. ->will($this->returnValue($user));
  145. $this->comment->expects($this->once())
  146. ->method('setMessage')
  147. ->with($msg);
  148. $this->comment->expects($this->any())
  149. ->method('getActorType')
  150. ->will($this->returnValue('users'));
  151. $this->comment->expects($this->any())
  152. ->method('getActorId')
  153. ->will($this->returnValue('alice'));
  154. $this->commentsManager->expects($this->once())
  155. ->method('save')
  156. ->with($this->comment);
  157. $this->assertTrue($this->node->updateComment($msg));
  158. }
  159. /**
  160. * @expectedException \Exception
  161. * @expectedExceptionMessage buh!
  162. */
  163. public function testUpdateCommentLogException() {
  164. $msg = null;
  165. $user = $this->getMockBuilder(IUser::class)
  166. ->disableOriginalConstructor()
  167. ->getMock();
  168. $user->expects($this->once())
  169. ->method('getUID')
  170. ->will($this->returnValue('alice'));
  171. $this->userSession->expects($this->once())
  172. ->method('getUser')
  173. ->will($this->returnValue($user));
  174. $this->comment->expects($this->once())
  175. ->method('setMessage')
  176. ->with($msg)
  177. ->will($this->throwException(new \Exception('buh!')));
  178. $this->comment->expects($this->any())
  179. ->method('getActorType')
  180. ->will($this->returnValue('users'));
  181. $this->comment->expects($this->any())
  182. ->method('getActorId')
  183. ->will($this->returnValue('alice'));
  184. $this->commentsManager->expects($this->never())
  185. ->method('save');
  186. $this->logger->expects($this->once())
  187. ->method('logException');
  188. $this->node->updateComment($msg);
  189. }
  190. /**
  191. * @expectedException \Sabre\DAV\Exception\BadRequest
  192. * @expectedExceptionMessage Message exceeds allowed character limit of
  193. */
  194. public function testUpdateCommentMessageTooLongException() {
  195. $user = $this->getMockBuilder(IUser::class)
  196. ->disableOriginalConstructor()
  197. ->getMock();
  198. $user->expects($this->once())
  199. ->method('getUID')
  200. ->will($this->returnValue('alice'));
  201. $this->userSession->expects($this->once())
  202. ->method('getUser')
  203. ->will($this->returnValue($user));
  204. $this->comment->expects($this->once())
  205. ->method('setMessage')
  206. ->will($this->throwException(new MessageTooLongException()));
  207. $this->comment->expects($this->any())
  208. ->method('getActorType')
  209. ->will($this->returnValue('users'));
  210. $this->comment->expects($this->any())
  211. ->method('getActorId')
  212. ->will($this->returnValue('alice'));
  213. $this->commentsManager->expects($this->never())
  214. ->method('save');
  215. $this->logger->expects($this->once())
  216. ->method('logException');
  217. // imagine 'foo' has >1k characters. comment is mocked anyway.
  218. $this->node->updateComment('foo');
  219. }
  220. /**
  221. * @expectedException \Sabre\DAV\Exception\Forbidden
  222. */
  223. public function testUpdateForbiddenByUser() {
  224. $msg = 'HaXX0r';
  225. $user = $this->getMockBuilder(IUser::class)
  226. ->disableOriginalConstructor()
  227. ->getMock();
  228. $user->expects($this->once())
  229. ->method('getUID')
  230. ->will($this->returnValue('mallory'));
  231. $this->userSession->expects($this->once())
  232. ->method('getUser')
  233. ->will($this->returnValue($user));
  234. $this->comment->expects($this->never())
  235. ->method('setMessage');
  236. $this->comment->expects($this->any())
  237. ->method('getActorType')
  238. ->will($this->returnValue('users'));
  239. $this->comment->expects($this->any())
  240. ->method('getActorId')
  241. ->will($this->returnValue('alice'));
  242. $this->commentsManager->expects($this->never())
  243. ->method('save');
  244. $this->node->updateComment($msg);
  245. }
  246. /**
  247. * @expectedException \Sabre\DAV\Exception\Forbidden
  248. */
  249. public function testUpdateForbiddenByType() {
  250. $msg = 'HaXX0r';
  251. $user = $this->getMockBuilder(IUser::class)
  252. ->disableOriginalConstructor()
  253. ->getMock();
  254. $user->expects($this->never())
  255. ->method('getUID');
  256. $this->userSession->expects($this->once())
  257. ->method('getUser')
  258. ->will($this->returnValue($user));
  259. $this->comment->expects($this->never())
  260. ->method('setMessage');
  261. $this->comment->expects($this->any())
  262. ->method('getActorType')
  263. ->will($this->returnValue('bots'));
  264. $this->commentsManager->expects($this->never())
  265. ->method('save');
  266. $this->node->updateComment($msg);
  267. }
  268. /**
  269. * @expectedException \Sabre\DAV\Exception\Forbidden
  270. */
  271. public function testUpdateForbiddenByNotLoggedIn() {
  272. $msg = 'HaXX0r';
  273. $this->userSession->expects($this->once())
  274. ->method('getUser')
  275. ->will($this->returnValue(null));
  276. $this->comment->expects($this->never())
  277. ->method('setMessage');
  278. $this->comment->expects($this->any())
  279. ->method('getActorType')
  280. ->will($this->returnValue('users'));
  281. $this->commentsManager->expects($this->never())
  282. ->method('save');
  283. $this->node->updateComment($msg);
  284. }
  285. public function testPropPatch() {
  286. $propPatch = $this->getMockBuilder(PropPatch::class)
  287. ->disableOriginalConstructor()
  288. ->getMock();
  289. $propPatch->expects($this->once())
  290. ->method('handle')
  291. ->with('{http://owncloud.org/ns}message');
  292. $this->node->propPatch($propPatch);
  293. }
  294. public function testGetProperties() {
  295. $ns = '{http://owncloud.org/ns}';
  296. $expected = [
  297. $ns . 'id' => '123',
  298. $ns . 'parentId' => '12',
  299. $ns . 'topmostParentId' => '2',
  300. $ns . 'childrenCount' => 3,
  301. $ns . 'message' => 'such a nice file you have…',
  302. $ns . 'mentions' => [
  303. [ $ns . 'mention' => [
  304. $ns . 'mentionType' => 'user',
  305. $ns . 'mentionId' => 'alice',
  306. $ns . 'mentionDisplayName' => 'Alice Al-Isson',
  307. ] ],
  308. [ $ns . 'mention' => [
  309. $ns . 'mentionType' => 'user',
  310. $ns . 'mentionId' => 'bob',
  311. $ns . 'mentionDisplayName' => 'Unknown user',
  312. ] ],
  313. ],
  314. $ns . 'verb' => 'comment',
  315. $ns . 'actorType' => 'users',
  316. $ns . 'actorId' => 'alice',
  317. $ns . 'actorDisplayName' => 'Alice of Wonderland',
  318. $ns . 'creationDateTime' => new \DateTime('2016-01-10 18:48:00'),
  319. $ns . 'latestChildDateTime' => new \DateTime('2016-01-12 18:48:00'),
  320. $ns . 'objectType' => 'files',
  321. $ns . 'objectId' => '1848',
  322. $ns . 'isUnread' => null,
  323. ];
  324. $this->commentsManager->expects($this->exactly(2))
  325. ->method('resolveDisplayName')
  326. ->withConsecutive(
  327. [$this->equalTo('user'), $this->equalTo('alice')],
  328. [$this->equalTo('user'), $this->equalTo('bob')]
  329. )
  330. ->willReturnOnConsecutiveCalls('Alice Al-Isson', 'Unknown user');
  331. $this->comment->expects($this->once())
  332. ->method('getId')
  333. ->will($this->returnValue($expected[$ns . 'id']));
  334. $this->comment->expects($this->once())
  335. ->method('getParentId')
  336. ->will($this->returnValue($expected[$ns . 'parentId']));
  337. $this->comment->expects($this->once())
  338. ->method('getTopmostParentId')
  339. ->will($this->returnValue($expected[$ns . 'topmostParentId']));
  340. $this->comment->expects($this->once())
  341. ->method('getChildrenCount')
  342. ->will($this->returnValue($expected[$ns . 'childrenCount']));
  343. $this->comment->expects($this->once())
  344. ->method('getMessage')
  345. ->will($this->returnValue($expected[$ns . 'message']));
  346. $this->comment->expects($this->once())
  347. ->method('getMentions')
  348. ->willReturn([
  349. ['type' => 'user', 'id' => 'alice'],
  350. ['type' => 'user', 'id' => 'bob'],
  351. ]);
  352. $this->comment->expects($this->once())
  353. ->method('getVerb')
  354. ->will($this->returnValue($expected[$ns . 'verb']));
  355. $this->comment->expects($this->exactly(2))
  356. ->method('getActorType')
  357. ->will($this->returnValue($expected[$ns . 'actorType']));
  358. $this->comment->expects($this->exactly(2))
  359. ->method('getActorId')
  360. ->will($this->returnValue($expected[$ns . 'actorId']));
  361. $this->comment->expects($this->once())
  362. ->method('getCreationDateTime')
  363. ->will($this->returnValue($expected[$ns . 'creationDateTime']));
  364. $this->comment->expects($this->once())
  365. ->method('getLatestChildDateTime')
  366. ->will($this->returnValue($expected[$ns . 'latestChildDateTime']));
  367. $this->comment->expects($this->once())
  368. ->method('getObjectType')
  369. ->will($this->returnValue($expected[$ns . 'objectType']));
  370. $this->comment->expects($this->once())
  371. ->method('getObjectId')
  372. ->will($this->returnValue($expected[$ns . 'objectId']));
  373. $user = $this->getMockBuilder(IUser::class)
  374. ->disableOriginalConstructor()
  375. ->getMock();
  376. $user->expects($this->once())
  377. ->method('getDisplayName')
  378. ->will($this->returnValue($expected[$ns . 'actorDisplayName']));
  379. $this->userManager->expects($this->once())
  380. ->method('get')
  381. ->with('alice')
  382. ->will($this->returnValue($user));
  383. $properties = $this->node->getProperties(null);
  384. foreach($properties as $name => $value) {
  385. $this->assertTrue(array_key_exists($name, $expected));
  386. $this->assertSame($expected[$name], $value);
  387. unset($expected[$name]);
  388. }
  389. $this->assertTrue(empty($expected));
  390. }
  391. public function readCommentProvider() {
  392. $creationDT = new \DateTime('2016-01-19 18:48:00');
  393. $diff = new \DateInterval('PT2H');
  394. $readDT1 = clone $creationDT; $readDT1->sub($diff);
  395. $readDT2 = clone $creationDT; $readDT2->add($diff);
  396. return [
  397. [$creationDT, $readDT1, 'true'],
  398. [$creationDT, $readDT2, 'false'],
  399. [$creationDT, null, 'true'],
  400. ];
  401. }
  402. /**
  403. * @dataProvider readCommentProvider
  404. * @param $expected
  405. */
  406. public function testGetPropertiesUnreadProperty($creationDT, $readDT, $expected) {
  407. $this->comment->expects($this->any())
  408. ->method('getCreationDateTime')
  409. ->will($this->returnValue($creationDT));
  410. $this->comment->expects($this->any())
  411. ->method('getMentions')
  412. ->willReturn([]);
  413. $this->commentsManager->expects($this->once())
  414. ->method('getReadMark')
  415. ->will($this->returnValue($readDT));
  416. $this->userSession->expects($this->once())
  417. ->method('getUser')
  418. ->will($this->returnValue(
  419. $this->getMockBuilder(IUser::class)
  420. ->disableOriginalConstructor()
  421. ->getMock()
  422. ));
  423. $properties = $this->node->getProperties(null);
  424. $this->assertTrue(array_key_exists(CommentNode::PROPERTY_NAME_UNREAD, $properties));
  425. $this->assertSame($properties[CommentNode::PROPERTY_NAME_UNREAD], $expected);
  426. }
  427. }