1<?php
2
3namespace Sabre\VObject;
4
5class VCardConverterTest extends \PHPUnit_Framework_TestCase {
6
7    use \Sabre\VObject\PHPUnitAssertions;
8
9    function testConvert30to40() {
10
11        $input = <<<IN
12BEGIN:VCARD
13VERSION:3.0
14PRODID:foo
15FN;CHARSET=UTF-8:Steve
16TEL;TYPE=PREF,HOME:+1 555 666 777
17ITEM1.TEL:+1 444 555 666
18ITEM1.X-ABLABEL:CustomLabel
19PHOTO;ENCODING=b;TYPE=JPEG,HOME:Zm9v
20PHOTO;ENCODING=b;TYPE=GIF:Zm9v
21PHOTO;X-PARAM=FOO;ENCODING=b;TYPE=PNG:Zm9v
22PHOTO;VALUE=URI:http://example.org/foo.png
23X-ABShowAs:COMPANY
24END:VCARD
25IN;
26
27        $output = <<<OUT
28BEGIN:VCARD
29VERSION:4.0
30FN:Steve
31TEL;PREF=1;TYPE=HOME:+1 555 666 777
32ITEM1.TEL:+1 444 555 666
33ITEM1.X-ABLABEL:CustomLabel
34PHOTO;TYPE=HOME:data:image/jpeg;base64,Zm9v
35PHOTO:data:image/gif;base64,Zm9v
36PHOTO;X-PARAM=FOO:data:image/png;base64,Zm9v
37PHOTO:http://example.org/foo.png
38KIND:ORG
39END:VCARD
40OUT;
41
42        $vcard = Reader::read($input);
43        $vcard = $vcard->convert(Document::VCARD40);
44
45        $this->assertVObjectEqualsVObject(
46            $output,
47            $vcard
48        );
49
50    }
51
52    function testConvert40to40() {
53
54        $input = <<<IN
55BEGIN:VCARD
56VERSION:4.0
57FN:Steve
58TEL;PREF=1;TYPE=HOME:+1 555 666 777
59PHOTO:data:image/jpeg;base64,Zm9v
60PHOTO:data:image/gif;base64,Zm9v
61PHOTO;X-PARAM=FOO:data:image/png;base64,Zm9v
62PHOTO:http://example.org/foo.png
63END:VCARD
64
65IN;
66
67        $output = <<<OUT
68BEGIN:VCARD
69VERSION:4.0
70FN:Steve
71TEL;PREF=1;TYPE=HOME:+1 555 666 777
72PHOTO:data:image/jpeg;base64,Zm9v
73PHOTO:data:image/gif;base64,Zm9v
74PHOTO;X-PARAM=FOO:data:image/png;base64,Zm9v
75PHOTO:http://example.org/foo.png
76END:VCARD
77
78OUT;
79
80        $vcard = Reader::read($input);
81        $vcard = $vcard->convert(Document::VCARD40);
82
83        $this->assertVObjectEqualsVObject(
84            $output,
85            $vcard
86        );
87
88    }
89
90    function testConvert21to40() {
91
92        $input = <<<IN
93BEGIN:VCARD
94VERSION:2.1
95N:Family;Johnson
96FN:Johnson Family
97TEL;HOME;VOICE:555-12345-345
98ADR;HOME:;;100 Street Lane;Saubel Beach;ON;H0H0H0
99LABEL;HOME;ENCODING=QUOTED-PRINTABLE:100 Street Lane=0D=0ASaubel Beach,
100 ON H0H0H0
101REV:20110731T040251Z
102UID:12345678
103END:VCARD
104IN;
105
106        $output = <<<OUT
107BEGIN:VCARD
108VERSION:4.0
109N:Family;Johnson;;;
110FN:Johnson Family
111TEL;TYPE=HOME,VOICE:555-12345-345
112ADR;TYPE=HOME:;;100 Street Lane;Saubel Beach;ON;H0H0H0;
113REV:20110731T040251Z
114UID:12345678
115END:VCARD
116
117OUT;
118
119        $vcard = Reader::read($input);
120        $vcard = $vcard->convert(Document::VCARD40);
121
122        $this->assertVObjectEqualsVObject(
123            $output,
124            $vcard
125        );
126
127    }
128
129    function testConvert30to30() {
130
131        $input = <<<IN
132BEGIN:VCARD
133VERSION:3.0
134PRODID:foo
135FN;CHARSET=UTF-8:Steve
136TEL;TYPE=PREF,HOME:+1 555 666 777
137PHOTO;ENCODING=b;TYPE=JPEG:Zm9v
138PHOTO;ENCODING=b;TYPE=GIF:Zm9v
139PHOTO;X-PARAM=FOO;ENCODING=b;TYPE=PNG:Zm9v
140PHOTO;VALUE=URI:http://example.org/foo.png
141END:VCARD
142
143IN;
144
145        $output = <<<OUT
146BEGIN:VCARD
147VERSION:3.0
148PRODID:foo
149FN;CHARSET=UTF-8:Steve
150TEL;TYPE=PREF,HOME:+1 555 666 777
151PHOTO;ENCODING=b;TYPE=JPEG:Zm9v
152PHOTO;ENCODING=b;TYPE=GIF:Zm9v
153PHOTO;X-PARAM=FOO;ENCODING=b;TYPE=PNG:Zm9v
154PHOTO;VALUE=URI:http://example.org/foo.png
155END:VCARD
156
157OUT;
158
159        $vcard = Reader::read($input);
160        $vcard = $vcard->convert(Document::VCARD30);
161
162        $this->assertVObjectEqualsVObject(
163            $output,
164            $vcard
165        );
166
167    }
168
169    function testConvert40to30() {
170
171        $input = <<<IN
172BEGIN:VCARD
173VERSION:4.0
174PRODID:foo
175FN:Steve
176TEL;PREF=1;TYPE=HOME:+1 555 666 777
177PHOTO:data:image/jpeg;base64,Zm9v
178PHOTO:data:image/gif,foo
179PHOTO;X-PARAM=FOO:data:image/png;base64,Zm9v
180PHOTO:http://example.org/foo.png
181KIND:ORG
182END:VCARD
183
184IN;
185
186        $output = <<<OUT
187BEGIN:VCARD
188VERSION:3.0
189FN:Steve
190TEL;TYPE=PREF,HOME:+1 555 666 777
191PHOTO;ENCODING=b;TYPE=JPEG:Zm9v
192PHOTO;ENCODING=b;TYPE=GIF:Zm9v
193PHOTO;ENCODING=b;TYPE=PNG;X-PARAM=FOO:Zm9v
194PHOTO;VALUE=URI:http://example.org/foo.png
195X-ABSHOWAS:COMPANY
196END:VCARD
197
198OUT;
199
200        $vcard = Reader::read($input);
201        $vcard = $vcard->convert(Document::VCARD30);
202
203        $this->assertVObjectEqualsVObject(
204            $output,
205            $vcard
206        );
207
208    }
209
210    function testConvertGroupCard() {
211
212        $input = <<<IN
213BEGIN:VCARD
214VERSION:3.0
215PRODID:foo
216X-ADDRESSBOOKSERVER-KIND:GROUP
217END:VCARD
218
219IN;
220
221        $output = <<<OUT
222BEGIN:VCARD
223VERSION:4.0
224KIND:GROUP
225END:VCARD
226
227OUT;
228
229        $vcard = Reader::read($input);
230        $vcard = $vcard->convert(Document::VCARD40);
231
232        $this->assertVObjectEqualsVObject(
233            $output,
234            $vcard
235        );
236
237        $input = $output;
238        $output = <<<OUT
239BEGIN:VCARD
240VERSION:3.0
241X-ADDRESSBOOKSERVER-KIND:GROUP
242END:VCARD
243
244OUT;
245
246        $vcard = Reader::read($input);
247        $vcard = $vcard->convert(Document::VCARD30);
248
249        $this->assertVObjectEqualsVObject(
250            $output,
251            $vcard
252        );
253
254    }
255
256    function testBDAYConversion() {
257
258        $input = <<<IN
259BEGIN:VCARD
260VERSION:3.0
261PRODID:foo
262BDAY;X-APPLE-OMIT-YEAR=1604:1604-04-16
263END:VCARD
264
265IN;
266
267        $output = <<<OUT
268BEGIN:VCARD
269VERSION:4.0
270BDAY:--04-16
271END:VCARD
272
273OUT;
274
275        $vcard = Reader::read($input);
276        $vcard = $vcard->convert(Document::VCARD40);
277
278        $this->assertVObjectEqualsVObject(
279            $output,
280            $vcard
281        );
282
283        $input = $output;
284        $output = <<<OUT
285BEGIN:VCARD
286VERSION:3.0
287BDAY;X-APPLE-OMIT-YEAR=1604:1604-04-16
288END:VCARD
289
290OUT;
291
292        $vcard = Reader::read($input);
293        $vcard = $vcard->convert(Document::VCARD30);
294
295        $this->assertVObjectEqualsVObject(
296            $output,
297            $vcard
298        );
299
300    }
301
302    /**
303     * @expectedException InvalidArgumentException
304     */
305    function testUnknownSourceVCardVersion() {
306
307        $input = <<<IN
308BEGIN:VCARD
309VERSION:4.2
310PRODID:foo
311FN;CHARSET=UTF-8:Steve
312TEL;TYPE=PREF,HOME:+1 555 666 777
313ITEM1.TEL:+1 444 555 666
314ITEM1.X-ABLABEL:CustomLabel
315PHOTO;ENCODING=b;TYPE=JPEG,HOME:Zm9v
316PHOTO;ENCODING=b;TYPE=GIF:Zm9v
317PHOTO;X-PARAM=FOO;ENCODING=b;TYPE=PNG:Zm9v
318PHOTO;VALUE=URI:http://example.org/foo.png
319X-ABShowAs:COMPANY
320END:VCARD
321
322IN;
323
324        $vcard = Reader::read($input);
325        $vcard->convert(Document::VCARD40);
326
327    }
328
329    /**
330     * @expectedException InvalidArgumentException
331     */
332    function testUnknownTargetVCardVersion() {
333
334        $input = <<<IN
335BEGIN:VCARD
336VERSION:3.0
337PRODID:foo
338END:VCARD
339
340IN;
341
342        $vcard = Reader::read($input);
343        $vcard->convert(Document::VCARD21);
344
345    }
346
347    function testConvertIndividualCard() {
348
349        $input = <<<IN
350BEGIN:VCARD
351VERSION:4.0
352PRODID:foo
353KIND:INDIVIDUAL
354END:VCARD
355
356IN;
357
358        $output = <<<OUT
359BEGIN:VCARD
360VERSION:3.0
361END:VCARD
362
363OUT;
364
365        $vcard = Reader::read($input);
366        $vcard = $vcard->convert(Document::VCARD30);
367
368        $this->assertVObjectEqualsVObject(
369            $output,
370            $vcard
371        );
372
373        $input = $output;
374        $output = <<<OUT
375BEGIN:VCARD
376VERSION:4.0
377END:VCARD
378
379OUT;
380
381        $vcard = Reader::read($input);
382        $vcard = $vcard->convert(Document::VCARD40);
383
384        $this->assertVObjectEqualsVObject(
385            $output,
386            $vcard
387        );
388
389    }
390
391    function testAnniversary() {
392
393        $input = <<<IN
394BEGIN:VCARD
395VERSION:4.0
396ITEM1.ANNIVERSARY:20081210
397END:VCARD
398
399IN;
400
401        $output = <<<'OUT'
402BEGIN:VCARD
403VERSION:3.0
404ITEM1.X-ABDATE;VALUE=DATE-AND-OR-TIME:20081210
405ITEM1.X-ABLABEL:_$!<Anniversary>!$_
406ITEM1.X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20081210
407END:VCARD
408
409OUT;
410
411        $vcard = Reader::read($input);
412        $vcard = $vcard->convert(Document::VCARD30);
413
414        $this->assertVObjectEqualsVObject(
415            $output,
416            $vcard
417        );
418
419        // Swapping input and output
420        list(
421            $input,
422            $output
423        ) = [
424            $output,
425            $input
426        ];
427
428        $vcard = Reader::read($input);
429        $vcard = $vcard->convert(Document::VCARD40);
430
431        $this->assertVObjectEqualsVObject(
432            $output,
433            $vcard
434        );
435
436    }
437
438    function testMultipleAnniversaries() {
439
440        $input = <<<IN
441BEGIN:VCARD
442VERSION:4.0
443ITEM1.ANNIVERSARY:20081210
444ITEM2.ANNIVERSARY:20091210
445ITEM3.ANNIVERSARY:20101210
446END:VCARD
447
448IN;
449
450        $output = <<<'OUT'
451BEGIN:VCARD
452VERSION:3.0
453ITEM1.X-ABDATE;VALUE=DATE-AND-OR-TIME:20081210
454ITEM1.X-ABLABEL:_$!<Anniversary>!$_
455ITEM1.X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20081210
456ITEM2.X-ABDATE;VALUE=DATE-AND-OR-TIME:20091210
457ITEM2.X-ABLABEL:_$!<Anniversary>!$_
458ITEM2.X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20091210
459ITEM3.X-ABDATE;VALUE=DATE-AND-OR-TIME:20101210
460ITEM3.X-ABLABEL:_$!<Anniversary>!$_
461ITEM3.X-ANNIVERSARY;VALUE=DATE-AND-OR-TIME:20101210
462END:VCARD
463
464OUT;
465
466        $vcard = Reader::read($input);
467        $vcard = $vcard->convert(Document::VCARD30);
468
469        $this->assertVObjectEqualsVObject(
470            $output,
471            $vcard
472        );
473
474        // Swapping input and output
475        list(
476            $input,
477            $output
478        ) = [
479            $output,
480            $input
481        ];
482
483        $vcard = Reader::read($input);
484        $vcard = $vcard->convert(Document::VCARD40);
485
486        $this->assertVObjectEqualsVObject(
487            $output,
488            $vcard
489        );
490
491    }
492
493    function testNoLabel() {
494
495      $input = <<<VCF
496BEGIN:VCARD
497VERSION:3.0
498UID:foo
499N:Doe;John;;;
500FN:John Doe
501item1.X-ABDATE;type=pref:2008-12-11
502END:VCARD
503
504VCF;
505
506      $vcard = Reader::read($input);
507
508      $this->assertInstanceOf('Sabre\\VObject\\Component\\VCard', $vcard);
509      $vcard = $vcard->convert(Document::VCARD40);
510      $vcard = $vcard->serialize();
511
512      $converted = Reader::read($vcard);
513      $converted->validate();
514
515      $version = Version::VERSION;
516
517      $expected = <<<VCF
518BEGIN:VCARD
519VERSION:4.0
520PRODID:-//Sabre//Sabre VObject $version//EN
521UID:foo
522N:Doe;John;;;
523FN:John Doe
524ITEM1.X-ABDATE;PREF=1:2008-12-11
525END:VCARD
526
527VCF;
528
529      $this->assertEquals($expected, str_replace("\r", "", $vcard));
530
531    }
532
533}
534