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.

BackendTest.php 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
  4. *
  5. * @author Joas Schilling <coding@schilljs.com>
  6. * @author Roeland Jago Douma <roeland@famdouma.nl>
  7. * @author Thomas Citharel <nextcloud@tcit.fr>
  8. *
  9. * @license GNU AGPL version 3 or any later version
  10. *
  11. * This program is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License as
  13. * published by the Free Software Foundation, either version 3 of the
  14. * License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. *
  24. */
  25. namespace OCA\DAV\Tests\unit\CalDAV\Activity;
  26. use OCA\DAV\CalDAV\Activity\Backend;
  27. use OCA\DAV\CalDAV\Activity\Provider\Calendar;
  28. use OCP\Activity\IEvent;
  29. use OCP\Activity\IManager;
  30. use OCP\IGroup;
  31. use OCP\IGroupManager;
  32. use OCP\IUser;
  33. use OCP\IUserSession;
  34. use Test\TestCase;
  35. class BackendTest extends TestCase {
  36. /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
  37. protected $activityManager;
  38. /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
  39. protected $groupManager;
  40. /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
  41. protected $userSession;
  42. protected function setUp(): void {
  43. parent::setUp();
  44. $this->activityManager = $this->createMock(IManager::class);
  45. $this->groupManager = $this->createMock(IGroupManager::class);
  46. $this->userSession = $this->createMock(IUserSession::class);
  47. }
  48. /**
  49. * @param array $methods
  50. * @return Backend|\PHPUnit_Framework_MockObject_MockObject
  51. */
  52. protected function getBackend(array $methods = []) {
  53. if (empty($methods)) {
  54. return new Backend(
  55. $this->activityManager,
  56. $this->groupManager,
  57. $this->userSession
  58. );
  59. } else {
  60. return $this->getMockBuilder(Backend::class)
  61. ->setConstructorArgs([
  62. $this->activityManager,
  63. $this->groupManager,
  64. $this->userSession,
  65. ])
  66. ->setMethods($methods)
  67. ->getMock();
  68. }
  69. }
  70. public function dataCallTriggerCalendarActivity() {
  71. return [
  72. ['onCalendarAdd', [['data']], Calendar::SUBJECT_ADD, [['data'], [], []]],
  73. ['onCalendarUpdate', [['data'], ['shares'], ['changed-properties']], Calendar::SUBJECT_UPDATE, [['data'], ['shares'], ['changed-properties']]],
  74. ['onCalendarDelete', [['data'], ['shares']], Calendar::SUBJECT_DELETE, [['data'], ['shares'], []]],
  75. ['onCalendarPublication', [['data'], true], Calendar::SUBJECT_PUBLISH, [['data'], [], []]],
  76. ];
  77. }
  78. /**
  79. * @dataProvider dataCallTriggerCalendarActivity
  80. *
  81. * @param string $method
  82. * @param array $payload
  83. * @param string $expectedSubject
  84. * @param array $expectedPayload
  85. */
  86. public function testCallTriggerCalendarActivity($method, array $payload, $expectedSubject, array $expectedPayload) {
  87. $backend = $this->getBackend(['triggerCalendarActivity']);
  88. $backend->expects($this->once())
  89. ->method('triggerCalendarActivity')
  90. ->willReturnCallback(function() use($expectedPayload, $expectedSubject) {
  91. $arguments = func_get_args();
  92. $this->assertSame($expectedSubject, array_shift($arguments));
  93. $this->assertEquals($expectedPayload, $arguments);
  94. });
  95. call_user_func_array([$backend, $method], $payload);
  96. }
  97. public function dataTriggerCalendarActivity() {
  98. return [
  99. // Add calendar
  100. [Calendar::SUBJECT_ADD, [], [], [], '', '', null, []],
  101. [Calendar::SUBJECT_ADD, [
  102. 'principaluri' => 'principal/user/admin',
  103. 'id' => 42,
  104. 'uri' => 'this-uri',
  105. '{DAV:}displayname' => 'Name of calendar',
  106. ], [], [], '', 'admin', null, ['admin']],
  107. [Calendar::SUBJECT_ADD, [
  108. 'principaluri' => 'principal/user/admin',
  109. 'id' => 42,
  110. 'uri' => 'this-uri',
  111. '{DAV:}displayname' => 'Name of calendar',
  112. ], [], [], 'test2', 'test2', null, ['admin']],
  113. // Update calendar
  114. [Calendar::SUBJECT_UPDATE, [], [], [], '', '', null, []],
  115. // No visible change - owner only
  116. [Calendar::SUBJECT_UPDATE, [
  117. 'principaluri' => 'principal/user/admin',
  118. 'id' => 42,
  119. 'uri' => 'this-uri',
  120. '{DAV:}displayname' => 'Name of calendar',
  121. ], ['shares'], [], '', 'admin', null, ['admin']],
  122. // Visible change
  123. [Calendar::SUBJECT_UPDATE, [
  124. 'principaluri' => 'principal/user/admin',
  125. 'id' => 42,
  126. 'uri' => 'this-uri',
  127. '{DAV:}displayname' => 'Name of calendar',
  128. ], ['shares'], ['{DAV:}displayname' => 'Name'], '', 'admin', ['user1'], ['user1', 'admin']],
  129. [Calendar::SUBJECT_UPDATE, [
  130. 'principaluri' => 'principal/user/admin',
  131. 'id' => 42,
  132. 'uri' => 'this-uri',
  133. '{DAV:}displayname' => 'Name of calendar',
  134. ], ['shares'], ['{DAV:}displayname' => 'Name'], 'test2', 'test2', ['user1'], ['user1', 'admin']],
  135. // Delete calendar
  136. [Calendar::SUBJECT_DELETE, [], [], [], '', '', null, []],
  137. [Calendar::SUBJECT_DELETE, [
  138. 'principaluri' => 'principal/user/admin',
  139. 'id' => 42,
  140. 'uri' => 'this-uri',
  141. '{DAV:}displayname' => 'Name of calendar',
  142. ], ['shares'], [], '', 'admin', [], ['admin']],
  143. [Calendar::SUBJECT_DELETE, [
  144. 'principaluri' => 'principal/user/admin',
  145. 'id' => 42,
  146. 'uri' => 'this-uri',
  147. '{DAV:}displayname' => 'Name of calendar',
  148. ], ['shares'], [], '', 'admin', ['user1'], ['user1', 'admin']],
  149. [Calendar::SUBJECT_DELETE, [
  150. 'principaluri' => 'principal/user/admin',
  151. 'id' => 42,
  152. 'uri' => 'this-uri',
  153. '{DAV:}displayname' => 'Name of calendar',
  154. ], ['shares'], [], 'test2', 'test2', ['user1'], ['user1', 'admin']],
  155. // Publish calendar
  156. [Calendar::SUBJECT_PUBLISH, [], [], [], '', '', null, []],
  157. [Calendar::SUBJECT_PUBLISH, [
  158. 'principaluri' => 'principal/user/admin',
  159. 'id' => 42,
  160. 'uri' => 'this-uri',
  161. '{DAV:}displayname' => 'Name of calendar',
  162. ], ['shares'], [], '', 'admin', [], ['admin']],
  163. // Unpublish calendar
  164. [Calendar::SUBJECT_UNPUBLISH, [], [], [], '', '', null, []],
  165. [Calendar::SUBJECT_UNPUBLISH, [
  166. 'principaluri' => 'principal/user/admin',
  167. 'id' => 42,
  168. 'uri' => 'this-uri',
  169. '{DAV:}displayname' => 'Name of calendar',
  170. ], ['shares'], [], '', 'admin', [], ['admin']],
  171. ];
  172. }
  173. /**
  174. * @dataProvider dataTriggerCalendarActivity
  175. * @param string $action
  176. * @param array $data
  177. * @param array $shares
  178. * @param array $changedProperties
  179. * @param string $currentUser
  180. * @param string $author
  181. * @param string[]|null $shareUsers
  182. * @param string[] $users
  183. */
  184. public function testTriggerCalendarActivity($action, array $data, array $shares, array $changedProperties, $currentUser, $author, $shareUsers, array $users) {
  185. $backend = $this->getBackend(['getUsersForShares']);
  186. if ($shareUsers === null) {
  187. $backend->expects($this->never())
  188. ->method('getUsersForShares');
  189. } else {
  190. $backend->expects($this->once())
  191. ->method('getUsersForShares')
  192. ->with($shares)
  193. ->willReturn($shareUsers);
  194. }
  195. if ($author !== '') {
  196. if ($currentUser !== '') {
  197. $this->userSession->expects($this->once())
  198. ->method('getUser')
  199. ->willReturn($this->getUserMock($currentUser));
  200. } else {
  201. $this->userSession->expects($this->once())
  202. ->method('getUser')
  203. ->willReturn(null);
  204. }
  205. $event = $this->createMock(IEvent::class);
  206. $this->activityManager->expects($this->once())
  207. ->method('generateEvent')
  208. ->willReturn($event);
  209. $event->expects($this->once())
  210. ->method('setApp')
  211. ->with('dav')
  212. ->willReturnSelf();
  213. $event->expects($this->once())
  214. ->method('setObject')
  215. ->with('calendar', $data['id'])
  216. ->willReturnSelf();
  217. $event->expects($this->once())
  218. ->method('setType')
  219. ->with('calendar')
  220. ->willReturnSelf();
  221. $event->expects($this->once())
  222. ->method('setAuthor')
  223. ->with($author)
  224. ->willReturnSelf();
  225. $event->expects($this->exactly(sizeof($users)))
  226. ->method('setAffectedUser')
  227. ->willReturnSelf();
  228. $event->expects($this->exactly(sizeof($users)))
  229. ->method('setSubject')
  230. ->willReturnSelf();
  231. $this->activityManager->expects($this->exactly(sizeof($users)))
  232. ->method('publish')
  233. ->with($event);
  234. } else {
  235. $this->activityManager->expects($this->never())
  236. ->method('generateEvent');
  237. }
  238. $this->invokePrivate($backend, 'triggerCalendarActivity', [$action, $data, $shares, $changedProperties]);
  239. }
  240. public function dataGetUsersForShares() {
  241. return [
  242. [
  243. [],
  244. [],
  245. [],
  246. ],
  247. [
  248. [
  249. ['{http://owncloud.org/ns}principal' => 'principal/users/user1'],
  250. ['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
  251. ['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
  252. ['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
  253. ['{http://owncloud.org/ns}principal' => 'principal/users/user3'],
  254. ],
  255. [],
  256. ['user1', 'user2', 'user3'],
  257. ],
  258. [
  259. [
  260. ['{http://owncloud.org/ns}principal' => 'principal/users/user1'],
  261. ['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
  262. ['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
  263. ['{http://owncloud.org/ns}principal' => 'principal/groups/group2'],
  264. ['{http://owncloud.org/ns}principal' => 'principal/groups/group3'],
  265. ],
  266. ['group2' => null, 'group3' => null],
  267. ['user1', 'user2'],
  268. ],
  269. [
  270. [
  271. ['{http://owncloud.org/ns}principal' => 'principal/users/user1'],
  272. ['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
  273. ['{http://owncloud.org/ns}principal' => 'principal/users/user2'],
  274. ['{http://owncloud.org/ns}principal' => 'principal/groups/group2'],
  275. ['{http://owncloud.org/ns}principal' => 'principal/groups/group3'],
  276. ],
  277. ['group2' => ['user1', 'user2', 'user3'], 'group3' => ['user2', 'user3', 'user4']],
  278. ['user1', 'user2', 'user3', 'user4'],
  279. ],
  280. ];
  281. }
  282. /**
  283. * @dataProvider dataGetUsersForShares
  284. * @param array $shares
  285. * @param array $groups
  286. * @param array $expected
  287. */
  288. public function testGetUsersForShares(array $shares, array $groups, array $expected) {
  289. $backend = $this->getBackend();
  290. $getGroups = [];
  291. foreach ($groups as $gid => $members) {
  292. if ($members === null) {
  293. $getGroups[] = [$gid, null];
  294. continue;
  295. }
  296. $group = $this->createMock(IGroup::class);
  297. $group->expects($this->once())
  298. ->method('getUsers')
  299. ->willReturn($this->getUsers($members));
  300. $getGroups[] = [$gid, $group];
  301. }
  302. $this->groupManager->expects($this->exactly(sizeof($getGroups)))
  303. ->method('get')
  304. ->willReturnMap($getGroups);
  305. $users = $this->invokePrivate($backend, 'getUsersForShares', [$shares]);
  306. sort($users);
  307. $this->assertEquals($expected, $users);
  308. }
  309. /**
  310. * @param string[] $users
  311. * @return IUser[]|\PHPUnit_Framework_MockObject_MockObject[]
  312. */
  313. protected function getUsers(array $users) {
  314. $list = [];
  315. foreach ($users as $user) {
  316. $list[] = $this->getUserMock($user);
  317. }
  318. return $list;
  319. }
  320. /**
  321. * @param string $uid
  322. * @return IUser|\PHPUnit_Framework_MockObject_MockObject
  323. */
  324. protected function getUserMock($uid) {
  325. $user = $this->createMock(IUser::class);
  326. $user->expects($this->once())
  327. ->method('getUID')
  328. ->willReturn($uid);
  329. return $user;
  330. }
  331. }