1<?php
2
3namespace Sabre\VObject\Component;
4
5use Sabre\VObject;
6use Sabre\VObject\Reader;
7use Sabre\VObject\Component;
8use Sabre\VObject\Component\VAvailability;
9
10/**
11 * We use `RFCxxx` has a placeholder for the
12 * https://tools.ietf.org/html/draft-daboo-calendar-availability-05 name.
13 */
14class VAvailabilityTest extends \PHPUnit_Framework_TestCase {
15
16    function testVAvailabilityComponent() {
17
18        $vcal = <<<VCAL
19BEGIN:VCALENDAR
20BEGIN:VAVAILABILITY
21END:VAVAILABILITY
22END:VCALENDAR
23VCAL;
24        $document = Reader::read($vcal);
25
26        $this->assertInstanceOf(__NAMESPACE__ . '\VAvailability', $document->VAVAILABILITY);
27
28    }
29
30    function testRFCxxxSection3_1_availabilityprop_required() {
31
32        // UID and DTSTAMP are present.
33        $this->assertIsValid(Reader::read(
34<<<VCAL
35BEGIN:VCALENDAR
36VERSION:2.0
37PRODID:-//id
38BEGIN:VAVAILABILITY
39UID:foo@test
40DTSTAMP:20111005T133225Z
41END:VAVAILABILITY
42END:VCALENDAR
43VCAL
44        ));
45
46        // UID and DTSTAMP are missing.
47        $this->assertIsNotValid(Reader::read(
48<<<VCAL
49BEGIN:VCALENDAR
50VERSION:2.0
51PRODID:-//id
52BEGIN:VAVAILABILITY
53END:VAVAILABILITY
54END:VCALENDAR
55VCAL
56        ));
57
58        // DTSTAMP is missing.
59        $this->assertIsNotValid(Reader::read(
60<<<VCAL
61BEGIN:VCALENDAR
62VERSION:2.0
63PRODID:-//id
64BEGIN:VAVAILABILITY
65UID:foo@test
66END:VAVAILABILITY
67END:VCALENDAR
68VCAL
69        ));
70
71        // UID is missing.
72        $this->assertIsNotValid(Reader::read(
73<<<VCAL
74BEGIN:VCALENDAR
75VERSION:2.0
76PRODID:-//id
77BEGIN:VAVAILABILITY
78DTSTAMP:20111005T133225Z
79END:VAVAILABILITY
80END:VCALENDAR
81VCAL
82        ));
83
84    }
85
86    function testRFCxxxSection3_1_availabilityprop_optional_once() {
87
88        $properties = array(
89            'BUSYTYPE:BUSY',
90            'CLASS:PUBLIC',
91            'CREATED:20111005T135125Z',
92            'DESCRIPTION:Long bla bla',
93            'DTSTART:20111005T020000',
94            'LAST-MODIFIED:20111005T135325Z',
95            'ORGANIZER:mailto:foo@example.com',
96            'PRIORITY:1',
97            'SEQUENCE:0',
98            'SUMMARY:Bla bla',
99            'URL:http://example.org/'
100        );
101
102        // They are all present, only once.
103        $this->assertIsValid(Reader::read($this->template($properties)));
104
105        // We duplicate each one to see if it fails.
106        foreach ($properties as $property) {
107            $this->assertIsNotValid(Reader::read($this->template(array(
108                $property,
109                $property
110            ))));
111        }
112
113    }
114
115    function testRFCxxxSection3_1_availabilityprop_dtend_duration() {
116
117        // Only DTEND.
118        $this->assertIsValid(Reader::read($this->template(array(
119            'DTEND:21111005T133225Z'
120        ))));
121
122        // Only DURATION.
123        $this->assertIsValid(Reader::read($this->template(array(
124            'DURATION:PT1H'
125        ))));
126
127        // Both (not allowed).
128        $this->assertIsNotValid(Reader::read($this->template(array(
129            'DTEND:21111005T133225Z',
130            'DURATION:PT1H'
131        ))));
132    }
133
134    function testAvailableSubComponent() {
135
136        $vcal = <<<VCAL
137BEGIN:VCALENDAR
138BEGIN:VAVAILABILITY
139BEGIN:AVAILABLE
140END:AVAILABLE
141END:VAVAILABILITY
142END:VCALENDAR
143VCAL;
144        $document = Reader::read($vcal);
145
146        $this->assertInstanceOf(__NAMESPACE__, $document->VAVAILABILITY->AVAILABLE);
147
148    }
149
150    function testRFCxxxSection3_1_availableprop_required() {
151
152        // UID, DTSTAMP and DTSTART are present.
153        $this->assertIsValid(Reader::read(
154<<<VCAL
155BEGIN:VCALENDAR
156VERSION:2.0
157PRODID:-//id
158BEGIN:VAVAILABILITY
159UID:foo@test
160DTSTAMP:20111005T133225Z
161BEGIN:AVAILABLE
162UID:foo@test
163DTSTAMP:20111005T133225Z
164DTSTART:20111005T133225Z
165END:AVAILABLE
166END:VAVAILABILITY
167END:VCALENDAR
168VCAL
169        ));
170
171        // UID, DTSTAMP and DTSTART are missing.
172        $this->assertIsNotValid(Reader::read(
173<<<VCAL
174BEGIN:VCALENDAR
175VERSION:2.0
176PRODID:-//id
177BEGIN:VAVAILABILITY
178UID:foo@test
179DTSTAMP:20111005T133225Z
180BEGIN:AVAILABLE
181END:AVAILABLE
182END:VAVAILABILITY
183END:VCALENDAR
184VCAL
185        ));
186
187        // UID is missing.
188        $this->assertIsNotValid(Reader::read(
189<<<VCAL
190BEGIN:VCALENDAR
191VERSION:2.0
192PRODID:-//id
193BEGIN:VAVAILABILITY
194UID:foo@test
195DTSTAMP:20111005T133225Z
196BEGIN:AVAILABLE
197DTSTAMP:20111005T133225Z
198DTSTART:20111005T133225Z
199END:AVAILABLE
200END:VAVAILABILITY
201END:VCALENDAR
202VCAL
203        ));
204
205        // DTSTAMP is missing.
206        $this->assertIsNotValid(Reader::read(
207<<<VCAL
208BEGIN:VCALENDAR
209VERSION:2.0
210PRODID:-//id
211BEGIN:VAVAILABILITY
212UID:foo@test
213DTSTAMP:20111005T133225Z
214BEGIN:AVAILABLE
215UID:foo@test
216DTSTART:20111005T133225Z
217END:AVAILABLE
218END:VAVAILABILITY
219END:VCALENDAR
220VCAL
221        ));
222
223        // DTSTART is missing.
224        $this->assertIsNotValid(Reader::read(
225<<<VCAL
226BEGIN:VCALENDAR
227VERSION:2.0
228PRODID:-//id
229BEGIN:VAVAILABILITY
230UID:foo@test
231DTSTAMP:20111005T133225Z
232BEGIN:AVAILABLE
233UID:foo@test
234DTSTAMP:20111005T133225Z
235END:AVAILABLE
236END:VAVAILABILITY
237END:VCALENDAR
238VCAL
239        ));
240
241    }
242
243    function testRFCxxxSection3_1_available_dtend_duration() {
244
245        // Only DTEND.
246        $this->assertIsValid(Reader::read($this->templateAvailable(array(
247            'DTEND:21111005T133225Z'
248        ))));
249
250        // Only DURATION.
251        $this->assertIsValid(Reader::read($this->templateAvailable(array(
252            'DURATION:PT1H'
253        ))));
254
255        // Both (not allowed).
256        $this->assertIsNotValid(Reader::read($this->templateAvailable(array(
257            'DTEND:21111005T133225Z',
258            'DURATION:PT1H'
259        ))));
260    }
261
262    function testRFCxxxSection3_1_available_optional_once() {
263
264        $properties = array(
265            'CREATED:20111005T135125Z',
266            'DESCRIPTION:Long bla bla',
267            'LAST-MODIFIED:20111005T135325Z',
268            'RECURRENCE-ID;RANGE=THISANDFUTURE:19980401T133000Z',
269            'RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR',
270            'SUMMARY:Bla bla'
271        );
272
273        // They are all present, only once.
274        $this->assertIsValid(Reader::read($this->templateAvailable($properties)));
275
276        // We duplicate each one to see if it fails.
277        foreach ($properties as $property) {
278            $this->assertIsNotValid(Reader::read($this->templateAvailable(array(
279                $property,
280                $property
281            ))));
282        }
283
284    }
285    function testRFCxxxSection3_2() {
286
287        $this->assertEquals(
288            'BUSY',
289            Reader::read($this->templateAvailable(array(
290                'BUSYTYPE:BUSY'
291            )))
292                ->VAVAILABILITY
293                ->AVAILABLE
294                ->BUSYTYPE
295                ->getValue()
296        );
297
298        $this->assertEquals(
299            'BUSY-UNAVAILABLE',
300            Reader::read($this->templateAvailable(array(
301                'BUSYTYPE:BUSY-UNAVAILABLE'
302            )))
303                ->VAVAILABILITY
304                ->AVAILABLE
305                ->BUSYTYPE
306                ->getValue()
307        );
308
309        $this->assertEquals(
310            'BUSY-TENTATIVE',
311            Reader::read($this->templateAvailable(array(
312                'BUSYTYPE:BUSY-TENTATIVE'
313            )))
314                ->VAVAILABILITY
315                ->AVAILABLE
316                ->BUSYTYPE
317                ->getValue()
318        );
319
320    }
321
322    protected function assertIsValid(VObject\Document $document) {
323
324        $this->assertEmpty($document->validate());
325
326    }
327
328    protected function assertIsNotValid(VObject\Document $document) {
329
330        $this->assertNotEmpty($document->validate());
331
332    }
333
334    protected function template(array $properties) {
335
336        return $this->_template(
337            <<<VCAL
338BEGIN:VCALENDAR
339VERSION:2.0
340PRODID:-//id
341BEGIN:VAVAILABILITY
342UID:foo@test
343DTSTAMP:20111005T133225Z
344
345END:VAVAILABILITY
346END:VCALENDAR
347VCAL
348,
349            $properties
350        );
351
352    }
353
354    protected function templateAvailable(array $properties) {
355
356        return $this->_template(
357            <<<VCAL
358BEGIN:VCALENDAR
359VERSION:2.0
360PRODID:-//id
361BEGIN:VAVAILABILITY
362UID:foo@test
363DTSTAMP:20111005T133225Z
364BEGIN:AVAILABLE
365UID:foo@test
366DTSTAMP:20111005T133225Z
367DTSTART:20111005T133225Z
368
369END:AVAILABLE
370END:VAVAILABILITY
371END:VCALENDAR
372VCAL
373,
374            $properties
375        );
376
377    }
378
379    protected function _template($template, array $properties) {
380
381        return str_replace('', implode("\r\n", $properties), $template);
382
383    }
384
385}
386