1<?php
2
3namespace Sabre\VObject;
4
5use Sabre\VObject\Component\VCalendar;
6use Sabre\VObject\Component\VCard;
7
8class PropertyTest extends \PHPUnit_Framework_TestCase {
9
10    function testToString() {
11
12        $cal = new VCalendar();
13
14        $property = $cal->createProperty('propname', 'propvalue');
15        $this->assertEquals('PROPNAME', $property->name);
16        $this->assertEquals('propvalue', $property->__toString());
17        $this->assertEquals('propvalue', (string)$property);
18        $this->assertEquals('propvalue', $property->getValue());
19
20    }
21
22    function testCreate() {
23
24        $cal = new VCalendar();
25
26        $params = [
27            'param1' => 'value1',
28            'param2' => 'value2',
29        ];
30
31        $property = $cal->createProperty('propname', 'propvalue', $params);
32
33        $this->assertEquals('value1', $property['param1']->getValue());
34        $this->assertEquals('value2', $property['param2']->getValue());
35
36    }
37
38    function testSetValue() {
39
40        $cal = new VCalendar();
41
42        $property = $cal->createProperty('propname', 'propvalue');
43        $property->setValue('value2');
44
45        $this->assertEquals('PROPNAME', $property->name);
46        $this->assertEquals('value2', $property->__toString());
47
48    }
49
50    function testParameterExists() {
51
52        $cal = new VCalendar();
53        $property = $cal->createProperty('propname', 'propvalue');
54        $property['paramname'] = 'paramvalue';
55
56        $this->assertTrue(isset($property['PARAMNAME']));
57        $this->assertTrue(isset($property['paramname']));
58        $this->assertFalse(isset($property['foo']));
59
60    }
61
62    function testParameterGet() {
63
64        $cal = new VCalendar();
65        $property = $cal->createProperty('propname', 'propvalue');
66        $property['paramname'] = 'paramvalue';
67
68        $this->assertInstanceOf('Sabre\\VObject\\Parameter', $property['paramname']);
69
70    }
71
72    function testParameterNotExists() {
73
74        $cal = new VCalendar();
75        $property = $cal->createProperty('propname', 'propvalue');
76        $property['paramname'] = 'paramvalue';
77
78        $this->assertInternalType('null', $property['foo']);
79
80    }
81
82    function testParameterMultiple() {
83
84        $cal = new VCalendar();
85        $property = $cal->createProperty('propname', 'propvalue');
86        $property['paramname'] = 'paramvalue';
87        $property->add('paramname', 'paramvalue');
88
89        $this->assertInstanceOf('Sabre\\VObject\\Parameter', $property['paramname']);
90        $this->assertEquals(2, count($property['paramname']->getParts()));
91
92    }
93
94    function testSetParameterAsString() {
95
96        $cal = new VCalendar();
97        $property = $cal->createProperty('propname', 'propvalue');
98        $property['paramname'] = 'paramvalue';
99
100        $this->assertEquals(1, count($property->parameters()));
101        $this->assertInstanceOf('Sabre\\VObject\\Parameter', $property->parameters['PARAMNAME']);
102        $this->assertEquals('PARAMNAME', $property->parameters['PARAMNAME']->name);
103        $this->assertEquals('paramvalue', $property->parameters['PARAMNAME']->getValue());
104
105    }
106
107    function testUnsetParameter() {
108
109        $cal = new VCalendar();
110        $property = $cal->createProperty('propname', 'propvalue');
111        $property['paramname'] = 'paramvalue';
112
113        unset($property['PARAMNAME']);
114        $this->assertEquals(0, count($property->parameters()));
115
116    }
117
118    function testSerialize() {
119
120        $cal = new VCalendar();
121        $property = $cal->createProperty('propname', 'propvalue');
122
123        $this->assertEquals("PROPNAME:propvalue\r\n", $property->serialize());
124
125    }
126
127    function testSerializeParam() {
128
129        $cal = new VCalendar();
130        $property = $cal->createProperty('propname', 'propvalue', [
131            'paramname'  => 'paramvalue',
132            'paramname2' => 'paramvalue2',
133        ]);
134
135        $this->assertEquals("PROPNAME;PARAMNAME=paramvalue;PARAMNAME2=paramvalue2:propvalue\r\n", $property->serialize());
136
137    }
138
139    function testSerializeNewLine() {
140
141        $cal = new VCalendar();
142        $property = $cal->createProperty('SUMMARY', "line1\nline2");
143
144        $this->assertEquals("SUMMARY:line1\\nline2\r\n", $property->serialize());
145
146    }
147
148    function testSerializeLongLine() {
149
150        $cal = new VCalendar();
151        $value = str_repeat('!', 200);
152        $property = $cal->createProperty('propname', $value);
153
154        $expected = "PROPNAME:" . str_repeat('!', 66) . "\r\n " . str_repeat('!', 74) . "\r\n " . str_repeat('!', 60) . "\r\n";
155
156        $this->assertEquals($expected, $property->serialize());
157
158    }
159
160    function testSerializeUTF8LineFold() {
161
162        $cal = new VCalendar();
163        $value = str_repeat('!', 65) . "\xc3\xa4bla"; // inserted umlaut-a
164        $property = $cal->createProperty('propname', $value);
165        $expected = "PROPNAME:" . str_repeat('!', 65) . "\r\n \xc3\xa4bla\r\n";
166        $this->assertEquals($expected, $property->serialize());
167
168    }
169
170    function testGetIterator() {
171
172        $cal = new VCalendar();
173        $it = new ElementList([]);
174        $property = $cal->createProperty('propname', 'propvalue');
175        $property->setIterator($it);
176        $this->assertEquals($it, $property->getIterator());
177
178    }
179
180
181    function testGetIteratorDefault() {
182
183        $cal = new VCalendar();
184        $property = $cal->createProperty('propname', 'propvalue');
185        $it = $property->getIterator();
186        $this->assertTrue($it instanceof ElementList);
187        $this->assertEquals(1, count($it));
188
189    }
190
191    function testAddScalar() {
192
193        $cal = new VCalendar();
194        $property = $cal->createProperty('EMAIL');
195
196        $property->add('myparam', 'value');
197
198        $this->assertEquals(1, count($property->parameters()));
199
200        $this->assertTrue($property->parameters['MYPARAM'] instanceof Parameter);
201        $this->assertEquals('MYPARAM', $property->parameters['MYPARAM']->name);
202        $this->assertEquals('value', $property->parameters['MYPARAM']->getValue());
203
204    }
205
206    function testAddParameter() {
207
208        $cal = new VCalendar();
209        $prop = $cal->createProperty('EMAIL');
210
211        $prop->add('MYPARAM', 'value');
212
213        $this->assertEquals(1, count($prop->parameters()));
214        $this->assertEquals('MYPARAM', $prop['myparam']->name);
215
216    }
217
218    function testAddParameterTwice() {
219
220        $cal = new VCalendar();
221        $prop = $cal->createProperty('EMAIL');
222
223        $prop->add('MYPARAM', 'value1');
224        $prop->add('MYPARAM', 'value2');
225
226        $this->assertEquals(1, count($prop->parameters));
227        $this->assertEquals(2, count($prop->parameters['MYPARAM']->getParts()));
228
229        $this->assertEquals('MYPARAM', $prop['MYPARAM']->name);
230
231    }
232
233
234    function testClone() {
235
236        $cal = new VCalendar();
237        $property = $cal->createProperty('EMAIL', 'value');
238        $property['FOO'] = 'BAR';
239
240        $property2 = clone $property;
241
242        $property['FOO'] = 'BAZ';
243        $this->assertEquals('BAR', (string)$property2['FOO']);
244
245    }
246
247    function testCreateParams() {
248
249        $cal = new VCalendar();
250        $property = $cal->createProperty('X-PROP', 'value', [
251            'param1' => 'value1',
252            'param2' => ['value2', 'value3']
253        ]);
254
255        $this->assertEquals(1, count($property['PARAM1']->getParts()));
256        $this->assertEquals(2, count($property['PARAM2']->getParts()));
257
258    }
259
260    function testValidateNonUTF8() {
261
262        $calendar = new VCalendar();
263        $property = $calendar->createProperty('X-PROP', "Bla\x00");
264        $result = $property->validate(Property::REPAIR);
265
266        $this->assertEquals('Property contained a control character (0x00)', $result[0]['message']);
267        $this->assertEquals('Bla', $property->getValue());
268
269    }
270
271    function testValidateControlChars() {
272
273        $s = "chars[";
274        foreach ([
275            0x7F, 0x5E, 0x5C, 0x3B, 0x3A, 0x2C, 0x22, 0x20,
276            0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
277            0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
278            0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
279            0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
280          ] as $c) {
281            $s .= sprintf('%02X(%c)', $c, $c);
282        }
283        $s .= "]end";
284
285        $calendar = new VCalendar();
286        $property = $calendar->createProperty('X-PROP', $s);
287        $result = $property->validate(Property::REPAIR);
288
289        $this->assertEquals('Property contained a control character (0x7f)', $result[0]['message']);
290        $this->assertEquals("chars[7F()5E(^)5C(\\\\)3B(\\;)3A(:)2C(\\,)22(\")20( )1F()1E()1D()1C()1B()1A()19()18()17()16()15()14()13()12()11()10()0F()0E()0D()0C()0B()0A(\\n)09(\t)08()07()06()05()04()03()02()01()00()]end", $property->getRawMimeDirValue());
291
292    }
293
294    function testValidateBadPropertyName() {
295
296        $calendar = new VCalendar();
297        $property = $calendar->createProperty("X_*&PROP*", "Bla");
298        $result = $property->validate(Property::REPAIR);
299
300        $this->assertEquals($result[0]['message'], 'The propertyname: X_*&PROP* contains invalid characters. Only A-Z, 0-9 and - are allowed');
301        $this->assertEquals('X-PROP', $property->name);
302
303    }
304
305    function testGetValue() {
306
307        $calendar = new VCalendar();
308        $property = $calendar->createProperty("SUMMARY", null);
309        $this->assertEquals([], $property->getParts());
310        $this->assertNull($property->getValue());
311
312        $property->setValue([]);
313        $this->assertEquals([], $property->getParts());
314        $this->assertNull($property->getValue());
315
316        $property->setValue([1]);
317        $this->assertEquals([1], $property->getParts());
318        $this->assertEquals(1, $property->getValue());
319
320        $property->setValue([1, 2]);
321        $this->assertEquals([1, 2], $property->getParts());
322        $this->assertEquals('1,2', $property->getValue());
323
324        $property->setValue('str');
325        $this->assertEquals(['str'], $property->getParts());
326        $this->assertEquals('str', $property->getValue());
327    }
328
329    /**
330     * ElementList should reject this.
331     *
332     * @expectedException \LogicException
333     */
334    function testArrayAccessSetInt() {
335
336        $calendar = new VCalendar();
337        $property = $calendar->createProperty("X-PROP", null);
338
339        $calendar->add($property);
340        $calendar->{'X-PROP'}[0] = 'Something!';
341
342    }
343
344    /**
345     * ElementList should reject this.
346     *
347     * @expectedException \LogicException
348     */
349    function testArrayAccessUnsetInt() {
350
351        $calendar = new VCalendar();
352        $property = $calendar->createProperty("X-PROP", null);
353
354        $calendar->add($property);
355        unset($calendar->{'X-PROP'}[0]);
356
357    }
358
359    function testValidateBadEncoding() {
360
361        $document = new VCalendar();
362        $property = $document->add('X-FOO', 'value');
363        $property['ENCODING'] = 'invalid';
364
365        $result = $property->validate();
366
367        $this->assertEquals('ENCODING=INVALID is not valid for this document type.', $result[0]['message']);
368        $this->assertEquals(3, $result[0]['level']);
369
370    }
371
372    function testValidateBadEncodingVCard4() {
373
374        $document = new VCard(['VERSION' => '4.0']);
375        $property = $document->add('X-FOO', 'value');
376        $property['ENCODING'] = 'BASE64';
377
378        $result = $property->validate();
379
380        $this->assertEquals('ENCODING parameter is not valid in vCard 4.', $result[0]['message']);
381        $this->assertEquals(3, $result[0]['level']);
382
383    }
384
385    function testValidateBadEncodingVCard3() {
386
387        $document = new VCard(['VERSION' => '3.0']);
388        $property = $document->add('X-FOO', 'value');
389        $property['ENCODING'] = 'BASE64';
390
391        $result = $property->validate();
392
393        $this->assertEquals('ENCODING=BASE64 is not valid for this document type.', $result[0]['message']);
394        $this->assertEquals(3, $result[0]['level']);
395
396    }
397
398    function testValidateBadEncodingVCard21() {
399
400        $document = new VCard(['VERSION' => '2.1']);
401        $property = $document->add('X-FOO', 'value');
402        $property['ENCODING'] = 'B';
403
404        $result = $property->validate();
405
406        $this->assertEquals('ENCODING=B is not valid for this document type.', $result[0]['message']);
407        $this->assertEquals(3, $result[0]['level']);
408
409    }
410}
411