1<?php 2 3namespace Sabre; 4 5use Sabre\HTTP\Request; 6use Sabre\HTTP\Response; 7use Sabre\HTTP\Sapi; 8 9/** 10 * This class may be used as a basis for other webdav-related unittests. 11 * 12 * This class is supposed to provide a reasonably big framework to quickly get 13 * a testing environment running. 14 * 15 * @copyright Copyright (C) fruux GmbH (https://fruux.com/) 16 * @author Evert Pot (http://evertpot.com/) 17 * @license http://sabre.io/license/ Modified BSD License 18 */ 19abstract class DAVServerTest extends \PHPUnit_Framework_TestCase { 20 21 protected $setupCalDAV = false; 22 protected $setupCardDAV = false; 23 protected $setupACL = false; 24 protected $setupCalDAVSharing = false; 25 protected $setupCalDAVScheduling = false; 26 protected $setupCalDAVSubscriptions = false; 27 protected $setupCalDAVICSExport = false; 28 protected $setupLocks = false; 29 protected $setupFiles = false; 30 protected $setupSharing = false; 31 protected $setupPropertyStorage = false; 32 33 /** 34 * An array with calendars. Every calendar should have 35 * - principaluri 36 * - uri 37 */ 38 protected $caldavCalendars = []; 39 protected $caldavCalendarObjects = []; 40 41 protected $carddavAddressBooks = []; 42 protected $carddavCards = []; 43 44 /** 45 * @var Sabre\DAV\Server 46 */ 47 protected $server; 48 protected $tree = []; 49 50 protected $caldavBackend; 51 protected $carddavBackend; 52 protected $principalBackend; 53 protected $locksBackend; 54 protected $propertyStorageBackend; 55 56 /** 57 * @var Sabre\CalDAV\Plugin 58 */ 59 protected $caldavPlugin; 60 61 /** 62 * @var Sabre\CardDAV\Plugin 63 */ 64 protected $carddavPlugin; 65 66 /** 67 * @var Sabre\DAVACL\Plugin 68 */ 69 protected $aclPlugin; 70 71 /** 72 * @var Sabre\CalDAV\SharingPlugin 73 */ 74 protected $caldavSharingPlugin; 75 76 /** 77 * CalDAV scheduling plugin 78 * 79 * @var CalDAV\Schedule\Plugin 80 */ 81 protected $caldavSchedulePlugin; 82 83 /** 84 * @var Sabre\DAV\Auth\Plugin 85 */ 86 protected $authPlugin; 87 88 /** 89 * @var Sabre\DAV\Locks\Plugin 90 */ 91 protected $locksPlugin; 92 93 /** 94 * Sharing plugin. 95 * 96 * @var \Sabre\DAV\Sharing\Plugin 97 */ 98 protected $sharingPlugin; 99 100 /* 101 * @var Sabre\DAV\PropertyStorage\Plugin 102 */ 103 protected $propertyStoragePlugin; 104 105 /** 106 * If this string is set, we will automatically log in the user with this 107 * name. 108 */ 109 protected $autoLogin = null; 110 111 function setUp() { 112 113 $this->initializeEverything(); 114 115 } 116 117 function initializeEverything() { 118 119 $this->setUpBackends(); 120 $this->setUpTree(); 121 122 $this->server = new DAV\Server($this->tree); 123 $this->server->sapi = new HTTP\SapiMock(); 124 $this->server->debugExceptions = true; 125 126 if ($this->setupCalDAV) { 127 $this->caldavPlugin = new CalDAV\Plugin(); 128 $this->server->addPlugin($this->caldavPlugin); 129 } 130 if ($this->setupCalDAVSharing || $this->setupSharing) { 131 $this->sharingPlugin = new DAV\Sharing\Plugin(); 132 $this->server->addPlugin($this->sharingPlugin); 133 } 134 if ($this->setupCalDAVSharing) { 135 $this->caldavSharingPlugin = new CalDAV\SharingPlugin(); 136 $this->server->addPlugin($this->caldavSharingPlugin); 137 } 138 if ($this->setupCalDAVScheduling) { 139 $this->caldavSchedulePlugin = new CalDAV\Schedule\Plugin(); 140 $this->server->addPlugin($this->caldavSchedulePlugin); 141 } 142 if ($this->setupCalDAVSubscriptions) { 143 $this->server->addPlugin(new CalDAV\Subscriptions\Plugin()); 144 } 145 if ($this->setupCalDAVICSExport) { 146 $this->caldavICSExportPlugin = new CalDAV\ICSExportPlugin(); 147 $this->server->addPlugin($this->caldavICSExportPlugin); 148 } 149 if ($this->setupCardDAV) { 150 $this->carddavPlugin = new CardDAV\Plugin(); 151 $this->server->addPlugin($this->carddavPlugin); 152 } 153 if ($this->setupLocks) { 154 $this->locksPlugin = new DAV\Locks\Plugin( 155 $this->locksBackend 156 ); 157 $this->server->addPlugin($this->locksPlugin); 158 } 159 if ($this->setupPropertyStorage) { 160 $this->propertyStoragePlugin = new DAV\PropertyStorage\Plugin( 161 $this->propertyStorageBackend 162 ); 163 $this->server->addPlugin($this->propertyStoragePlugin); 164 } 165 if ($this->autoLogin) { 166 $this->autoLogin($this->autoLogin); 167 } 168 if ($this->setupACL) { 169 $this->aclPlugin = new DAVACL\Plugin(); 170 if (!$this->autoLogin) { 171 $this->aclPlugin->allowUnauthenticatedAccess = false; 172 } 173 $this->aclPlugin->adminPrincipals = ['principals/admin']; 174 $this->server->addPlugin($this->aclPlugin); 175 } 176 177 } 178 179 /** 180 * Makes a request, and returns a response object. 181 * 182 * You can either pass an instance of Sabre\HTTP\Request, or an array, 183 * which will then be used as the _SERVER array. 184 * 185 * If $expectedStatus is set, we'll compare it with the HTTP status of 186 * the returned response. If it doesn't match, we'll immediately fail 187 * the test. 188 * 189 * @param array|\Sabre\HTTP\Request $request 190 * @param int $expectedStatus 191 * @return \Sabre\HTTP\Response 192 */ 193 function request($request, $expectedStatus = null) { 194 195 if (is_array($request)) { 196 $request = HTTP\Request::createFromServerArray($request); 197 } 198 $response = new HTTP\ResponseMock(); 199 200 $this->server->httpRequest = $request; 201 $this->server->httpResponse = $response; 202 $this->server->exec(); 203 204 if ($expectedStatus) { 205 $responseBody = $expectedStatus !== $response->getStatus() ? $response->getBodyAsString() : ''; 206 $this->assertEquals($expectedStatus, $response->getStatus(), 'Incorrect HTTP status received for request. Response body: ' . $responseBody); 207 } 208 return $this->server->httpResponse; 209 210 } 211 212 /** 213 * This function takes a username and sets the server in a state where 214 * this user is logged in, and no longer requires an authentication check. 215 * 216 * @param string $userName 217 */ 218 function autoLogin($userName) { 219 $authBackend = new DAV\Auth\Backend\Mock(); 220 $authBackend->setPrincipal('principals/' . $userName); 221 $this->authPlugin = new DAV\Auth\Plugin($authBackend); 222 223 // If the auth plugin already exists, we're removing its hooks: 224 if ($oldAuth = $this->server->getPlugin('auth')) { 225 $this->server->removeListener('beforeMethod', [$oldAuth, 'beforeMethod']); 226 } 227 $this->server->addPlugin($this->authPlugin); 228 229 // This will trigger the actual login procedure 230 $this->authPlugin->beforeMethod(new Request(), new Response()); 231 } 232 233 /** 234 * Override this to provide your own Tree for your test-case. 235 */ 236 function setUpTree() { 237 238 if ($this->setupCalDAV) { 239 $this->tree[] = new CalDAV\CalendarRoot( 240 $this->principalBackend, 241 $this->caldavBackend 242 ); 243 } 244 if ($this->setupCardDAV) { 245 $this->tree[] = new CardDAV\AddressBookRoot( 246 $this->principalBackend, 247 $this->carddavBackend 248 ); 249 } 250 251 if ($this->setupCalDAV) { 252 $this->tree[] = new CalDAV\Principal\Collection( 253 $this->principalBackend 254 ); 255 } elseif ($this->setupCardDAV || $this->setupACL) { 256 $this->tree[] = new DAVACL\PrincipalCollection( 257 $this->principalBackend 258 ); 259 } 260 if ($this->setupFiles) { 261 262 $this->tree[] = new DAV\Mock\Collection('files'); 263 264 } 265 266 } 267 268 function setUpBackends() { 269 270 if ($this->setupCalDAVSharing && is_null($this->caldavBackend)) { 271 $this->caldavBackend = new CalDAV\Backend\MockSharing($this->caldavCalendars, $this->caldavCalendarObjects); 272 } 273 if ($this->setupCalDAVSubscriptions && is_null($this->caldavBackend)) { 274 $this->caldavBackend = new CalDAV\Backend\MockSubscriptionSupport($this->caldavCalendars, $this->caldavCalendarObjects); 275 } 276 if ($this->setupCalDAV && is_null($this->caldavBackend)) { 277 if ($this->setupCalDAVScheduling) { 278 $this->caldavBackend = new CalDAV\Backend\MockScheduling($this->caldavCalendars, $this->caldavCalendarObjects); 279 } else { 280 $this->caldavBackend = new CalDAV\Backend\Mock($this->caldavCalendars, $this->caldavCalendarObjects); 281 } 282 } 283 if ($this->setupCardDAV && is_null($this->carddavBackend)) { 284 $this->carddavBackend = new CardDAV\Backend\Mock($this->carddavAddressBooks, $this->carddavCards); 285 } 286 if ($this->setupCardDAV || $this->setupCalDAV || $this->setupACL) { 287 $this->principalBackend = new DAVACL\PrincipalBackend\Mock(); 288 } 289 if ($this->setupLocks) { 290 $this->locksBackend = new DAV\Locks\Backend\Mock(); 291 } 292 if ($this->setupPropertyStorage) { 293 $this->propertyStorageBackend = new DAV\PropertyStorage\Backend\Mock(); 294 } 295 296 } 297 298 299 function assertHttpStatus($expectedStatus, HTTP\Request $req) { 300 301 $resp = $this->request($req); 302 $this->assertEquals((int)$expectedStatus, (int)$resp->status, 'Incorrect HTTP status received: ' . $resp->body); 303 304 } 305 306} 307