Completed
Branch 2.0.0-dev (4220a4)
by Jeroen
03:47
created

VCardTest::testNamePropertyContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 9
c 2
b 0
f 0
dl 0
loc 17
rs 9.9666
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace JeroenDesloovere\Tests\VCard;
6
7
use JeroenDesloovere\VCard\Formatter\Formatter;
8
use JeroenDesloovere\VCard\Formatter\VcfFormatter;
9
use JeroenDesloovere\VCard\Parser\Parser;
10
use JeroenDesloovere\VCard\Parser\VcfParser;
11
use JeroenDesloovere\VCard\Property\Address;
12
use JeroenDesloovere\VCard\Property\Anniversary;
13
use JeroenDesloovere\VCard\Property\Birthdate;
14
use JeroenDesloovere\VCard\Property\Email;
15
use JeroenDesloovere\VCard\Property\Gender;
16
use JeroenDesloovere\VCard\Property\Logo;
17
use JeroenDesloovere\VCard\Property\Name;
18
use JeroenDesloovere\VCard\Property\Nickname;
19
use JeroenDesloovere\VCard\Property\Note;
20
use JeroenDesloovere\VCard\Property\Parameter\Kind;
21
use JeroenDesloovere\VCard\Property\Parameter\Revision;
22
use JeroenDesloovere\VCard\Property\Parameter\Type;
23
use JeroenDesloovere\VCard\Property\Parameter\Version;
24
use JeroenDesloovere\VCard\Property\Photo;
25
use JeroenDesloovere\VCard\Property\Telephone;
26
use JeroenDesloovere\VCard\Property\Title;
27
use JeroenDesloovere\VCard\Property\Role;
28
use JeroenDesloovere\VCard\VCard;
29
use org\bovigo\vfs\vfsStream;
30
use org\bovigo\vfs\vfsStreamDirectory;
31
use PHPUnit\Framework\TestCase;
32
33
/**
34
 * How to execute all tests: `vendor/bin/phpunit tests`
35
 */
