activitymanager.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. <?php
  2. /**
  3. * Copyright (c) 2014 Thomas Müller <deepdiver@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. *
  8. */
  9. class Test_ActivityManager extends \Test\TestCase {
  10. /** @var \OC\ActivityManager */
  11. private $activityManager;
  12. /** @var \PHPUnit_Framework_MockObject_MockObject */
  13. protected $request;
  14. /** @var \PHPUnit_Framework_MockObject_MockObject */
  15. protected $session;
  16. /** @var \PHPUnit_Framework_MockObject_MockObject */
  17. protected $config;
  18. protected function setUp() {
  19. parent::setUp();
  20. $this->request = $this->getMockBuilder('OCP\IRequest')
  21. ->disableOriginalConstructor()
  22. ->getMock();
  23. $this->session = $this->getMockBuilder('OCP\IUserSession')
  24. ->disableOriginalConstructor()
  25. ->getMock();
  26. $this->config = $this->getMockBuilder('OCP\IConfig')
  27. ->disableOriginalConstructor()
  28. ->getMock();
  29. $this->activityManager = new \OC\ActivityManager(
  30. $this->request,
  31. $this->session,
  32. $this->config
  33. );
  34. $this->assertSame([], $this->invokePrivate($this->activityManager, 'getConsumers'));
  35. $this->assertSame([], $this->invokePrivate($this->activityManager, 'getExtensions'));
  36. $this->activityManager->registerConsumer(function() {
  37. return new NoOpConsumer();
  38. });
  39. $this->activityManager->registerExtension(function() {
  40. return new NoOpExtension();
  41. });
  42. $this->activityManager->registerExtension(function() {
  43. return new SimpleExtension();
  44. });
  45. $this->assertNotEmpty($this->invokePrivate($this->activityManager, 'getConsumers'));
  46. $this->assertNotEmpty($this->invokePrivate($this->activityManager, 'getConsumers'));
  47. $this->assertNotEmpty($this->invokePrivate($this->activityManager, 'getExtensions'));
  48. $this->assertNotEmpty($this->invokePrivate($this->activityManager, 'getExtensions'));
  49. }
  50. public function testGetConsumers() {
  51. $consumers = $this->invokePrivate($this->activityManager, 'getConsumers');
  52. $this->assertNotEmpty($consumers);
  53. }
  54. /**
  55. * @expectedException \InvalidArgumentException
  56. */
  57. public function testGetConsumersInvalidConsumer() {
  58. $this->activityManager->registerConsumer(function() {
  59. return new StdClass();
  60. });
  61. $this->invokePrivate($this->activityManager, 'getConsumers');
  62. }
  63. public function testGetExtensions() {
  64. $extensions = $this->invokePrivate($this->activityManager, 'getExtensions');
  65. $this->assertNotEmpty($extensions);
  66. }
  67. /**
  68. * @expectedException \InvalidArgumentException
  69. */
  70. public function testGetExtensionsInvalidExtension() {
  71. $this->activityManager->registerExtension(function() {
  72. return new StdClass();
  73. });
  74. $this->invokePrivate($this->activityManager, 'getExtensions');
  75. }
  76. public function testNotificationTypes() {
  77. $result = $this->activityManager->getNotificationTypes('en');
  78. $this->assertTrue(is_array($result));
  79. $this->assertEquals(2, sizeof($result));
  80. }
  81. public function testDefaultTypes() {
  82. $result = $this->activityManager->getDefaultTypes('stream');
  83. $this->assertTrue(is_array($result));
  84. $this->assertEquals(1, sizeof($result));
  85. $result = $this->activityManager->getDefaultTypes('email');
  86. $this->assertTrue(is_array($result));
  87. $this->assertEquals(0, sizeof($result));
  88. }
  89. public function testTypeIcon() {
  90. $result = $this->activityManager->getTypeIcon('NT1');
  91. $this->assertEquals('icon-nt-one', $result);
  92. $result = $this->activityManager->getTypeIcon('NT2');
  93. $this->assertEquals('', $result);
  94. }
  95. public function testTranslate() {
  96. $result = $this->activityManager->translate('APP0', '', '', array(), false, false, 'en');
  97. $this->assertEquals('Stupid translation', $result);
  98. $result = $this->activityManager->translate('APP1', '', '', array(), false, false, 'en');
  99. $this->assertFalse($result);
  100. }
  101. public function testGetSpecialParameterList() {
  102. $result = $this->activityManager->getSpecialParameterList('APP0', '');
  103. $this->assertEquals(array(0 => 'file', 1 => 'username'), $result);
  104. $result = $this->activityManager->getSpecialParameterList('APP1', '');
  105. $this->assertFalse($result);
  106. }
  107. public function testGroupParameter() {
  108. $result = $this->activityManager->getGroupParameter(array());
  109. $this->assertEquals(5, $result);
  110. }
  111. public function testNavigation() {
  112. $result = $this->activityManager->getNavigation();
  113. $this->assertEquals(4, sizeof($result['apps']));
  114. $this->assertEquals(2, sizeof($result['top']));
  115. }
  116. public function testIsFilterValid() {
  117. $result = $this->activityManager->isFilterValid('fv01');
  118. $this->assertTrue($result);
  119. $result = $this->activityManager->isFilterValid('InvalidFilter');
  120. $this->assertFalse($result);
  121. }
  122. public function testFilterNotificationTypes() {
  123. $result = $this->activityManager->filterNotificationTypes(array('NT0', 'NT1', 'NT2', 'NT3'), 'fv01');
  124. $this->assertTrue(is_array($result));
  125. $this->assertEquals(3, sizeof($result));
  126. $result = $this->activityManager->filterNotificationTypes(array('NT0', 'NT1', 'NT2', 'NT3'), 'InvalidFilter');
  127. $this->assertTrue(is_array($result));
  128. $this->assertEquals(4, sizeof($result));
  129. }
  130. public function testQueryForFilter() {
  131. // Register twice, to test the created sql part
  132. $this->activityManager->registerExtension(function() {
  133. return new SimpleExtension();
  134. });
  135. $result = $this->activityManager->getQueryForFilter('fv01');
  136. $this->assertEquals(
  137. array(
  138. ' and ((`app` = ? and `message` like ?) or (`app` = ? and `message` like ?))',
  139. array('mail', 'ownCloud%', 'mail', 'ownCloud%')
  140. ), $result
  141. );
  142. $result = $this->activityManager->getQueryForFilter('InvalidFilter');
  143. $this->assertEquals(array(null, null), $result);
  144. }
  145. public function getUserFromTokenThrowInvalidTokenData() {
  146. return [
  147. [null, []],
  148. ['', []],
  149. ['12345678901234567890123456789', []],
  150. ['1234567890123456789012345678901', []],
  151. ['123456789012345678901234567890', []],
  152. ['123456789012345678901234567890', ['user1', 'user2']],
  153. ];
  154. }
  155. /**
  156. * @expectedException \UnexpectedValueException
  157. * @dataProvider getUserFromTokenThrowInvalidTokenData
  158. *
  159. * @param string $token
  160. * @param array $users
  161. */
  162. public function testGetUserFromTokenThrowInvalidToken($token, $users) {
  163. $this->mockRSSToken($token, $token, $users);
  164. self::invokePrivate($this->activityManager, 'getUserFromToken');
  165. }
  166. public function getUserFromTokenData() {
  167. return [
  168. [null, '123456789012345678901234567890', 'user1'],
  169. ['user2', null, 'user2'],
  170. ['user2', '123456789012345678901234567890', 'user2'],
  171. ];
  172. }
  173. /**
  174. * @dataProvider getUserFromTokenData
  175. *
  176. * @param string $userLoggedIn
  177. * @param string $token
  178. * @param string $expected
  179. */
  180. public function testGetUserFromToken($userLoggedIn, $token, $expected) {
  181. if ($userLoggedIn !== null) {
  182. $this->mockUserSession($userLoggedIn);
  183. }
  184. $this->mockRSSToken($token, '123456789012345678901234567890', ['user1']);
  185. $this->assertEquals($expected, $this->activityManager->getCurrentUserId());
  186. }
  187. protected function mockRSSToken($requestToken, $userToken, $users) {
  188. if ($requestToken !== null) {
  189. $this->request->expects($this->any())
  190. ->method('getParam')
  191. ->with('token', '')
  192. ->willReturn($requestToken);
  193. }
  194. $this->config->expects($this->any())
  195. ->method('getUsersForUserValue')
  196. ->with('activity', 'rsstoken', $userToken)
  197. ->willReturn($users);
  198. }
  199. protected function mockUserSession($user) {
  200. $mockUser = $this->getMockBuilder('\OCP\IUser')
  201. ->disableOriginalConstructor()
  202. ->getMock();
  203. $mockUser->expects($this->any())
  204. ->method('getUID')
  205. ->willReturn($user);
  206. $this->session->expects($this->any())
  207. ->method('isLoggedIn')
  208. ->willReturn(true);
  209. $this->session->expects($this->any())
  210. ->method('getUser')
  211. ->willReturn($mockUser);
  212. }
  213. /**
  214. * @expectedException BadMethodCallException
  215. * @expectedExceptionMessage App not set
  216. * @expectedExceptionCode 10
  217. */
  218. public function testPublishExceptionNoApp() {
  219. $event = new \OC\Activity\Event();
  220. $this->activityManager->publish($event);
  221. }
  222. /**
  223. * @expectedException BadMethodCallException
  224. * @expectedExceptionMessage Type not set
  225. * @expectedExceptionCode 11
  226. */
  227. public function testPublishExceptionNoType() {
  228. $event = new \OC\Activity\Event();
  229. $event->setApp('test');
  230. $this->activityManager->publish($event);
  231. }
  232. /**
  233. * @expectedException BadMethodCallException
  234. * @expectedExceptionMessage Affected user not set
  235. * @expectedExceptionCode 12
  236. */
  237. public function testPublishExceptionNoAffectedUser() {
  238. $event = new \OC\Activity\Event();
  239. $event->setApp('test')
  240. ->setType('test_type');
  241. $this->activityManager->publish($event);
  242. }
  243. /**
  244. * @expectedException BadMethodCallException
  245. * @expectedExceptionMessage Subject not set
  246. * @expectedExceptionCode 13
  247. */
  248. public function testPublishExceptionNoSubject() {
  249. $event = new \OC\Activity\Event();
  250. $event->setApp('test')
  251. ->setType('test_type')
  252. ->setAffectedUser('test_affected');
  253. $this->activityManager->publish($event);
  254. }
  255. public function dataPublish() {
  256. return [
  257. [null],
  258. ['test_author'],
  259. ];
  260. }
  261. /**
  262. * @dataProvider dataPublish
  263. * @param string $author
  264. */
  265. public function testPublish($author) {
  266. if ($author !== null) {
  267. $authorObject = $this->getMockBuilder('OCP\IUser')
  268. ->disableOriginalConstructor()
  269. ->getMock();
  270. $authorObject->expects($this->once())
  271. ->method('getUID')
  272. ->willReturn($author);
  273. $this->session->expects($this->atLeastOnce())
  274. ->method('getUser')
  275. ->willReturn($authorObject);
  276. }
  277. $event = new \OC\Activity\Event();
  278. $event->setApp('test')
  279. ->setType('test_type')
  280. ->setSubject('test_subject', [])
  281. ->setAffectedUser('test_affected');
  282. $consumer = $this->getMockBuilder('OCP\Activity\IConsumer')
  283. ->disableOriginalConstructor()
  284. ->getMock();
  285. $consumer->expects($this->once())
  286. ->method('receive')
  287. ->with($event)
  288. ->willReturnCallback(function(\OCP\Activity\IEvent $event) use ($author) {
  289. $this->assertLessThanOrEqual(time() + 2, $event->getTimestamp(), 'Timestamp not set correctly');
  290. $this->assertGreaterThanOrEqual(time() - 2, $event->getTimestamp(), 'Timestamp not set correctly');
  291. $this->assertSame($author, $event->getAuthor(), 'Author name not set correctly');
  292. });
  293. $this->activityManager->registerConsumer(function () use ($consumer) {
  294. return $consumer;
  295. });
  296. $this->activityManager->publish($event);
  297. }
  298. public function testPublishAllManually() {
  299. $event = new \OC\Activity\Event();
  300. $event->setApp('test_app')
  301. ->setType('test_type')
  302. ->setAffectedUser('test_affected')
  303. ->setAuthor('test_author')
  304. ->setTimestamp(1337)
  305. ->setSubject('test_subject', ['test_subject_param'])
  306. ->setMessage('test_message', ['test_message_param'])
  307. ->setObject('test_object_type', 42, 'test_object_name')
  308. ->setLink('test_link')
  309. ;
  310. $consumer = $this->getMockBuilder('OCP\Activity\IConsumer')
  311. ->disableOriginalConstructor()
  312. ->getMock();
  313. $consumer->expects($this->once())
  314. ->method('receive')
  315. ->willReturnCallback(function(\OCP\Activity\IEvent $event) {
  316. $this->assertSame('test_app', $event->getApp(), 'App not set correctly');
  317. $this->assertSame('test_type', $event->getType(), 'Type not set correctly');
  318. $this->assertSame('test_affected', $event->getAffectedUser(), 'Affected user not set correctly');
  319. $this->assertSame('test_author', $event->getAuthor(), 'Author not set correctly');
  320. $this->assertSame(1337, $event->getTimestamp(), 'Timestamp not set correctly');
  321. $this->assertSame('test_subject', $event->getSubject(), 'Subject not set correctly');
  322. $this->assertSame(['test_subject_param'], $event->getSubjectParameters(), 'Subject parameter not set correctly');
  323. $this->assertSame('test_message', $event->getMessage(), 'Message not set correctly');
  324. $this->assertSame(['test_message_param'], $event->getMessageParameters(), 'Message parameter not set correctly');
  325. $this->assertSame('test_object_type', $event->getObjectType(), 'Object type not set correctly');
  326. $this->assertSame(42, $event->getObjectId(), 'Object ID not set correctly');
  327. $this->assertSame('test_object_name', $event->getObjectName(), 'Object name not set correctly');
  328. $this->assertSame('test_link', $event->getLink(), 'Link not set correctly');
  329. });
  330. $this->activityManager->registerConsumer(function () use ($consumer) {
  331. return $consumer;
  332. });
  333. $this->activityManager->publish($event);
  334. }
  335. public function testDeprecatedPublishActivity() {
  336. $event = new \OC\Activity\Event();
  337. $event->setApp('test_app')
  338. ->setType('test_type')
  339. ->setAffectedUser('test_affected')
  340. ->setAuthor('test_author')
  341. ->setTimestamp(1337)
  342. ->setSubject('test_subject', ['test_subject_param'])
  343. ->setMessage('test_message', ['test_message_param'])
  344. ->setObject('test_object_type', 42, 'test_object_name')
  345. ->setLink('test_link')
  346. ;
  347. $consumer = $this->getMockBuilder('OCP\Activity\IConsumer')
  348. ->disableOriginalConstructor()
  349. ->getMock();
  350. $consumer->expects($this->once())
  351. ->method('receive')
  352. ->willReturnCallback(function(\OCP\Activity\IEvent $event) {
  353. $this->assertSame('test_app', $event->getApp(), 'App not set correctly');
  354. $this->assertSame('test_type', $event->getType(), 'Type not set correctly');
  355. $this->assertSame('test_affected', $event->getAffectedUser(), 'Affected user not set correctly');
  356. $this->assertSame('test_subject', $event->getSubject(), 'Subject not set correctly');
  357. $this->assertSame(['test_subject_param'], $event->getSubjectParameters(), 'Subject parameter not set correctly');
  358. $this->assertSame('test_message', $event->getMessage(), 'Message not set correctly');
  359. $this->assertSame(['test_message_param'], $event->getMessageParameters(), 'Message parameter not set correctly');
  360. $this->assertSame('test_object_name', $event->getObjectName(), 'Object name not set correctly');
  361. $this->assertSame('test_link', $event->getLink(), 'Link not set correctly');
  362. // The following values can not be used via publishActivity()
  363. $this->assertLessThanOrEqual(time() + 2, $event->getTimestamp(), 'Timestamp not set correctly');
  364. $this->assertGreaterThanOrEqual(time() - 2, $event->getTimestamp(), 'Timestamp not set correctly');
  365. $this->assertSame(null, $event->getAuthor(), 'Author not set correctly');
  366. $this->assertSame('', $event->getObjectType(), 'Object type should not be set');
  367. $this->assertSame(0, $event->getObjectId(), 'Object ID should not be set');
  368. });
  369. $this->activityManager->registerConsumer(function () use ($consumer) {
  370. return $consumer;
  371. });
  372. $this->activityManager->publishActivity(
  373. $event->getApp(),
  374. $event->getSubject(), $event->getSubjectParameters(),
  375. $event->getMessage(), $event->getMessageParameters(),
  376. $event->getObjectName(),
  377. $event->getLink(),
  378. $event->getAffectedUser(),
  379. $event->getType(),
  380. \OCP\Activity\IExtension::PRIORITY_MEDIUM
  381. );
  382. }
  383. }
  384. class SimpleExtension implements \OCP\Activity\IExtension {
  385. public function getNotificationTypes($languageCode) {
  386. return array('NT1', 'NT2');
  387. }
  388. public function getDefaultTypes($method) {
  389. if ($method === 'stream') {
  390. return array('DT0');
  391. }
  392. return array();
  393. }
  394. public function getTypeIcon($type) {
  395. if ($type === 'NT1') {
  396. return 'icon-nt-one';
  397. }
  398. return '';
  399. }
  400. public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
  401. if ($app === 'APP0') {
  402. return "Stupid translation";
  403. }
  404. return false;
  405. }
  406. public function getSpecialParameterList($app, $text) {
  407. if ($app === 'APP0') {
  408. return array(0 => 'file', 1 => 'username');
  409. }
  410. return false;
  411. }
  412. public function getGroupParameter($activity) {
  413. return 5;
  414. }
  415. public function getNavigation() {
  416. return array(
  417. 'apps' => array('nav1', 'nav2', 'nav3', 'nav4'),
  418. 'top' => array('top1', 'top2')
  419. );
  420. }
  421. public function isFilterValid($filterValue) {
  422. if ($filterValue === 'fv01') {
  423. return true;
  424. }
  425. return false;
  426. }
  427. public function filterNotificationTypes($types, $filter) {
  428. if ($filter === 'fv01') {
  429. unset($types[0]);
  430. }
  431. return $types;
  432. }
  433. public function getQueryForFilter($filter) {
  434. if ($filter === 'fv01') {
  435. return array('`app` = ? and `message` like ?', array('mail', 'ownCloud%'));
  436. }
  437. return false;
  438. }
  439. }
  440. class NoOpExtension implements \OCP\Activity\IExtension {
  441. public function getNotificationTypes($languageCode) {
  442. return false;
  443. }
  444. public function getDefaultTypes($method) {
  445. return false;
  446. }
  447. public function getTypeIcon($type) {
  448. return false;
  449. }
  450. public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
  451. return false;
  452. }
  453. public function getSpecialParameterList($app, $text) {
  454. return false;
  455. }
  456. public function getGroupParameter($activity) {
  457. return false;
  458. }
  459. public function getNavigation() {
  460. return false;
  461. }
  462. public function isFilterValid($filterValue) {
  463. return false;
  464. }
  465. public function filterNotificationTypes($types, $filter) {
  466. return false;
  467. }
  468. public function getQueryForFilter($filter) {
  469. return false;
  470. }
  471. }
  472. class NoOpConsumer implements \OCP\Activity\IConsumer {
  473. public function receive(\OCP\Activity\IEvent $event) {
  474. }
  475. }