broker = new TipBroker(); // construct calendar with a 1 hour event and same start/end time zones $this->vCalendar1a = new VCalendar(); /** @var VEvent $vEvent */ $vEvent = $this->vCalendar1a->add('VEVENT', []); $vEvent->add('UID', '96a0e6b1-d886-4a55-a60d-152b31401dcc'); $vEvent->add('DTSTAMP', '20240701T000000Z'); $vEvent->add('CREATED', '20240701T000000Z'); $vEvent->add('LAST-MODIFIED', '20240701T000000Z'); $vEvent->add('SEQUENCE', '1'); $vEvent->add('STATUS', 'CONFIRMED'); $vEvent->add('DTSTART', '20240701T080000', ['TZID' => 'America/Toronto']); $vEvent->add('DTEND', '20240701T090000', ['TZID' => 'America/Toronto']); $vEvent->add('SUMMARY', 'Test Event'); $vEvent->add('ORGANIZER', 'mailto:organizer@testing.com', ['CN' => 'Organizer']); $vEvent->add('ATTENDEE', 'mailto:attendee1@testing.com', [ 'CN' => 'Attendee One', 'CUTYPE' => 'INDIVIDUAL', 'PARTSTAT' => 'NEEDS-ACTION', 'ROLE' => 'REQ-PARTICIPANT', 'RSVP' => 'TRUE' ]); } public function testParseEventForOrganizerOnCreate(): void { // construct calendar and generate event info for newly created event with one attendee $calendar = clone $this->vCalendar1a; $previousEventInfo = [ 'organizer' => null, 'significantChangeHash' => '', 'attendees' => [], ]; $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); // test iTip generation $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]); $this->assertCount(1, $messages); $this->assertEquals('REQUEST', $messages[0]->method); $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender); $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient); } public function testParseEventForOrganizerOnModify(): void { // construct calendar and generate event info for modified event with one attendee $calendar = clone $this->vCalendar1a; $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); $calendar->VEVENT->{'LAST-MODIFIED'}->setValue('20240701T020000Z'); $calendar->VEVENT->SEQUENCE->setValue(2); $calendar->VEVENT->SUMMARY->setValue('Test Event Modified'); $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); // test iTip generation $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]); $this->assertCount(1, $messages); $this->assertEquals('REQUEST', $messages[0]->method); $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender); $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient); } public function testParseEventForOrganizerOnDelete(): void { // construct calendar and generate event info for modified event with one attendee $calendar = clone $this->vCalendar1a; $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); $currentEventInfo = $previousEventInfo; $currentEventInfo['attendees'] = []; ++$currentEventInfo['sequence']; // test iTip generation $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]); $this->assertCount(1, $messages); $this->assertEquals('CANCEL', $messages[0]->method); $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender); $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient); } public function testParseEventForOrganizerOnStatusCancelled(): void { // construct calendar and generate event info for modified event with one attendee $calendar = clone $this->vCalendar1a; $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); $calendar->VEVENT->{'LAST-MODIFIED'}->setValue('20240701T020000Z'); $calendar->VEVENT->SEQUENCE->setValue(2); $calendar->VEVENT->STATUS->setValue('CANCELLED'); $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); // test iTip generation $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]); $this->assertCount(1, $messages); $this->assertEquals('CANCEL', $messages[0]->method); $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender); $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient); } public function testParseEventForOrganizerOnAddAttendee(): void { // construct calendar and generate event info for modified event with two attendees $calendar = clone $this->vCalendar1a; $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); $calendar->VEVENT->{'LAST-MODIFIED'}->setValue('20240701T020000Z'); $calendar->VEVENT->SEQUENCE->setValue(2); $calendar->VEVENT->add('ATTENDEE', 'mailto:attendee2@testing.com', [ 'CN' => 'Attendee Two', 'CUTYPE' => 'INDIVIDUAL', 'PARTSTAT' => 'NEEDS-ACTION', 'ROLE' => 'REQ-PARTICIPANT', 'RSVP' => 'TRUE' ]); $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); // test iTip generation $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]); $this->assertCount(2, $messages); $this->assertEquals('REQUEST', $messages[0]->method); $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender); $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient); $this->assertEquals('REQUEST', $messages[1]->method); $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[1]->sender); $this->assertEquals($calendar->VEVENT->ATTENDEE[1]->getValue(), $messages[1]->recipient); } public function testParseEventForOrganizerOnRemoveAttendee(): void { // construct calendar and generate event info for modified event with two attendees $calendar = clone $this->vCalendar1a; $calendar->VEVENT->add('ATTENDEE', 'mailto:attendee2@testing.com', [ 'CN' => 'Attendee Two', 'CUTYPE' => 'INDIVIDUAL', 'PARTSTAT' => 'NEEDS-ACTION', 'ROLE' => 'REQ-PARTICIPANT', 'RSVP' => 'TRUE' ]); $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); $calendar->VEVENT->{'LAST-MODIFIED'}->setValue('20240701T020000Z'); $calendar->VEVENT->SEQUENCE->setValue(2); $calendar->VEVENT->remove('ATTENDEE'); $calendar->VEVENT->add('ATTENDEE', 'mailto:attendee1@testing.com', [ 'CN' => 'Attendee One', 'CUTYPE' => 'INDIVIDUAL', 'PARTSTAT' => 'NEEDS-ACTION', 'ROLE' => 'REQ-PARTICIPANT', 'RSVP' => 'TRUE' ]); $currentEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); // test iTip generation $messages = $this->invokePrivate($this->broker, 'parseEventForOrganizer', [$calendar, $currentEventInfo, $previousEventInfo]); $this->assertCount(2, $messages); $this->assertEquals('REQUEST', $messages[0]->method); $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[0]->sender); $this->assertEquals($calendar->VEVENT->ATTENDEE[0]->getValue(), $messages[0]->recipient); $this->assertEquals('CANCEL', $messages[1]->method); $this->assertEquals($calendar->VEVENT->ORGANIZER->getValue(), $messages[1]->sender); $this->assertEquals('mailto:attendee2@testing.com', $messages[1]->recipient); } }