1<?php 2 3namespace Sabre\VObject; 4 5use Sabre\VObject\Component\VCalendar; 6use Sabre\VObject\Component\VCard; 7 8class ComponentTest extends \PHPUnit_Framework_TestCase { 9 10 function testIterate() { 11 12 $comp = new VCalendar([], false); 13 14 $sub = $comp->createComponent('VEVENT'); 15 $comp->add($sub); 16 17 $sub = $comp->createComponent('VTODO'); 18 $comp->add($sub); 19 20 $count = 0; 21 foreach ($comp->children() as $key => $subcomponent) { 22 23 $count++; 24 $this->assertInstanceOf('Sabre\\VObject\\Component', $subcomponent); 25 26 } 27 $this->assertEquals(2, $count); 28 $this->assertEquals(1, $key); 29 30 } 31 32 function testMagicGet() { 33 34 $comp = new VCalendar([], false); 35 36 $sub = $comp->createComponent('VEVENT'); 37 $comp->add($sub); 38 39 $sub = $comp->createComponent('VTODO'); 40 $comp->add($sub); 41 42 $event = $comp->vevent; 43 $this->assertInstanceOf('Sabre\\VObject\\Component', $event); 44 $this->assertEquals('VEVENT', $event->name); 45 46 $this->assertInternalType('null', $comp->vjournal); 47 48 } 49 50 function testMagicGetGroups() { 51 52 $comp = new VCard(); 53 54 $sub = $comp->createProperty('GROUP1.EMAIL', '1@1.com'); 55 $comp->add($sub); 56 57 $sub = $comp->createProperty('GROUP2.EMAIL', '2@2.com'); 58 $comp->add($sub); 59 60 $sub = $comp->createProperty('EMAIL', '3@3.com'); 61 $comp->add($sub); 62 63 $emails = $comp->email; 64 $this->assertEquals(3, count($emails)); 65 66 $email1 = $comp->{"group1.email"}; 67 $this->assertEquals('EMAIL', $email1[0]->name); 68 $this->assertEquals('GROUP1', $email1[0]->group); 69 70 $email3 = $comp->{".email"}; 71 $this->assertEquals('EMAIL', $email3[0]->name); 72 $this->assertEquals(null, $email3[0]->group); 73 74 } 75 76 function testMagicIsset() { 77 78 $comp = new VCalendar(); 79 80 $sub = $comp->createComponent('VEVENT'); 81 $comp->add($sub); 82 83 $sub = $comp->createComponent('VTODO'); 84 $comp->add($sub); 85 86 $this->assertTrue(isset($comp->vevent)); 87 $this->assertTrue(isset($comp->vtodo)); 88 $this->assertFalse(isset($comp->vjournal)); 89 90 } 91 92 function testMagicSetScalar() { 93 94 $comp = new VCalendar(); 95 $comp->myProp = 'myValue'; 96 97 $this->assertInstanceOf('Sabre\\VObject\\Property', $comp->MYPROP); 98 $this->assertEquals('myValue', (string)$comp->MYPROP); 99 100 101 } 102 103 function testMagicSetScalarTwice() { 104 105 $comp = new VCalendar([], false); 106 $comp->myProp = 'myValue'; 107 $comp->myProp = 'myValue'; 108 109 $this->assertEquals(1, count($comp->children())); 110 $this->assertInstanceOf('Sabre\\VObject\\Property', $comp->MYPROP); 111 $this->assertEquals('myValue', (string)$comp->MYPROP); 112 113 } 114 115 function testMagicSetArray() { 116 117 $comp = new VCalendar(); 118 $comp->ORG = ['Acme Inc', 'Section 9']; 119 120 $this->assertInstanceOf('Sabre\\VObject\\Property', $comp->ORG); 121 $this->assertEquals(['Acme Inc', 'Section 9'], $comp->ORG->getParts()); 122 123 } 124 125 function testMagicSetComponent() { 126 127 $comp = new VCalendar(); 128 129 // Note that 'myProp' is ignored here. 130 $comp->myProp = $comp->createComponent('VEVENT'); 131 132 $this->assertEquals(1, count($comp)); 133 134 $this->assertEquals('VEVENT', $comp->VEVENT->name); 135 136 } 137 138 function testMagicSetTwice() { 139 140 $comp = new VCalendar([], false); 141 142 $comp->VEVENT = $comp->createComponent('VEVENT'); 143 $comp->VEVENT = $comp->createComponent('VEVENT'); 144 145 $this->assertEquals(1, count($comp->children())); 146 147 $this->assertEquals('VEVENT', $comp->VEVENT->name); 148 149 } 150 151 function testArrayAccessGet() { 152 153 $comp = new VCalendar([], false); 154 155 $event = $comp->createComponent('VEVENT'); 156 $event->summary = 'Event 1'; 157 158 $comp->add($event); 159 160 $event2 = clone $event; 161 $event2->summary = 'Event 2'; 162 163 $comp->add($event2); 164 165 $this->assertEquals(2, count($comp->children())); 166 $this->assertTrue($comp->vevent[1] instanceof Component); 167 $this->assertEquals('Event 2', (string)$comp->vevent[1]->summary); 168 169 } 170 171 function testArrayAccessExists() { 172 173 $comp = new VCalendar(); 174 175 $event = $comp->createComponent('VEVENT'); 176 $event->summary = 'Event 1'; 177 178 $comp->add($event); 179 180 $event2 = clone $event; 181 $event2->summary = 'Event 2'; 182 183 $comp->add($event2); 184 185 $this->assertTrue(isset($comp->vevent[0])); 186 $this->assertTrue(isset($comp->vevent[1])); 187 188 } 189 190 /** 191 * @expectedException LogicException 192 */ 193 function testArrayAccessSet() { 194 195 $comp = new VCalendar(); 196 $comp['hey'] = 'hi there'; 197 198 } 199 /** 200 * @expectedException LogicException 201 */ 202 function testArrayAccessUnset() { 203 204 $comp = new VCalendar(); 205 unset($comp[0]); 206 207 } 208 209 function testAddScalar() { 210 211 $comp = new VCalendar([], false); 212 213 $comp->add('myprop', 'value'); 214 215 $this->assertEquals(1, count($comp->children())); 216 217 $bla = $comp->children()[0]; 218 219 $this->assertTrue($bla instanceof Property); 220 $this->assertEquals('MYPROP', $bla->name); 221 $this->assertEquals('value', (string)$bla); 222 223 } 224 225 function testAddScalarParams() { 226 227 $comp = new VCalendar([], false); 228 229 $comp->add('myprop', 'value', ['param1' => 'value1']); 230 231 $this->assertEquals(1, count($comp->children())); 232 233 $bla = $comp->children()[0]; 234 235 $this->assertInstanceOf('Sabre\\VObject\\Property', $bla); 236 $this->assertEquals('MYPROP', $bla->name); 237 $this->assertEquals('value', (string)$bla); 238 239 $this->assertEquals(1, count($bla->parameters())); 240 241 $this->assertEquals('PARAM1', $bla->parameters['PARAM1']->name); 242 $this->assertEquals('value1', $bla->parameters['PARAM1']->getValue()); 243 244 } 245 246 247 function testAddComponent() { 248 249 $comp = new VCalendar([], false); 250 251 $comp->add($comp->createComponent('VEVENT')); 252 253 $this->assertEquals(1, count($comp->children())); 254 255 $this->assertEquals('VEVENT', $comp->VEVENT->name); 256 257 } 258 259 function testAddComponentTwice() { 260 261 $comp = new VCalendar([], false); 262 263 $comp->add($comp->createComponent('VEVENT')); 264 $comp->add($comp->createComponent('VEVENT')); 265 266 $this->assertEquals(2, count($comp->children())); 267 268 $this->assertEquals('VEVENT', $comp->VEVENT->name); 269 270 } 271 272 /** 273 * @expectedException InvalidArgumentException 274 */ 275 function testAddArgFail() { 276 277 $comp = new VCalendar(); 278 $comp->add($comp->createComponent('VEVENT'), 'hello'); 279 280 } 281 282 /** 283 * @expectedException InvalidArgumentException 284 */ 285 function testAddArgFail2() { 286 287 $comp = new VCalendar(); 288 $comp->add([]); 289 290 } 291 292 function testMagicUnset() { 293 294 $comp = new VCalendar([], false); 295 $comp->add($comp->createComponent('VEVENT')); 296 297 unset($comp->vevent); 298 299 $this->assertEquals(0, count($comp->children())); 300 301 } 302 303 304 function testCount() { 305 306 $comp = new VCalendar(); 307 $this->assertEquals(1, $comp->count()); 308 309 } 310 311 function testChildren() { 312 313 $comp = new VCalendar([], false); 314 315 // Note that 'myProp' is ignored here. 316 $comp->add($comp->createComponent('VEVENT')); 317 $comp->add($comp->createComponent('VTODO')); 318 319 $r = $comp->children(); 320 $this->assertInternalType('array', $r); 321 $this->assertEquals(2, count($r)); 322 } 323 324 function testGetComponents() { 325 326 $comp = new VCalendar(); 327 328 $comp->add($comp->createProperty('FOO', 'BAR')); 329 $comp->add($comp->createComponent('VTODO')); 330 331 $r = $comp->getComponents(); 332 $this->assertInternalType('array', $r); 333 $this->assertEquals(1, count($r)); 334 $this->assertEquals('VTODO', $r[0]->name); 335 } 336 337 function testSerialize() { 338 339 $comp = new VCalendar([], false); 340 $this->assertEquals("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n", $comp->serialize()); 341 342 } 343 344 function testSerializeChildren() { 345 346 $comp = new VCalendar([], false); 347 $event = $comp->add($comp->createComponent('VEVENT')); 348 unset($event->DTSTAMP, $event->UID); 349 $todo = $comp->add($comp->createComponent('VTODO')); 350 unset($todo->DTSTAMP, $todo->UID); 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([], 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 = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; 376 377 $comp = new VCard([], 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([ 403 'ORG' => ['Acme Inc.', 'Section 9'], 404 'FN' => 'Finn The Human', 405 ]); 406 407 $this->assertEquals(['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', [ 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([], 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([], 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([], 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', [], $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', [], $defaults = false); 481 $component->validate(Component::REPAIR); 482 $this->assertEquals('yow', $component->BAR->getValue()); 483 484 } 485 486 function ruleData() { 487 488 return [ 489 490 [[], 2], 491 [['FOO'], 3], 492 [['BAR'], 1], 493 [['BAZ'], 1], 494 [['BAR','BAZ'], 0], 495 [['BAR','BAZ','ZIM',], 0], 496 [['BAR','BAZ','ZIM','GIR'], 0], 497 [['BAR','BAZ','ZIM','GIR','GIR'], 1], 498 499 ]; 500 501 } 502 503} 504 505class FakeComponent extends Component { 506 507 function getValidationRules() { 508 509 return [ 510 'FOO' => '0', 511 'BAR' => '1', 512 'BAZ' => '+', 513 'ZIM' => '*', 514 'GIR' => '?', 515 ]; 516 517 } 518 519 function getDefaults() { 520 521 return [ 522 'BAR' => 'yow', 523 ]; 524 525 } 526 527} 528