1<?php
2
3namespace Sabre\CalDAV\Xml\Request;
4
5use Sabre\DAV\Xml\XmlTest;
6
7class CalendarQueryReportTest extends XmlTest {
8
9    protected $elementMap = [
10        '{urn:ietf:params:xml:ns:caldav}calendar-query' => 'Sabre\\CalDAV\\Xml\\Request\CalendarQueryReport',
11    ];
12
13    function testDeserialize() {
14
15        $xml = <<<XML
16<?xml version="1.0"?>
17<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
18    <d:prop>
19      <d:getetag />
20    </d:prop>
21    <c:filter>
22        <c:comp-filter name="VCALENDAR" />
23    </c:filter>
24</c:calendar-query>
25XML;
26
27        $result = $this->parse($xml);
28        $calendarQueryReport = new CalendarQueryReport();
29        $calendarQueryReport->properties = [
30            '{DAV:}getetag',
31        ];
32        $calendarQueryReport->filters = [
33            'name'           => 'VCALENDAR',
34            'is-not-defined' => false,
35            'comp-filters'   => [],
36            'prop-filters'   => [],
37            'time-range'     => false,
38        ];
39
40        $this->assertEquals(
41            $calendarQueryReport,
42            $result['value']
43        );
44
45    }
46
47    /**
48     * @expectedException Sabre\DAV\Exception\BadRequest
49     */
50    function testDeserializeNoFilter() {
51
52        $xml = <<<XML
53<?xml version="1.0"?>
54<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
55    <d:prop>
56      <d:getetag />
57    </d:prop>
58</c:calendar-query>
59XML;
60
61        $this->parse($xml);
62
63    }
64
65    function testDeserializeComplex() {
66
67        $xml = <<<XML
68<?xml version="1.0"?>
69<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
70    <d:prop>
71      <d:getetag />
72      <c:calendar-data content-type="application/json+calendar" version="2.0">
73            <c:expand start="20150101T000000Z" end="20160101T000000Z" />
74      </c:calendar-data>
75    </d:prop>
76    <c:filter>
77        <c:comp-filter name="VCALENDAR">
78            <c:comp-filter name="VEVENT">
79                <c:time-range start="20150101T000000Z" end="20160101T000000Z" />
80                <c:prop-filter name="UID" />
81                <c:comp-filter name="VALARM">
82                    <c:is-not-defined />
83                </c:comp-filter>
84                <c:prop-filter name="X-PROP">
85                    <c:param-filter name="X-PARAM" />
86                    <c:param-filter name="X-PARAM2">
87                        <c:is-not-defined />
88                    </c:param-filter>
89                    <c:param-filter name="X-PARAM3">
90                        <c:text-match negate-condition="yes">hi</c:text-match>
91                    </c:param-filter>
92                </c:prop-filter>
93                <c:prop-filter name="X-PROP2">
94                    <c:is-not-defined />
95                </c:prop-filter>
96                <c:prop-filter name="X-PROP3">
97                    <c:time-range start="20150101T000000Z" end="20160101T000000Z" />
98                </c:prop-filter>
99                <c:prop-filter name="X-PROP4">
100                    <c:text-match>Hello</c:text-match>
101                </c:prop-filter>
102            </c:comp-filter>
103        </c:comp-filter>
104    </c:filter>
105</c:calendar-query>
106XML;
107
108        $result = $this->parse($xml);
109        $calendarQueryReport = new CalendarQueryReport();
110        $calendarQueryReport->version = '2.0';
111        $calendarQueryReport->contentType = 'application/json+calendar';
112        $calendarQueryReport->properties = [
113            '{DAV:}getetag',
114            '{urn:ietf:params:xml:ns:caldav}calendar-data',
115        ];
116        $calendarQueryReport->expand = [
117            'start' => new \DateTime('2015-01-01 00:00:00', new \DateTimeZone('UTC')),
118            'end'   => new \DateTime('2016-01-01 00:00:00', new \DateTimeZone('UTC')),
119        ];
120        $calendarQueryReport->filters = [
121            'name'           => 'VCALENDAR',
122            'is-not-defined' => false,
123            'comp-filters'   => [
124                [
125                    'name'           => 'VEVENT',
126                    'is-not-defined' => false,
127                    'comp-filters'   => [
128                        [
129                            'name'           => 'VALARM',
130                            'is-not-defined' => true,
131                            'comp-filters'   => [],
132                            'prop-filters'   => [],
133                            'time-range'     => false,
134                        ],
135                    ],
136                    'prop-filters' => [
137                        [
138                            'name'           => 'UID',
139                            'is-not-defined' => false,
140                            'time-range'     => false,
141                            'text-match'     => null,
142                            'param-filters'  => [],
143                        ],
144                        [
145                            'name'           => 'X-PROP',
146                            'is-not-defined' => false,
147                            'time-range'     => false,
148                            'text-match'     => null,
149                            'param-filters'  => [
150                                [
151                                    'name'           => 'X-PARAM',
152                                    'is-not-defined' => false,
153                                    'text-match'     => null,
154                                ],
155                                [
156                                    'name'           => 'X-PARAM2',
157                                    'is-not-defined' => true,
158                                    'text-match'     => null,
159                                ],
160                                [
161                                    'name'           => 'X-PARAM3',
162                                    'is-not-defined' => false,
163                                    'text-match'     => [
164                                        'negate-condition' => true,
165                                        'collation'        => 'i;ascii-casemap',
166                                        'value'            => 'hi',
167                                    ],
168                                ],
169                            ],
170                        ],
171                        [
172                            'name'           => 'X-PROP2',
173                            'is-not-defined' => true,
174                            'time-range'     => false,
175                            'text-match'     => null,
176                            'param-filters'  => [],
177                        ],
178                        [
179                            'name'           => 'X-PROP3',
180                            'is-not-defined' => false,
181                            'time-range'     => [
182                                'start' => new \DateTime('2015-01-01 00:00:00', new \DateTimeZone('UTC')),
183                                'end'   => new \DateTime('2016-01-01 00:00:00', new \DateTimeZone('UTC')),
184                            ],
185                            'text-match'    => null,
186                            'param-filters' => [],
187                        ],
188                        [
189                            'name'           => 'X-PROP4',
190                            'is-not-defined' => false,
191                            'time-range'     => false,
192                            'text-match'     => [
193                                'negate-condition' => false,
194                                'collation'        => 'i;ascii-casemap',
195                                'value'            => 'Hello',
196                            ],
197                            'param-filters' => [],
198                        ],
199                    ],
200                    'time-range' => [
201                        'start' => new \DateTime('2015-01-01 00:00:00', new \DateTimeZone('UTC')),
202                        'end'   => new \DateTime('2016-01-01 00:00:00', new \DateTimeZone('UTC')),
203                    ]
204                ],
205            ],
206            'prop-filters' => [],
207            'time-range'   => false,
208        ];
209
210        $this->assertEquals(
211            $calendarQueryReport,
212            $result['value']
213        );
214
215    }
216
217    /**
218     * @expectedException \Sabre\DAV\Exception\BadRequest
219     */
220    function testDeserializeDoubleTopCompFilter() {
221
222        $xml = <<<XML
223<?xml version="1.0"?>
224<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
225    <d:prop>
226      <d:getetag />
227      <c:calendar-data content-type="application/json+calendar" version="2.0">
228            <c:expand start="20150101T000000Z" end="20160101T000000Z" />
229      </c:calendar-data>
230    </d:prop>
231    <c:filter>
232        <c:comp-filter name="VCALENDAR" />
233        <c:comp-filter name="VCALENDAR" />
234    </c:filter>
235</c:calendar-query>
236XML;
237
238        $this->parse($xml);
239
240    }
241
242    /**
243     * @expectedException \Sabre\DAV\Exception\BadRequest
244     */
245    function testDeserializeMissingExpandEnd() {
246
247        $xml = <<<XML
248<?xml version="1.0"?>
249<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
250    <d:prop>
251      <d:getetag />
252      <c:calendar-data content-type="application/json+calendar" version="2.0">
253            <c:expand start="20150101T000000Z" />
254      </c:calendar-data>
255    </d:prop>
256    <c:filter>
257        <c:comp-filter name="VCALENDAR" />
258    </c:filter>
259</c:calendar-query>
260XML;
261
262        $this->parse($xml);
263
264    }
265
266    /**
267     * @expectedException \Sabre\DAV\Exception\BadRequest
268     */
269    function testDeserializeExpandEndBeforeStart() {
270
271        $xml = <<<XML
272<?xml version="1.0"?>
273<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
274    <d:prop>
275      <d:getetag />
276      <c:calendar-data content-type="application/json+calendar" version="2.0">
277            <c:expand start="20150101T000000Z" end="20140101T000000Z" />
278      </c:calendar-data>
279    </d:prop>
280    <c:filter>
281        <c:comp-filter name="VCALENDAR" />
282    </c:filter>
283</c:calendar-query>
284XML;
285
286        $this->parse($xml);
287
288    }
289
290    /**
291     * @expectedException \Sabre\DAV\Exception\BadRequest
292     */
293    function testDeserializeTimeRangeOnVCALENDAR() {
294
295        $xml = <<<XML
296<?xml version="1.0"?>
297<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
298    <d:prop>
299      <d:getetag />
300      <c:calendar-data />
301    </d:prop>
302    <c:filter>
303        <c:comp-filter name="VCALENDAR">
304            <c:time-range start="20150101T000000Z" end="20160101T000000Z" />
305        </c:comp-filter>
306    </c:filter>
307</c:calendar-query>
308XML;
309
310        $this->parse($xml);
311
312    }
313
314    /**
315     * @expectedException \Sabre\DAV\Exception\BadRequest
316     */
317    function testDeserializeTimeRangeEndBeforeStart() {
318
319        $xml = <<<XML
320<?xml version="1.0"?>
321<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
322    <d:prop>
323      <d:getetag />
324      <c:calendar-data />
325    </d:prop>
326    <c:filter>
327        <c:comp-filter name="VCALENDAR">
328            <c:comp-filter name="VEVENT">
329                <c:time-range start="20150101T000000Z" end="20140101T000000Z" />
330            </c:comp-filter>
331        </c:comp-filter>
332    </c:filter>
333</c:calendar-query>
334XML;
335
336        $this->parse($xml);
337
338    }
339
340    /**
341     * @expectedException \Sabre\DAV\Exception\BadRequest
342     */
343    function testDeserializeTimeRangePropEndBeforeStart() {
344
345        $xml = <<<XML
346<?xml version="1.0"?>
347<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
348    <d:prop>
349      <d:getetag />
350      <c:calendar-data />
351    </d:prop>
352    <c:filter>
353        <c:comp-filter name="VCALENDAR">
354            <c:comp-filter name="VEVENT">
355                <c:prop-filter name="DTSTART">
356                    <c:time-range start="20150101T000000Z" end="20140101T000000Z" />
357                </c:prop-filter>
358            </c:comp-filter>
359        </c:comp-filter>
360    </c:filter>
361</c:calendar-query>
362XML;
363
364        $this->parse($xml);
365
366    }
367}
368