1 <?php
2 
3 namespace Sabre\VObject;
4 
5 use
6     Sabre\VObject\Component\VCalendar,
7     Sabre\VObject\Component\VCard;
8 
9 class 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 
505 class 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