1<?php
2
3namespace Sabre\VObject;
4
5use
6    Sabre\VObject\Component\VCalendar,
7    Sabre\VObject\Component\VCard;
8
9class ComponentTest extends \PHPUnit_Framework_TestCase {
10
11    function testIterate() {
12
13        $comp = new VCalendar(array(), false);
14
15        $sub = $comp->createComponent('VEVENT');
16        $comp->add($sub);
17
18        $sub = $comp->createComponent('VTODO');
19        $comp->add($sub);
20
21        $count = 0;
22        foreach($comp->children() as $key=>$subcomponent) {
23
24           $count++;
25           $this->assertInstanceOf('Sabre\\VObject\\Component',$subcomponent);
26
27        }
28        $this->assertEquals(2,$count);
29        $this->assertEquals(1,$key);
30
31    }
32
33    function testMagicGet() {
34
35        $comp = new VCalendar(array(), false);
36
37        $sub = $comp->createComponent('VEVENT');
38        $comp->add($sub);
39
40        $sub = $comp->createComponent('VTODO');
41        $comp->add($sub);
42
43        $event = $comp->vevent;
44        $this->assertInstanceOf('Sabre\\VObject\\Component', $event);
45        $this->assertEquals('VEVENT', $event->name);
46
47        $this->assertInternalType('null', $comp->vjournal);
48
49    }
50
51    function testMagicGetGroups() {
52
53        $comp = new VCard();
54
55        $sub = $comp->createProperty('GROUP1.EMAIL','1@1.com');
56        $comp->add($sub);
57
58        $sub = $comp->createProperty('GROUP2.EMAIL','2@2.com');
59        $comp->add($sub);
60
61        $sub = $comp->createProperty('EMAIL','3@3.com');
62        $comp->add($sub);
63
64        $emails = $comp->email;
65        $this->assertEquals(3, count($emails));
66
67        $email1 = $comp->{"group1.email"};
68        $this->assertEquals('EMAIL', $email1[0]->name);
69        $this->assertEquals('GROUP1', $email1[0]->group);
70
71        $email3 = $comp->{".email"};
72        $this->assertEquals('EMAIL', $email3[0]->name);
73        $this->assertEquals(null, $email3[0]->group);
74
75    }
76
77    function testMagicIsset() {
78
79        $comp = new VCalendar();
80
81        $sub = $comp->createComponent('VEVENT');
82        $comp->add($sub);
83
84        $sub = $comp->createComponent('VTODO');
85        $comp->add($sub);
86
87        $this->assertTrue(isset($comp->vevent));
88        $this->assertTrue(isset($comp->vtodo));
89        $this->assertFalse(isset($comp->vjournal));
90
91    }
92
93    function testMagicSetScalar() {
94
95        $comp = new VCalendar();
96        $comp->myProp = 'myValue';
97
98        $this->assertInstanceOf('Sabre\\VObject\\Property',$comp->MYPROP);
99        $this->assertEquals('myValue',(string)$comp->MYPROP);
100
101
102    }
103
104    function testMagicSetScalarTwice() {
105
106        $comp = new VCalendar(array(), false);
107        $comp->myProp = 'myValue';
108        $comp->myProp = 'myValue';
109
110        $this->assertEquals(1,count($comp->children()));
111        $this->assertInstanceOf('Sabre\\VObject\\Property',$comp->MYPROP);
112        $this->assertEquals('myValue',(string)$comp->MYPROP);
113
114    }
115
116    function testMagicSetArray() {
117
118        $comp = new VCalendar();
119        $comp->ORG = array('Acme Inc', 'Section 9');
120
121        $this->assertInstanceOf('Sabre\\VObject\\Property',$comp->ORG);
122        $this->assertEquals(array('Acme Inc', 'Section 9'),$comp->ORG->getParts());
123
124    }
125
126    function testMagicSetComponent() {
127
128        $comp = new VCalendar();
129
130        // Note that 'myProp' is ignored here.
131        $comp->myProp = $comp->createComponent('VEVENT');
132
133        $this->assertEquals(1, count($comp));
134
135        $this->assertEquals('VEVENT',$comp->VEVENT->name);
136
137    }
138
139    function testMagicSetTwice() {
140
141        $comp = new VCalendar(array(), false);
142
143        $comp->VEVENT = $comp->createComponent('VEVENT');
144        $comp->VEVENT = $comp->createComponent('VEVENT');
145
146        $this->assertEquals(1, count($comp->children()));
147
148        $this->assertEquals('VEVENT',$comp->VEVENT->name);
149
150    }
151
152    function testArrayAccessGet() {
153
154        $comp = new VCalendar(array(), false);
155
156        $event = $comp->createComponent('VEVENT');
157        $event->summary = 'Event 1';
158
159        $comp->add($event);
160
161        $event2 = clone $event;
162        $event2->summary = 'Event 2';
163
164        $comp->add($event2);
165
166        $this->assertEquals(2,count($comp->children()));
167        $this->assertTrue($comp->vevent[1] instanceof Component);
168        $this->assertEquals('Event 2', (string)$comp->vevent[1]->summary);
169
170    }
171
172    function testArrayAccessExists() {
173
174        $comp = new VCalendar();
175
176        $event = $comp->createComponent('VEVENT');
177        $event->summary = 'Event 1';
178
179        $comp->add($event);
180
181        $event2 = clone $event;
182        $event2->summary = 'Event 2';
183
184        $comp->add($event2);
185
186        $this->assertTrue(isset($comp->vevent[0]));
187        $this->assertTrue(isset($comp->vevent[1]));
188
189    }
190
191    /**
192     * @expectedException LogicException
193     */
194    function testArrayAccessSet() {
195
196        $comp = new VCalendar();
197        $comp['hey'] = 'hi there';
198
199    }
200    /**
201     * @expectedException LogicException
202     */
203    function testArrayAccessUnset() {
204
205        $comp = new VCalendar();
206        unset($comp[0]);
207
208    }
209
210    function testAddScalar() {
211
212        $comp = new VCalendar(array(), false);
213
214        $comp->add('myprop','value');
215
216        $this->assertEquals(1, count($comp->children()));
217
218        $bla = $comp->children[0];
219
220        $this->assertTrue($bla instanceof Property);
221        $this->assertEquals('MYPROP',$bla->name);
222        $this->assertEquals('value',(string)$bla);
223
224    }
225
226    function testAddScalarParams() {
227
228        $comp = new VCalendar(array(), false);
229
230        $comp->add('myprop','value',array('param1'=>'value1'));
231
232        $this->assertEquals(1, count($comp->children()));
233
234        $bla = $comp->children[0];
235
236        $this->assertInstanceOf('Sabre\\VObject\\Property', $bla);
237        $this->assertEquals('MYPROP',$bla->name);
238        $this->assertEquals('value', (string)$bla);
239
240        $this->assertEquals(1, count($bla->parameters()));
241
242        $this->assertEquals('PARAM1',$bla->parameters['PARAM1']->name);
243        $this->assertEquals('value1',$bla->parameters['PARAM1']->getValue());
244
245    }
246
247
248    function testAddComponent() {
249
250        $comp = new VCalendar(array(), false);
251
252        $comp->add($comp->createComponent('VEVENT'));
253
254        $this->assertEquals(1, count($comp->children()));
255
256        $this->assertEquals('VEVENT',$comp->VEVENT->name);
257
258    }
259
260    function testAddComponentTwice() {
261
262        $comp = new VCalendar(array(), false);
263
264        $comp->add($comp->createComponent('VEVENT'));
265        $comp->add($comp->createComponent('VEVENT'));
266
267        $this->assertEquals(2, count($comp->children()));
268
269        $this->assertEquals('VEVENT',$comp->VEVENT->name);
270
271    }
272
273    /**
274     * @expectedException InvalidArgumentException
275     */
276    function testAddArgFail() {
277
278        $comp = new VCalendar();
279        $comp->add($comp->createComponent('VEVENT'),'hello');
280
281    }
282
283    /**
284     * @expectedException InvalidArgumentException
285     */
286    function testAddArgFail2() {
287
288        $comp = new VCalendar();
289        $comp->add(array());
290
291    }
292
293    function testMagicUnset() {
294
295        $comp = new VCalendar(array(), false);
296        $comp->add($comp->createComponent('VEVENT'));
297
298        unset($comp->vevent);
299
300        $this->assertEquals(0, count($comp->children()));
301
302    }
303
304
305    function testCount() {
306
307        $comp = new VCalendar();
308        $this->assertEquals(1,$comp->count());
309
310    }
311
312    function testChildren() {
313
314        $comp = new VCalendar(array(), false);
315
316        // Note that 'myProp' is ignored here.
317        $comp->add($comp->createComponent('VEVENT'));
318        $comp->add($comp->createComponent('VTODO'));
319
320        $r = $comp->children();
321        $this->assertInternalType('array', $r);
322        $this->assertEquals(2,count($r));
323    }
324
325    function testGetComponents() {
326
327        $comp = new VCalendar();
328
329        $comp->add($comp->createProperty('FOO','BAR'));
330        $comp->add($comp->createComponent('VTODO'));
331
332        $r = $comp->getComponents();
333        $this->assertInternalType('array', $r);
334        $this->assertEquals(1, count($r));
335        $this->assertEquals('VTODO', $r[0]->name);
336    }
337
338    function testSerialize() {
339
340        $comp = new VCalendar(array(), false);
341        $this->assertEquals("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n", $comp->serialize());
342
343    }
344
345    function testSerializeChildren() {
346
347        $comp = new VCalendar(array(), false);
348        $event = $comp->add($comp->createComponent('VEVENT'));
349        unset($event->DTSTAMP, $event->UID);
350        $comp->add($comp->createComponent('VTODO'));
351
352        $str = $comp->serialize();
353
354        $this->assertEquals("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n", $str);
355
356    }
357
358    function testSerializeOrderCompAndProp() {
359
360        $comp = new VCalendar(array(), false);
361        $comp->add($event = $comp->createComponent('VEVENT'));
362        $comp->add('PROP1','BLABLA');
363        $comp->add('VERSION','2.0');
364        $comp->add($comp->createComponent('VTIMEZONE'));
365
366        unset($event->DTSTAMP, $event->UID);
367        $str = $comp->serialize();
368
369        $this->assertEquals("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPROP1:BLABLA\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", $str);
370
371    }
372
373    function testAnotherSerializeOrderProp() {
374
375        $prop4s=array('1', '2', '3', '4', '5', '6', '7', '8', '9', '10');
376
377        $comp = new VCard(array(), false);
378
379        $comp->__set('SOMEPROP','FOO');
380        $comp->__set('ANOTHERPROP','FOO');
381        $comp->__set('THIRDPROP','FOO');
382        foreach ($prop4s as $prop4) {
383            $comp->add('PROP4', 'FOO '.$prop4);
384        }
385        $comp->__set('PROPNUMBERFIVE', 'FOO');
386        $comp->__set('PROPNUMBERSIX', 'FOO');
387        $comp->__set('PROPNUMBERSEVEN', 'FOO');
388        $comp->__set('PROPNUMBEREIGHT', 'FOO');
389        $comp->__set('PROPNUMBERNINE', 'FOO');
390        $comp->__set('PROPNUMBERTEN', 'FOO');
391        $comp->__set('VERSION','2.0');
392        $comp->__set('UID', 'FOO');
393
394        $str = $comp->serialize();
395
396        $this->assertEquals("BEGIN:VCARD\r\nVERSION:2.0\r\nSOMEPROP:FOO\r\nANOTHERPROP:FOO\r\nTHIRDPROP:FOO\r\nPROP4:FOO 1\r\nPROP4:FOO 2\r\nPROP4:FOO 3\r\nPROP4:FOO 4\r\nPROP4:FOO 5\r\nPROP4:FOO 6\r\nPROP4:FOO 7\r\nPROP4:FOO 8\r\nPROP4:FOO 9\r\nPROP4:FOO 10\r\nPROPNUMBERFIVE:FOO\r\nPROPNUMBERSIX:FOO\r\nPROPNUMBERSEVEN:FOO\r\nPROPNUMBEREIGHT:FOO\r\nPROPNUMBERNINE:FOO\r\nPROPNUMBERTEN:FOO\r\nUID:FOO\r\nEND:VCARD\r\n", $str);
397
398    }
399
400    function testInstantiateWithChildren() {
401
402        $comp = new VCard(array(
403            'ORG' => array('Acme Inc.', 'Section 9'),
404            'FN' => 'Finn The Human',
405        ));
406
407        $this->assertEquals(array('Acme Inc.', 'Section 9'), $comp->ORG->getParts());
408        $this->assertEquals('Finn The Human', $comp->FN->getValue());
409
410    }
411
412    function testInstantiateSubComponent() {
413
414        $comp = new VCalendar();
415        $event = $comp->createComponent('VEVENT', array(
416            $comp->createProperty('UID', '12345'),
417        ));
418        $comp->add($event);
419
420        $this->assertEquals('12345', $comp->VEVENT->UID->getValue());
421
422    }
423
424    function testRemoveByName() {
425
426        $comp = new VCalendar(array(), false);
427        $comp->add('prop1','val1');
428        $comp->add('prop2','val2');
429        $comp->add('prop2','val2');
430
431        $comp->remove('prop2');
432        $this->assertFalse(isset($comp->prop2));
433        $this->assertTrue(isset($comp->prop1));
434
435    }
436
437    function testRemoveByObj() {
438
439        $comp = new VCalendar(array(), false);
440        $comp->add('prop1','val1');
441        $prop = $comp->add('prop2','val2');
442
443        $comp->remove($prop);
444        $this->assertFalse(isset($comp->prop2));
445        $this->assertTrue(isset($comp->prop1));
446
447    }
448
449    /**
450     * @expectedException InvalidArgumentException
451     */
452    function testRemoveNotFound() {
453
454        $comp = new VCalendar(array(), false);
455        $prop = $comp->createProperty('A','B');
456        $comp->remove($prop);
457
458    }
459
460    /**
461     * @dataProvider ruleData
462     */
463    function testValidateRules($componentList, $errorCount) {
464
465        $vcard = new Component\VCard();
466
467        $component = new FakeComponent($vcard,'Hi', array(), $defaults = false );
468        foreach($componentList as $v) {
469            $component->add($v,'Hello.');
470        }
471
472        $this->assertEquals($errorCount, count($component->validate()));
473
474    }
475
476    function testValidateRepair() {
477
478        $vcard = new Component\VCard();
479
480        $component = new FakeComponent($vcard,'Hi', array(), $defaults = false );
481        $component->validate(Component::REPAIR);
482        $this->assertEquals('yow', $component->BAR->getValue());
483
484    }
485
486    function ruleData() {
487
488        return array(
489
490            array(array(), 2),
491            array(array('FOO'), 3),
492            array(array('BAR'), 1),
493            array(array('BAZ'), 1),
494            array(array('BAR','BAZ'), 0),
495            array(array('BAR','BAZ','ZIM',), 0),
496            array(array('BAR','BAZ','ZIM','GIR'), 0),
497            array(array('BAR','BAZ','ZIM','GIR','GIR'), 1),
498
499        );
500
501    }
502
503}
504
505class FakeComponent extends Component {
506
507    public function getValidationRules() {
508
509        return array(
510            'FOO' => '0',
511            'BAR' => '1',
512            'BAZ' => '+',
513            'ZIM' => '*',
514            'GIR' => '?',
515        );
516
517    }
518
519    public function getDefaults() {
520
521        return array(
522            'BAR' => 'yow',
523        );
524
525    }
526
527}
528
529