TipBrokerTest.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OCA\DAV\Tests\unit\CalDAV;
  7. use OCA\DAV\CalDAV\TipBroker;
  8. use Sabre\VObject\Component\VCalendar;
  9. use Test\TestCase;
  10. class TipBrokerTest extends TestCase {
  11. private TipBroker $broker;
  12. private VCalendar $vCalendar1a;
  13. protected function setUp(): void {
  14. parent::setUp();
  15. $this->broker = new TipBroker();
  16. // construct calendar with a 1 hour event and same start/end time zones
  17. $this->vCalendar1a = new VCalendar();
  18. /** @var VEvent $vEvent */
  19. $vEvent = $this->vCalendar1a->add('VEVENT', []);
  20. $vEvent->add('UID', '96a0e6b1-d886-4a55-a60d-152b31401dcc');
  21. $vEvent->add('DTSTAMP', '20240701T000000Z');
  22. $vEvent->add('CREATED', '20240701T000000Z');
  23. $vEvent->add('LAST-MODIFIED', '20240701T000000Z');
  24. $vEvent->add('SEQUENCE', '1');
  25. $vEvent->add('STATUS', 'CONFIRMED');
  26. $vEvent->add('DTSTART', '20240701T080000', ['TZID' => 'America/Toronto']);
  27. $vEvent->add('DTEND', '20240701T090000', ['TZID' => 'America/Toronto']);
  28. $vEvent->add('SUMMARY', 'Test Event');
  29. $vEvent->add('ORGANIZER', 'mailto:organizer@testing.com', ['CN' => 'Organizer']);
  30. $vEvent->add('ATTENDEE', 'mailto:attendee1@testing.com', [
  31. 'CN' => 'Attendee One',
  32. 'CUTYPE' => 'INDIVIDUAL',
  33. 'PARTSTAT' => 'NEEDS-ACTION',
  34. 'ROLE' => 'REQ-PARTICIPANT',
  35. 'RSVP' => 'TRUE'
  36. ]);
  37. }
  38. public function testParseEventForOrganizerOnCreate(): void {
  39. // construct calendar and generate event info for newly created event with one attendee
  40. $calendar = clone $this->vCalendar1a;
  41. $previousEventInfo = [
  42. 'organizer' => null,
  43. 'significantChangeHash' => '',
  44. 'attendees' => [],
  45. ];
  46. $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  47. // test iTip generation
  48. $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]);
  49. $this->assertCount(1, $messages);
  50. $this->assertEquals('REQUEST', $messages[0]->method);
  51. $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender);
  52. $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient);
  53. }
  54. public function testParseEventForOrganizerOnModify(): void {
  55. // construct calendar and generate event info for modified event with one attendee
  56. $calendar = clone $this->vCalendar1a;
  57. $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  58. $calendar->VEVENT->{'LAST-MODIFIED'}->setValue('20240701T020000Z');
  59. $calendar->VEVENT->SEQUENCE->setValue(2);
  60. $calendar->VEVENT->SUMMARY->setValue('Test Event Modified');
  61. $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  62. // test iTip generation
  63. $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]);
  64. $this->assertCount(1, $messages);
  65. $this->assertEquals('REQUEST', $messages[0]->method);
  66. $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender);
  67. $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient);
  68. }
  69. public function testParseEventForOrganizerOnDelete(): void {
  70. // construct calendar and generate event info for modified event with one attendee
  71. $calendar = clone $this->vCalendar1a;
  72. $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  73. $currentEventInfo = $previousEventInfo;
  74. $currentEventInfo['attendees'] = [];
  75. ++$currentEventInfo['sequence'];
  76. // test iTip generation
  77. $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]);
  78. $this->assertCount(1, $messages);
  79. $this->assertEquals('CANCEL', $messages[0]->method);
  80. $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender);
  81. $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient);
  82. }
  83. public function testParseEventForOrganizerOnStatusCancelled(): void {
  84. // construct calendar and generate event info for modified event with one attendee
  85. $calendar = clone $this->vCalendar1a;
  86. $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  87. $calendar->VEVENT->{'LAST-MODIFIED'}->setValue('20240701T020000Z');
  88. $calendar->VEVENT->SEQUENCE->setValue(2);
  89. $calendar->VEVENT->STATUS->setValue('CANCELLED');
  90. $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  91. // test iTip generation
  92. $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]);
  93. $this->assertCount(1, $messages);
  94. $this->assertEquals('CANCEL', $messages[0]->method);
  95. $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender);
  96. $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient);
  97. }
  98. public function testParseEventForOrganizerOnAddAttendee(): void {
  99. // construct calendar and generate event info for modified event with two attendees
  100. $calendar = clone $this->vCalendar1a;
  101. $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  102. $calendar->VEVENT->{'LAST-MODIFIED'}->setValue('20240701T020000Z');
  103. $calendar->VEVENT->SEQUENCE->setValue(2);
  104. $calendar->VEVENT->add('ATTENDEE', 'mailto:attendee2@testing.com', [
  105. 'CN' => 'Attendee Two',
  106. 'CUTYPE' => 'INDIVIDUAL',
  107. 'PARTSTAT' => 'NEEDS-ACTION',
  108. 'ROLE' => 'REQ-PARTICIPANT',
  109. 'RSVP' => 'TRUE'
  110. ]);
  111. $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  112. // test iTip generation
  113. $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]);
  114. $this->assertCount(2, $messages);
  115. $this->assertEquals('REQUEST', $messages[0]->method);
  116. $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender);
  117. $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient);
  118. $this->assertEquals('REQUEST', $messages[1]->method);
  119. $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[1]->sender);
  120. $this->assertEquals($calendar->VEVENT->ATTENDEE[1]->getValue(), $messages[1]->recipient);
  121. }
  122. public function testParseEventForOrganizerOnRemoveAttendee(): void {
  123. // construct calendar and generate event info for modified event with two attendees
  124. $calendar = clone $this->vCalendar1a;
  125. $calendar->VEVENT->add('ATTENDEE', 'mailto:attendee2@testing.com', [
  126. 'CN' => 'Attendee Two',
  127. 'CUTYPE' => 'INDIVIDUAL',
  128. 'PARTSTAT' => 'NEEDS-ACTION',
  129. 'ROLE' => 'REQ-PARTICIPANT',
  130. 'RSVP' => 'TRUE'
  131. ]);
  132. $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  133. $calendar->VEVENT->{'LAST-MODIFIED'}->setValue('20240701T020000Z');
  134. $calendar->VEVENT->SEQUENCE->setValue(2);
  135. $calendar->VEVENT->remove('ATTENDEE');
  136. $calendar->VEVENT->add('ATTENDEE', 'mailto:attendee1@testing.com', [
  137. 'CN' => 'Attendee One',
  138. 'CUTYPE' => 'INDIVIDUAL',
  139. 'PARTSTAT' => 'NEEDS-ACTION',
  140. 'ROLE' => 'REQ-PARTICIPANT',
  141. 'RSVP' => 'TRUE'
  142. ]);
  143. $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]);
  144. // test iTip generation
  145. $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]);
  146. $this->assertCount(2, $messages);
  147. $this->assertEquals('REQUEST', $messages[0]->method);
  148. $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender);
  149. $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient);
  150. $this->assertEquals('CANCEL', $messages[1]->method);
  151. $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[1]->sender);
  152. $this->assertEquals('mailto:attendee2@testing.com', $messages[1]->recipient);
  153. }
  154. }