CalendarTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  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. /** @var MockObject | CalDavBackend $backend */
  78. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  79. $backend->expects($this->once())->method('updateShares');
  80. $backend->expects($this->any())->method('getShares')->willReturn([
  81. ['href' => 'principal:group2']
  82. ]);
  83. $calendarInfo = [
  84. '{http://owncloud.org/ns}owner-principal' => 'user1',
  85. 'principaluri' => 'user2',
  86. 'id' => 666,
  87. 'uri' => 'cal',
  88. ];
  89. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  90. $c->delete();
  91. }
  92. public function testDeleteOwn(): void {
  93. /** @var MockObject | CalDavBackend $backend */
  94. $backend = $this->createMock(CalDavBackend::class);
  95. $backend->expects($this->never())->method('updateShares');
  96. $backend->expects($this->never())->method('getShares');
  97. $this->config->expects($this->never())->method('setUserValue');
  98. $backend->expects($this->once())->method('deleteCalendar')
  99. ->with(666);
  100. $calendarInfo = [
  101. '{http://owncloud.org/ns}owner-principal' => 'user1',
  102. 'principaluri' => 'user1',
  103. 'id' => 666,
  104. 'uri' => 'cal',
  105. ];
  106. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  107. $c->delete();
  108. }
  109. public function testDeleteBirthdayCalendar(): void {
  110. /** @var MockObject | CalDavBackend $backend */
  111. $backend = $this->createMock(CalDavBackend::class);
  112. $backend->expects($this->once())->method('deleteCalendar')
  113. ->with(666);
  114. $this->config->expects($this->once())
  115. ->method('setUserValue')
  116. ->with('user1', 'dav', 'generateBirthdayCalendar', 'no');
  117. $calendarInfo = [
  118. '{http://owncloud.org/ns}owner-principal' => 'principals/users/user1',
  119. 'principaluri' => 'principals/users/user1',
  120. 'id' => 666,
  121. 'uri' => 'contact_birthdays',
  122. ];
  123. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  124. $c->delete();
  125. }
  126. public function dataPropPatch() {
  127. return [
  128. ['user1', 'user2', [], true],
  129. ['user1', 'user2', [
  130. '{http://owncloud.org/ns}calendar-enabled' => true,
  131. ], true],
  132. ['user1', 'user2', [
  133. '{DAV:}displayname' => true,
  134. ], true],
  135. ['user1', 'user2', [
  136. '{DAV:}displayname' => true,
  137. '{http://owncloud.org/ns}calendar-enabled' => true,
  138. ], true],
  139. ['user1', 'user1', [], false],
  140. ['user1', 'user1', [
  141. '{http://owncloud.org/ns}calendar-enabled' => true,
  142. ], false],
  143. ['user1', 'user1', [
  144. '{DAV:}displayname' => true,
  145. ], false],
  146. ['user1', 'user1', [
  147. '{DAV:}displayname' => true,
  148. '{http://owncloud.org/ns}calendar-enabled' => true,
  149. ], false],
  150. ];
  151. }
  152. /**
  153. * @dataProvider dataPropPatch
  154. */
  155. public function testPropPatch($ownerPrincipal, $principalUri, $mutations, $shared): void {
  156. /** @var MockObject | CalDavBackend $backend */
  157. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  158. $calendarInfo = [
  159. '{http://owncloud.org/ns}owner-principal' => $ownerPrincipal,
  160. 'principaluri' => $principalUri,
  161. 'id' => 666,
  162. 'uri' => 'default'
  163. ];
  164. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  165. $propPatch = new PropPatch($mutations);
  166. if (!$shared) {
  167. $backend->expects($this->once())
  168. ->method('updateCalendar')
  169. ->with(666, $propPatch);
  170. }
  171. $c->propPatch($propPatch);
  172. $this->addToAssertionCount(1);
  173. }
  174. /**
  175. * @dataProvider providesReadOnlyInfo
  176. */
  177. public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet, $uri = 'default'): void {
  178. /** @var MockObject | CalDavBackend $backend */
  179. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  180. $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1);
  181. $calendarInfo = [
  182. 'principaluri' => 'user2',
  183. 'id' => 666,
  184. 'uri' => $uri
  185. ];
  186. if (!is_null($readOnlyValue)) {
  187. $calendarInfo['{http://owncloud.org/ns}read-only'] = $readOnlyValue;
  188. }
  189. if ($hasOwnerSet) {
  190. $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1';
  191. }
  192. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  193. $acl = $c->getACL();
  194. $childAcl = $c->getChildACL();
  195. $expectedAcl = [[
  196. 'privilege' => '{DAV:}read',
  197. 'principal' => $hasOwnerSet ? 'user1' : 'user2',
  198. 'protected' => true
  199. ], [
  200. 'privilege' => '{DAV:}read',
  201. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
  202. 'protected' => true,
  203. ], [
  204. 'privilege' => '{DAV:}read',
  205. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-read',
  206. 'protected' => true,
  207. ]];
  208. if ($uri === BirthdayService::BIRTHDAY_CALENDAR_URI) {
  209. $expectedAcl[] = [
  210. 'privilege' => '{DAV:}write-properties',
  211. 'principal' => $hasOwnerSet ? 'user1' : 'user2',
  212. 'protected' => true
  213. ];
  214. $expectedAcl[] = [
  215. 'privilege' => '{DAV:}write-properties',
  216. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
  217. 'protected' => true
  218. ];
  219. } else {
  220. $expectedAcl[] = [
  221. 'privilege' => '{DAV:}write',
  222. 'principal' => $hasOwnerSet ? 'user1' : 'user2',
  223. 'protected' => true
  224. ];
  225. $expectedAcl[] = [
  226. 'privilege' => '{DAV:}write',
  227. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-write',
  228. 'protected' => true
  229. ];
  230. }
  231. $expectedAcl[] = [
  232. 'privilege' => '{DAV:}write-properties',
  233. 'principal' => ($hasOwnerSet ? 'user1' : 'user2') . '/calendar-proxy-read',
  234. 'protected' => true
  235. ];
  236. if ($hasOwnerSet) {
  237. $expectedAcl[] = [
  238. 'privilege' => '{DAV:}read',
  239. 'principal' => 'user2',
  240. 'protected' => true
  241. ];
  242. if ($expectsWrite) {
  243. $expectedAcl[] = [
  244. 'privilege' => '{DAV:}write',
  245. 'principal' => 'user2',
  246. 'protected' => true
  247. ];
  248. } else {
  249. $expectedAcl[] = [
  250. 'privilege' => '{DAV:}write-properties',
  251. 'principal' => 'user2',
  252. 'protected' => true
  253. ];
  254. }
  255. }
  256. $this->assertEquals($expectedAcl, $acl);
  257. $this->assertEquals($expectedAcl, $childAcl);
  258. }
  259. public function providesReadOnlyInfo() {
  260. return [
  261. 'read-only property not set' => [true, null, true],
  262. 'read-only property is false' => [true, false, true],
  263. 'read-only property is true' => [false, true, true],
  264. 'read-only property not set and no owner' => [true, null, false],
  265. 'read-only property is false and no owner' => [true, false, false],
  266. 'read-only property is true and no owner' => [false, true, false],
  267. 'birthday calendar' => [false, false, false, BirthdayService::BIRTHDAY_CALENDAR_URI]
  268. ];
  269. }
  270. /**
  271. * @dataProvider providesConfidentialClassificationData
  272. * @param int $expectedChildren
  273. * @param bool $isShared
  274. */
  275. public function testPrivateClassification($expectedChildren, $isShared): void {
  276. $calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC];
  277. $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL];
  278. $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE];
  279. /** @var MockObject | CalDavBackend $backend */
  280. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  281. $backend->expects($this->any())->method('getCalendarObjects')->willReturn([
  282. $calObject0, $calObject1, $calObject2
  283. ]);
  284. $backend->expects($this->any())->method('getMultipleCalendarObjects')
  285. ->with(666, ['event-0', 'event-1', 'event-2'])
  286. ->willReturn([
  287. $calObject0, $calObject1, $calObject2
  288. ]);
  289. $backend->expects($this->any())->method('getCalendarObject')
  290. ->willReturn($calObject2)->with(666, 'event-2');
  291. $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1);
  292. $calendarInfo = [
  293. 'principaluri' => 'user2',
  294. 'id' => 666,
  295. 'uri' => 'cal',
  296. ];
  297. if ($isShared) {
  298. $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1';
  299. }
  300. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  301. $children = $c->getChildren();
  302. $this->assertEquals($expectedChildren, count($children));
  303. $children = $c->getMultipleChildren(['event-0', 'event-1', 'event-2']);
  304. $this->assertEquals($expectedChildren, count($children));
  305. $this->assertEquals(!$isShared, $c->childExists('event-2'));
  306. }
  307. /**
  308. * @dataProvider providesConfidentialClassificationData
  309. * @param int $expectedChildren
  310. * @param bool $isShared
  311. */
  312. public function testConfidentialClassification($expectedChildren, $isShared): void {
  313. $start = '20160609';
  314. $end = '20160610';
  315. $calData = <<<EOD
  316. BEGIN:VCALENDAR
  317. PRODID:-//ownCloud calendar v1.2.2
  318. BEGIN:VEVENT
  319. CREATED:20160602T133732
  320. DTSTAMP:20160602T133732
  321. LAST-MODIFIED:20160602T133732
  322. UID:wej2z68l9h
  323. SUMMARY:Test Event
  324. LOCATION:Somewhere ...
  325. ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CUTYPE=INDIVIDUAL;CN=de
  326. epdiver:MAILTO:thomas.mueller@tmit.eu
  327. ORGANIZER;CN=deepdiver:MAILTO:thomas.mueller@tmit.eu
  328. DESCRIPTION:maybe ....
  329. DTSTART;TZID=Europe/Berlin;VALUE=DATE:$start
  330. DTEND;TZID=Europe/Berlin;VALUE=DATE:$end
  331. RRULE:FREQ=DAILY
  332. BEGIN:VALARM
  333. ACTION:AUDIO
  334. TRIGGER:-PT15M
  335. END:VALARM
  336. END:VEVENT
  337. BEGIN:VTIMEZONE
  338. TZID:Europe/Berlin
  339. BEGIN:DAYLIGHT
  340. DTSTART:19810329T020000
  341. RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
  342. TZNAME:MESZ
  343. TZOFFSETFROM:+0100
  344. TZOFFSETTO:+0200
  345. END:DAYLIGHT
  346. BEGIN:STANDARD
  347. DTSTART:19961027T030000
  348. RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
  349. TZNAME:MEZ
  350. TZOFFSETFROM:+0200
  351. TZOFFSETTO:+0100
  352. END:STANDARD
  353. END:VTIMEZONE
  354. END:VCALENDAR
  355. EOD;
  356. $calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC];
  357. $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'calendardata' => $calData];
  358. $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE];
  359. /** @var MockObject | CalDavBackend $backend */
  360. $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock();
  361. $backend->expects($this->any())->method('getCalendarObjects')->willReturn([
  362. $calObject0, $calObject1, $calObject2
  363. ]);
  364. $backend->expects($this->any())->method('getMultipleCalendarObjects')
  365. ->with(666, ['event-0', 'event-1', 'event-2'])
  366. ->willReturn([
  367. $calObject0, $calObject1, $calObject2
  368. ]);
  369. $backend->expects($this->any())->method('getCalendarObject')
  370. ->willReturn($calObject1)->with(666, 'event-1');
  371. $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1);
  372. $calendarInfo = [
  373. '{http://owncloud.org/ns}owner-principal' => $isShared ? 'user1' : 'user2',
  374. 'principaluri' => 'user2',
  375. 'id' => 666,
  376. 'uri' => 'cal',
  377. ];
  378. $c = new Calendar($backend, $calendarInfo, $this->l10n, $this->config, $this->logger);
  379. $this->assertEquals(count($c->getChildren()), $expectedChildren);
  380. // test private event
  381. $privateEvent = $c->getChild('event-1');
  382. $calData = $privateEvent->get();
  383. $event = Reader::read($calData);
  384. $this->assertEquals($start, $event->VEVENT->DTSTART->getValue());
  385. $this->assertEquals($end, $event->VEVENT->DTEND->getValue());
  386. if ($isShared) {
  387. $this->assertEquals('Busy', $event->VEVENT->SUMMARY->getValue());
  388. $this->assertArrayNotHasKey('ATTENDEE', $event->VEVENT);
  389. $this->assertArrayNotHasKey('LOCATION', $event->VEVENT);
  390. $this->assertArrayNotHasKey('DESCRIPTION', $event->VEVENT);
  391. $this->assertArrayNotHasKey('ORGANIZER', $event->VEVENT);
  392. } else {
  393. $this->assertEquals('Test Event', $event->VEVENT->SUMMARY->getValue());
  394. }
  395. // Test l10n
  396. $l10n = $this->createMock(IL10N::class);
  397. if ($isShared) {
  398. $l10n->expects($this->once())
  399. ->method('t')
  400. ->with('Busy')
  401. ->willReturn("Translated busy");
  402. } else {
  403. $l10n->expects($this->never())
  404. ->method('t');
  405. }
  406. $c = new Calendar($backend, $calendarInfo, $l10n, $this->config, $this->logger);
  407. $calData = $c->getChild('event-1')->get();
  408. $event = Reader::read($calData);
  409. if ($isShared) {
  410. $this->assertEquals('Translated busy', $event->VEVENT->SUMMARY->getValue());
  411. } else {
  412. $this->assertEquals('Test Event', $event->VEVENT->SUMMARY->getValue());
  413. }
  414. }
  415. public function providesConfidentialClassificationData() {
  416. return [
  417. [3, false],
  418. [2, true]
  419. ];
  420. }
  421. public function testRemoveVAlarms() {
  422. $publicObjectData = <<<EOD
  423. BEGIN:VCALENDAR
  424. VERSION:2.0
  425. PRODID:-//Nextcloud calendar v1.5.6
  426. CALSCALE:GREGORIAN
  427. BEGIN:VEVENT
  428. CREATED:20171022T125130
  429. DTSTAMP:20171022T125130
  430. LAST-MODIFIED:20171022T125130
  431. UID:PPL24TH8UGOWE94XET87ER
  432. SUMMARY:Foo bar blub
  433. CLASS:PUBLIC
  434. STATUS:CONFIRMED
  435. DTSTART;VALUE=DATE:20171024
  436. DTEND;VALUE=DATE:20171025
  437. BEGIN:VALARM
  438. ACTION:AUDIO
  439. TRIGGER:-PT15M
  440. END:VALARM
  441. END:VEVENT
  442. END:VCALENDAR
  443. EOD;
  444. $confidentialObjectData = <<<EOD
  445. BEGIN:VCALENDAR
  446. VERSION:2.0
  447. PRODID:-//Nextcloud calendar v1.5.6
  448. CALSCALE:GREGORIAN
  449. BEGIN:VEVENT
  450. CREATED:20171022T125130
  451. DTSTAMP:20171022T125130
  452. LAST-MODIFIED:20171022T125130
  453. UID:PPL24TH8UGOWE94XET87ER
  454. SUMMARY:Foo bar blub
  455. CLASS:CONFIDENTIAL
  456. STATUS:CONFIRMED
  457. DTSTART;VALUE=DATE:20171024
  458. DTEND;VALUE=DATE:20171025
  459. BEGIN:VALARM
  460. ACTION:AUDIO
  461. TRIGGER:-PT15M
  462. END:VALARM
  463. END:VEVENT
  464. END:VCALENDAR
  465. EOD;
  466. $publicObjectDataWithoutVAlarm = <<<EOD
  467. BEGIN:VCALENDAR
  468. VERSION:2.0
  469. PRODID:-//Nextcloud calendar v1.5.6
  470. CALSCALE:GREGORIAN
  471. BEGIN:VEVENT
  472. CREATED:20171022T125130
  473. DTSTAMP:20171022T125130
  474. LAST-MODIFIED:20171022T125130
  475. UID:PPL24TH8UGOWE94XET87ER
  476. SUMMARY:Foo bar blub
  477. CLASS:PUBLIC
  478. STATUS:CONFIRMED
  479. DTSTART;VALUE=DATE:20171024
  480. DTEND;VALUE=DATE:20171025
  481. END:VEVENT
  482. END:VCALENDAR
  483. EOD;
  484. $confidentialObjectCleaned = <<<EOD
  485. BEGIN:VCALENDAR
  486. VERSION:2.0
  487. PRODID:-//Nextcloud calendar v1.5.6
  488. CALSCALE:GREGORIAN
  489. BEGIN:VEVENT
  490. CREATED:20171022T125130
  491. UID:PPL24TH8UGOWE94XET87ER
  492. SUMMARY:Busy
  493. CLASS:CONFIDENTIAL
  494. DTSTART;VALUE=DATE:20171024
  495. DTEND;VALUE=DATE:20171025
  496. END:VEVENT
  497. END:VCALENDAR
  498. EOD;
  499. $publicObject = ['uri' => 'event-0',
  500. 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC,
  501. 'calendardata' => $publicObjectData];
  502. $confidentialObject = ['uri' => 'event-1',
  503. 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL,
  504. 'calendardata' => $confidentialObjectData];
  505. /** @var MockObject | CalDavBackend $backend */
  506. $backend = $this->createMock(CalDavBackend::class);
  507. $backend->expects($this->any())
  508. ->method('getCalendarObjects')
  509. ->willReturn([$publicObject, $confidentialObject]);
  510. $backend->expects($this->any())
  511. ->method('getMultipleCalendarObjects')
  512. ->with(666, ['event-0', 'event-1'])
  513. ->willReturn([$publicObject, $confidentialObject]);
  514. $backend->expects($this->any())
  515. ->method('getCalendarObject')
  516. ->willReturnCallback(function ($cId, $uri) use ($publicObject, $confidentialObject) {
  517. switch ($uri) {
  518. case 'event-0':
  519. return $publicObject;
  520. case 'event-1':
  521. return $confidentialObject;
  522. default:
  523. throw new \Exception('unexpected uri');
  524. }
  525. });
  526. $backend->expects($this->any())
  527. ->method('applyShareAcl')
  528. ->willReturnArgument(1);
  529. $calendarInfoOwner = [
  530. '{http://owncloud.org/ns}owner-principal' => 'user1',
  531. 'principaluri' => 'user1',
  532. 'id' => 666,
  533. 'uri' => 'cal',
  534. ];
  535. $calendarInfoSharedRW = [
  536. '{http://owncloud.org/ns}owner-principal' => 'user1',
  537. 'principaluri' => 'user2',
  538. 'id' => 666,
  539. 'uri' => 'cal',
  540. ];
  541. $calendarInfoSharedRO = [
  542. '{http://owncloud.org/ns}owner-principal' => 'user1',
  543. '{http://owncloud.org/ns}read-only' => true,
  544. 'principaluri' => 'user2',
  545. 'id' => 666,
  546. 'uri' => 'cal',
  547. ];
  548. $ownerCalendar = new Calendar($backend, $calendarInfoOwner, $this->l10n, $this->config, $this->logger);
  549. $rwCalendar = new Calendar($backend, $calendarInfoSharedRW, $this->l10n, $this->config, $this->logger);
  550. $roCalendar = new Calendar($backend, $calendarInfoSharedRO, $this->l10n, $this->config, $this->logger);
  551. $this->assertCount(2, $ownerCalendar->getChildren());
  552. $this->assertCount(2, $rwCalendar->getChildren());
  553. $this->assertCount(2, $roCalendar->getChildren());
  554. // calendar data shall not be altered for the owner
  555. $this->assertEquals($ownerCalendar->getChild('event-0')->get(), $publicObjectData);
  556. $this->assertEquals($ownerCalendar->getChild('event-1')->get(), $confidentialObjectData);
  557. // valarms shall not be removed for read-write shares
  558. $this->assertEquals(
  559. $this->fixLinebreak($rwCalendar->getChild('event-0')->get()),
  560. $this->fixLinebreak($publicObjectData));
  561. $this->assertEquals(
  562. $this->fixLinebreak($rwCalendar->getChild('event-1')->get()),
  563. $this->fixLinebreak($confidentialObjectCleaned));
  564. // valarms shall be removed for read-only shares
  565. $this->assertEquals(
  566. $this->fixLinebreak($roCalendar->getChild('event-0')->get()),
  567. $this->fixLinebreak($publicObjectDataWithoutVAlarm));
  568. $this->assertEquals(
  569. $this->fixLinebreak($roCalendar->getChild('event-1')->get()),
  570. $this->fixLinebreak($confidentialObjectCleaned));
  571. }
  572. private function fixLinebreak($str) {
  573. return preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $str);
  574. }
  575. }