MoveCalendarTest.php 12 KB

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