1<?php
2
3namespace Sabre\VObject\Parser;
4
5use
6    Sabre\VObject;
7
8class JsonTest extends \PHPUnit_Framework_TestCase {
9
10    function testRoundTripJCard() {
11
12        $input = [
13            "vcard",
14            [
15                [
16                    "version",
17                    new \StdClass(),
18                    "text",
19                    "4.0"
20                ],
21                [
22                    "prodid",
23                    new \StdClass(),
24                    "text",
25                    "-//Sabre//Sabre VObject " . VObject\Version::VERSION . "//EN",
26                ],
27                [
28                    "uid",
29                    new \StdClass(),
30                    "text",
31                    "foo",
32                ],
33                [
34                    "bday",
35                    new \StdClass(),
36                    "date-and-or-time",
37                    "1985-04-07",
38                ],
39                [
40                    "bday",
41                    (object)[
42                        'x-param' => [1,2],
43                    ],
44                    "date",
45                    "1979-12-25",
46                ],
47                [
48                    "bday",
49                    new \StdClass(),
50                    "date-time",
51                    "1979-12-25T02:00:00",
52                ],
53                [
54                    "rev",
55                    new \StdClass(),
56                    "timestamp",
57                    "1995-10-31T22:27:10Z",
58                ],
59                [
60                    "lang",
61                    new \StdClass(),
62                    "language-tag",
63                    "nl",
64                ],
65                [
66                    "n",
67                    new \StdClass(),
68                    "text",
69                    ["Last", "First", "Middle", "", ""],
70                ],
71                [
72                    "tel",
73                    (object)[
74                        "group" => "item1",
75                    ],
76                    "text",
77                    "+1 555 123456",
78                ],
79                [
80                    "x-ab-label",
81                    (object)[
82                        "group" => "item1",
83                    ],
84                    "unknown",
85                    "Walkie Talkie",
86                ],
87                [
88                    "adr",
89                    new \StdClass(),
90                    "text",
91                        [
92                            "",
93                            "",
94                            ["My Street", "Left Side", "Second Shack"],
95                            "Hometown",
96                            "PA",
97                            "18252",
98                            "U.S.A",
99                        ],
100                ],
101
102                [
103                    "x-truncated",
104                    new \StdClass(),
105                    "date",
106                    "--12-25",
107                ],
108                [
109                    "x-time-local",
110                    new \StdClass(),
111                    "time",
112                    "12:30:00"
113                ],
114                [
115                    "x-time-utc",
116                    new \StdClass(),
117                    "time",
118                    "12:30:00Z"
119                ],
120                [
121                    "x-time-offset",
122                    new \StdClass(),
123                    "time",
124                    "12:30:00-08:00"
125                ],
126                [
127                    "x-time-reduced",
128                    new \StdClass(),
129                    "time",
130                    "23"
131                ],
132                [
133                    "x-time-truncated",
134                    new \StdClass(),
135                    "time",
136                    "--30"
137                ],
138                [
139                    "x-karma-points",
140                    new \StdClass(),
141                    "integer",
142                    42
143                ],
144                [
145                    "x-grade",
146                    new \StdClass(),
147                    "float",
148                    1.3
149                ],
150                [
151                    "tz",
152                    new \StdClass(),
153                    "utc-offset",
154                    "-05:00",
155                ],
156            ],
157        ];
158
159        $parser = new Json(json_encode($input));
160        $vobj = $parser->parse();
161
162        $version = VObject\Version::VERSION;
163
164        $result = $vobj->serialize();
165        $expected = <<<VCF
166BEGIN:VCARD
167VERSION:4.0
168PRODID:-//Sabre//Sabre VObject $version//EN
169UID:foo
170BDAY:1985-04-07
171BDAY;X-PARAM=1,2;VALUE=DATE:1979-12-25
172BDAY;VALUE=DATE-TIME:1979-12-25T02:00:00
173REV:1995-10-31T22:27:10Z
174LANG:nl
175N:Last;First;Middle;;
176item1.TEL:+1 555 123456
177item1.X-AB-LABEL:Walkie Talkie
178ADR:;;My Street,Left Side,Second Shack;Hometown;PA;18252;U.S.A
179X-TRUNCATED;VALUE=DATE:--12-25
180X-TIME-LOCAL;VALUE=TIME:123000
181X-TIME-UTC;VALUE=TIME:123000Z
182X-TIME-OFFSET;VALUE=TIME:123000-0800
183X-TIME-REDUCED;VALUE=TIME:23
184X-TIME-TRUNCATED;VALUE=TIME:--30
185X-KARMA-POINTS;VALUE=INTEGER:42
186X-GRADE;VALUE=FLOAT:1.3
187TZ;VALUE=UTC-OFFSET:-0500
188END:VCARD
189
190VCF;
191        $this->assertEquals($expected, str_replace("\r", "", $result));
192
193        $this->assertEquals(
194            $input,
195            $vobj->jsonSerialize()
196        );
197
198    }
199
200    function testRoundTripJCal() {
201
202        $input = [
203            "vcalendar",
204            [
205                [
206                    "version",
207                    new \StdClass(),
208                    "text",
209                    "2.0"
210                ],
211                [
212                    "prodid",
213                    new \StdClass(),
214                    "text",
215                    "-//Sabre//Sabre VObject " . VObject\Version::VERSION . "//EN",
216                ],
217                [
218                    "calscale",
219                    new \StdClass(),
220                    "text",
221                    "GREGORIAN"
222                ],
223            ],
224            [
225                ["vevent",
226                    [
227                        [
228                            "uid", new \StdClass(), "text", "foo",
229                        ],
230                        [
231                            "dtstart", new \StdClass(), "date", "2013-05-26",
232                        ],
233                        [
234                            "duration", new \StdClass(), "duration", "P1D",
235                        ],
236                        [
237                            "categories", new \StdClass(), "text", "home", "testing",
238                        ],
239                        [
240                            "created", new \StdClass(), "date-time", "2013-05-26T18:10:00Z",
241                        ],
242                        [
243                            "attach", new \StdClass(), "binary", base64_encode('attachment')
244                        ],
245                        [
246                            "attendee", new \StdClass(), "cal-address", "mailto:armin@example.org",
247                        ],
248                        [
249                            "attendee",
250                            (object)[
251                                "cn"       => "Dominik",
252                                "partstat" => "DECLINED",
253                            ],
254                            "cal-address",
255                            "mailto:dominik@example.org"
256                        ],
257                        [
258                            "geo", new \StdClass(), "float", [51.96668, 7.61876],
259                        ],
260                        [
261                            "sequence", new \StdClass(), "integer", 5
262                        ],
263                        [
264                            "freebusy", new \StdClass(), "period",  ["2013-05-26T21:02:13", "PT1H"], ["2013-06-26T12:00:00", "2013-06-26T13:00:00"],
265                        ],
266                        [
267                            "url", new \StdClass(), "uri", "http://example.org/",
268                        ],
269                        [
270                            "tzoffsetfrom", new \StdClass(), "utc-offset", "+05:00",
271                        ],
272                        [
273                            "rrule", new \StdClass(), "recur", [
274                                'freq'  => 'WEEKLY',
275                                'byday' => ['MO', 'TU'],
276                            ],
277                        ],
278                        [
279                            "x-bool", new \StdClass(), "boolean", true
280                        ],
281                        [
282                            "x-time", new \StdClass(), "time", "08:00:00",
283                        ],
284                        [
285                            "request-status",
286                            new \StdClass(),
287                            "text",
288                            ["2.0", "Success"],
289                        ],
290                        [
291                            "request-status",
292                            new \StdClass(),
293                            "text",
294                            ["3.7", "Invalid Calendar User", "ATTENDEE:mailto:jsmith@example.org"],
295                        ],
296                    ],
297                    [
298                        ["valarm",
299                            [
300                                [
301                                    "action", new \StdClass(), "text", "DISPLAY",
302                                ],
303                            ],
304                            [],
305                        ],
306                    ],
307                ]
308            ],
309        ];
310
311        $parser = new Json(json_encode($input));
312        $vobj = $parser->parse();
313        $result = $vobj->serialize();
314
315        $version = VObject\Version::VERSION;
316
317        $expected = <<<VCF
318BEGIN:VCALENDAR
319VERSION:2.0
320PRODID:-//Sabre//Sabre VObject $version//EN
321CALSCALE:GREGORIAN
322BEGIN:VEVENT
323UID:foo
324DTSTART;VALUE=DATE:20130526
325DURATION:P1D
326CATEGORIES:home,testing
327CREATED:20130526T181000Z
328ATTACH;VALUE=BINARY:YXR0YWNobWVudA==
329ATTENDEE:mailto:armin@example.org
330ATTENDEE;CN=Dominik;PARTSTAT=DECLINED:mailto:dominik@example.org
331GEO:51.96668;7.61876
332SEQUENCE:5
333FREEBUSY:20130526T210213/PT1H,20130626T120000/20130626T130000
334URL;VALUE=URI:http://example.org/
335TZOFFSETFROM:+0500
336RRULE:FREQ=WEEKLY;BYDAY=MO,TU
337X-BOOL;VALUE=BOOLEAN:TRUE
338X-TIME;VALUE=TIME:080000
339REQUEST-STATUS:2.0;Success
340REQUEST-STATUS:3.7;Invalid Calendar User;ATTENDEE:mailto:jsmith@example.org
341BEGIN:VALARM
342ACTION:DISPLAY
343END:VALARM
344END:VEVENT
345END:VCALENDAR
346
347VCF;
348        $this->assertEquals($expected, str_replace("\r", "", $result));
349
350        $this->assertEquals(
351            $input,
352            $vobj->jsonSerialize()
353        );
354
355    }
356
357    function testParseStreamArg() {
358
359        $input = [
360            "vcard",
361            [
362                [
363                    "FN", new \StdClass(), 'text', "foo",
364                ],
365            ],
366        ];
367
368        $stream = fopen('php://memory', 'r+');
369        fwrite($stream, json_encode($input));
370        rewind($stream);
371
372        $result = VObject\Reader::readJson($stream, 0);
373        $this->assertEquals('foo', $result->FN->getValue());
374
375    }
376
377    /**
378     * @expectedException \Sabre\VObject\ParseException
379     */
380    function testParseInvalidData() {
381
382        $json = new Json();
383        $input = [
384            "vlist",
385            [
386                [
387                    "FN", new \StdClass(), 'text', "foo",
388                ],
389            ],
390        ];
391
392        $json->parse(json_encode($input), 0);
393
394    }
395}
396