d727fab0f17d9e80545a3d232b184733246dd9d9
[tine20] / tests / tine20 / Calendar / Convert / Event / VCalendar / GenericTest.php
1 <?php
2 /**
3  * Tine 2.0 - http://www.tine20.org
4  * 
5  * @package     Calendar
6  * @license     http://www.gnu.org/licenses/agpl.html
7  * @copyright   Copyright (c) 2011-2014 Metaways Infosystems GmbH (http://www.metaways.de)
8  * @author      Lars Kneschke <l.kneschke@metaways.de>
9  */
10
11 /**
12  * Test helper
13  */
14 require_once dirname(dirname(dirname(dirname(dirname(__FILE__))))) . DIRECTORY_SEPARATOR . 'TestHelper.php';
15
16 /**
17  * Test class for Calendar_Convert_Event_VCalendar_Generic
18  */
19 class Calendar_Convert_Event_VCalendar_GenericTest extends PHPUnit_Framework_TestCase
20 {
21     /**
22      * @var array test objects
23      */
24     protected $objects = array();
25     
26     /**
27      * the converter
28      * 
29      * @var Calendar_Convert_Event_VCalendar_Abstract
30      */
31     protected $_converter = null;
32     
33     /**
34      * Runs the test methods of this class.
35      *
36      * @access public
37      * @static
38      */
39     public static function main()
40     {
41         $suite  = new PHPUnit_Framework_TestSuite('Tine 2.0 Calendar WebDAV Generic Event Tests');
42         PHPUnit_TextUI_TestRunner::run($suite);
43     }
44
45     /**
46      * Sets up the fixture.
47      * This method is called before a test is executed.
48      *
49      * @access protected
50      */
51     protected function setUp()
52     {
53         Calendar_Controller_Event::getInstance()->sendNotifications(false);
54         Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
55     }
56
57     /**
58      * Tears down the fixture
59      * This method is called after a test is executed.
60      *
61      * @access protected
62      */
63     protected function tearDown()
64     {
65         Tinebase_TransactionManager::getInstance()->rollBack();
66     }
67     
68     /**
69      * test converting vcard from lighting to Calendar_Model_Event
70      * 
71      * @return Calendar_Model_Event
72      */
73     public function testConvertToTine20Model()
74     {
75         $event = $this->_convertHelper(dirname(__FILE__) . '/../../../Import/files/lightning.ics');
76         //var_dump($event->toArray());
77         
78         $this->assertEquals(Calendar_Model_Event::CLASS_PRIVATE, $event->class);
79         $this->assertEquals('Hamburg',                           $event->location);
80         $this->assertEquals('Europe/Berlin',                     $event->originator_tz);
81         $this->assertEquals("2011-10-04 10:00:00",               (string)$event->dtend);
82         $this->assertEquals("2011-10-04 08:00:00",               (string)$event->dtstart);
83         $this->assertEquals("2011-10-04 06:45:00",               (string)$event->alarms[0]->alarm_time);
84         $this->assertEquals("75",                                (string)$event->alarms[0]->minutes_before);
85         $this->assertEquals("This is a descpription\nwith a linebreak and a ; , and : a", $event->description);
86         $this->assertEquals(2, count($event->attendee));
87         $this->assertEquals(1, count($event->alarms));
88         $this->assertContains('CATEGORY 1',                      $event->tags->name);
89         $this->assertContains('CATEGORY 2',                      $event->tags->name);
90         
91         return $event;
92     }
93     
94     /**
95      * convert helper
96      * 
97      * @param string $filename
98      * @return Calendar_Model_Event
99      */
100     protected function _convertHelper($filename)
101     {
102         $vcalendar = Calendar_Frontend_WebDAV_EventTest::getVCalendar($filename);
103         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
104         $event = $this->_converter->toTine20Model($vcalendar);
105         
106         return $event;
107     }
108     
109     /**
110      * test converting vcalendar from iCloud to Calendar_Model_Event
111      *
112      * @return Calendar_Model_Event
113      */
114     public function testConvertToTine20ModelFromICloud()
115     {
116         $vcalendar = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/calendarserver_external_invitation.ics');
117         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
118         $event = $this->_converter->toTine20Model($vcalendar);
119     
120         //var_dump($event->toArray());
121     
122         $this->assertEquals(Calendar_Model_Event::CLASS_PUBLIC,     $event->class);
123         $this->assertEquals('9320E052-6AF0-45E7-9352-04BBEC898D47', $event->uid);
124         $this->assertEquals(2, count($event->attendee));
125         $this->assertTrue(!empty($event->organizer));
126         $this->assertEquals('2012-02-27 15:56:00', $event->creation_time->toString(), 'CREATED not taken from ics');
127         $this->assertEquals('2012-02-27 15:56:20', $event->last_modified_time, 'DTSTAMP not taken from ics');
128         $this->assertEquals(3, $event->seq, 'SEQUENCE not taken from ics');
129         
130         
131         return $event;
132     }
133     
134     /**
135      * test converting vcalendar from Lotus Notes to Calendar_Model_Event
136      *
137      * @return Calendar_Model_Event
138      */
139     public function testConvertToTine20ModelFromLotusNotes()
140     {
141         $vcalendar = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lotusnotes_external_invitation.ics');
142         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
143         $event = $this->_converter->toTine20Model($vcalendar);
144     
145         //var_dump($event->toArray());
146     
147         $this->assertEquals(Calendar_Model_Event::CLASS_PUBLIC,     $event->class);
148         $this->assertEquals('A5C4058C8C5926C8C12579B100622D66-Lotus_Notes_Generated', $event->uid);
149         $this->assertEquals(3, count($event->attendee));
150         $this->assertTrue(!empty($event->organizer));
151     
152         return $event;
153     }
154     
155     /**
156     * test converting vcard from lighting to Calendar_Model_Event (with unrecognized timezone)
157     */
158     public function testConvertToTine20ModelWithBadTZ()
159     {
160         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning_badTZ.ics', 'r');
161         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
162         $event = $this->_converter->toTine20Model($vcalendarStream);
163         
164         $this->assertEquals('Europe/Berlin', $event->originator_tz);
165     }
166     
167     /**
168      * test converting vcard from lighting to Calendar_Model_Event
169      *
170      * @return Calendar_Model_Event
171      */
172     public function testConvertToTine20ModelWithGroupInvitation()
173     {
174         $smtpConfig = Tinebase_Config::getInstance()->get(Tinebase_Model_Config::SMTP, new Tinebase_Config_Struct())->toArray();
175         if (!isset($smtpConfig['primarydomain'])) {
176             $this->markTestSkipped('no primary smtp domain configured');
177         }
178         
179         $vcalendar = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning.ics');
180     
181         $vcalendar = preg_replace('/lars@kneschke.de/', 'Users@' . $smtpConfig['primarydomain'], $vcalendar);
182     
183         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
184         $event = $this->_converter->toTine20Model($vcalendar);
185     
186         //var_dump($event->attendee->toArray());
187     
188         $this->assertEquals(2, count($event->attendee));
189         $this->assertContains('group', $event->attendee->user_type);
190     
191         return $event;
192     }
193     
194    /**
195     * test converting vcard with status
196     */
197     public function testConvertToTine20ModelWithStatus()
198     {
199         $vcalendar = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning.ics', 'r');
200         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
201         
202         $vcalendar = str_replace('LOCATION:Hamburg', 'STATUS:CONFIRMED', $vcalendar);
203         $event = $this->_converter->toTine20Model($vcalendar);
204         $this->assertEquals(Calendar_Model_Event::STATUS_CONFIRMED, $event->status);
205         
206         $vcalendar = str_replace('STATUS:CONFIRMED', 'STATUS:TENTATIVE', $vcalendar);
207         $event = $this->_converter->toTine20Model($vcalendar);
208         $this->assertEquals(Calendar_Model_Event::STATUS_TENTATIVE, $event->status);
209         
210         $vcalendar = str_replace('STATUS:TENTATIVE', 'STATUS:CANCELED', $vcalendar);
211         $event = $this->_converter->toTine20Model($vcalendar);
212         $this->assertEquals(Calendar_Model_Event::STATUS_CANCELED, $event->status);
213     }
214     
215     /**
216      * test converting vcard from sogo connector to Calendar_Model_Event
217      * @return Calendar_Model_Event
218      */
219     public function _testConvertFromIcalToTine20Model()
220     {
221         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning.ics', 'r');
222     
223         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
224     
225         $event = $this->_converter->toTine20Model($vcalendarStream);
226     
227         #var_dump($event->toArray());
228     
229         $this->assertEquals(Calendar_Model_Event::CLASS_PRIVATE, $event->class);
230         $this->assertEquals('Hamburg',                           $event->location);
231         $this->assertEquals('Europe/Berlin',                     $event->originator_tz);
232         $this->assertEquals("2011-10-04 10:00:00",               (string)$event->dtend);
233         $this->assertEquals("2011-10-04 08:00:00",               (string)$event->dtstart);
234         $this->assertEquals("2011-10-04 06:45:00",               (string)$event->alarms[0]->alarm_time);
235         $this->assertEquals("75",                                (string)$event->alarms[0]->minutes_before);
236     
237         return $event;
238     }
239     
240     /**
241      * test converting vcard from sogo connector to Calendar_Model_Event
242      * @return Calendar_Model_Event
243      */
244     public function testConvertAllDayEventToTine20Model()
245     {
246         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning_allday.ics', 'r');
247     
248         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
249     
250         $event = $this->_converter->toTine20Model($vcalendarStream);
251         
252         #var_dump($event->toArray());
253         #var_dump($event->dtend);
254         
255         $this->assertEquals(Calendar_Model_Event::CLASS_PRIVATE, $event->class);
256         $this->assertEquals('Hamburg',                           $event->location);
257         $this->assertEquals("2011-10-19 21:59:59",               (string)$event->dtend   , 'DTEND mismatch');
258         $this->assertEquals("2011-10-18 22:00:00",               (string)$event->dtstart , 'DTSTART mismatch');
259         $this->assertTrue($event->is_all_day_event , 'All day event mismatch');
260         $this->assertEquals("2011-10-19 00:00:00",               (string)$event->alarms[0]->alarm_time);
261     
262         return $event;
263     }
264     
265     /**
266      * test converting vcard with daily repeating event to Calendar_Model_Event
267      * @return Calendar_Model_Event
268      */
269     public function testConvertRepeatingDailyEventToTine20Model()
270     {
271         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning_repeating_daily.ics', 'r');
272     
273         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
274     
275         $event = $this->_converter->toTine20Model($vcalendarStream);
276     
277         #var_dump($event->exdate[3]->recurid->format('hm'));
278         #var_dump($event->dtstart->format('hm'));
279     
280         $this->assertEquals('FREQ=DAILY;UNTIL=2011-10-30 06:00:00', $event->rrule);
281         $this->assertEquals(4, count($event->exdate));
282         $this->assertEquals($event->uid,            $event->exdate[3]->uid);
283         $this->assertEquals("2011-10-08 13:00:00",  (string)$event->exdate[3]->dtend   , 'DTEND mismatch');
284         $this->assertEquals("2011-10-08 11:00:00",  (string)$event->exdate[3]->dtstart , 'DTSTART mismatch');
285         $this->assertEquals($event->dtstart->format('hm'),  $event->exdate[3]->recurid->format('hm') , 'Recurid mismatch');
286         
287         return $event;
288     }
289     
290     /**
291      * test converting vcard with daily repeating event to Calendar_Model_Event
292      * @return Calendar_Model_Event
293      */
294     public function testConvertRepeatingAllDayDailyEventToTine20Model()
295     {
296         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/apple_caldendar_repeating_allday.ics', 'r');
297     
298         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
299     
300         $event = $this->_converter->toTine20Model($vcalendarStream);
301     
302         #var_dump($event->exdate->toArray());
303         #var_dump($event->dtstart->format('hm'));
304         
305         $this->assertEquals('FREQ=DAILY;INTERVAL=1;UNTIL=2011-11-11 23:00:00', $event->rrule, 'until must be converted');
306         $this->assertEquals(TRUE, $event->is_all_day_event);
307         $this->assertEquals('TRANSPARENT', $event->transp);
308         $this->assertEquals('PUBLIC', $event->class);
309         $this->assertEquals("2011-11-07 23:00:00", (string) $event->dtstart, 'DTEND mismatch');
310         $this->assertEquals("2011-11-08 22:59:59", (string) $event->dtend,   'DTSTART mismatch');
311         $this->assertEquals("2011-11-10 23:00:00", (string) $event->exdate[0]->recurid, 'RECURID fallout mismatch');
312         $this->assertEquals("2011-11-08 23:00:00", (string) $event->exdate[1]->recurid, 'RECURID exdate mismatch');
313         
314         return $event;
315     }
316     
317     /**
318      * test converting vcard with daily repeating event to Calendar_Model_Event
319      * @return Calendar_Model_Event
320      */
321     public function testConvertRepeatingAllDayDailyEventFromTine20Model()
322     {
323         $event = $this->testConvertRepeatingAllDayDailyEventToTine20Model();
324         foreach(array($event, $event->exdate[1]) as $raw) {
325             $raw->creation_time      = new Tinebase_DateTime('2011-11-11 11:11', 'UTC');
326             $raw->last_modified_time = new Tinebase_DateTime('2011-11-11 12:12', 'UTC');
327             $raw->organizer          = Tinebase_Core::getUser()->contact_id;
328         }
329         
330         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
331         
332         $vevent = $this->_converter->fromTine20Model($event)->serialize();
333         
334         //var_dump($vevent);
335         $this->assertContains('VERSION:2.0',                                    $vevent, $vevent);
336         $this->assertContains('PRODID:-//tine20.com//Tine 2.0 Calendar V',      $vevent, $vevent);
337         $this->assertContains('CREATED:20111111T111100Z',                       $vevent, $vevent);
338         $this->assertContains('LAST-MODIFIED:20111111T121200Z',                 $vevent, $vevent);
339         $this->assertContains('DTSTAMP:',                                       $vevent, $vevent);
340         $this->assertContains('RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20111112',     $vevent, $vevent);
341         $this->assertContains('EXDATE;VALUE=DATE:20111111',                     $vevent, $vevent);
342         #$this->assertContains('ORGANIZER;CN="' . Tinebase_Core::getUser()->accountDisplayName . '";EMAIL=' . Tinebase_Core::getUser()->accountEmailAddress . ':', $vevent, $vevent);
343         $this->assertContains('ORGANIZER;CN=', $vevent, $vevent);
344     }
345     
346     /**
347      * test converting vcard with daily repeating event to Calendar_Model_Event
348      * and merge with existing event
349      * @return Calendar_Model_Event
350      */
351     public function disabled_testConvertRepeatingDailyEventToTine20ModelWithMerge()
352     {
353         $event = $this->testConvertRepeatingDailyEventToTine20Model();
354         
355         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning_repeating_daily.ics', 'r');
356     
357         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
358         
359         $event->exdate[3]->attendee[0]->status_authkey = 'TestMe';
360         
361         $updatedEvent = $this->_converter->toTine20Model($vcalendarStream, clone $event);
362     
363         $this->assertTrue(! empty($updatedEvent->exdate[3]->attendee[0]->status_authkey));
364         $this->assertEquals($event->exdate[3]->attendee[0]->status_authkey, $updatedEvent->exdate[3]->attendee[0]->status_authkey);
365     
366         return $event;
367     }
368     
369     /**
370      * test converting vcard from sogo connector to Calendar_Model_Event 
371      */
372     public function testConvertToTine20ModelWithUpdate()
373     {
374         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning.ics', 'r');
375         
376         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
377         
378         $event = $this->_converter->toTine20Model($vcalendarStream);
379         
380         // status_authkey must be kept after second convert
381         $event->attendee[0]->quantity = 10;
382         
383         $vcalendar = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/lightning.ics');
384         
385         // remove alarm part from vcalendar
386         $vcalendar = preg_replace('/BEGIN:VALARM.*END:VALARM(\n|\r\n)/s', null, $vcalendar);
387         
388         // add a sequence
389         $vcalendar = preg_replace('/DTSTAMP:20111007T160719Z(\n|\r\n)/s', "DTSTAMP:20121007T160719Z\nSEQUENCE:5\n", $vcalendar);
390         
391         $event = $this->_converter->toTine20Model($vcalendar, $event, array(
392             Calendar_Convert_Event_VCalendar_Abstract::OPTION_USE_SERVER_MODLOG => true
393         ));
394         
395         $this->assertEquals(10, $event->attendee[0]->quantity);
396         $this->assertTrue($event->alarms instanceof Tinebase_Record_RecordSet);
397         $this->assertEquals(0, count($event->alarms));
398         $this->assertEquals(1, $event->seq, 'seq should be preserved');
399         $this->assertEquals('2011-10-07 16:07:19', $event->last_modified_time->toString(), 'last_modified_time should be preserved');
400     }
401
402     /**
403      * @depends testConvertToTine20Model
404      */
405     public function testConvertFromTine20Model()
406     {
407         $event = $this->testConvertToTine20Model();
408         $event->creation_time      = new Tinebase_DateTime('2011-11-11 11:11', 'UTC');
409         $event->last_modified_time = new Tinebase_DateTime('2011-11-11 12:12', 'UTC');
410         $event->attendee = new Tinebase_Record_RecordSet('Calendar_Model_Attender');
411         
412         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
413         
414         $vevent = $this->_converter->fromTine20Model($event)->serialize();
415         // var_dump($vevent);
416         // required fields
417         $this->assertContains('VERSION:2.0',                                    $vevent, $vevent);
418         $this->assertContains('PRODID:-//tine20.com//Tine 2.0 Calendar V',      $vevent, $vevent);
419         $this->assertContains('CREATED:20111111T111100Z',         $vevent, $vevent);
420         $this->assertContains('LAST-MODIFIED:20111111T121200Z',   $vevent, $vevent);
421         $this->assertContains('DTSTAMP:',                         $vevent, $vevent);
422         $this->assertContains('TZID:Europe/Berlin',               $vevent, $vevent);
423         $this->assertContains('UID:' . $event->uid,               $vevent, $vevent);
424         $this->assertContains('LOCATION:' . $event->location,     $vevent, $vevent);
425         $this->assertContains('CLASS:PRIVATE',                    $vevent, $vevent);
426         $this->assertContains('TZOFFSETFROM:+0100',  $vevent, $vevent);
427         $this->assertContains('TZOFFSETTO:+0200',    $vevent, $vevent);
428         $this->assertContains('TZNAME:CEST',         $vevent, $vevent);
429         $this->assertContains('TZOFFSETFROM:+0200',  $vevent, $vevent);
430         $this->assertContains('TZOFFSETTO:+0100',    $vevent, $vevent);
431         $this->assertContains('TZNAME:CET',          $vevent, $vevent);
432         $this->assertContains('CATEGORIES:CATEGORY 1,CATEGORY 2', $vevent, $vevent);
433         $this->assertNotContains('X-MOZ-LASTACK', $vevent, $vevent);
434     }
435     
436     /**
437      * @depends testConvertToTine20Model
438      */
439     public function testConvertFromTine20ModelWithCurrentUserAsAttendee()
440     {
441         $event = $this->testConvertToTine20Model();
442         $event->creation_time      = new Tinebase_DateTime('2011-11-11 11:11', 'UTC');
443         $event->last_modified_time = new Tinebase_DateTime('2011-11-11 12:12', 'UTC');
444         $event->attendee->addRecord(new Calendar_Model_Attender(array(
445             'user_id'   => Tinebase_Core::getUser()->contact_id,
446             'user_type' => Calendar_Model_Attender::USERTYPE_USER,
447             'role'      => Calendar_Model_Attender::ROLE_REQUIRED,
448             'status'    => Calendar_Model_Attender::STATUS_ACCEPTED
449         )));
450         
451         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
452         
453         $vevent = $this->_converter->fromTine20Model($event)->serialize();
454         // var_dump($vevent);
455         // required fields
456         $this->assertContains('VERSION:2.0',                               $vevent, $vevent);
457         $this->assertContains('PRODID:-//tine20.com//Tine 2.0 Calendar V', $vevent, $vevent);
458         $this->assertContains('CREATED:20111111T111100Z',                  $vevent, $vevent);
459         $this->assertContains('LAST-MODIFIED:20111111T121200Z',            $vevent, $vevent);
460         $this->assertContains('DTSTAMP:',                                  $vevent, $vevent);
461         $this->assertContains('TZID:Europe/Berlin',               $vevent, $vevent);
462         $this->assertContains('UID:' . $event->uid,               $vevent, $vevent);
463         $this->assertContains('LOCATION:' . $event->location,     $vevent, $vevent);
464         $this->assertContains('CLASS:PRIVATE',                    $vevent, $vevent);
465         $this->assertContains('TRIGGER;VALUE=DURATION:-PT1H15M',  $vevent, $vevent);
466         $this->assertContains('TZOFFSETFROM:+0100',  $vevent, $vevent);
467         $this->assertContains('TZOFFSETTO:+0200',  $vevent, $vevent);
468         $this->assertContains('TZNAME:CEST',  $vevent, $vevent);
469         $this->assertContains('TZOFFSETFROM:+0200',  $vevent, $vevent);
470         $this->assertContains('TZOFFSETTO:+0100',  $vevent, $vevent);
471         $this->assertContains('TZNAME:CET',  $vevent, $vevent);
472         
473     }
474     
475     /**
476      * 
477      * @depends testConvertAllDayEventToTine20Model
478      */
479     public function testConvertFromAllDayEventTine20Model()
480     {
481         $event = $this->testConvertAllDayEventToTine20Model();
482         $event->creation_time      = new Tinebase_DateTime('2011-11-11 11:11', 'UTC');
483         $event->last_modified_time = new Tinebase_DateTime('2011-11-11 12:12', 'UTC');
484         $event->attendee->addRecord(new Calendar_Model_Attender(array(
485             'user_id'   => Tinebase_Core::getUser()->contact_id,
486             'user_type' => Calendar_Model_Attender::USERTYPE_USER,
487             'role'      => Calendar_Model_Attender::ROLE_REQUIRED,
488             'status'    => Calendar_Model_Attender::STATUS_ACCEPTED
489         )));
490         
491         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
492         
493         $vevent = $this->_converter->fromTine20Model($event)->serialize();
494         // var_dump($vevent);
495         // required fields
496         $this->assertContains('VERSION:2.0',                                    $vevent, $vevent);
497         $this->assertContains('PRODID:-//tine20.com//Tine 2.0 Calendar V',      $vevent, $vevent);
498         $this->assertContains('CREATED:20111111T111100Z',         $vevent, $vevent);
499         $this->assertContains('LAST-MODIFIED:20111111T121200Z',   $vevent, $vevent);
500         $this->assertContains('DTSTAMP:',                         $vevent, $vevent);
501         $this->assertContains('DTSTART;VALUE=DATE:20111019',      $vevent, $vevent);
502         $this->assertContains('DTEND;VALUE=DATE:20111020',        $vevent, $vevent);
503         $this->assertContains('TZID:Europe/Berlin',               $vevent, $vevent);
504         $this->assertContains('UID:' . $event->uid,               $vevent, $vevent);
505         $this->assertContains('LOCATION:' . $event->location,     $vevent, $vevent);
506         $this->assertContains('CLASS:PRIVATE',                    $vevent, $vevent);
507         $this->assertContains('TRIGGER;VALUE=DATE-TIME:20111019T000000Z',  $vevent, $vevent);
508         $this->assertContains('TZOFFSETFROM:+0100',  $vevent, $vevent);
509         $this->assertContains('TZOFFSETTO:+0200',    $vevent, $vevent);
510         $this->assertContains('TZNAME:CEST',         $vevent, $vevent);
511         $this->assertContains('TZOFFSETFROM:+0200',  $vevent, $vevent);
512         $this->assertContains('TZOFFSETTO:+0100',    $vevent, $vevent);
513         $this->assertContains('TZNAME:CET',          $vevent, $vevent);
514         
515     }
516     
517     /**
518      * 
519      * @depends testConvertToTine20Model
520      */
521     public function testConvertRepeatingEventFromTine20Model()
522     {
523         $event = $this->testConvertRepeatingDailyEventToTine20Model();
524         $event->creation_time          = new Tinebase_DateTime('2011-11-11 11:11', 'UTC');
525         $event->last_modified_time     = new Tinebase_DateTime('2011-11-11 12:12', 'UTC');
526         $event->exdate->creation_time  = new Tinebase_DateTime('2011-11-11 11:11', 'UTC');
527         
528         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
529         
530         $vevent = $this->_converter->fromTine20Model($event)->serialize();
531         #var_dump($vevent);
532         // required fields
533         $this->assertContains('VERSION:2.0', $vevent, $vevent);
534         $this->assertContains('PRODID:-//tine20.com//Tine 2.0 Calendar V', $vevent, $vevent);
535         $this->assertContains('CREATED:20111111T111100Z',                  $vevent, $vevent);
536         $this->assertContains('LAST-MODIFIED:20111111T121200Z',            $vevent, $vevent);
537         $this->assertContains('DTSTAMP:',                                  $vevent, $vevent);
538         $this->assertContains('RRULE:FREQ=DAILY;UNTIL=20111030T060000Z',   $vevent, $vevent);
539         $this->assertContains('EXDATE:20111005T080000Z',      $vevent, $vevent);
540         $this->assertContains('EXDATE:20111006T080000Z',      $vevent, $vevent);
541         $this->assertContains('EXDATE:20111007T080000Z',      $vevent, $vevent);
542         $this->assertContains('TZID:Europe/Berlin',           $vevent, $vevent);
543         $this->assertContains('UID:' . $event->uid,           $vevent, $vevent);
544         $this->assertContains('LOCATION:' . $event->location, $vevent, $vevent);
545         $this->assertContains('CLASS:PRIVATE',                $vevent, $vevent);
546     }
547     
548     public function testConvertFromTine20ModelWithCustomAlarm()
549     {
550         $event = $this->testConvertToTine20Model();
551         $event->creation_time      = new Tinebase_DateTime('2011-11-11 11:11', 'UTC');
552         $event->last_modified_time = new Tinebase_DateTime('2011-11-11 12:12', 'UTC');
553         $event->organizer          = Tinebase_Core::getUser()->contact_id;
554         
555         $event->alarms = new Tinebase_Record_RecordSet('Tinebase_Model_Alarm', array(array(
556             'model'            => 'Calendar_Model_Event',
557             'alarm_time'       => '2011-10-04 07:10:00',
558             'minutes_before'   => Tinebase_Model_Alarm::OPTION_CUSTOM
559         )));
560         
561         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
562         
563         $vevent = $this->_converter->fromTine20Model($event)->serialize();
564         #var_dump($vevent);
565         $this->assertContains('TRIGGER;VALUE=DATE-TIME:20111004T071000Z',        $vevent, $vevent);
566     }
567     
568     public function testConvertFromTine20ModelWithStatus()
569     {
570         $event = $this->testConvertToTine20Model();
571         $event->creation_time      = new Tinebase_DateTime('2011-11-11 11:11', 'UTC');
572         $event->last_modified_time = new Tinebase_DateTime('2011-11-11 12:12', 'UTC');
573         $event->organizer          = Tinebase_Core::getUser()->contact_id;
574         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
575         
576         $event->status = Calendar_Model_Event::STATUS_CONFIRMED;
577         $vevent = $this->_converter->fromTine20Model($event)->serialize();
578         #var_dump($vevent);
579         $this->assertContains('STATUS:CONFIRMED',        $vevent, $vevent);
580         
581         $event->is_deleted = 1;
582         $vevent = $this->_converter->fromTine20Model($event)->serialize();
583         #var_dump($vevent);
584         $this->assertContains('STATUS:CANCELED',        $vevent, $vevent);
585     }
586     
587     public function testConvertToTine20ModelWithCustomAlarm()
588     {
589         $vcalendar = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/event_with_custom_alarm.ics');
590         
591         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
592         
593         $event = $this->_converter->toTine20Model($vcalendar);
594         
595         $this->assertTrue($event->alarms instanceof Tinebase_Record_RecordSet);
596         $this->assertEquals(1, count($event->alarms));
597         
598         $alarm = $event->alarms->getFirstRecord();
599         
600         $this->assertEquals(Tinebase_Model_Alarm::OPTION_CUSTOM, $alarm->minutes_before);
601         $this->assertEquals('2012-02-14 17:00:00', $alarm->alarm_time->toString());
602     }
603     
604     /**
605      * testConvertFromGoogleToTine20Model
606      * 
607      * @see 0006110: handle iMIP messages from outlook
608      */
609     public function testConvertFromGoogleToTine20Model()
610     {
611         $event = $this->_convertHelper(dirname(__FILE__) . '/../../../Import/files/invite_google.ics');
612         
613         $this->assertEquals('133st5tjius426l9n1k1sil5rk@google.com', $event->uid);
614         $this->assertEquals('Test-Termin aus Google an Tine20', $event->summary);
615         $this->assertEquals('REQUEST', $this->_converter->getMethod());
616     }
617
618     /**
619      * testConvertExdateRequest
620      * 
621      * @see 0009598: imip invitation mails show js error (in Felamimail)
622      */
623     public function testConvertExdateRequest()
624     {
625         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/request_exdate.ics', 'r');
626         
627         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
628         
629         $event = $this->_converter->toTine20Model($vcalendarStream);
630         
631         $this->assertEquals('meeting Philipp / Lars', $event->summary, print_r($event->toArray(), true));
632     }
633
634     /**
635      * testConvertWithInvalidAlarmTime
636      * 
637      * @see 0010058: vevent with lots of exdates leads alarm saving failure
638      */
639     public function testConvertWithInvalidAlarmTime()
640     {
641         $savedEvent = $this->_saveIcsEvent('invalid_alarm_time.ics');
642         $this->assertEquals(104, count($savedEvent->exdate), print_r($savedEvent->toArray(), true));
643         $this->assertEquals(2, count($savedEvent->alarms), print_r($savedEvent->toArray(), true));
644     }
645     
646     /**
647      * save ics test event
648      * 
649      * @param string $filename
650      * @return Calendar_Model_Event
651      */
652     protected function _saveIcsEvent($filename)
653     {
654         $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/' . $filename, 'r');
655         
656         $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
657         
658         $event = $this->_converter->toTine20Model($vcalendarStream);
659         
660         return Calendar_Controller_MSEventFacade::getInstance()->create($event);
661     }
662
663     /**
664      * testRruleWithBysetpos
665      * 
666      * @see 0010058: vevent with lots of exdates leads alarm saving failure
667      */
668     public function testRruleWithBysetpos()
669     {
670         $savedEvent = $this->_saveIcsEvent('outlook_bysetpos.ics');
671         
672         $this->assertEquals(1, $savedEvent->rrule->bymonthday, print_r($savedEvent->toArray(), true));
673         $this->assertTrue(! isset($savedEvent->rrule->byday), print_r($savedEvent->toArray(), true));
674     }
675 }