You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

554 lines
16 KiB

  1. <?php
  2. /**
  3. *
  4. * @copyright Copyright (c) 2017, Daniel Calviño Sánchez (danxuliu@gmail.com)
  5. *
  6. * @license GNU AGPL version 3 or any later version
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License as
  10. * published by the Free Software Foundation, either version 3 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. namespace OCA\Spreed\Tests\php\Chat;
  23. use OCA\Spreed\Chat\Notifier;
  24. use OCA\Spreed\Exceptions\ParticipantNotFoundException;
  25. use OCA\Spreed\Files\Util;
  26. use OCA\Spreed\Manager;
  27. use OCA\Spreed\Participant;
  28. use OCA\Spreed\Room;
  29. use OCP\Comments\IComment;
  30. use OCP\Notification\IManager as INotificationManager;
  31. use OCP\Notification\INotification;
  32. use OCP\IUserManager;
  33. class NotifierTest extends \Test\TestCase {
  34. /** @var \OCP\Notification\IManager|\PHPUnit_Framework_MockObject_MockObject */
  35. protected $notificationManager;
  36. /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */
  37. protected $userManager;
  38. /** @var \OCA\Spreed\Manager|\PHPUnit_Framework_MockObject_MockObject */
  39. protected $manager;
  40. /** @var \OCA\Spreed\Files\Util|\PHPUnit_Framework_MockObject_MockObject */
  41. protected $util;
  42. /** @var \OCA\Spreed\Chat\Notifier */
  43. protected $notifier;
  44. public function setUp() {
  45. parent::setUp();
  46. $this->notificationManager = $this->createMock(INotificationManager::class);
  47. $this->userManager = $this->createMock(IUserManager::class);
  48. $this->userManager
  49. ->method('userExists')
  50. ->will($this->returnCallback(function($userId) {
  51. if ($userId === 'unknownUser') {
  52. return false;
  53. }
  54. return true;
  55. }));
  56. $this->manager = $this->createMock(Manager::class);
  57. $this->util = $this->createMock(Util::class);
  58. $this->notifier = new Notifier($this->notificationManager,
  59. $this->userManager,
  60. $this->manager,
  61. $this->util);
  62. }
  63. private function newComment($id, $actorType, $actorId, $creationDateTime, $message) {
  64. // $mentionMatches[0] contains the whole matches, while
  65. // $mentionMatches[1] contains the matched subpattern.
  66. $mentionMatches = [];
  67. preg_match_all('/@([a-zA-Z0-9]+)/', $message, $mentionMatches);
  68. $mentions = array_map(function($mentionMatch) {
  69. return [ 'type' => 'user', 'id' => $mentionMatch ];
  70. }, $mentionMatches[1]);
  71. $comment = $this->createMock(IComment::class);
  72. $comment->method('getId')->willReturn($id);
  73. $comment->method('getObjectId')->willReturn(1234);
  74. $comment->method('getActorType')->willReturn($actorType);
  75. $comment->method('getActorId')->willReturn($actorId);
  76. $comment->method('getCreationDateTime')->willReturn($creationDateTime);
  77. $comment->method('getMessage')->willReturn($message);
  78. $comment->method('getMentions')->willReturn($mentions);
  79. $comment->method('getVerb')->willReturn('comment');
  80. return $comment;
  81. }
  82. private function newNotification($room, IComment $comment) {
  83. $notification = $this->createMock(INotification::class);
  84. $notification->expects($this->once())
  85. ->method('setApp')
  86. ->with('spreed')
  87. ->willReturnSelf();
  88. $notification->expects($this->once())
  89. ->method('setObject')
  90. ->with('chat', $room->getToken())
  91. ->willReturnSelf();
  92. $notification->expects($this->once())
  93. ->method('setSubject')
  94. ->with('mention', [
  95. 'userType' => $comment->getActorType(),
  96. 'userId' => $comment->getActorId(),
  97. ])
  98. ->willReturnSelf();
  99. $notification->expects($this->once())
  100. ->method('setMessage')
  101. ->willReturnSelf();
  102. $notification->expects($this->once())
  103. ->method('setDateTime')
  104. ->with($comment->getCreationDateTime())
  105. ->willReturnSelf();
  106. return $notification;
  107. }
  108. public function testNotifyMentionedUsers() {
  109. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016), 'Mention @anotherUser');
  110. $room = $this->createMock(Room::class);
  111. $room->expects($this->any())
  112. ->method('getToken')
  113. ->willReturn('Token123');
  114. $notification = $this->newNotification($room, $comment);
  115. $this->notificationManager->expects($this->once())
  116. ->method('createNotification')
  117. ->willReturn($notification);
  118. $notification->expects($this->once())
  119. ->method('setUser')
  120. ->with('anotherUser')
  121. ->willReturnSelf();
  122. $notification->expects($this->once())
  123. ->method('setMessage')
  124. ->with('comment')
  125. ->willReturnSelf();
  126. $this->manager->expects($this->once())
  127. ->method('getRoomById')
  128. ->with(1234)
  129. ->willReturn($room);
  130. $participant = $this->createMock(Participant::class);
  131. $room->expects($this->once())
  132. ->method('getParticipant')
  133. ->with('anotherUser')
  134. ->willReturn($participant);
  135. $this->notificationManager->expects($this->once())
  136. ->method('notify')
  137. ->with($notification);
  138. $this->notifier->notifyMentionedUsers($room, $comment, []);
  139. }
  140. public function testNotNotifyMentionedUserIfReplyToAuthor() {
  141. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016), 'Mention @anotherUser');
  142. $room = $this->createMock(Room::class);
  143. $room->expects($this->any())
  144. ->method('getToken')
  145. ->willReturn('Token123');
  146. $notification = $this->newNotification($room, $comment);
  147. $this->notificationManager->expects($this->once())
  148. ->method('createNotification')
  149. ->willReturn($notification);
  150. $notification->expects($this->never())
  151. ->method('setUser');
  152. $notification->expects($this->once())
  153. ->method('setMessage')
  154. ->with('comment')
  155. ->willReturnSelf();
  156. $this->notificationManager->expects($this->never())
  157. ->method('notify');
  158. $this->notifier->notifyMentionedUsers($room, $comment, ['anotherUser']);
  159. }
  160. public function testNotifyMentionedUsersByGuest() {
  161. $comment = $this->newComment(108, 'guests', 'testSpreedSession', new \DateTime('@' . 1000000016), 'Mention @anotherUser');
  162. $room = $this->createMock(Room::class);
  163. $room->expects($this->any())
  164. ->method('getToken')
  165. ->willReturn('Token123');
  166. $notification = $this->newNotification($room, $comment);
  167. $this->notificationManager->expects($this->once())
  168. ->method('createNotification')
  169. ->willReturn($notification);
  170. $notification->expects($this->once())
  171. ->method('setUser')
  172. ->with('anotherUser')
  173. ->willReturnSelf();
  174. $notification->expects($this->once())
  175. ->method('setMessage')
  176. ->with('comment')
  177. ->willReturnSelf();
  178. $this->manager->expects($this->once())
  179. ->method('getRoomById')
  180. ->with(1234)
  181. ->willReturn($room);
  182. $participant = $this->createMock(Participant::class);
  183. $room->expects($this->once())
  184. ->method('getParticipant')
  185. ->with('anotherUser')
  186. ->willReturn($participant);
  187. $this->notificationManager->expects($this->once())
  188. ->method('notify')
  189. ->with($notification);
  190. $this->notifier->notifyMentionedUsers($room, $comment, []);
  191. }
  192. public function testNotifyMentionedUsersWithLongMessageStartMention() {
  193. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016),
  194. '123456789 @anotherUserWithOddLengthName 123456789-123456789-123456789-123456789-123456789-123456789');
  195. $room = $this->createMock(Room::class);
  196. $room->expects($this->any())
  197. ->method('getToken')
  198. ->willReturn('Token123');
  199. $notification = $this->newNotification($room, $comment);
  200. $this->notificationManager->expects($this->once())
  201. ->method('createNotification')
  202. ->willReturn($notification);
  203. $notification->expects($this->once())
  204. ->method('setUser')
  205. ->with('anotherUserWithOddLengthName')
  206. ->willReturnSelf();
  207. $notification->expects($this->once())
  208. ->method('setMessage')
  209. ->with('comment')
  210. ->willReturnSelf();
  211. $this->manager->expects($this->once())
  212. ->method('getRoomById')
  213. ->with(1234)
  214. ->willReturn($room);
  215. $participant = $this->createMock(Participant::class);
  216. $room->expects($this->once())
  217. ->method('getParticipant')
  218. ->with('anotherUserWithOddLengthName')
  219. ->willReturn($participant);
  220. $this->notificationManager->expects($this->once())
  221. ->method('notify')
  222. ->with($notification);
  223. $this->notifier->notifyMentionedUsers($room, $comment, []);
  224. }
  225. public function testNotifyMentionedUsersWithLongMessageMiddleMention() {
  226. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016),
  227. '123456789-123456789-123456789-1234 @anotherUserWithOddLengthName 6789-123456789-123456789-123456789');
  228. $room = $this->createMock(Room::class);
  229. $room->expects($this->any())
  230. ->method('getToken')
  231. ->willReturn('Token123');
  232. $notification = $this->newNotification($room, $comment);
  233. $this->notificationManager->expects($this->once())
  234. ->method('createNotification')
  235. ->willReturn($notification);
  236. $notification->expects($this->once())
  237. ->method('setUser')
  238. ->with('anotherUserWithOddLengthName')
  239. ->willReturnSelf();
  240. $notification->expects($this->once())
  241. ->method('setMessage')
  242. ->with('comment')
  243. ->willReturnSelf();
  244. $this->manager->expects($this->once())
  245. ->method('getRoomById')
  246. ->with(1234)
  247. ->willReturn($room);
  248. $participant = $this->createMock(Participant::class);
  249. $room->expects($this->once())
  250. ->method('getParticipant')
  251. ->with('anotherUserWithOddLengthName')
  252. ->willReturn($participant);
  253. $this->notificationManager->expects($this->once())
  254. ->method('notify')
  255. ->with($notification);
  256. $this->notifier->notifyMentionedUsers($room, $comment, []);
  257. }
  258. public function testNotifyMentionedUsersWithLongMessageEndMention() {
  259. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016),
  260. '123456789-123456789-123456789-123456789-123456789-123456789 @anotherUserWithOddLengthName 123456789');
  261. $room = $this->createMock(Room::class);
  262. $room->expects($this->any())
  263. ->method('getToken')
  264. ->willReturn('Token123');
  265. $notification = $this->newNotification($room, $comment);
  266. $this->notificationManager->expects($this->once())
  267. ->method('createNotification')
  268. ->willReturn($notification);
  269. $notification->expects($this->once())
  270. ->method('setUser')
  271. ->with('anotherUserWithOddLengthName')
  272. ->willReturnSelf();
  273. $notification->expects($this->once())
  274. ->method('setMessage')
  275. ->with('comment')
  276. ->willReturnSelf();
  277. $this->manager->expects($this->once())
  278. ->method('getRoomById')
  279. ->with(1234)
  280. ->willReturn($room);
  281. $participant = $this->createMock(Participant::class);
  282. $room->expects($this->once())
  283. ->method('getParticipant')
  284. ->with('anotherUserWithOddLengthName')
  285. ->willReturn($participant);
  286. $this->notificationManager->expects($this->once())
  287. ->method('notify')
  288. ->with($notification);
  289. $this->notifier->notifyMentionedUsers($room, $comment, []);
  290. }
  291. public function testNotifyMentionedUsersToSelf() {
  292. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016), 'Mention @testUser');
  293. $room = $this->createMock(Room::class);
  294. $room->expects($this->any())
  295. ->method('getToken')
  296. ->willReturn('Token123');
  297. $notification = $this->newNotification($room, $comment);
  298. $this->notificationManager->expects($this->once())
  299. ->method('createNotification')
  300. ->willReturn($notification);
  301. $this->notificationManager->expects($this->never())
  302. ->method('notify');
  303. $this->notifier->notifyMentionedUsers($room, $comment, []);
  304. }
  305. public function testNotifyMentionedUsersToUnknownUser() {
  306. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016), 'Mention @unknownUser');
  307. $room = $this->createMock(Room::class);
  308. $room->expects($this->any())
  309. ->method('getToken')
  310. ->willReturn('Token123');
  311. $notification = $this->newNotification($room, $comment);
  312. $this->notificationManager->expects($this->once())
  313. ->method('createNotification')
  314. ->willReturn($notification);
  315. $this->notificationManager->expects($this->never())
  316. ->method('notify');
  317. $this->notifier->notifyMentionedUsers($room, $comment, []);
  318. }
  319. public function testNotifyMentionedUsersToUserNotInvitedToChat() {
  320. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016), 'Mention @userNotInOneToOneChat');
  321. $room = $this->createMock(Room::class);
  322. $room->expects($this->any())
  323. ->method('getToken')
  324. ->willReturn('Token123');
  325. $room = $this->createMock(Room::class);
  326. $this->manager->expects($this->once())
  327. ->method('getRoomById')
  328. ->with(1234)
  329. ->willReturn($room);
  330. $room->expects($this->once())
  331. ->method('getParticipant')
  332. ->with('userNotInOneToOneChat')
  333. ->will($this->throwException(new ParticipantNotFoundException()));
  334. $notification = $this->newNotification($room, $comment);
  335. $this->notificationManager->expects($this->once())
  336. ->method('createNotification')
  337. ->willReturn($notification);
  338. $this->notificationManager->expects($this->never())
  339. ->method('notify');
  340. $this->notifier->notifyMentionedUsers($room, $comment, []);
  341. }
  342. public function testNotifyMentionedUsersNoMentions() {
  343. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016), 'No mentions');
  344. $room = $this->createMock(Room::class);
  345. $room->expects($this->any())
  346. ->method('getToken')
  347. ->willReturn('Token123');
  348. $this->notificationManager->expects($this->never())
  349. ->method('createNotification');
  350. $this->notificationManager->expects($this->never())
  351. ->method('notify');
  352. $this->notifier->notifyMentionedUsers($room, $comment, []);
  353. }
  354. public function testNotifyMentionedUsersSeveralMentions() {
  355. $comment = $this->newComment(108, 'users', 'testUser', new \DateTime('@' . 1000000016), 'Mention @anotherUser, and @unknownUser, and @testUser, and @userAbleToJoin');
  356. $room = $this->createMock(Room::class);
  357. $room->expects($this->any())
  358. ->method('getToken')
  359. ->willReturn('Token123');
  360. $notification = $this->newNotification($room, $comment);
  361. $this->notificationManager->expects($this->once())
  362. ->method('createNotification')
  363. ->willReturn($notification);
  364. $notification->expects($this->once())
  365. ->method('setMessage')
  366. ->with('comment')
  367. ->willReturnSelf();
  368. $notification->expects($this->exactly(2))
  369. ->method('setUser')
  370. ->withConsecutive(
  371. [ 'anotherUser' ],
  372. [ 'userAbleToJoin' ]
  373. )
  374. ->willReturnSelf();
  375. $this->manager->expects($this->exactly(2))
  376. ->method('getRoomById')
  377. ->with(1234)
  378. ->willReturn($room);
  379. $participant = $this->createMock(Participant::class);
  380. $room->expects($this->exactly(2))
  381. ->method('getParticipant')
  382. ->withConsecutive(['anotherUser'], ['userAbleToJoin'])
  383. ->willReturn($participant);
  384. $this->notificationManager->expects($this->exactly(2))
  385. ->method('notify')
  386. ->withConsecutive(
  387. [ $notification ],
  388. [ $notification ]
  389. );
  390. $this->notifier->notifyMentionedUsers($room, $comment, []);
  391. }
  392. public function testRemovePendingNotificationsForRoom() {
  393. $notification = $this->createMock(INotification::class);
  394. $room = $this->createMock(Room::class);
  395. $room->expects($this->any())
  396. ->method('getToken')
  397. ->willReturn('Token123');
  398. $this->notificationManager->expects($this->once())
  399. ->method('createNotification')
  400. ->willReturn($notification);
  401. $notification->expects($this->once())
  402. ->method('setApp')
  403. ->with('spreed')
  404. ->willReturnSelf();
  405. $notification->expects($this->exactly(3))
  406. ->method('setObject')
  407. ->withConsecutive(
  408. ['chat', 'Token123'],
  409. ['room', 'Token123'],
  410. ['call', 'Token123']
  411. )
  412. ->willReturnSelf();
  413. $this->notificationManager->expects($this->exactly(3))
  414. ->method('markProcessed')
  415. ->with($notification);
  416. $this->notifier->removePendingNotificationsForRoom($room);
  417. }
  418. }