1<?php
2
3namespace Sabre\CardDAV\Xml\Request;
4use Sabre\DAV\Xml\XmlTest;
5
6class AddressBookQueryReportTest extends XmlTest {
7
8    protected $elementMap = [
9        '{urn:ietf:params:xml:ns:carddav}addressbook-query' => 'Sabre\\CardDAV\\Xml\\Request\AddressBookQueryReport',
10    ];
11
12    function testDeserialize() {
13
14        $xml = <<<XML
15<?xml version="1.0"?>
16<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
17    <d:prop>
18      <d:getetag />
19    </d:prop>
20    <c:filter>
21        <c:prop-filter name="uid" />
22    </c:filter>
23</c:addressbook-query>
24XML;
25
26        $result = $this->parse($xml);
27        $addressBookQueryReport = new AddressBookQueryReport();
28        $addressBookQueryReport->properties = [
29            '{DAV:}getetag',
30        ];
31        $addressBookQueryReport->test = 'anyof';
32        $addressBookQueryReport->filters = [
33            [
34                'name' => 'uid',
35                'test' => 'anyof',
36                'is-not-defined' => false,
37                'param-filters' => [],
38                'text-matches' => [],
39            ]
40        ];
41
42        $this->assertEquals(
43            $addressBookQueryReport,
44            $result['value']
45        );
46
47    }
48
49    function testDeserializeAllOf() {
50
51        $xml = <<<XML
52<?xml version="1.0"?>
53<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
54    <d:prop>
55      <d:getetag />
56    </d:prop>
57    <c:filter test="allof">
58        <c:prop-filter name="uid" />
59    </c:filter>
60</c:addressbook-query>
61XML;
62
63        $result = $this->parse($xml);
64        $addressBookQueryReport = new AddressBookQueryReport();
65        $addressBookQueryReport->properties = [
66            '{DAV:}getetag',
67        ];
68        $addressBookQueryReport->test = 'allof';
69        $addressBookQueryReport->filters = [
70            [
71                'name' => 'uid',
72                'test' => 'anyof',
73                'is-not-defined' => false,
74                'param-filters' => [],
75                'text-matches' => [],
76            ]
77        ];
78
79        $this->assertEquals(
80            $addressBookQueryReport,
81            $result['value']
82        );
83
84    }
85
86    /**
87     * @expectedException \Sabre\DAV\Exception\BadRequest
88     */
89    function testDeserializeBadTest() {
90
91        $xml = <<<XML
92<?xml version="1.0"?>
93<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
94    <d:prop>
95      <d:getetag />
96    </d:prop>
97    <c:filter test="bad">
98        <c:prop-filter name="uid" />
99    </c:filter>
100</c:addressbook-query>
101XML;
102
103        $this->parse($xml);
104
105    }
106
107    /**
108     * We should error on this, but KDE does this, so we chose to support it.
109     */
110    function testDeserializeNoFilter() {
111
112        $xml = <<<XML
113<?xml version="1.0"?>
114<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
115    <d:prop>
116      <d:getetag />
117    </d:prop>
118</c:addressbook-query>
119XML;
120
121        $result = $this->parse($xml);
122        $addressBookQueryReport = new AddressBookQueryReport();
123        $addressBookQueryReport->properties = [
124            '{DAV:}getetag',
125        ];
126        $addressBookQueryReport->test = 'anyof';
127        $addressBookQueryReport->filters = [];
128
129        $this->assertEquals(
130            $addressBookQueryReport,
131            $result['value']
132        );
133
134    }
135
136    function testDeserializeComplex() {
137
138        $xml = <<<XML
139<?xml version="1.0"?>
140<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
141    <d:prop>
142      <d:getetag />
143      <c:address-data content-type="application/vcard+json" version="4.0" />
144    </d:prop>
145    <c:filter>
146        <c:prop-filter name="uid">
147            <c:is-not-defined />
148        </c:prop-filter>
149        <c:prop-filter name="x-foo" test="allof">
150            <c:param-filter name="x-param1" />
151            <c:param-filter name="x-param2">
152                <c:is-not-defined />
153            </c:param-filter>
154            <c:param-filter name="x-param3">
155                <c:text-match match-type="contains">Hello!</c:text-match>
156            </c:param-filter>
157        </c:prop-filter>
158        <c:prop-filter name="x-prop2">
159            <c:text-match match-type="starts-with" negate-condition="yes">No</c:text-match>
160        </c:prop-filter>
161    </c:filter>
162    <c:limit><c:nresults>10</c:nresults></c:limit>
163</c:addressbook-query>
164XML;
165
166        $result = $this->parse($xml);
167        $addressBookQueryReport = new AddressBookQueryReport();
168        $addressBookQueryReport->properties = [
169            '{DAV:}getetag',
170            '{urn:ietf:params:xml:ns:carddav}address-data',
171        ];
172        $addressBookQueryReport->test = 'anyof';
173        $addressBookQueryReport->filters = [
174            [
175                'name' => 'uid',
176                'test' => 'anyof',
177                'is-not-defined' => true,
178                'param-filters' => [],
179                'text-matches' => [],
180            ],
181            [
182                'name' => 'x-foo',
183                'test' => 'allof',
184                'is-not-defined' => false,
185                'param-filters' => [
186                    [
187                        'name' => 'x-param1',
188                        'is-not-defined' => false,
189                        'text-match' => null,
190                    ],
191                    [
192                        'name' => 'x-param2',
193                        'is-not-defined' => true,
194                        'text-match' => null,
195                    ],
196                    [
197                        'name' => 'x-param3',
198                        'is-not-defined' => false,
199                        'text-match' => [
200                            'negate-condition' => false,
201                            'value' => 'Hello!',
202                            'match-type' => 'contains',
203                            'collation' => 'i;unicode-casemap',
204                        ],
205                    ],
206                ],
207                'text-matches' => [],
208            ],
209            [
210                'name' => 'x-prop2',
211                'test' => 'anyof',
212                'is-not-defined' => false,
213                'param-filters' => [],
214                'text-matches' => [
215                    [
216                        'negate-condition' => true,
217                        'value' => 'No',
218                        'match-type' => 'starts-with',
219                        'collation' => 'i;unicode-casemap',
220                    ],
221                ],
222            ]
223        ];
224
225        $addressBookQueryReport->version = '4.0';
226        $addressBookQueryReport->contentType = 'application/vcard+json';
227        $addressBookQueryReport->limit = 10;
228
229        $this->assertEquals(
230            $addressBookQueryReport,
231            $result['value']
232        );
233
234    }
235
236    /**
237     * @expectedException \Sabre\DAV\Exception\BadRequest
238     */
239    function testDeserializeBadMatchType() {
240
241        $xml = <<<XML
242<?xml version="1.0"?>
243<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
244    <d:prop>
245      <d:getetag />
246    </d:prop>
247    <c:filter>
248        <c:prop-filter name="x-foo" test="allof">
249            <c:param-filter name="x-param3">
250                <c:text-match match-type="bad">Hello!</c:text-match>
251            </c:param-filter>
252        </c:prop-filter>
253    </c:filter>
254</c:addressbook-query>
255XML;
256        $this->parse($xml);
257
258    }
259
260    /**
261     * @expectedException \Sabre\DAV\Exception\BadRequest
262     */
263    function testDeserializeBadMatchType2() {
264
265        $xml = <<<XML
266<?xml version="1.0"?>
267<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
268    <d:prop>
269      <d:getetag />
270    </d:prop>
271    <c:filter>
272        <c:prop-filter name="x-prop2">
273            <c:text-match match-type="bad" negate-condition="yes">No</c:text-match>
274        </c:prop-filter>
275    </c:filter>
276</c:addressbook-query>
277XML;
278        $this->parse($xml);
279
280    }
281
282    /**
283     * @expectedException \Sabre\DAV\Exception\BadRequest
284     */
285    function testDeserializeDoubleFilter() {
286
287        $xml = <<<XML
288<?xml version="1.0"?>
289<c:addressbook-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:carddav">
290    <d:prop>
291      <d:getetag />
292    </d:prop>
293    <c:filter>
294    </c:filter>
295    <c:filter>
296    </c:filter>
297</c:addressbook-query>
298XML;
299        $this->parse($xml);
300
301    }
302}
303