1<?php
2
3namespace Sabre\CalDAV;
4
5use Sabre\DAV;
6use Sabre\DAVACL;
7use Sabre\HTTP;
8use Sabre\VObject;
9
10class ICSExportPluginTest extends \Sabre\DAVServerTest {
11
12    protected $setupCalDAV = true;
13
14    protected $icsExportPlugin;
15
16    function setUp() {
17
18        parent::setUp();
19        $this->icsExportPlugin = new ICSExportPlugin();
20        $this->server->addPlugin(
21            $this->icsExportPlugin
22        );
23
24        $id = $this->caldavBackend->createCalendar(
25            'principals/admin',
26            'UUID-123467',
27            [
28                '{DAV:}displayname'                         => 'Hello!',
29                '{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF',
30            ]
31        );
32
33        $this->caldavBackend->createCalendarObject(
34            $id,
35            'event-1',
36            <<<ICS
37BEGIN:VCALENDAR
38BEGIN:VTIMEZONE
39TZID:Europe/Amsterdam
40END:VTIMEZONE
41BEGIN:VEVENT
42UID:event-1
43DTSTART;TZID=Europe/Amsterdam:20151020T000000
44END:VEVENT
45END:VCALENDAR
46ICS
47        );
48        $this->caldavBackend->createCalendarObject(
49            $id,
50            'todo-1',
51            <<<ICS
52BEGIN:VCALENDAR
53BEGIN:VTODO
54UID:todo-1
55END:VTODO
56END:VCALENDAR
57ICS
58        );
59
60
61    }
62
63    function testInit() {
64
65        $this->assertEquals(
66            $this->icsExportPlugin,
67            $this->server->getPlugin('ics-export')
68        );
69        $this->assertEquals($this->icsExportPlugin, $this->server->getPlugin('ics-export'));
70        $this->assertEquals('ics-export', $this->icsExportPlugin->getPluginInfo()['name']);
71
72    }
73
74    function testBeforeMethod() {
75
76        $request = new HTTP\Request(
77            'GET',
78            '/calendars/admin/UUID-123467?export'
79        );
80
81        $response = $this->request($request);
82
83        $this->assertEquals(200, $response->getStatus());
84        $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
85
86        $obj = VObject\Reader::read($response->body);
87
88        $this->assertEquals(8, count($obj->children()));
89        $this->assertEquals(1, count($obj->VERSION));
90        $this->assertEquals(1, count($obj->CALSCALE));
91        $this->assertEquals(1, count($obj->PRODID));
92        $this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
93        $this->assertEquals(1, count($obj->VTIMEZONE));
94        $this->assertEquals(1, count($obj->VEVENT));
95        $this->assertEquals("Hello!", $obj->{"X-WR-CALNAME"});
96        $this->assertEquals("#AA0000FF", $obj->{"X-APPLE-CALENDAR-COLOR"});
97
98    }
99    function testBeforeMethodNoVersion() {
100
101        $request = new HTTP\Request(
102            'GET',
103            '/calendars/admin/UUID-123467?export'
104        );
105        DAV\Server::$exposeVersion = false;
106        $response = $this->request($request);
107        DAV\Server::$exposeVersion = true;
108
109        $this->assertEquals(200, $response->getStatus());
110        $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
111
112        $obj = VObject\Reader::read($response->body);
113
114        $this->assertEquals(8, count($obj->children()));
115        $this->assertEquals(1, count($obj->VERSION));
116        $this->assertEquals(1, count($obj->CALSCALE));
117        $this->assertEquals(1, count($obj->PRODID));
118        $this->assertFalse(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
119        $this->assertEquals(1, count($obj->VTIMEZONE));
120        $this->assertEquals(1, count($obj->VEVENT));
121
122    }
123
124    function testBeforeMethodNoExport() {
125
126        $request = new HTTP\Request(
127            'GET',
128            '/calendars/admin/UUID-123467'
129        );
130        $response = new HTTP\Response();
131        $this->assertNull($this->icsExportPlugin->httpGet($request, $response));
132
133    }
134
135    function testACLIntegrationBlocked() {
136
137        $aclPlugin = new DAVACL\Plugin();
138        $aclPlugin->allowUnauthenticatedAccess = false;
139        $this->server->addPlugin(
140            $aclPlugin
141        );
142
143        $request = new HTTP\Request(
144            'GET',
145            '/calendars/admin/UUID-123467?export'
146        );
147
148        $this->request($request, 403);
149
150    }
151
152    function testACLIntegrationNotBlocked() {
153
154        $aclPlugin = new DAVACL\Plugin();
155        $aclPlugin->allowUnauthenticatedAccess = false;
156        $this->server->addPlugin(
157            $aclPlugin
158        );
159        $this->server->addPlugin(
160            new Plugin()
161        );
162
163        $this->autoLogin('admin');
164
165        $request = new HTTP\Request(
166            'GET',
167            '/calendars/admin/UUID-123467?export'
168        );
169
170        $response = $this->request($request, 200);
171        $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
172
173        $obj = VObject\Reader::read($response->body);
174
175        $this->assertEquals(8, count($obj->children()));
176        $this->assertEquals(1, count($obj->VERSION));
177        $this->assertEquals(1, count($obj->CALSCALE));
178        $this->assertEquals(1, count($obj->PRODID));
179        $this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
180        $this->assertEquals(1, count($obj->VTIMEZONE));
181        $this->assertEquals(1, count($obj->VEVENT));
182
183    }
184
185    function testBadStartParam() {
186
187        $request = new HTTP\Request(
188            'GET',
189            '/calendars/admin/UUID-123467?export&start=foo'
190        );
191        $this->request($request, 400);
192
193    }
194
195    function testBadEndParam() {
196
197        $request = new HTTP\Request(
198            'GET',
199            '/calendars/admin/UUID-123467?export&end=foo'
200        );
201        $this->request($request, 400);
202
203    }
204
205    function testFilterStartEnd() {
206
207        $request = new HTTP\Request(
208            'GET',
209            '/calendars/admin/UUID-123467?export&start=1&end=2'
210        );
211        $response = $this->request($request, 200);
212
213        $obj = VObject\Reader::read($response->getBody());
214
215        $this->assertEquals(0, count($obj->VTIMEZONE));
216        $this->assertEquals(0, count($obj->VEVENT));
217
218    }
219
220    function testExpandNoStart() {
221
222        $request = new HTTP\Request(
223            'GET',
224            '/calendars/admin/UUID-123467?export&expand=1&end=2'
225        );
226        $this->request($request, 400);
227
228    }
229
230    function testExpand() {
231
232        $request = new HTTP\Request(
233            'GET',
234            '/calendars/admin/UUID-123467?export&start=1&end=2000000000&expand=1'
235        );
236        $response = $this->request($request, 200);
237
238        $obj = VObject\Reader::read($response->getBody());
239
240        $this->assertEquals(0, count($obj->VTIMEZONE));
241        $this->assertEquals(1, count($obj->VEVENT));
242
243    }
244
245    function testJCal() {
246
247        $request = new HTTP\Request(
248            'GET',
249            '/calendars/admin/UUID-123467?export',
250            ['Accept' => 'application/calendar+json']
251        );
252
253        $response = $this->request($request, 200);
254        $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
255
256    }
257
258    function testJCalInUrl() {
259
260        $request = new HTTP\Request(
261            'GET',
262            '/calendars/admin/UUID-123467?export&accept=jcal'
263        );
264
265        $response = $this->request($request, 200);
266        $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
267
268    }
269
270    function testNegotiateDefault() {
271
272        $request = new HTTP\Request(
273            'GET',
274            '/calendars/admin/UUID-123467?export',
275            ['Accept' => 'text/plain']
276        );
277
278        $response = $this->request($request, 200);
279        $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
280
281    }
282
283    function testFilterComponentVEVENT() {
284
285        $request = new HTTP\Request(
286            'GET',
287            '/calendars/admin/UUID-123467?export&componentType=VEVENT'
288        );
289
290        $response = $this->request($request, 200);
291
292        $obj = VObject\Reader::read($response->body);
293        $this->assertEquals(1, count($obj->VTIMEZONE));
294        $this->assertEquals(1, count($obj->VEVENT));
295        $this->assertEquals(0, count($obj->VTODO));
296
297    }
298
299    function testFilterComponentVTODO() {
300
301        $request = new HTTP\Request(
302            'GET',
303            '/calendars/admin/UUID-123467?export&componentType=VTODO'
304        );
305
306        $response = $this->request($request, 200);
307
308        $obj = VObject\Reader::read($response->body);
309
310        $this->assertEquals(0, count($obj->VTIMEZONE));
311        $this->assertEquals(0, count($obj->VEVENT));
312        $this->assertEquals(1, count($obj->VTODO));
313
314    }
315
316    function testFilterComponentBadComponent() {
317
318        $request = new HTTP\Request(
319            'GET',
320            '/calendars/admin/UUID-123467?export&componentType=VVOODOO'
321        );
322
323        $response = $this->request($request, 400);
324
325    }
326
327    function testContentDisposition() {
328
329        $request = new HTTP\Request(
330            'GET',
331            '/calendars/admin/UUID-123467?export'
332        );
333
334        $response = $this->request($request, 200);
335        $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
336        $this->assertEquals(
337            'attachment; filename="UUID-123467-' . date('Y-m-d') . '.ics"',
338            $response->getHeader('Content-Disposition')
339        );
340
341    }
342
343    function testContentDispositionJson() {
344
345        $request = new HTTP\Request(
346            'GET',
347            '/calendars/admin/UUID-123467?export',
348            ['Accept' => 'application/calendar+json']
349        );
350
351        $response = $this->request($request, 200);
352        $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
353        $this->assertEquals(
354            'attachment; filename="UUID-123467-' . date('Y-m-d') . '.json"',
355            $response->getHeader('Content-Disposition')
356        );
357
358    }
359
360    function testContentDispositionBadChars() {
361
362        $this->caldavBackend->createCalendar(
363            'principals/admin',
364            'UUID-b_ad"(ch)ars',
365            [
366                '{DAV:}displayname'                         => 'Test bad characters',
367                '{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF',
368            ]
369        );
370
371        $request = new HTTP\Request(
372            'GET',
373            '/calendars/admin/UUID-b_ad"(ch)ars?export',
374            ['Accept' => 'application/calendar+json']
375        );
376
377        $response = $this->request($request, 200);
378        $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
379        $this->assertEquals(
380            'attachment; filename="UUID-b_adchars-' . date('Y-m-d') . '.json"',
381            $response->getHeader('Content-Disposition')
382        );
383
384    }
385
386}
387