CalendarTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. * @copyright Copyright (c) 2020, Gary Kim <gary@garykim.dev>
  5. *
  6. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author Gary Kim <gary@garykim.dev>
  8. * @author Georg Ehrke <oc.list@georgehrke.com>
  9. * @author Joas Schilling <coding@schilljs.com>
  10. * @author Morris Jobke <hey@morrisjobke.de>
  11. * @author Roeland Jago Douma <roeland@famdouma.nl>
  12. * @author Thomas Müller <thomas.mueller@tmit.eu>
  13. *
  14. * @license AGPL-3.0
  15. *
  16. * This code is free software: you can redistribute it and/or modify
  17. * it under the terms of the GNU Affero General Public License, version 3,
  18. * as published by the Free Software Foundation.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU Affero General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU Affero General Public License, version 3,
  26. * along with this program. If not, see <http://www.gnu.org/licenses/>
  27. *
  28. */
  29. namespace OCA\DAV\Tests\unit\CalDAV;
  30. use OCA\DAV\CalDAV\BirthdayService;
  31. use OCA\DAV\CalDAV\CalDavBackend;
  32. use OCA\DAV\CalDAV\Calendar;
  33. use OCP\IConfig;
  34. use OCP\IL10N;
  35. use PHPUnit\Framework\MockObject\MockObject;
  36. use Psr\Log\LoggerInterface;
  37. use Sabre\DAV\PropPatch;
  38. use Sabre\VObject\Reader;
  39. use Test\TestCase;
  40. class CalendarTest extends TestCase {
  41. /** @var IL10N */
  42. protected $l10n;
  43. /** @var IConfig */
  44. protected $config;
  45. /** @var MockObject|LoggerInterface */
  46. protected $logger;
  47. protected function setUp(): void {
  48. parent::setUp();
  49. $this->l10n = $this->getMockBuilder(IL10N::class)
  50. ->disableOriginalConstructor()->getMock();
  51. $this->config = $this->createMock(IConfig::class);
  52. $this->logger = $this->createMock(LoggerInterface::class);
  53. $this->l10n
  54. ->expects($this->any())
  55. ->method('t')
  56. ->willReturnCallback(function ($text, $parameters = []) {
  57. return vsprintf($text, $parameters);
  58. });
  59. }
  60. public function testDelete(): void {
  61. /** @var MockObject | CalDavBackend $backend */
  62. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  63. $backend->expects($this->once())->method('updateShares');
  64. $backend->expects($this->any())->method('getShares')->willReturn([
  65. ['href' => 'principal:user2']
  66. ]);
  67. $calendarInfo = [
  68. '{http://owncloud.org/ns}owner-principal' => 'user1',
  69. 'principaluri' => 'user2',
  70. 'id' => 666,
  71. 'uri' => 'cal',
  72. ];
  73. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  74. $c->delete();
  75. }
  76. public function testDeleteFromGroup(): void {
  77. $this->expectException(\Sabre\DAV\Exception\Forbidden::class);
  78. /** @var MockObject | CalDavBackend $backend */
  79. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  80. $backend->expects($this->never())->method('updateShares');
  81. $backend->expects($this->any())->method('getShares')->willReturn([
  82. ['href' => 'principal:group2']
  83. ]);
  84. $calendarInfo = [
  85. '{http://owncloud.org/ns}owner-principal' => 'user1',
  86. 'principaluri' => 'user2',
  87. 'id' => 666,
  88. 'uri' => 'cal',
  89. ];
  90. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  91. $c->delete();
  92. }
  93. public function testDeleteOwn(): void {
  94. /** @var MockObject | CalDavBackend $backend */
  95. $backend = $this->createMock(CalDavBackend::class);
  96. $backend->expects($this->never())->method('updateShares');
  97. $backend->expects($this->never())->method('getShares');
  98. $this->config->expects($this->never())->method('setUserValue');
  99. $backend->expects($this->once())->method('deleteCalendar')
  100. ->with(666);
  101. $calendarInfo = [
  102. '{http://owncloud.org/ns}owner-principal' => 'user1',
  103. 'principaluri' => 'user1',
  104. 'id' => 666,
  105. 'uri' => 'cal',
  106. ];
  107. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  108. $c->delete();
  109. }
  110. public function testDeleteBirthdayCalendar(): void {
  111. /** @var MockObject | CalDavBackend $backend */
  112. $backend = $this->createMock(CalDavBackend::class);
  113. $backend->expects($this->once())->method('deleteCalendar')
  114. ->with(666);
  115. $this->config->expects($this->once())
  116. ->method('setUserValue')
  117. ->with('user1', 'dav', 'generateBirthdayCalendar', 'no');
  118. $calendarInfo = [
  119. '{http://owncloud.org/ns}owner-principal' => 'principals/users/user1',
  120. 'principaluri' => 'principals/users/user1',
  121. 'id' => 666,
  122. 'uri' => 'contact_birthdays',
  123. ];
  124. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  125. $c->delete();
  126. }
  127. public function dataPropPatch() {
  128. return [
  129. ['user1', 'user2', [], true],
  130. ['user1', 'user2', [
  131. '{http://owncloud.org/ns}calendar-enabled' => true,
  132. ], true],
  133. ['user1', 'user2', [
  134. '{DAV:}displayname' => true,
  135. ], true],
  136. ['user1', 'user2', [
  137. '{DAV:}displayname' => true,
  138. '{http://owncloud.org/ns}calendar-enabled' => true,
  139. ], true],
  140. ['user1', 'user1', [], false],
  141. ['user1', 'user1', [
  142. '{http://owncloud.org/ns}calendar-enabled' => true,
  143. ], false],
  144. ['user1', 'user1', [
  145. '{DAV:}displayname' => true,
  146. ], false],
  147. ['user1', 'user1', [
  148. '{DAV:}displayname' => true,
  149. '{http://owncloud.org/ns}calendar-enabled' => true,
  150. ], false],
  151. ];
  152. }
  153. /**
  154. * @dataProvider dataPropPatch
  155. */
  156. public function testPropPatch($ownerPrincipal, $principalUri, $mutations, $shared): void {
  157. /** @var MockObject | CalDavBackend $backend */
  158. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  159. $calendarInfo = [
  160. '{http://owncloud.org/ns}owner-principal' => $ownerPrincipal,
  161. 'principaluri' => $principalUri,
  162. 'id' => 666,
  163. 'uri' => 'default'
  164. ];
  165. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  166. $propPatch = new PropPatch($mutations);
  167. if (!$shared) {
  168. $backend->expects($this->once())
  169. ->method('updateCalendar')
  170. ->with(666, $propPatch);
  171. }
  172. $c->propPatch($propPatch);
  173. $this->addToAssertionCount(1);
  174. }
  175. /**
  176. * @dataProvider providesReadOnlyInfo
  177. */
  178. public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet, $uri = 'default'): void {
  179. /** @var MockObject | CalDavBackend $backend */
  180. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  181. $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1);
  182. $calendarInfo = [
  183. 'principaluri' => 'user2',
  184. 'id' => 666,
  185. 'uri' => $uri
  186. ];
  187. if (!is_null($readOnlyValue)) {
  188. $calendarInfo['{http://owncloud.org/ns}read-only'] = $readOnlyValue;
  189. }
  190. if ($hasOwnerSet) {
  191. $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1';
  192. }
  193. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  194. $acl = $c->getACL();
  195. $childAcl = $c->getChildACL();
  196. $expectedAcl = [[
  197. 'privilege' => '{DAV:}read',
  198. 'principal' => $hasOwnerSet ? 'user1' : 'user2',
  199. 'protected' => true
  200. ], [
  201. 'privilege' => '{DAV:}read',
  202. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
  203. 'protected' => true,
  204. ], [
  205. 'privilege' => '{DAV:}read',
  206. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-read',
  207. 'protected' => true,
  208. ]];
  209. if ($uri === BirthdayService::BIRTHDAY_CALENDAR_URI) {
  210. $expectedAcl[] = [
  211. 'privilege' => '{DAV:}write-properties',
  212. 'principal' => $hasOwnerSet ? 'user1' : 'user2',
  213. 'protected' => true
  214. ];
  215. $expectedAcl[] = [
  216. 'privilege' => '{DAV:}write-properties',
  217. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
  218. 'protected' => true
  219. ];
  220. } else {
  221. $expectedAcl[] = [
  222. 'privilege' => '{DAV:}write',
  223. 'principal' => $hasOwnerSet ? 'user1' : 'user2',
  224. 'protected' => true
  225. ];
  226. $expectedAcl[] = [
  227. 'privilege' => '{DAV:}write',
  228. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
  229. 'protected' => true
  230. ];
  231. }
  232. $expectedAcl[] = [
  233. 'privilege' => '{DAV:}write-properties',
  234. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-read',
  235. 'protected' => true
  236. ];
  237. if ($hasOwnerSet) {
  238. $expectedAcl[] = [
  239. 'privilege' => '{DAV:}read',
  240. 'principal' => 'user2',
  241. 'protected' => true
  242. ];
  243. if ($expectsWrite) {
  244. $expectedAcl[] = [
  245. 'privilege' => '{DAV:}write',
  246. 'principal' => 'user2',
  247. 'protected' => true
  248. ];
  249. } else {
  250. $expectedAcl[] = [
  251. 'privilege' => '{DAV:}write-properties',
  252. 'principal' => 'user2',
  253. 'protected' => true
  254. ];
  255. }
  256. }
  257. $this->assertEquals($expectedAcl, $acl);
  258. $this->assertEquals($expectedAcl, $childAcl);
  259. }
  260. public function providesReadOnlyInfo() {
  261. return [
  262. 'read-only property not set' => [true, null, true],
  263. 'read-only property is false' => [true, false, true],
  264. 'read-only property is true' => [false, true, true],
  265. 'read-only property not set and no owner' => [true, null, false],
  266. 'read-only property is false and no owner' => [true, false, false],
  267. 'read-only property is true and no owner' => [false, true, false],
  268. 'birthday calendar' => [false, false, false, BirthdayService::BIRTHDAY_CALENDAR_URI]
  269. ];
  270. }
  271. /**
  272. * @dataProvider providesConfidentialClassificationData
  273. * @param int $expectedChildren
  274. * @param bool $isShared
  275. */
  276. public function testPrivateClassification($expectedChildren, $isShared): void {
  277. $calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC];
  278. $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL];
  279. $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE];
  280. /** @var MockObject | CalDavBackend $backend */
  281. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  282. $backend->expects($this->any())->method('getCalendarObjects')->willReturn([
  283. $calObject0, $calObject1, $calObject2
  284. ]);
  285. $backend->expects($this->any())->method('getMultipleCalendarObjects')
  286. ->with(666, ['event-0', 'event-1', 'event-2'])
  287. ->willReturn([
  288. $calObject0, $calObject1, $calObject2
  289. ]);
  290. $backend->expects($this->any())->method('getCalendarObject')
  291. ->willReturn($calObject2)->with(666, 'event-2');
  292. $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1);
  293. $calendarInfo = [
  294. 'principaluri' => 'user2',
  295. 'id' => 666,
  296. 'uri' => 'cal',
  297. ];
  298. if ($isShared) {
  299. $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1';
  300. }
  301. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  302. $children = $c->getChildren();
  303. $this->assertEquals($expectedChildren, count($children));
  304. $children = $c->getMultipleChildren(['event-0', 'event-1', 'event-2']);
  305. $this->assertEquals($expectedChildren, count($children));
  306. $this->assertEquals(!$isShared, $c->childExists('event-2'));
  307. }
  308. /**
  309. * @dataProvider providesConfidentialClassificationData
  310. * @param int $expectedChildren
  311. * @param bool $isShared
  312. */
  313. public function testConfidentialClassification($expectedChildren, $isShared): void {
  314. $start = '20160609';
  315. $end = '20160610';
  316. $calData = <<<EOD
  317. BEGIN:VCALENDAR
  318. PRODID:-//ownCloud calendar v1.2.2
  319. BEGIN:VEVENT
  320. CREATED:20160602T133732
  321. DTSTAMP:20160602T133732
  322. LAST-MODIFIED:20160602T133732
  323. UID:wej2z68l9h
  324. SUMMARY:Test Event
  325. LOCATION:Somewhere ...
  326. ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CUTYPE=INDIVIDUAL;CN=de
  327. epdiver:MAILTO:thomas.mueller@tmit.eu
  328. ORGANIZER;CN=deepdiver:MAILTO:thomas.mueller@tmit.eu
  329. DESCRIPTION:maybe ....
  330. DTSTART;TZID=Europe/Berlin;VALUE=DATE:$start
  331. DTEND;TZID=Europe/Berlin;VALUE=DATE:$end
  332. RRULE:FREQ=DAILY
  333. BEGIN:VALARM
  334. ACTION:AUDIO
  335. TRIGGER:-PT15M
  336. END:VALARM
  337. END:VEVENT
  338. BEGIN:VTIMEZONE
  339. TZID:Europe/Berlin
  340. BEGIN:DAYLIGHT
  341. DTSTART:19810329T020000
  342. RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
  343. TZNAME:MESZ
  344. TZOFFSETFROM:+0100
  345. TZOFFSETTO:+0200
  346. END:DAYLIGHT
  347. BEGIN:STANDARD
  348. DTSTART:19961027T030000
  349. RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
  350. TZNAME:MEZ
  351. TZOFFSETFROM:+0200
  352. TZOFFSETTO:+0100
  353. END:STANDARD
  354. END:VTIMEZONE
  355. END:VCALENDAR
  356. EOD;
  357. $calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC];
  358. $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'calendardata' => $calData];
  359. $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE];
  360. /** @var MockObject | CalDavBackend $backend */
  361. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  362. $backend->expects($this->any())->method('getCalendarObjects')->willReturn([
  363. $calObject0, $calObject1, $calObject2
  364. ]);
  365. $backend->expects($this->any())->method('getMultipleCalendarObjects')
  366. ->with(666, ['event-0', 'event-1', 'event-2'])
  367. ->willReturn([
  368. $calObject0, $calObject1, $calObject2
  369. ]);
  370. $backend->expects($this->any())->method('getCalendarObject')
  371. ->willReturn($calObject1)->with(666, 'event-1');
  372. $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1);
  373. $calendarInfo = [
  374. '{http://owncloud.org/ns}owner-principal' => $isShared ? 'user1' : 'user2',
  375. 'principaluri' => 'user2',
  376. 'id' => 666,
  377. 'uri' => 'cal',
  378. ];
  379. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  380. $this->assertEquals(count($c->getChildren()), $expectedChildren);
  381. // test private event
  382. $privateEvent = $c->getChild('event-1');
  383. $calData = $privateEvent->get();
  384. $event = Reader::read($calData);
  385. $this->assertEquals($start, $event->VEVENT->DTSTART->getValue());
  386. $this->assertEquals($end, $event->VEVENT->DTEND->getValue());
  387. if ($isShared) {
  388. $this->assertEquals('Busy', $event->VEVENT->SUMMARY->getValue());
  389. $this->assertArrayNotHasKey('ATTENDEE', $event->VEVENT);
  390. $this->assertArrayNotHasKey('LOCATION', $event->VEVENT);
  391. $this->assertArrayNotHasKey('DESCRIPTION', $event->VEVENT);
  392. $this->assertArrayNotHasKey('ORGANIZER', $event->VEVENT);
  393. } else {
  394. $this->assertEquals('Test Event', $event->VEVENT->SUMMARY->getValue());
  395. }
  396. // Test l10n
  397. $l10n = $this->createMock(IL10N::class);
  398. if ($isShared) {
  399. $l10n->expects($this->once())
  400. ->method('t')
  401. ->with('Busy')
  402. ->willReturn("Translated busy");
  403. } else {
  404. $l10n->expects($this->never())
  405. ->method('t');
  406. }
  407. $c = new Calendar($backend, $calendarInfo, $l10n, $this->config, $this->logger);
  408. $calData = $c->getChild('event-1')->get();
  409. $event = Reader::read($calData);
  410. if ($isShared) {
  411. $this->assertEquals('Translated busy', $event->VEVENT->SUMMARY->getValue());
  412. } else {
  413. $this->assertEquals('Test Event', $event->VEVENT->SUMMARY->getValue());
  414. }
  415. }
  416. public function providesConfidentialClassificationData() {
  417. return [
  418. [3, false],
  419. [2, true]
  420. ];
  421. }
  422. public function testRemoveVAlarms() {
  423. $publicObjectData = <<<EOD
  424. BEGIN:VCALENDAR
  425. VERSION:2.0
  426. PRODID:-//Nextcloud calendar v1.5.6
  427. CALSCALE:GREGORIAN
  428. BEGIN:VEVENT
  429. CREATED:20171022T125130
  430. DTSTAMP:20171022T125130
  431. LAST-MODIFIED:20171022T125130
  432. UID:PPL24TH8UGOWE94XET87ER
  433. SUMMARY:Foo bar blub
  434. CLASS:PUBLIC
  435. STATUS:CONFIRMED
  436. DTSTART;VALUE=DATE:20171024
  437. DTEND;VALUE=DATE:20171025
  438. BEGIN:VALARM
  439. ACTION:AUDIO
  440. TRIGGER:-PT15M
  441. END:VALARM
  442. END:VEVENT
  443. END:VCALENDAR
  444. EOD;
  445. $confidentialObjectData = <<<EOD
  446. BEGIN:VCALENDAR
  447. VERSION:2.0
  448. PRODID:-//Nextcloud calendar v1.5.6
  449. CALSCALE:GREGORIAN
  450. BEGIN:VEVENT
  451. CREATED:20171022T125130
  452. DTSTAMP:20171022T125130
  453. LAST-MODIFIED:20171022T125130
  454. UID:PPL24TH8UGOWE94XET87ER
  455. SUMMARY:Foo bar blub
  456. CLASS:CONFIDENTIAL
  457. STATUS:CONFIRMED
  458. DTSTART;VALUE=DATE:20171024
  459. DTEND;VALUE=DATE:20171025
  460. BEGIN:VALARM
  461. ACTION:AUDIO
  462. TRIGGER:-PT15M
  463. END:VALARM
  464. END:VEVENT
  465. END:VCALENDAR
  466. EOD;
  467. $publicObjectDataWithoutVAlarm = <<<EOD
  468. BEGIN:VCALENDAR
  469. VERSION:2.0
  470. PRODID:-//Nextcloud calendar v1.5.6
  471. CALSCALE:GREGORIAN
  472. BEGIN:VEVENT
  473. CREATED:20171022T125130
  474. DTSTAMP:20171022T125130
  475. LAST-MODIFIED:20171022T125130
  476. UID:PPL24TH8UGOWE94XET87ER
  477. SUMMARY:Foo bar blub
  478. CLASS:PUBLIC
  479. STATUS:CONFIRMED
  480. DTSTART;VALUE=DATE:20171024
  481. DTEND;VALUE=DATE:20171025
  482. END:VEVENT
  483. END:VCALENDAR
  484. EOD;
  485. $confidentialObjectCleaned = <<<EOD
  486. BEGIN:VCALENDAR
  487. VERSION:2.0
  488. PRODID:-//Nextcloud calendar v1.5.6
  489. CALSCALE:GREGORIAN
  490. BEGIN:VEVENT
  491. CREATED:20171022T125130
  492. UID:PPL24TH8UGOWE94XET87ER
  493. SUMMARY:Busy
  494. CLASS:CONFIDENTIAL
  495. DTSTART;VALUE=DATE:20171024
  496. DTEND;VALUE=DATE:20171025
  497. END:VEVENT
  498. END:VCALENDAR
  499. EOD;
  500. $publicObject = ['uri' => 'event-0',
  501. 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC,
  502. 'calendardata' => $publicObjectData];
  503. $confidentialObject = ['uri' => 'event-1',
  504. 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL,
  505. 'calendardata' => $confidentialObjectData];
  506. /** @var MockObject | CalDavBackend $backend */
  507. $backend = $this->createMock(CalDavBackend::class);
  508. $backend->expects($this->any())
  509. ->method('getCalendarObjects')
  510. ->willReturn([$publicObject, $confidentialObject]);
  511. $backend->expects($this->any())
  512. ->method('getMultipleCalendarObjects')
  513. ->with(666, ['event-0', 'event-1'])
  514. ->willReturn([$publicObject, $confidentialObject]);
  515. $backend->expects($this->any())
  516. ->method('getCalendarObject')
  517. ->willReturnCallback(function ($cId, $uri) use ($publicObject, $confidentialObject) {
  518. switch ($uri) {
  519. case 'event-0':
  520. return $publicObject;
  521. case 'event-1':
  522. return $confidentialObject;
  523. default:
  524. throw new \Exception('unexpected uri');
  525. }
  526. });
  527. $backend->expects($this->any())
  528. ->method('applyShareAcl')
  529. ->willReturnArgument(1);
  530. $calendarInfoOwner = [
  531. '{http://owncloud.org/ns}owner-principal' => 'user1',
  532. 'principaluri' => 'user1',
  533. 'id' => 666,
  534. 'uri' => 'cal',
  535. ];
  536. $calendarInfoSharedRW = [
  537. '{http://owncloud.org/ns}owner-principal' => 'user1',
  538. 'principaluri' => 'user2',
  539. 'id' => 666,
  540. 'uri' => 'cal',
  541. ];
  542. $calendarInfoSharedRO = [
  543. '{http://owncloud.org/ns}owner-principal' => 'user1',
  544. '{http://owncloud.org/ns}read-only' => true,
  545. 'principaluri' => 'user2',
  546. 'id' => 666,
  547. 'uri' => 'cal',
  548. ];
  549. $ownerCalendar = new Calendar($backend, $calendarInfoOwner, $this->l10n, $this->config, $this->logger);
  550. $rwCalendar = new Calendar($backend, $calendarInfoSharedRW, $this->l10n, $this->config, $this->logger);
  551. $roCalendar = new Calendar($backend, $calendarInfoSharedRO, $this->l10n, $this->config, $this->logger);
  552. $this->assertCount(2, $ownerCalendar->getChildren());
  553. $this->assertCount(2, $rwCalendar->getChildren());
  554. $this->assertCount(2, $roCalendar->getChildren());
  555. // calendar data shall not be altered for the owner
  556. $this->assertEquals($ownerCalendar->getChild('event-0')->get(), $publicObjectData);
  557. $this->assertEquals($ownerCalendar->getChild('event-1')->get(), $confidentialObjectData);
  558. // valarms shall not be removed for read-write shares
  559. $this->assertEquals(
  560. $this->fixLinebreak($rwCalendar->getChild('event-0')->get()),
  561. $this->fixLinebreak($publicObjectData));
  562. $this->assertEquals(
  563. $this->fixLinebreak($rwCalendar->getChild('event-1')->get()),
  564. $this->fixLinebreak($confidentialObjectCleaned));
  565. // valarms shall be removed for read-only shares
  566. $this->assertEquals(
  567. $this->fixLinebreak($roCalendar->getChild('event-0')->get()),
  568. $this->fixLinebreak($publicObjectDataWithoutVAlarm));
  569. $this->assertEquals(
  570. $this->fixLinebreak($roCalendar->getChild('event-1')->get()),
  571. $this->fixLinebreak($confidentialObjectCleaned));
  572. }
  573. private function fixLinebreak($str) {
  574. return preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $str);
  575. }
  576. }