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