1<?php
2
3namespace Sabre\VObject\ITip;
4
5class BrokerAttendeeReplyTest extends BrokerTester {
6
7    function testAccepted() {
8
9        $oldMessage = <<<ICS
10BEGIN:VCALENDAR
11VERSION:2.0
12BEGIN:VEVENT
13UID:foobar
14SUMMARY:B-day party
15SEQUENCE:1
16ORGANIZER;CN=Strunk:mailto:strunk@example.org
17ATTENDEE;CN=One:mailto:one@example.org
18DTSTART:20140716T120000Z
19END:VEVENT
20END:VCALENDAR
21ICS;
22
23
24        $newMessage = <<<ICS
25BEGIN:VCALENDAR
26VERSION:2.0
27BEGIN:VEVENT
28UID:foobar
29SUMMARY:B-day party
30SEQUENCE:1
31ORGANIZER;CN=Strunk:mailto:strunk@example.org
32ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
33DTSTART:20140716T120000Z
34END:VEVENT
35END:VCALENDAR
36ICS;
37
38        $version = \Sabre\VObject\Version::VERSION;
39
40        $expected = [
41            [
42                'uid'           => 'foobar',
43                'method'        => 'REPLY',
44                'component'     => 'VEVENT',
45                'sender'        => 'mailto:one@example.org',
46                'senderName'    => 'One',
47                'recipient'     => 'mailto:strunk@example.org',
48                'recipientName' => 'Strunk',
49                'message'       => <<<ICS
50BEGIN:VCALENDAR
51VERSION:2.0
52PRODID:-//Sabre//Sabre VObject $version//EN
53CALSCALE:GREGORIAN
54METHOD:REPLY
55BEGIN:VEVENT
56UID:foobar
57DTSTAMP:**ANY**
58SEQUENCE:1
59DTSTART:20140716T120000Z
60SUMMARY:B-day party
61ORGANIZER;CN=Strunk:mailto:strunk@example.org
62ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
63END:VEVENT
64END:VCALENDAR
65ICS
66
67            ],
68
69        ];
70
71        $this->parse($oldMessage, $newMessage, $expected);
72
73    }
74
75    function testRecurringReply() {
76
77        $oldMessage = <<<ICS
78BEGIN:VCALENDAR
79VERSION:2.0
80BEGIN:VEVENT
81UID:foobar
82SEQUENCE:1
83ORGANIZER;CN=Strunk:mailto:strunk@example.org
84ATTENDEE;CN=One:mailto:one@example.org
85DTSTART:20140724T120000Z
86SUMMARY:Daily sprint
87RRULE;FREQ=DAILY
88END:VEVENT
89END:VCALENDAR
90ICS;
91
92
93        $newMessage = <<<ICS
94BEGIN:VCALENDAR
95VERSION:2.0
96BEGIN:VEVENT
97UID:foobar
98SEQUENCE:1
99ORGANIZER;CN=Strunk:mailto:strunk@example.org
100ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
101DTSTART:20140724T120000Z
102SUMMARY:Daily sprint
103END:VEVENT
104BEGIN:VEVENT
105UID:foobar
106SEQUENCE:1
107ORGANIZER;CN=Strunk:mailto:strunk@example.org
108ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
109DTSTART:20140726T120000Z
110RECURRENCE-ID:20140726T120000Z
111END:VEVENT
112BEGIN:VEVENT
113UID:foobar
114SEQUENCE:1
115ORGANIZER;CN=Strunk:mailto:strunk@example.org
116ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
117DTSTART:20140724T120000Z
118RECURRENCE-ID:20140724T120000Z
119END:VEVENT
120BEGIN:VEVENT
121UID:foobar
122SEQUENCE:1
123ORGANIZER;CN=Strunk:mailto:strunk@example.org
124ATTENDEE;PARTSTAT=TENTATIVE;CN=One:mailto:one@example.org
125DTSTART:20140728T120000Z
126RECURRENCE-ID:20140728T120000Z
127END:VEVENT
128BEGIN:VEVENT
129UID:foobar
130SEQUENCE:1
131ORGANIZER;CN=Strunk:mailto:strunk@example.org
132ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
133DTSTART:20140729T120000Z
134RECURRENCE-ID:20140729T120000Z
135END:VEVENT
136BEGIN:VEVENT
137UID:foobar
138SEQUENCE:1
139ORGANIZER;CN=Strunk:mailto:strunk@example.org
140ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
141DTSTART:20140725T120000Z
142RECURRENCE-ID:20140725T120000Z
143END:VEVENT
144END:VCALENDAR
145ICS;
146
147        $version = \Sabre\VObject\Version::VERSION;
148
149        $expected = [
150            [
151                'uid'           => 'foobar',
152                'method'        => 'REPLY',
153                'component'     => 'VEVENT',
154                'sender'        => 'mailto:one@example.org',
155                'senderName'    => 'One',
156                'recipient'     => 'mailto:strunk@example.org',
157                'recipientName' => 'Strunk',
158                'message'       => <<<ICS
159BEGIN:VCALENDAR
160VERSION:2.0
161PRODID:-//Sabre//Sabre VObject $version//EN
162CALSCALE:GREGORIAN
163METHOD:REPLY
164BEGIN:VEVENT
165UID:foobar
166DTSTAMP:**ANY**
167SEQUENCE:1
168DTSTART:20140726T120000Z
169SUMMARY:Daily sprint
170RECURRENCE-ID:20140726T120000Z
171ORGANIZER;CN=Strunk:mailto:strunk@example.org
172ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
173END:VEVENT
174BEGIN:VEVENT
175UID:foobar
176DTSTAMP:**ANY**
177SEQUENCE:1
178DTSTART:20140724T120000Z
179SUMMARY:Daily sprint
180RECURRENCE-ID:20140724T120000Z
181ORGANIZER;CN=Strunk:mailto:strunk@example.org
182ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
183END:VEVENT
184BEGIN:VEVENT
185UID:foobar
186DTSTAMP:**ANY**
187SEQUENCE:1
188DTSTART:20140728T120000Z
189SUMMARY:Daily sprint
190RECURRENCE-ID:20140728T120000Z
191ORGANIZER;CN=Strunk:mailto:strunk@example.org
192ATTENDEE;PARTSTAT=TENTATIVE;CN=One:mailto:one@example.org
193END:VEVENT
194BEGIN:VEVENT
195UID:foobar
196DTSTAMP:**ANY**
197SEQUENCE:1
198DTSTART:20140729T120000Z
199SUMMARY:Daily sprint
200RECURRENCE-ID:20140729T120000Z
201ORGANIZER;CN=Strunk:mailto:strunk@example.org
202ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
203END:VEVENT
204BEGIN:VEVENT
205UID:foobar
206DTSTAMP:**ANY**
207SEQUENCE:1
208DTSTART:20140725T120000Z
209SUMMARY:Daily sprint
210RECURRENCE-ID:20140725T120000Z
211ORGANIZER;CN=Strunk:mailto:strunk@example.org
212ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
213END:VEVENT
214END:VCALENDAR
215ICS
216
217            ],
218
219        ];
220
221        $this->parse($oldMessage, $newMessage, $expected);
222
223    }
224
225    function testRecurringAllDay() {
226
227        $oldMessage = <<<ICS
228BEGIN:VCALENDAR
229VERSION:2.0
230BEGIN:VEVENT
231UID:foobar
232SEQUENCE:1
233ORGANIZER;CN=Strunk:mailto:strunk@example.org
234ATTENDEE;CN=One:mailto:one@example.org
235DTSTART;VALUE=DATE:20140724
236RRULE;FREQ=DAILY
237END:VEVENT
238END:VCALENDAR
239ICS;
240
241
242    $newMessage = <<<ICS
243BEGIN:VCALENDAR
244VERSION:2.0
245BEGIN:VEVENT
246UID:foobar
247SEQUENCE:1
248ORGANIZER;CN=Strunk:mailto:strunk@example.org
249ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
250DTSTART;VALUE=DATE:20140724
251END:VEVENT
252BEGIN:VEVENT
253UID:foobar
254SEQUENCE:1
255ORGANIZER;CN=Strunk:mailto:strunk@example.org
256ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
257DTSTART;VALUE=DATE:20140726
258RECURRENCE-ID;VALUE=DATE:20140726
259END:VEVENT
260BEGIN:VEVENT
261UID:foobar
262SEQUENCE:1
263ORGANIZER;CN=Strunk:mailto:strunk@example.org
264ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
265DTSTART;VALUE=DATE:20140724
266RECURRENCE-ID;VALUE=DATE:20140724
267END:VEVENT
268BEGIN:VEVENT
269UID:foobar
270SEQUENCE:1
271ORGANIZER;CN=Strunk:mailto:strunk@example.org
272ATTENDEE;PARTSTAT=TENTATIVE;CN=One:mailto:one@example.org
273DTSTART;VALUE=DATE:20140728
274RECURRENCE-ID;VALUE=DATE:20140728
275END:VEVENT
276BEGIN:VEVENT
277UID:foobar
278SEQUENCE:1
279ORGANIZER;CN=Strunk:mailto:strunk@example.org
280ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
281DTSTART;VALUE=DATE:20140729
282RECURRENCE-ID;VALUE=DATE:20140729
283END:VEVENT
284BEGIN:VEVENT
285UID:foobar
286SEQUENCE:1
287ORGANIZER;CN=Strunk:mailto:strunk@example.org
288ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
289DTSTART;VALUE=DATE:20140725
290RECURRENCE-ID;VALUE=DATE:20140725
291END:VEVENT
292END:VCALENDAR
293ICS;
294
295    $version = \Sabre\VObject\Version::VERSION;
296
297    $expected = [
298        [
299            'uid'           => 'foobar',
300            'method'        => 'REPLY',
301            'component'     => 'VEVENT',
302            'sender'        => 'mailto:one@example.org',
303            'senderName'    => 'One',
304            'recipient'     => 'mailto:strunk@example.org',
305            'recipientName' => 'Strunk',
306            'message'       => <<<ICS
307BEGIN:VCALENDAR
308VERSION:2.0
309PRODID:-//Sabre//Sabre VObject $version//EN
310CALSCALE:GREGORIAN
311METHOD:REPLY
312BEGIN:VEVENT
313UID:foobar
314DTSTAMP:**ANY**
315SEQUENCE:1
316DTSTART;VALUE=DATE:20140726
317RECURRENCE-ID;VALUE=DATE:20140726
318ORGANIZER;CN=Strunk:mailto:strunk@example.org
319ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
320END:VEVENT
321BEGIN:VEVENT
322UID:foobar
323DTSTAMP:**ANY**
324SEQUENCE:1
325DTSTART;VALUE=DATE:20140724
326RECURRENCE-ID;VALUE=DATE:20140724
327ORGANIZER;CN=Strunk:mailto:strunk@example.org
328ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
329END:VEVENT
330BEGIN:VEVENT
331UID:foobar
332DTSTAMP:**ANY**
333SEQUENCE:1
334DTSTART;VALUE=DATE:20140728
335RECURRENCE-ID;VALUE=DATE:20140728
336ORGANIZER;CN=Strunk:mailto:strunk@example.org
337ATTENDEE;PARTSTAT=TENTATIVE;CN=One:mailto:one@example.org
338END:VEVENT
339BEGIN:VEVENT
340UID:foobar
341DTSTAMP:**ANY**
342SEQUENCE:1
343DTSTART;VALUE=DATE:20140729
344RECURRENCE-ID;VALUE=DATE:20140729
345ORGANIZER;CN=Strunk:mailto:strunk@example.org
346ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
347END:VEVENT
348BEGIN:VEVENT
349UID:foobar
350DTSTAMP:**ANY**
351SEQUENCE:1
352DTSTART;VALUE=DATE:20140725
353RECURRENCE-ID;VALUE=DATE:20140725
354ORGANIZER;CN=Strunk:mailto:strunk@example.org
355ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
356END:VEVENT
357END:VCALENDAR
358ICS
359
360            ],
361
362        ];
363
364        $this->parse($oldMessage, $newMessage, $expected);
365
366    }
367
368    function testNoChange() {
369
370        $oldMessage = <<<ICS
371BEGIN:VCALENDAR
372VERSION:2.0
373BEGIN:VEVENT
374UID:foobar
375SEQUENCE:1
376ORGANIZER;CN=Strunk:mailto:strunk@example.org
377ATTENDEE;CN=One:mailto:one@example.org
378DTSTART:20140716T120000Z
379END:VEVENT
380END:VCALENDAR
381ICS;
382
383
384        $newMessage = <<<ICS
385BEGIN:VCALENDAR
386VERSION:2.0
387BEGIN:VEVENT
388UID:foobar
389SEQUENCE:1
390ORGANIZER;CN=Strunk:mailto:strunk@example.org
391ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
392DTSTART:20140716T120000Z
393END:VEVENT
394END:VCALENDAR
395ICS;
396
397
398        $expected = [];
399        $this->parse($oldMessage, $newMessage, $expected);
400
401    }
402
403    function testNoChangeForceSend() {
404
405        $oldMessage = <<<ICS
406BEGIN:VCALENDAR
407VERSION:2.0
408BEGIN:VEVENT
409UID:foobar
410SEQUENCE:1
411ORGANIZER;CN=Strunk:mailto:strunk@example.org
412ATTENDEE;CN=One:mailto:one@example.org
413DTSTART:20140716T120000Z
414END:VEVENT
415END:VCALENDAR
416ICS;
417
418
419        $newMessage = <<<ICS
420BEGIN:VCALENDAR
421VERSION:2.0
422BEGIN:VEVENT
423UID:foobar
424SEQUENCE:1
425ORGANIZER;SCHEDULE-FORCE-SEND=REPLY;CN=Strunk:mailto:strunk@example.org
426ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
427DTSTART:20140716T120000Z
428END:VEVENT
429END:VCALENDAR
430ICS;
431
432        $version = \Sabre\VObject\Version::VERSION;
433        $expected = [
434            [
435                'uid'           => 'foobar',
436                'method'        => 'REPLY',
437                'component'     => 'VEVENT',
438                'sender'        => 'mailto:one@example.org',
439                'senderName'    => 'One',
440                'recipient'     => 'mailto:strunk@example.org',
441                'recipientName' => 'Strunk',
442                'message'       => <<<ICS
443BEGIN:VCALENDAR
444VERSION:2.0
445PRODID:-//Sabre//Sabre VObject $version//EN
446CALSCALE:GREGORIAN
447METHOD:REPLY
448BEGIN:VEVENT
449UID:foobar
450DTSTAMP:**ANY**
451SEQUENCE:1
452DTSTART:20140716T120000Z
453ORGANIZER;CN=Strunk:mailto:strunk@example.org
454ATTENDEE;PARTSTAT=NEEDS-ACTION;CN=One:mailto:one@example.org
455END:VEVENT
456END:VCALENDAR
457ICS
458            ]
459
460        ];
461        $this->parse($oldMessage, $newMessage, $expected);
462
463    }
464
465    function testNoRelevantAttendee() {
466
467        $oldMessage = <<<ICS
468BEGIN:VCALENDAR
469VERSION:2.0
470BEGIN:VEVENT
471UID:foobar
472SEQUENCE:1
473ORGANIZER;CN=Strunk:mailto:strunk@example.org
474ATTENDEE;CN=Two:mailto:two@example.org
475DTSTART:20140716T120000Z
476END:VEVENT
477END:VCALENDAR
478ICS;
479
480
481        $newMessage = <<<ICS
482BEGIN:VCALENDAR
483VERSION:2.0
484BEGIN:VEVENT
485UID:foobar
486SEQUENCE:1
487ORGANIZER;CN=Strunk:mailto:strunk@example.org
488ATTENDEE;PARTSTAT=ACCEPTED;CN=Two:mailto:two@example.org
489DTSTART:20140716T120000Z
490END:VEVENT
491END:VCALENDAR
492ICS;
493
494        $expected = [];
495        $this->parse($oldMessage, $newMessage, $expected);
496
497    }
498
499    /**
500     * In this test, an event exists in an attendees calendar. The event
501     * is recurring, and the attendee deletes 1 instance of the event.
502     * This instance shows up in EXDATE
503     *
504     * This should automatically generate a DECLINED message for that
505     * specific instance.
506     */
507    function testCreateReplyByException() {
508
509
510        $oldMessage = <<<ICS
511BEGIN:VCALENDAR
512VERSION:2.0
513BEGIN:VEVENT
514UID:foobar
515SEQUENCE:1
516DTSTART:20140811T200000Z
517RRULE:FREQ=WEEKLY
518ORGANIZER:mailto:organizer@example.org
519ATTENDEE:mailto:one@example.org
520END:VEVENT
521END:VCALENDAR
522ICS;
523
524        $newMessage = <<<ICS
525BEGIN:VCALENDAR
526VERSION:2.0
527BEGIN:VEVENT
528UID:foobar
529SEQUENCE:1
530DTSTART:20140811T200000Z
531RRULE:FREQ=WEEKLY
532ORGANIZER:mailto:organizer@example.org
533ATTENDEE:mailto:one@example.org
534EXDATE:20140818T200000Z
535END:VEVENT
536END:VCALENDAR
537ICS;
538
539        $version = \Sabre\VObject\Version::VERSION;
540        $expected = [
541            [
542                'uid'           => 'foobar',
543                'method'        => 'REPLY',
544                'component'     => 'VEVENT',
545                'sender'        => 'mailto:one@example.org',
546                'senderName'    => null,
547                'recipient'     => 'mailto:organizer@example.org',
548                'recipientName' => null,
549                'message'       => <<<ICS
550BEGIN:VCALENDAR
551VERSION:2.0
552PRODID:-//Sabre//Sabre VObject $version//EN
553CALSCALE:GREGORIAN
554METHOD:REPLY
555BEGIN:VEVENT
556UID:foobar
557DTSTAMP:**ANY**
558SEQUENCE:1
559DTSTART:20140818T200000Z
560RECURRENCE-ID:20140818T200000Z
561ORGANIZER:mailto:organizer@example.org
562ATTENDEE;PARTSTAT=DECLINED:mailto:one@example.org
563END:VEVENT
564END:VCALENDAR
565ICS
566
567            ],
568        ];
569        $this->parse($oldMessage, $newMessage, $expected);
570
571    }
572
573    /**
574     * This test is identical to the last, but now we're working with
575     * timezones.
576     *
577     * @depends testCreateReplyByException
578     */
579    function testCreateReplyByExceptionTz() {
580
581
582        $oldMessage = <<<ICS
583BEGIN:VCALENDAR
584VERSION:2.0
585BEGIN:VEVENT
586UID:foobar
587SEQUENCE:1
588DTSTART;TZID=America/Toronto:20140811T200000
589RRULE:FREQ=WEEKLY
590ORGANIZER:mailto:organizer@example.org
591ATTENDEE:mailto:one@example.org
592END:VEVENT
593END:VCALENDAR
594ICS;
595
596        $newMessage = <<<ICS
597BEGIN:VCALENDAR
598VERSION:2.0
599BEGIN:VEVENT
600UID:foobar
601SEQUENCE:1
602DTSTART;TZID=America/Toronto:20140811T200000
603RRULE:FREQ=WEEKLY
604ORGANIZER:mailto:organizer@example.org
605ATTENDEE:mailto:one@example.org
606EXDATE;TZID=America/Toronto:20140818T200000
607END:VEVENT
608END:VCALENDAR
609ICS;
610
611        $version = \Sabre\VObject\Version::VERSION;
612        $expected = [
613            [
614                'uid'           => 'foobar',
615                'method'        => 'REPLY',
616                'component'     => 'VEVENT',
617                'sender'        => 'mailto:one@example.org',
618                'senderName'    => null,
619                'recipient'     => 'mailto:organizer@example.org',
620                'recipientName' => null,
621                'message'       => <<<ICS
622BEGIN:VCALENDAR
623VERSION:2.0
624PRODID:-//Sabre//Sabre VObject $version//EN
625CALSCALE:GREGORIAN
626METHOD:REPLY
627BEGIN:VEVENT
628UID:foobar
629DTSTAMP:**ANY**
630SEQUENCE:1
631DTSTART;TZID=America/Toronto:20140818T200000
632RECURRENCE-ID;TZID=America/Toronto:20140818T200000
633ORGANIZER:mailto:organizer@example.org
634ATTENDEE;PARTSTAT=DECLINED:mailto:one@example.org
635END:VEVENT
636END:VCALENDAR
637ICS
638
639            ],
640        ];
641        $this->parse($oldMessage, $newMessage, $expected);
642
643    }
644
645    /**
646     * @depends testCreateReplyByException
647     */
648    function testCreateReplyByExceptionAllDay() {
649
650
651        $oldMessage = <<<ICS
652BEGIN:VCALENDAR
653VERSION:2.0
654BEGIN:VEVENT
655SUMMARY:Weekly meeting
656UID:foobar
657SEQUENCE:1
658DTSTART;VALUE=DATE:20140811
659RRULE:FREQ=WEEKLY
660ORGANIZER:mailto:organizer@example.org
661ATTENDEE:mailto:one@example.org
662END:VEVENT
663END:VCALENDAR
664ICS;
665
666        $newMessage = <<<ICS
667BEGIN:VCALENDAR
668VERSION:2.0
669BEGIN:VEVENT
670SUMMARY:Weekly meeting
671UID:foobar
672SEQUENCE:1
673DTSTART;VALUE=DATE:20140811
674RRULE:FREQ=WEEKLY
675ORGANIZER:mailto:organizer@example.org
676ATTENDEE:mailto:one@example.org
677EXDATE;VALUE=DATE:20140818
678END:VEVENT
679END:VCALENDAR
680ICS;
681
682        $version = \Sabre\VObject\Version::VERSION;
683        $expected = [
684            [
685                'uid'           => 'foobar',
686                'method'        => 'REPLY',
687                'component'     => 'VEVENT',
688                'sender'        => 'mailto:one@example.org',
689                'senderName'    => null,
690                'recipient'     => 'mailto:organizer@example.org',
691                'recipientName' => null,
692                'message'       => <<<ICS
693BEGIN:VCALENDAR
694VERSION:2.0
695PRODID:-//Sabre//Sabre VObject $version//EN
696CALSCALE:GREGORIAN
697METHOD:REPLY
698BEGIN:VEVENT
699UID:foobar
700DTSTAMP:**ANY**
701SEQUENCE:1
702DTSTART;VALUE=DATE:20140818
703SUMMARY:Weekly meeting
704RECURRENCE-ID;VALUE=DATE:20140818
705ORGANIZER:mailto:organizer@example.org
706ATTENDEE;PARTSTAT=DECLINED:mailto:one@example.org
707END:VEVENT
708END:VCALENDAR
709ICS
710
711            ],
712        ];
713        $this->parse($oldMessage, $newMessage, $expected);
714
715    }
716
717    function testDeclined() {
718
719        $oldMessage = <<<ICS
720BEGIN:VCALENDAR
721VERSION:2.0
722BEGIN:VEVENT
723UID:foobar
724SEQUENCE:1
725ORGANIZER;CN=Strunk:mailto:strunk@example.org
726ATTENDEE;CN=One:mailto:one@example.org
727DTSTART:20140716T120000Z
728END:VEVENT
729END:VCALENDAR
730ICS;
731
732
733        $newMessage = <<<ICS
734BEGIN:VCALENDAR
735VERSION:2.0
736BEGIN:VEVENT
737UID:foobar
738SEQUENCE:1
739ORGANIZER;CN=Strunk:mailto:strunk@example.org
740ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
741DTSTART:20140716T120000Z
742END:VEVENT
743END:VCALENDAR
744ICS;
745
746        $version = \Sabre\VObject\Version::VERSION;
747
748        $expected = [
749            [
750                'uid'           => 'foobar',
751                'method'        => 'REPLY',
752                'component'     => 'VEVENT',
753                'sender'        => 'mailto:one@example.org',
754                'senderName'    => 'One',
755                'recipient'     => 'mailto:strunk@example.org',
756                'recipientName' => 'Strunk',
757                'message'       => <<<ICS
758BEGIN:VCALENDAR
759VERSION:2.0
760PRODID:-//Sabre//Sabre VObject $version//EN
761CALSCALE:GREGORIAN
762METHOD:REPLY
763BEGIN:VEVENT
764UID:foobar
765DTSTAMP:**ANY**
766SEQUENCE:1
767DTSTART:20140716T120000Z
768ORGANIZER;CN=Strunk:mailto:strunk@example.org
769ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
770END:VEVENT
771END:VCALENDAR
772ICS
773
774            ],
775
776        ];
777
778        $this->parse($oldMessage, $newMessage, $expected);
779
780    }
781
782    function testDeclinedCancelledEvent() {
783
784        $oldMessage = <<<ICS
785BEGIN:VCALENDAR
786VERSION:2.0
787BEGIN:VEVENT
788STATUS:CANCELLED
789UID:foobar
790SEQUENCE:1
791ORGANIZER;CN=Strunk:mailto:strunk@example.org
792ATTENDEE;CN=One:mailto:one@example.org
793DTSTART:20140716T120000Z
794END:VEVENT
795END:VCALENDAR
796ICS;
797
798
799        $newMessage = <<<ICS
800BEGIN:VCALENDAR
801VERSION:2.0
802BEGIN:VEVENT
803STATUS:CANCELLED
804UID:foobar
805SEQUENCE:1
806ORGANIZER;CN=Strunk:mailto:strunk@example.org
807ATTENDEE;PARTSTAT=DECLINED;CN=One:mailto:one@example.org
808DTSTART:20140716T120000Z
809END:VEVENT
810END:VCALENDAR
811ICS;
812
813        $version = \Sabre\VObject\Version::VERSION;
814
815        $expected = [];
816
817        $this->parse($oldMessage, $newMessage, $expected);
818
819    }
820
821    /**
822     * In this test, a new exception is created by an attendee as well.
823     *
824     * Except in this case, there was already an overridden event, and the
825     * overridden event was marked as cancelled by the attendee.
826     *
827     * For any other attendence status, the new status would have been
828     * declined, but for this, no message should we sent.
829     */
830    function testDontCreateReplyWhenEventWasDeclined() {
831
832
833        $oldMessage = <<<ICS
834BEGIN:VCALENDAR
835VERSION:2.0
836BEGIN:VEVENT
837UID:foobar
838SEQUENCE:1
839DTSTART:20140811T200000Z
840RRULE:FREQ=WEEKLY
841ORGANIZER:mailto:organizer@example.org
842ATTENDEE:mailto:one@example.org
843END:VEVENT
844BEGIN:VEVENT
845RECURRENCE-ID:20140818T200000Z
846UID:foobar
847SEQUENCE:1
848DTSTART:20140818T200000Z
849RRULE:FREQ=WEEKLY
850ORGANIZER:mailto:organizer@example.org
851ATTENDEE;PARTSTAT=DECLINED:mailto:one@example.org
852END:VEVENT
853END:VCALENDAR
854ICS;
855
856        $newMessage = <<<ICS
857BEGIN:VCALENDAR
858VERSION:2.0
859BEGIN:VEVENT
860UID:foobar
861SEQUENCE:1
862DTSTART:20140811T200000Z
863RRULE:FREQ=WEEKLY
864ORGANIZER:mailto:organizer@example.org
865ATTENDEE:mailto:one@example.org
866EXDATE:20140818T200000Z
867END:VEVENT
868END:VCALENDAR
869ICS;
870
871        $expected = [];
872
873        $this->parse($oldMessage, $newMessage, $expected);
874
875    }
876
877    function testScheduleAgentOnOrganizer() {
878
879        $oldMessage = <<<ICS
880BEGIN:VCALENDAR
881VERSION:2.0
882BEGIN:VEVENT
883UID:foobar
884SEQUENCE:1
885ORGANIZER;CN=Strunk:mailto:strunk@example.org
886ATTENDEE;CN=One:mailto:one@example.org
887DTSTART:20140716T120000Z
888END:VEVENT
889END:VCALENDAR
890ICS;
891
892
893        $newMessage = <<<ICS
894BEGIN:VCALENDAR
895VERSION:2.0
896BEGIN:VEVENT
897UID:foobar
898SEQUENCE:1
899ORGANIZER;SCHEDULE-AGENT=CLIENT;CN=Strunk:mailto:strunk@example.org
900ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
901DTSTART:20140716T120000Z
902END:VEVENT
903END:VCALENDAR
904ICS;
905
906        $version = \Sabre\VObject\Version::VERSION;
907
908        $expected = [];
909        $this->parse($oldMessage, $newMessage, $expected);
910
911    }
912
913    function testAcceptedAllDay() {
914
915        $oldMessage = <<<ICS
916BEGIN:VCALENDAR
917VERSION:2.0
918BEGIN:VEVENT
919UID:foobar
920SEQUENCE:1
921ORGANIZER;CN=Strunk:mailto:strunk@example.org
922ATTENDEE;CN=One:mailto:one@example.org
923DTSTART;VALUE=DATE:20140716
924END:VEVENT
925END:VCALENDAR
926ICS;
927
928
929        $newMessage = <<<ICS
930BEGIN:VCALENDAR
931VERSION:2.0
932BEGIN:VEVENT
933UID:foobar
934SEQUENCE:1
935ORGANIZER;CN=Strunk:mailto:strunk@example.org
936ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
937DTSTART;VALUE=DATE:20140716
938END:VEVENT
939END:VCALENDAR
940ICS;
941
942        $version = \Sabre\VObject\Version::VERSION;
943
944        $expected = [
945            [
946                'uid'           => 'foobar',
947                'method'        => 'REPLY',
948                'component'     => 'VEVENT',
949                'sender'        => 'mailto:one@example.org',
950                'senderName'    => 'One',
951                'recipient'     => 'mailto:strunk@example.org',
952                'recipientName' => 'Strunk',
953                'message'       => <<<ICS
954BEGIN:VCALENDAR
955VERSION:2.0
956PRODID:-//Sabre//Sabre VObject $version//EN
957CALSCALE:GREGORIAN
958METHOD:REPLY
959BEGIN:VEVENT
960UID:foobar
961DTSTAMP:**ANY**
962SEQUENCE:1
963DTSTART;VALUE=DATE:20140716
964ORGANIZER;CN=Strunk:mailto:strunk@example.org
965ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
966END:VEVENT
967END:VCALENDAR
968ICS
969
970            ],
971
972        ];
973
974        $this->parse($oldMessage, $newMessage, $expected);
975
976    }
977
978    /**
979     * This function tests an attendee updating their status to an event where
980     * they don't have the master event of.
981     *
982     * This is possible in cases an organizer created a recurring event, and
983     * invited an attendee for one instance of the event.
984     */
985    function testReplyNoMasterEvent() {
986
987        $oldMessage = <<<ICS
988BEGIN:VCALENDAR
989VERSION:2.0
990BEGIN:VEVENT
991UID:foobar
992SEQUENCE:1
993ORGANIZER;CN=Strunk:mailto:strunk@example.org
994ATTENDEE;CN=One:mailto:one@example.org
995RECURRENCE-ID:20140724T120000Z
996DTSTART:20140724T120000Z
997SUMMARY:Daily sprint
998END:VEVENT
999END:VCALENDAR
1000ICS;
1001
1002
1003        $newMessage = <<<ICS
1004BEGIN:VCALENDAR
1005VERSION:2.0
1006BEGIN:VEVENT
1007UID:foobar
1008SEQUENCE:1
1009ORGANIZER;CN=Strunk:mailto:strunk@example.org
1010ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
1011RECURRENCE-ID:20140724T120000Z
1012DTSTART:20140724T120000Z
1013SUMMARY:Daily sprint
1014END:VEVENT
1015END:VCALENDAR
1016ICS;
1017
1018        $version = \Sabre\VObject\Version::VERSION;
1019
1020        $expected = [
1021            [
1022                'uid'           => 'foobar',
1023                'method'        => 'REPLY',
1024                'component'     => 'VEVENT',
1025                'sender'        => 'mailto:one@example.org',
1026                'senderName'    => 'One',
1027                'recipient'     => 'mailto:strunk@example.org',
1028                'recipientName' => 'Strunk',
1029                'message'       => <<<ICS
1030BEGIN:VCALENDAR
1031VERSION:2.0
1032CALSCALE:GREGORIAN
1033METHOD:REPLY
1034BEGIN:VEVENT
1035UID:foobar
1036DTSTAMP:**ANY**
1037SEQUENCE:1
1038DTSTART:20140724T120000Z
1039SUMMARY:Daily sprint
1040RECURRENCE-ID:20140724T120000Z
1041ORGANIZER;CN=Strunk:mailto:strunk@example.org
1042ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
1043END:VEVENT
1044END:VCALENDAR
1045ICS
1046
1047            ],
1048
1049        ];
1050
1051        $this->parse($oldMessage, $newMessage, $expected);
1052
1053    }
1054
1055    /**
1056     * A party crasher is an attendee that accepted an event, but was not in
1057     * any original invite.
1058     *
1059     * @depends testAccepted
1060     */
1061    function testPartyCrasher() {
1062
1063        $oldMessage = <<<ICS
1064BEGIN:VCALENDAR
1065VERSION:2.0
1066BEGIN:VEVENT
1067UID:foobar
1068SUMMARY:B-day party
1069SEQUENCE:1
1070ORGANIZER;CN=Strunk:mailto:strunk@example.org
1071DTSTART:20140716T120000Z
1072RRULE:FREQ=DAILY
1073END:VEVENT
1074BEGIN:VEVENT
1075UID:foobar
1076RECURRENCE-ID:20140717T120000Z
1077SUMMARY:B-day party
1078SEQUENCE:1
1079ORGANIZER;CN=Strunk:mailto:strunk@example.org
1080DTSTART:20140717T120000Z
1081RRULE:FREQ=DAILY
1082END:VEVENT
1083END:VCALENDAR
1084ICS;
1085
1086
1087        $newMessage = <<<ICS
1088BEGIN:VCALENDAR
1089VERSION:2.0
1090BEGIN:VEVENT
1091UID:foobar
1092SUMMARY:B-day party
1093SEQUENCE:1
1094ORGANIZER;CN=Strunk:mailto:strunk@example.org
1095DTSTART:20140716T120000Z
1096RRULE:FREQ=DAILY
1097END:VEVENT
1098BEGIN:VEVENT
1099UID:foobar
1100RECURRENCE-ID:20140717T120000Z
1101SUMMARY:B-day party
1102SEQUENCE:1
1103ORGANIZER;CN=Strunk:mailto:strunk@example.org
1104ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
1105DTSTART:20140717T120000Z
1106RRULE:FREQ=DAILY
1107END:VEVENT
1108END:VCALENDAR
1109ICS;
1110
1111        $expected = [
1112            [
1113                'uid'           => 'foobar',
1114                'method'        => 'REPLY',
1115                'component'     => 'VEVENT',
1116                'sender'        => 'mailto:one@example.org',
1117                'senderName'    => 'One',
1118                'recipient'     => 'mailto:strunk@example.org',
1119                'recipientName' => 'Strunk',
1120                'message'       => <<<ICS
1121BEGIN:VCALENDAR
1122VERSION:2.0
1123CALSCALE:GREGORIAN
1124METHOD:REPLY
1125BEGIN:VEVENT
1126UID:foobar
1127DTSTAMP:**ANY**
1128SEQUENCE:1
1129DTSTART:20140717T120000Z
1130SUMMARY:B-day party
1131RECURRENCE-ID:20140717T120000Z
1132ORGANIZER;CN=Strunk:mailto:strunk@example.org
1133ATTENDEE;PARTSTAT=ACCEPTED;CN=One:mailto:one@example.org
1134END:VEVENT
1135END:VCALENDAR
1136
1137ICS
1138
1139            ],
1140
1141        ];
1142
1143        $this->parse($oldMessage, $newMessage, $expected);
1144
1145    }
1146}
1147