diff options
Diffstat (limited to 'vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php')
-rw-r--r-- | vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php | 966 |
1 files changed, 966 insertions, 0 deletions
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php new file mode 100644 index 000000000..a45dafdf1 --- /dev/null +++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php @@ -0,0 +1,966 @@ +<?php + +namespace Sabre\DAV\Locks; + +use Sabre\HTTP; +use Sabre\DAV; + +require_once 'Sabre/DAV/AbstractServer.php'; + +class PluginTest extends DAV\AbstractServer { + + /** + * @var Sabre\DAV\Locks\Plugin + */ + protected $locksPlugin; + + function setUp() { + + parent::setUp(); + $locksBackend = new Backend\File(SABRE_TEMPDIR . '/locksdb'); + $locksPlugin = new Plugin($locksBackend); + $this->server->addPlugin($locksPlugin); + $this->locksPlugin = $locksPlugin; + + } + + function testGetFeatures() { + + $this->assertEquals(array(2),$this->locksPlugin->getFeatures()); + + } + + function testGetHTTPMethods() { + + $this->assertEquals(array('LOCK','UNLOCK'),$this->locksPlugin->getHTTPMethods('')); + + } + + function testGetHTTPMethodsNoBackend() { + + $locksPlugin = new Plugin(); + $this->server->addPlugin($locksPlugin); + $this->assertEquals(array(),$locksPlugin->getHTTPMethods('')); + + } + + function testUnknownMethodPassthough() { + + $this->assertNull($this->locksPlugin->unknownMethod('BLA','/')); + + } + + function testLockNoBody() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody(''); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status); + + } + + function testLock() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'Got an incorrect status back. Response body: ' . $this->response->body); + + $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body); + $xml = simplexml_load_string($body); + $xml->registerXPathNamespace('d','urn:DAV'); + + $elements = array( + '/d:prop', + '/d:prop/d:lockdiscovery', + '/d:prop/d:lockdiscovery/d:activelock', + '/d:prop/d:lockdiscovery/d:activelock/d:locktype', + '/d:prop/d:lockdiscovery/d:activelock/d:lockroot', + '/d:prop/d:lockdiscovery/d:activelock/d:lockroot/d:href', + '/d:prop/d:lockdiscovery/d:activelock/d:locktype/d:write', + '/d:prop/d:lockdiscovery/d:activelock/d:lockscope', + '/d:prop/d:lockdiscovery/d:activelock/d:lockscope/d:exclusive', + '/d:prop/d:lockdiscovery/d:activelock/d:depth', + '/d:prop/d:lockdiscovery/d:activelock/d:owner', + '/d:prop/d:lockdiscovery/d:activelock/d:timeout', + '/d:prop/d:lockdiscovery/d:activelock/d:locktoken', + '/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href', + ); + + foreach($elements as $elem) { + $data = $xml->xpath($elem); + $this->assertEquals(1,count($data),'We expected 1 match for the xpath expression "' . $elem . '". ' . count($data) . ' were found. Full response body: ' . $this->response->body); + } + + $depth = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:depth'); + $this->assertEquals('infinity',(string)$depth[0]); + + $token = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href'); + $this->assertEquals($this->response->headers['Lock-Token'],'<' . (string)$token[0] . '>','Token in response body didn\'t match token in response header.'); + + } + + /** + * @depends testLock + */ + function testDoubleLock() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->response = new HTTP\ResponseMock(); + $this->server->httpResponse = $this->response; + + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status); + + } + + /** + * @depends testLock + */ + function testLockRefresh() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $lockToken = $this->response->headers['Lock-Token']; + + $this->response = new HTTP\ResponseMock(); + $this->server->httpResponse = $this->response; + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + 'HTTP_IF' => '(' . $lockToken . ')', + ); + $request = new HTTP\Request($serverVars); + $request->setBody(''); + $this->server->httpRequest = $request; + + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'We received an incorrect status code. Full response body: ' . $this->response->body); + + } + + /** + * @depends testLock + */ + function testLockNoFile() { + + $serverVars = array( + 'REQUEST_URI' => '/notfound.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + + } + + /** + * @depends testLock + */ + function testUnlockNoToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'UNLOCK', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status); + + } + + /** + * @depends testLock + */ + function testUnlockBadToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'UNLOCK', + 'HTTP_LOCK_TOKEN' => '<opaquelocktoken:blablabla>', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->exec(); + + $this->assertEquals(array( + 'Content-Type' => 'application/xml; charset=utf-8', + ), + $this->response->headers + ); + + $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status,'Got an incorrect status code. Full response body: ' . $this->response->body); + + } + + /** + * @depends testLock + */ + function testLockPutNoToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status); + + } + + /** + * @depends testLock + */ + function testUnlock() { + + $request = new HTTP\Request(array()); + $this->server->httpRequest = $request; + + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->invokeMethod('LOCK','test.txt'); + $lockToken = $this->server->httpResponse->headers['Lock-Token']; + + $serverVars = array( + 'HTTP_LOCK_TOKEN' => $lockToken, + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->httpResponse = new HTTP\ResponseMock(); + $this->server->invokeMethod('UNLOCK', 'test.txt'); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body); + $this->assertEquals(array( + 'Content-Length' => '0', + ), + $this->server->httpResponse->headers + ); + + + } + + /** + * @depends testLock + */ + function testUnlockWindowsBug() { + + $request = new HTTP\Request(array()); + $this->server->httpRequest = $request; + + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->invokeMethod('LOCK','test.txt'); + $lockToken = $this->server->httpResponse->headers['Lock-Token']; + + // See Issue 123 + $lockToken = trim($lockToken,'<>'); + + $serverVars = array( + 'HTTP_LOCK_TOKEN' => $lockToken, + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = ($request); + $this->server->httpResponse = new HTTP\ResponseMock(); + $this->server->invokeMethod('UNLOCK', 'test.txt'); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body); + $this->assertEquals(array( + 'Content-Length' => '0', + ), + $this->server->httpResponse->headers + ); + + + } + + /** + * @depends testLock + */ + function testLockRetainOwner() { + + $request = new HTTP\Request(array()); + $this->server->httpRequest = $request; + + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner>Evert</D:owner> +</D:lockinfo>'); + + $this->server->invokeMethod('LOCK','test.txt'); + $lockToken = $this->server->httpResponse->headers['Lock-Token']; + + $locks = $this->locksPlugin->getLocks('test.txt'); + $this->assertEquals(1,count($locks)); + $this->assertEquals('Evert',$locks[0]->owner); + + + } + + /** + * @depends testLock + */ + function testLockPutBadToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF' => '(<opaquelocktoken:token1>)', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status); + + } + + /** + * @depends testLock + */ + function testLockDeleteParent() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir', + 'REQUEST_METHOD' => 'DELETE', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + /** + * @depends testLock + */ + function testLockDeleteSucceed() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'DELETE', + 'HTTP_IF' => '(' . $this->response->headers['Lock-Token'] . ')', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + + /** + * @depends testLock + */ + function testLockCopyLockSource() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/dir/child2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Copy must succeed if only the source is locked, but not the destination'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + /** + * @depends testLock + */ + function testLockCopyLockDestination() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child2.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'COPY', + 'HTTP_DESTINATION' => '/dir/child2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + + /** + * @depends testLock + */ + function testLockMoveLockSourceLocked() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/dir/child2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + + /** + * @depends testLock + */ + function testLockMoveLockSourceSucceed() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/dir/child2.txt', + 'HTTP_IF' => '(' . $this->response->headers['Lock-Token'] . ')', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'A valid lock-token was provided for the source, so this MOVE operation must succeed. Full response body: ' . $this->response->body); + + } + + /** + * @depends testLock + */ + function testLockMoveLockDestination() { + + $serverVars = array( + 'REQUEST_URI' => '/dir/child2.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/dir/child2.txt', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + /** + * @depends testLock + */ + function testLockMoveLockParent() { + + $serverVars = array( + 'REQUEST_URI' => '/dir', + 'REQUEST_METHOD' => 'LOCK', + 'HTTP_DEPTH' => 'infinite', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/dir/child.txt', + 'REQUEST_METHOD' => 'MOVE', + 'HTTP_DESTINATION' => '/dir/child2.txt', + 'HTTP_IF' => '</dir> (' . $this->response->headers['Lock-Token'] . ')', + ); + + $request = new HTTP\Request($serverVars); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'We locked the parent of both the source and destination, but the move didn\'t succeed.'); + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + + } + + /** + * @depends testLock + */ + function testLockPutGoodToken() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'LOCK', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('<?xml version="1.0"?> +<D:lockinfo xmlns:D="DAV:"> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + <D:owner> + <D:href>http://example.org/~ejw/contact.html</D:href> + </D:owner> +</D:lockinfo>'); + + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 200 OK',$this->response->status); + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF' => '('.$this->response->headers['Lock-Token'].')', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + + $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']); + $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')'); + + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status); + + } + + function testPutWithIncorrectETag() { + + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF' => '(["etag1"])', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status); + + } + + /** + * @depends testPutWithIncorrectETag + */ + function testPutWithCorrectETag() { + + // We need an etag-enabled file node. + $tree = new DAV\ObjectTree(new DAV\FSExt\Directory(SABRE_TEMPDIR)); + $this->server->tree = $tree; + + $etag = md5(file_get_contents(SABRE_TEMPDIR . '/test.txt')); + $serverVars = array( + 'REQUEST_URI' => '/test.txt', + 'REQUEST_METHOD' => 'PUT', + 'HTTP_IF' => '(["'.$etag.'"])', + ); + + $request = new HTTP\Request($serverVars); + $request->setBody('newbody'); + $this->server->httpRequest = $request; + $this->server->exec(); + $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status, 'Incorrect status received. Full response body:' . $this->response->body); + + } + + function testGetTimeoutHeader() { + + $request = new HTTP\Request(array( + 'HTTP_TIMEOUT' => 'second-100', + )); + + $this->server->httpRequest = $request; + $this->assertEquals(100, $this->locksPlugin->getTimeoutHeader()); + + } + + + function testGetTimeoutHeaderNotSet() { + + $request = new HTTP\Request(array( + )); + + $this->server->httpRequest = $request; + $this->assertEquals(0, $this->locksPlugin->getTimeoutHeader()); + + } + + + function testGetTimeoutHeaderInfinite() { + + $request = new HTTP\Request(array( + 'HTTP_TIMEOUT' => 'infinite', + )); + + $this->server->httpRequest = $request; + $this->assertEquals(LockInfo::TIMEOUT_INFINITE, $this->locksPlugin->getTimeoutHeader()); + + } + + /** + * @expectedException Sabre\DAV\Exception\BadRequest + */ + function testGetTimeoutHeaderInvalid() { + + $request = new HTTP\Request(array( + 'HTTP_TIMEOUT' => 'yourmom', + )); + + $this->server->httpRequest = $request; + $this->locksPlugin->getTimeoutHeader(); + + } + + +} |