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