MoveCalendarTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OCA\DAV\Tests\Command;
  7. use InvalidArgumentException;
  8. use OCA\DAV\CalDAV\CalDavBackend;
  9. use OCA\DAV\Command\MoveCalendar;
  10. use OCP\IConfig;
  11. use OCP\IGroupManager;
  12. use OCP\IL10N;
  13. use OCP\IUserManager;
  14. use OCP\Share\IManager;
  15. use PHPUnit\Framework\MockObject\MockObject;
  16. use Psr\Log\LoggerInterface;
  17. use Symfony\Component\Console\Tester\CommandTester;
  18. use Test\TestCase;
  19. /**
  20. * Class MoveCalendarTest
  21. *
  22. * @package OCA\DAV\Tests\Command
  23. */
  24. class MoveCalendarTest extends TestCase {
  25. /** @var IUserManager|MockObject $userManager */
  26. private $userManager;
  27. /** @var IGroupManager|MockObject $groupManager */
  28. private $groupManager;
  29. /** @var \OCP\Share\IManager|MockObject $shareManager */
  30. private $shareManager;
  31. /** @var IConfig|MockObject $l10n */
  32. private $config;
  33. /** @var IL10N|MockObject $l10n */
  34. private $l10n;
  35. /** @var CalDavBackend|MockObject $l10n */
  36. private $calDav;
  37. /** @var MoveCalendar */
  38. private $command;
  39. /** @var LoggerInterface|MockObject */
  40. private $logger;
  41. protected function setUp(): void {
  42. parent::setUp();
  43. $this->userManager = $this->createMock(IUserManager::class);
  44. $this->groupManager = $this->createMock(IGroupManager::class);
  45. $this->shareManager = $this->createMock(IManager::class);
  46. $this->config = $this->createMock(IConfig::class);
  47. $this->l10n = $this->createMock(IL10N::class);
  48. $this->calDav = $this->createMock(CalDavBackend::class);
  49. $this->logger = $this->createMock(LoggerInterface::class);
  50. $this->command = new MoveCalendar(
  51. $this->userManager,
  52. $this->groupManager,
  53. $this->shareManager,
  54. $this->config,
  55. $this->l10n,
  56. $this->calDav,
  57. $this->logger
  58. );
  59. }
  60. public function dataExecute() {
  61. return [
  62. [false, true],
  63. [true, false]
  64. ];
  65. }
  66. /**
  67. * @dataProvider dataExecute
  68. *
  69. * @param $userOriginExists
  70. * @param $userDestinationExists
  71. */
  72. public function testWithBadUserOrigin($userOriginExists, $userDestinationExists): void {
  73. $this->expectException(\InvalidArgumentException::class);
  74. $this->userManager->expects($this->exactly($userOriginExists ? 2 : 1))
  75. ->method('userExists')
  76. ->withConsecutive(
  77. ['user'],
  78. ['user2'],
  79. )
  80. ->willReturnOnConsecutiveCalls(
  81. $userOriginExists,
  82. $userDestinationExists,
  83. );
  84. $commandTester = new CommandTester($this->command);
  85. $commandTester->execute([
  86. 'name' => $this->command->getName(),
  87. 'sourceuid' => 'user',
  88. 'destinationuid' => 'user2',
  89. ]);
  90. }
  91. public function testMoveWithInexistantCalendar(): void {
  92. $this->expectException(\InvalidArgumentException::class);
  93. $this->expectExceptionMessage('User <user> has no calendar named <personal>. You can run occ dav:list-calendars to list calendars URIs for this user.');
  94. $this->userManager->expects($this->exactly(2))
  95. ->method('userExists')
  96. ->withConsecutive(
  97. ['user'],
  98. ['user2'],
  99. )
  100. ->willReturn(true);
  101. $this->calDav->expects($this->once())->method('getCalendarByUri')
  102. ->with('principals/users/user', 'personal')
  103. ->willReturn(null);
  104. $commandTester = new CommandTester($this->command);
  105. $commandTester->execute([
  106. 'name' => 'personal',
  107. 'sourceuid' => 'user',
  108. 'destinationuid' => 'user2',
  109. ]);
  110. }
  111. public function testMoveWithExistingDestinationCalendar(): void {
  112. $this->expectException(\InvalidArgumentException::class);
  113. $this->expectExceptionMessage('User <user2> already has a calendar named <personal>.');
  114. $this->userManager->expects($this->exactly(2))
  115. ->method('userExists')
  116. ->withConsecutive(
  117. ['user'],
  118. ['user2'],
  119. )
  120. ->willReturn(true);
  121. $this->calDav->expects($this->exactly(2))
  122. ->method('getCalendarByUri')
  123. ->withConsecutive(
  124. ['principals/users/user', 'personal'],
  125. ['principals/users/user2', 'personal'],
  126. )
  127. ->willReturn([
  128. 'id' => 1234,
  129. ]);
  130. $commandTester = new CommandTester($this->command);
  131. $commandTester->execute([
  132. 'name' => 'personal',
  133. 'sourceuid' => 'user',
  134. 'destinationuid' => 'user2',
  135. ]);
  136. }
  137. public function testMove(): void {
  138. $this->userManager->expects($this->exactly(2))
  139. ->method('userExists')
  140. ->withConsecutive(
  141. ['user'],
  142. ['user2'],
  143. )
  144. ->willReturn(true);
  145. $this->calDav->expects($this->exactly(2))
  146. ->method('getCalendarByUri')
  147. ->withConsecutive(
  148. ['principals/users/user', 'personal'],
  149. ['principals/users/user2', 'personal'],
  150. )
  151. ->willReturnOnConsecutiveCalls(
  152. [
  153. 'id' => 1234,
  154. ],
  155. null,
  156. );
  157. $this->calDav->expects($this->once())->method('getShares')
  158. ->with(1234)
  159. ->willReturn([]);
  160. $commandTester = new CommandTester($this->command);
  161. $commandTester->execute([
  162. 'name' => 'personal',
  163. 'sourceuid' => 'user',
  164. 'destinationuid' => 'user2',
  165. ]);
  166. $this->assertStringContainsString('[OK] Calendar <personal> was moved from user <user> to <user2>', $commandTester->getDisplay());
  167. }
  168. public function dataTestMoveWithDestinationNotPartOfGroup(): array {
  169. return [
  170. [true],
  171. [false]
  172. ];
  173. }
  174. /**
  175. * @dataProvider dataTestMoveWithDestinationNotPartOfGroup
  176. */
  177. public function testMoveWithDestinationNotPartOfGroup(bool $shareWithGroupMembersOnly): void {
  178. $this->userManager->expects($this->exactly(2))
  179. ->method('userExists')
  180. ->withConsecutive(
  181. ['user'],
  182. ['user2'],
  183. )
  184. ->willReturn(true);
  185. $this->calDav->expects($this->exactly(2))
  186. ->method('getCalendarByUri')
  187. ->withConsecutive(
  188. ['principals/users/user', 'personal'],
  189. ['principals/users/user2', 'personal'],
  190. )
  191. ->willReturnOnConsecutiveCalls(
  192. [
  193. 'id' => 1234,
  194. 'uri' => 'personal',
  195. ],
  196. null,
  197. );
  198. $this->shareManager->expects($this->once())->method('shareWithGroupMembersOnly')
  199. ->willReturn($shareWithGroupMembersOnly);
  200. $this->calDav->expects($this->once())->method('getShares')
  201. ->with(1234)
  202. ->willReturn([
  203. ['href' => 'principal:principals/groups/nextclouders']
  204. ]);
  205. if ($shareWithGroupMembersOnly === true) {
  206. $this->expectException(InvalidArgumentException::class);
  207. $this->expectExceptionMessage('User <user2> is not part of the group <nextclouders> with whom the calendar <personal> was shared. You may use -f to move the calendar while deleting this share.');
  208. }
  209. $commandTester = new CommandTester($this->command);
  210. $commandTester->execute([
  211. 'name' => 'personal',
  212. 'sourceuid' => 'user',
  213. 'destinationuid' => 'user2',
  214. ]);
  215. }
  216. public function testMoveWithDestinationPartOfGroup(): void {
  217. $this->userManager->expects($this->exactly(2))
  218. ->method('userExists')
  219. ->withConsecutive(
  220. ['user'],
  221. ['user2'],
  222. )
  223. ->willReturn(true);
  224. $this->calDav->expects($this->exactly(2))
  225. ->method('getCalendarByUri')
  226. ->withConsecutive(
  227. ['principals/users/user', 'personal'],
  228. ['principals/users/user2', 'personal'],
  229. )
  230. ->willReturnOnConsecutiveCalls(
  231. [
  232. 'id' => 1234,
  233. 'uri' => 'personal',
  234. ],
  235. null,
  236. );
  237. $this->shareManager->expects($this->once())->method('shareWithGroupMembersOnly')
  238. ->willReturn(true);
  239. $this->calDav->expects($this->once())->method('getShares')
  240. ->with(1234)
  241. ->willReturn([
  242. ['href' => 'principal:principals/groups/nextclouders']
  243. ]);
  244. $this->groupManager->expects($this->once())->method('isInGroup')
  245. ->with('user2', 'nextclouders')
  246. ->willReturn(true);
  247. $commandTester = new CommandTester($this->command);
  248. $commandTester->execute([
  249. 'name' => 'personal',
  250. 'sourceuid' => 'user',
  251. 'destinationuid' => 'user2',
  252. ]);
  253. $this->assertStringContainsString('[OK] Calendar <personal> was moved from user <user> to <user2>', $commandTester->getDisplay());
  254. }
  255. public function testMoveWithDestinationNotPartOfGroupAndForce(): void {
  256. $this->userManager->expects($this->exactly(2))
  257. ->method('userExists')
  258. ->withConsecutive(
  259. ['user'],
  260. ['user2'],
  261. )
  262. ->willReturn(true);
  263. $this->calDav->expects($this->exactly(2))
  264. ->method('getCalendarByUri')
  265. ->withConsecutive(
  266. ['principals/users/user', 'personal'],
  267. ['principals/users/user2', 'personal'],
  268. )
  269. ->willReturnOnConsecutiveCalls(
  270. [
  271. 'id' => 1234,
  272. 'uri' => 'personal',
  273. '{DAV:}displayname' => 'Personal'
  274. ],
  275. null,
  276. );
  277. $this->shareManager->expects($this->once())->method('shareWithGroupMembersOnly')
  278. ->willReturn(true);
  279. $this->calDav->expects($this->once())->method('getShares')
  280. ->with(1234)
  281. ->willReturn([
  282. [
  283. 'href' => 'principal:principals/groups/nextclouders',
  284. '{DAV:}displayname' => 'Personal'
  285. ]
  286. ]);
  287. $this->calDav->expects($this->once())->method('updateShares');
  288. $commandTester = new CommandTester($this->command);
  289. $commandTester->execute([
  290. 'name' => 'personal',
  291. 'sourceuid' => 'user',
  292. 'destinationuid' => 'user2',
  293. '--force' => true
  294. ]);
  295. $this->assertStringContainsString('[OK] Calendar <personal> was moved from user <user> to <user2>', $commandTester->getDisplay());
  296. }
  297. public function dataTestMoveWithCalendarAlreadySharedToDestination(): array {
  298. return [
  299. [true],
  300. [false]
  301. ];
  302. }
  303. /**
  304. * @dataProvider dataTestMoveWithCalendarAlreadySharedToDestination
  305. */
  306. public function testMoveWithCalendarAlreadySharedToDestination(bool $force): void {
  307. $this->userManager->expects($this->exactly(2))
  308. ->method('userExists')
  309. ->withConsecutive(
  310. ['user'],
  311. ['user2'],
  312. )
  313. ->willReturn(true);
  314. $this->calDav->expects($this->exactly(2))
  315. ->method('getCalendarByUri')
  316. ->withConsecutive(
  317. ['principals/users/user', 'personal'],
  318. ['principals/users/user2', 'personal'],
  319. )
  320. ->willReturnOnConsecutiveCalls(
  321. [
  322. 'id' => 1234,
  323. 'uri' => 'personal',
  324. '{DAV:}displayname' => 'Personal'
  325. ],
  326. null,
  327. );
  328. $this->calDav->expects($this->once())->method('getShares')
  329. ->with(1234)
  330. ->willReturn([
  331. [
  332. 'href' => 'principal:principals/users/user2',
  333. '{DAV:}displayname' => 'Personal'
  334. ]
  335. ]);
  336. if ($force === false) {
  337. $this->expectException(InvalidArgumentException::class);
  338. $this->expectExceptionMessage('The calendar <personal> is already shared to user <user2>.You may use -f to move the calendar while deleting this share.');
  339. } else {
  340. $this->calDav->expects($this->once())->method('updateShares');
  341. }
  342. $commandTester = new CommandTester($this->command);
  343. $commandTester->execute([
  344. 'name' => 'personal',
  345. 'sourceuid' => 'user',
  346. 'destinationuid' => 'user2',
  347. '--force' => $force,
  348. ]);
  349. }
  350. }