36
final class VCardTest extends TestCase
37
{
38
    /** @var VCard */
39
    private $firstVCard;
40
41
    /** @var VCard */
42
    private $secondVCard;
43
44
    /** @var VCard */
45
    private $thirdVCard;
46
47
    /** @var vfsStreamDirectory - We save the generated vCard to a virtual storage */
48
    private $virtualStorage;
49
50
    public function setUp(): void
51
    {
52
        $this->setUpFirstVCard();
53
        $this->setUpSecondVCard();
54
        $this->setUpThirdVCard();
55
        $this->virtualStorage = vfsStream::setup();
56
    }
57
58
    private function setUpFirstVCard(): void
59
    {
60
        $this->firstVCard = (new VCard())
61
            ->add(Gender::male('Dude'))
62
            ->add(new Nickname('Web developer'))
63
            ->add(new Name('Desloovere', 'Jeroen'))
64
            ->add(new Address(null, null, 'Markt 1', 'Brugge', 'West-Vlaanderen', '8000', 'België', Type::work()))
65
            ->add(new Address(null, 'Penthouse', 'Korenmarkt 1', 'Gent', 'Oost-Vlaanderen', '9000', 'België', Type::home()))
66
            ->add(new Email('[email protected]', Type::work()))
67
            ->add(new Email('[email protected]', Type::home()))
68
            ->add(new Note('VCard library is amazing.'))
69
            ->add(new Birthdate(new \DateTime('2015-12-05')))
70
            ->add(new Anniversary(new \DateTime('2017-12-05')))
71
            ->add(new Telephone('+33 01 23 45 67'))
72
            ->add(new Telephone('+33-05-42-41-96', Type::work()));
73
    }
74
75
    private function setUpSecondVCard(): void
76
    {
77
        $this->secondVCard = (new VCard())
78
            ->add(new Name('Doe', 'John'))
79
            ->add(new Address(null, 'Penthouse', 'Korenmarkt 1', 'Gent', 'Oost-Vlaanderen', '9000', 'België', Type::work()));
80
    }
81
82
    private function setUpThirdVCard(): void
83
    {
84
        $this->thirdVCard = (new VCard(Kind::organization()))
85
            ->add(new Title('Apple'))
86
            ->add(new Role('Fruit'))
87
            ->add(new Photo(__DIR__ . '/assets/landscape.jpeg'))
88
            ->add(new Logo(__DIR__ . '/assets/landscape.jpeg'))
89
            ->add(new Telephone('+32 486 00 00 00'));
90
    }
91
92
    public function testFormatterSavingMultipleVCardsToVcfFile(): void
93
    {
94
        // Saving "vcards-export.vcf"
95
        $formatter = new Formatter(new VcfFormatter(), 'vcards-export');
96
        $formatter->addVCard($this->firstVCard);
97
        $formatter->addVCard($this->secondVCard);
98
99
        $this->assertFalse($this->virtualStorage->hasChild('vcards-export.vcf'));
100
        $formatter->save($this->virtualStorage->url());
101
        $this->assertTrue($this->virtualStorage->hasChild('vcards-export.vcf'));
102
    }
103
104
    public function testFormatterSavingOneVCardToVcfFile(): void
105
    {
106
        // Saving "vcard-export.vcf"
107
        $formatter = new Formatter(new VcfFormatter(), 'vcard-export');
108
        $formatter->addVCard($this->firstVCard);
109
110
        $this->assertFalse($this->virtualStorage->hasChild('vcard-export.vcf'));
111
        $formatter->save($this->virtualStorage->url());
112
        $this->assertTrue($this->virtualStorage->hasChild('vcard-export.vcf'));
113
    }
114
115
    /**
116
     * @expectedException \JeroenDesloovere\VCard\Exception\VCardException
117
     */
118
    public function testMultipleNotAllowedProperties(): void
119
    {
120
        (new VCard())
121
            ->add(new Nickname('Jeroen'))
122
            ->add(new Nickname('Jeroen2'));
123
    }
124
125
    /**
126
     * @expectedException \JeroenDesloovere\VCard\Exception\VCardException
127
     */
128
    public function testMultipleNotAllowedPropertyParameters(): void
129
    {
130
        (new VCard())
131
            ->add(new Revision(new \DateTime))
132
            ->add(new Revision(new \DateTime));
133
    }
134
135
    /**
136
     * @expectedException \JeroenDesloovere\VCard\Exception\ParserException
137
     * @expectedExceptionMessage File "Lorem ipsum dolor sit amet, consectetur adipiscing elit." is not readable, or doesn't exist.
138
     */
139
    public function testParserCorruptVCard(): void
140
    {
141
        new Parser(new VcfParser(), 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.');
142
    }
143
144
    /**
145
     * @expectedException \JeroenDesloovere\VCard\Exception\ParserException
146
     * @expectedExceptionMessage File "" is not readable, or doesn't exist.
147
     */
148
    public function testParserEmptyVCard(): void
149
    {
150
        new Parser(new VcfParser(), '');
151
    }
152
153
    /**
154
     * @expectedException \JeroenDesloovere\VCard\Exception\ParserException
155
     */
156
    public function testParserGetFileContentsException(): void
157
    {
158
        Parser::getFileContents(__DIR__ . '/not-existing');
159
    }
160
161
    /**
162
     * Test the Telephone parser independently.
163
     */
164
    public function testTelephoneParser(): void
165
    {
166
        // Given
167
        $vcard = (new Vcard())->add(new Telephone('+33-01-23-45-67'));
168
        $content = "BEGIN:VCARD\r\nVERSION:4.0\r\nTEL;VALUE=uri;TYPE=home:tel:+33-01-23-45-67\r\nEND:VCARD";
169
170
        // When
171
        $parser = new Parser(new VcfParser(), $content);
172
173
        // Then
174
        $this->assertEquals($vcard->getProperties(Telephone::class), $parser->getVCards()[0]->getProperties(Telephone::class));
175
    }
176
177
    /**
178
     * Test the Version parameter parser independently.
179
     * With version 4 and version 3, should result in not equal (bad weather)
180
     */
181
    public function testVersionParameterParserBadWeather(): void
182
    {
183
        // Given
184
        // Version 4
185
        $vcard = new Vcard(null, Version::version4());
186
        // Version 3
187
        $content = "BEGIN:VCARD\r\nVERSION:3.0\r\nEND:VCARD";
188
189
        // When
190
        $parser = new Parser(new VcfParser(), $content);
191
192
        // Then
193
        $this->assertNotEquals($vcard->getParameters(), $parser->getVCards()[0]->getParameters());
194
    }
195
196
    /**
197
     * Test the Version parameter parser independently.
198
     * Both version 4 (good weather)
199
     */
200
    public function testVersionParameterParserGoodWeather(): void
201
    {
202
        // Given
203
        $vcard = new Vcard(null, Version::version4());
204
        $content = "BEGIN:VCARD\r\nVERSION:4.0\r\nEND:VCARD";
205
206
        // When
207
        $parser = new Parser(new VcfParser(), $content);
208
209
        // Then
210
        $this->assertEquals($vcard->getParameters(), $parser->getVCards()[0]->getParameters());
211
    }
212
213
    /**
214
     * Test the Version parameter parser independently.
215
     * Without any version specified, should use the default Version value (4.0)
216
     */
217
    public function testVersionParameterParserWithoutVersion(): void
218
    {
219
        // Given
220
        $vcard = new Vcard();
221
        $content = "BEGIN:VCARD\r\nEND:VCARD";
222
223
        // When
224
        $parser = new Parser(new VcfParser(), $content);
225
226
        // Then
227
        $this->assertEquals($vcard->getParameters(), $parser->getVCards()[0]->getParameters());
228
    }
229
230
    /**
231
     * Test the Kind parameter parser independently.
232
     * Test vcard with individual person (is default kind)
233
     */
234
    public function testKindIndividual(): void
235
    {
236
        // Given
237
        $vcard = new Vcard();
238
        $content = "BEGIN:VCARD\r\nVERSION:4.0\r\nKIND:individual\r\nEND:VCARD";
239
240
        // When
241
        $parser = new Parser(new VcfParser(), $content);
242
243
        // Then
244
        $this->assertEquals($vcard->getParameters(), $parser->getVCards()[0]->getParameters());
245
    }
246
247
    /**
248
     * Test the Kind parameter parser independently.
249
     * Test vcard with department/organization
250
     */
251
    public function testKindOrganization(): void
252
    {
253
        // Given
254
        $vcard = new Vcard(Kind::organization());
255
        $content = "BEGIN:VCARD\r\nVERSION:4.0\r\nKIND:org\r\nEND:VCARD";
256
257
        // When
258
        $parser = new Parser(new VcfParser(), $content);
259
260
        // Then
261
        $this->assertEquals($vcard->getParameters(), $parser->getVCards()[0]->getParameters());
262
    }
263
264
    /**
265
     * Test the Kind parameter parser independently.
266
     * Test vcard with group
267
     */
268
    public function testKindGroup(): void
269
    {
270
        // Given
271
        $vcard = new Vcard(Kind::group());
272
        $content = "BEGIN:VCARD\r\nVERSION:4.0\r\nKIND:group\r\nEND:VCARD";
273
274
        // When
275
        $parser = new Parser(new VcfParser(), $content);
276
277
        // Then
278
        $this->assertEquals($vcard->getParameters(), $parser->getVCards()[0]->getParameters());
279
    }
280
281
    public function testParserMultipleVCardsFromVcfFile(): void
282
    {
283
        $parser = new Parser(new VcfParser(), Parser::getFileContents(__DIR__ . '/assets/vcards.vcf'));
284
285
        $this->assertEquals($this->firstVCard->getProperties(), $parser->getVCards()[0]->getProperties());
286
        $this->assertEquals($this->secondVCard->getProperties(), $parser->getVCards()[1]->getProperties());
287
    }
288
289
    public function testParserOneVCardFromVcfFile(): void
290
    {
291
        $parser = new Parser(new VcfParser(), Parser::getFileContents(__DIR__ . '/assets/vcard.vcf'));
292
293
        $this->assertEquals($this->firstVCard->getProperties(), $parser->getVCards()[0]->getProperties());
294
    }
295
296
    /**
297
     * Integration test:
298
     * Validate the number of properties from the created vCards in the Setup.
299
     */
300
    public function testVCardGetProperties(): void
301
    {
302
        $this->assertCount(12, $this->firstVCard->getProperties());
303
        $this->assertCount(1, $this->firstVCard->getProperties(Gender::class));
304
        $this->assertCount(1, $this->firstVCard->getProperties(Nickname::class));
305
        $this->assertCount(1, $this->firstVCard->getProperties(Name::class));
306
        $this->assertCount(2, $this->firstVCard->getProperties(Address::class));
307
        $this->assertCount(2, $this->firstVCard->getProperties(Email::class));
308
        $this->assertCount(1, $this->firstVCard->getProperties(Note::class));
309
        $this->assertCount(1, $this->firstVCard->getProperties(Birthdate::class));
310
        $this->assertCount(1, $this->firstVCard->getProperties(Anniversary::class));
311
        $this->assertCount(2, $this->firstVCard->getProperties(Telephone::class));
312
313
        $this->assertCount(2, $this->secondVCard->getProperties());
314
        $this->assertCount(1, $this->secondVCard->getProperties(Name::class));
315
        $this->assertCount(1, $this->secondVCard->getProperties(Address::class));
316
317
        $this->assertCount(5, $this->thirdVCard->getProperties());
318
        $this->assertCount(1, $this->thirdVCard->getProperties(Title::class));
319
        $this->assertCount(1, $this->thirdVCard->getProperties(Role::class));
320
        $this->assertCount(1, $this->thirdVCard->getProperties(Photo::class));
321
        $this->assertCount(1, $this->thirdVCard->getProperties(Logo::class));
322
        $this->assertCount(1, $this->thirdVCard->getProperties(Telephone::class));
323
    }
324
325
    /**
326
     * Verify if multiple telephone numbers are correctly formatted
327
     */
328
    public function testTelephonePropertyContent(): void
329
    {
330
      // Given
331
      $expectedContent = "BEGIN:VCARD\r\n" .
332
        "VERSION:4.0\r\n" .
333
        "KIND:individual\r\n" .
334
        "TEL;TYPE=home;VALUE=uri:tel:+33-01-23-45-67\r\n" .
335
        "TEL;TYPE=work;VALUE=uri:tel:+33-05-42-41-96\r\n" .
336
        "END:VCARD\r\n";
337
338
      $formatter = new Formatter(new VcfFormatter(), '');
339
      $vcard = (new VCard())
340
        ->add(new Telephone('+33 01 23 45 67'))
341
        ->add(new Telephone('+33-05-42-41-96', Type::work()));
342
343
      // When
344
      $formatter->addVCard($vcard);
345
346
      // Then
347
      $this->assertEquals($expectedContent, $formatter->getContent());
348
    }
349
350
    /**
351
     * Verify if a full name gets correctly formatted
352
     */
353
    public function testNamePropertyContent(): void
354
    {
355
      // Given
356
      $expectedContent = "BEGIN:VCARD\r\n" .
357
        "VERSION:4.0\r\n" .
358
        "KIND:individual\r\n" .
359
        "N:van den Berg;Melroy;Antoine;Mr.;\r\n" .
360
        "END:VCARD\r\n";
361
362
      $formatter = new Formatter(new VcfFormatter(), '');
363
      $vcard = (new VCard())->add(new Name('van den Berg', 'Melroy', 'Antoine', 'Mr.'));
364
365
      // When
366
      $formatter->addVCard($vcard);
367
368
      // Then
369
      $this->assertEquals($expectedContent, $formatter->getContent());
370
    }
371
372
    /**
373
     * Verify if an address gets correctly formatted,
374
     * even with a long text over the 75 chars limit (excl. line breaks)
375
     */
376
    public function testAddressPropertyContentWithLineBreak() : void
377
    {
378
      // Given
379
      $expectedContent = "BEGIN:VCARD\r\n" .
380
        "VERSION:4.0\r\n" .
381
        "KIND:individual\r\n" .
382
        "ADR;TYPE=home:42;Villa;Main Street 500;London;Barnet;EN4 0AG;United Kingd\r\n" .
383
        // Line break because of 75 octets width limit, immediately followed by a single white space.
384
        " om\r\n" .
385
        "END:VCARD\r\n";
386
      $formatter = new Formatter(new VcfFormatter(), '');
387
      $vcard = (new VCard())->add(new Address('42', 'Villa', 'Main Street 500', 'London', 'Barnet', 'EN4 0AG', 'United Kingdom'));
388
389
      // When
390
      $formatter->addVCard($vcard);
391
392
      // Then
393
      $this->assertEquals($expectedContent, $formatter->getContent());
394
    }
395
}
396