1<?php
2
3namespace Sabre\CalDAV;
4
5use Sabre\DAV;
6use Sabre\DAVACL;
7use Sabre\HTTP;
8
9require_once 'Sabre/HTTP/ResponseMock.php';
10
11class ValidateICalTest extends \PHPUnit_Framework_TestCase {
12
13    /**
14     * @var Sabre\DAV\Server
15     */
16    protected $server;
17    /**
18     * @var Sabre\CalDAV\Backend\Mock
19     */
20    protected $calBackend;
21
22    function setUp() {
23
24        $calendars = array(
25            array(
26                'id' => 'calendar1',
27                'principaluri' => 'principals/admin',
28                'uri' => 'calendar1',
29                '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet( ['VEVENT','VTODO','VJOURNAL'] ),
30            ),
31            array(
32                'id' => 'calendar2',
33                'principaluri' => 'principals/admin',
34                'uri' => 'calendar2',
35                '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet( ['VTODO','VJOURNAL'] ),
36            )
37        );
38
39        $this->calBackend = new Backend\Mock($calendars, []);
40        $principalBackend = new DAVACL\PrincipalBackend\Mock();
41
42        $tree = [
43            new CalendarRoot($principalBackend, $this->calBackend),
44        ];
45
46        $this->server = new DAV\Server($tree);
47        $this->server->sapi = new HTTP\SapiMock();
48        $this->server->debugExceptions = true;
49
50        $plugin = new Plugin();
51        $this->server->addPlugin($plugin);
52
53        $response = new HTTP\ResponseMock();
54        $this->server->httpResponse = $response;
55
56    }
57
58    function request(HTTP\Request $request) {
59
60        $this->server->httpRequest = $request;
61        $this->server->exec();
62
63        return $this->server->httpResponse;
64
65    }
66
67    function testCreateFile() {
68
69        $request = HTTP\Sapi::createFromServerArray(array(
70            'REQUEST_METHOD' => 'PUT',
71            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
72        ));
73
74        $response = $this->request($request);
75
76        $this->assertEquals(415, $response->status);
77
78    }
79
80    function testCreateFileValid() {
81
82        $request = HTTP\Sapi::createFromServerArray(array(
83            'REQUEST_METHOD' => 'PUT',
84            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
85        ));
86        $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
87
88        $response = $this->request($request);
89
90        $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
91        $this->assertEquals(array(
92            'X-Sabre-Version' => [DAV\Version::VERSION],
93            'Content-Length' => ['0'],
94            'ETag' => ['"' . md5("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n") . '"'],
95        ), $response->getHeaders());
96
97        $expected = array(
98            'uri'          => 'blabla.ics',
99            'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
100            'calendarid'   => 'calendar1',
101            'lastmodified' => null,
102        );
103
104        $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1','blabla.ics'));
105
106    }
107
108    function testCreateFileNoComponents() {
109
110        $request = HTTP\Sapi::createFromServerArray(array(
111            'REQUEST_METHOD' => 'PUT',
112            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
113        ));
114        $request->setBody("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n");
115
116        $response = $this->request($request);
117
118        $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
119
120    }
121
122    function testCreateFileNoUID() {
123
124        $request = HTTP\Sapi::createFromServerArray(array(
125            'REQUEST_METHOD' => 'PUT',
126            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
127        ));
128        $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
129
130        $response = $this->request($request);
131
132        $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
133
134    }
135
136    function testCreateFileVCard() {
137
138        $request = HTTP\Sapi::createFromServerArray(array(
139            'REQUEST_METHOD' => 'PUT',
140            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
141        ));
142        $request->setBody("BEGIN:VCARD\r\nEND:VCARD\r\n");
143
144        $response = $this->request($request);
145
146        $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
147
148    }
149
150    function testCreateFile2Components() {
151
152        $request = HTTP\Sapi::createFromServerArray(array(
153            'REQUEST_METHOD' => 'PUT',
154            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
155        ));
156        $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VJOURNAL\r\nUID:foo\r\nEND:VJOURNAL\r\nEND:VCALENDAR\r\n");
157
158        $response = $this->request($request);
159
160        $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
161
162    }
163
164    function testCreateFile2UIDS() {
165
166        $request = HTTP\Sapi::createFromServerArray(array(
167            'REQUEST_METHOD' => 'PUT',
168            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
169        ));
170        $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nUID:bar\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
171
172        $response = $this->request($request);
173
174        $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
175
176    }
177
178    function testCreateFileWrongComponent() {
179
180        $request = HTTP\Sapi::createFromServerArray(array(
181            'REQUEST_METHOD' => 'PUT',
182            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
183        ));
184        $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VFREEBUSY\r\nUID:foo\r\nEND:VFREEBUSY\r\nEND:VCALENDAR\r\n");
185
186        $response = $this->request($request);
187
188        $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
189
190    }
191
192    function testUpdateFile() {
193
194        $this->calBackend->createCalendarObject('calendar1','blabla.ics','foo');
195        $request = HTTP\Sapi::createFromServerArray(array(
196            'REQUEST_METHOD' => 'PUT',
197            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
198        ));
199
200        $response = $this->request($request);
201
202        $this->assertEquals(415, $response->status);
203
204    }
205
206    function testUpdateFileParsableBody() {
207
208        $this->calBackend->createCalendarObject('calendar1','blabla.ics','foo');
209        $request = HTTP\Sapi::createFromServerArray(array(
210            'REQUEST_METHOD' => 'PUT',
211            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
212        ));
213        $body = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
214        $request->setBody($body);
215
216        $response = $this->request($request);
217
218        $this->assertEquals(204, $response->status);
219
220        $expected = array(
221            'uri'          => 'blabla.ics',
222            'calendardata' => $body,
223            'calendarid'   => 'calendar1',
224            'lastmodified' => null,
225        );
226
227        $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1','blabla.ics'));
228
229    }
230
231    function testCreateFileInvalidComponent() {
232
233        $request = HTTP\Sapi::createFromServerArray(array(
234            'REQUEST_METHOD' => 'PUT',
235            'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
236        ));
237        $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
238
239        $response = $this->request($request);
240
241        $this->assertEquals(403, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
242
243    }
244
245    function testUpdateFileInvalidComponent() {
246
247        $this->calBackend->createCalendarObject('calendar2','blabla.ics','foo');
248        $request = HTTP\Sapi::createFromServerArray(array(
249            'REQUEST_METHOD' => 'PUT',
250            'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
251        ));
252        $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
253
254        $response = $this->request($request);
255
256        $this->assertEquals(403, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
257
258    }
259
260    /**
261     * What we are testing here, is if we send in a latin1 character, the
262     * server should automatically transform this into UTF-8.
263     *
264     * More importantly. If any transformation happens, the etag must no longer
265     * be returned by the server.
266     */
267    function testCreateFileModified() {
268
269        $request = HTTP\Sapi::createFromServerArray(array(
270            'REQUEST_METHOD' => 'PUT',
271            'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
272        ));
273        $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nSUMMARY:Meeting in M\xfcnster\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
274
275        $response = $this->request($request);
276
277        $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
278        $this->assertNull($response->getHeader('ETag'));
279
280    }
281}
282