<?php
namespace Sabre\DAV;
use Sabre\HTTP;
require_once 'Sabre/HTTP/ResponseMock.php';
require_once 'Sabre/DAV/AbstractServer.php';
require_once 'Sabre/DAV/Exception.php';
class ServerSimpleTest extends AbstractServer{
function testConstructArray() {
$nodes = array(
new SimpleCollection('hello')
);
$server = new Server($nodes);
$this->assertEquals($nodes[0], $server->tree->getNodeForPath('hello'));
}
/**
* @expectedException Sabre\DAV\Exception
*/
function testConstructIncorrectObj() {
$nodes = array(
new SimpleCollection('hello'),
new \STDClass(),
);
$server = new Server($nodes);
}
/**
* @expectedException Sabre\DAV\Exception
*/
function testConstructInvalidArg() {
$server = new Server(1);
}
function testGet() {
$serverVars = array(
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'GET',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/octet-stream',
'Content-Length' => 13,
'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
),
$this->response->headers
);
$this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
$this->assertEquals('Test contents', stream_get_contents($this->response->body));
}
function testGetHttp10() {
$serverVars = array(
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'GET',
'SERVER_PROTOCOL' => 'HTTP/1.0',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/octet-stream',
'Content-Length' => 13,
'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
),
$this->response->headers
);
$this->assertEquals('HTTP/1.0 200 OK',$this->response->status);
$this->assertEquals('Test contents', stream_get_contents($this->response->body));
}
function testGetDoesntExist() {
$serverVars = array(
'REQUEST_URI' => '/test.txt_randomblbla',
'REQUEST_METHOD' => 'GET',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals('HTTP/1.1 404 Not Found',$this->response->status);
}
function testGetDoesntExist2() {
$serverVars = array(
'REQUEST_URI' => '/test.txt/randomblbla',
'REQUEST_METHOD' => 'GET',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals('HTTP/1.1 404 Not Found',$this->response->status);
}
/**
* This test should have the exact same result as testGet.
*
* The idea is that double slashes // are converted to single ones /
*
*/
function testGetDoubleSlash() {
$serverVars = array(
'REQUEST_URI' => '//test.txt',
'REQUEST_METHOD' => 'GET',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/octet-stream',
'Content-Length' => 13,
'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
),
$this->response->headers
);
$this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
$this->assertEquals('Test contents', stream_get_contents($this->response->body));
}
function testHEAD() {
$serverVars = array(
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'HEAD',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/octet-stream',
'Content-Length' => 13,
'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
),
$this->response->headers
);
$this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
$this->assertEquals('', $this->response->body);
}
function testPut() {
$serverVars = array(
'REQUEST_URI' => '/testput.txt',
'REQUEST_METHOD' => 'PUT',
);
$request = new HTTP\Request($serverVars);
$request->setBody('Testing new file');
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals('', $this->response->body);
$this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
$this->assertEquals(array(
"Content-Length" => "0",
), $this->response->headers);
$this->assertEquals('Testing new file',file_get_contents($this->tempDir . '/testput.txt'));
}
function testPutAlreadyExists() {
$serverVars = array(
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'PUT',
'HTTP_IF_NONE_MATCH' => '*',
);
$request = new HTTP\Request($serverVars);
$request->setBody('Testing new file');
$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 412 Precondition failed',$this->response->status);
$this->assertNotEquals('Testing new file',file_get_contents($this->tempDir . '/test.txt'));
}
function testPutUpdate() {
$serverVars = array(
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'PUT',
);
$request = new HTTP\Request($serverVars);
$request->setBody('Testing updated file');
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals('0', $this->response->headers['Content-Length']);
$this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
$this->assertEquals('', $this->response->body);
$this->assertEquals('Testing updated file',file_get_contents($this->tempDir . '/test.txt'));
}
function testPutNoParentCollection() {
$serverVars = array(
'REQUEST_URI' => '/test.txt/item.txt',
'REQUEST_METHOD' => 'PUT',
);
$request = new HTTP\Request($serverVars);
$request->setBody('Testing updated file');
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status);
}
function testPutContentRange() {
$serverVars = array(
'REQUEST_URI' => '/testput.txt',
'REQUEST_METHOD' => 'PUT',
'HTTP_CONTENT_RANGE' => 'bytes/100-200',
);
$request = new HTTP\Request($serverVars);
$request->setBody('Testing new file');
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals('HTTP/1.1 501 Not Implemented',$this->response->status);
}
function testDelete() {
$serverVars = array(
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'DELETE',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Length' => '0',
),$this->response->headers);
$this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
$this->assertEquals('', $this->response->body);
$this->assertFalse(file_exists($this->tempDir . '/test.txt'));
}
function testDeleteDirectory() {
$serverVars = array(
'REQUEST_URI' => '/testcol',
'REQUEST_METHOD' => 'DELETE',
);
mkdir($this->tempDir.'/testcol');
file_put_contents($this->tempDir.'/testcol/test.txt','Hi! I\'m a file with a short lifespan');
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Length' => '0',
),$this->response->headers);
$this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
$this->assertEquals('', $this->response->body);
$this->assertFalse(file_exists($this->tempDir . '/col'));
}
function testOptions() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'OPTIONS',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'DAV' => '1, 3, extended-mkcol',
'MS-Author-Via' => 'DAV',
'Allow' => 'OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT',
'Accept-Ranges' => 'bytes',
'Content-Length' => '0',
'X-Sabre-Version' => Version::VERSION,
),$this->response->headers);
$this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
$this->assertEquals('', $this->response->body);
}
function testNonExistantMethod() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'BLABLA',
);
$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 501 Not Implemented',$this->response->status);
}
function testGETOnCollection() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'GET',
);
$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 501 Not Implemented',$this->response->status);
}
function testHEADOnCollection() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'HEAD',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
}
function testBaseUri() {
$serverVars = array(
'REQUEST_URI' => '/blabla/test.txt',
'REQUEST_METHOD' => 'GET',
);
$request = new HTTP\Request($serverVars);
$this->server->setBaseUri('/blabla/');
$this->assertEquals('/blabla/',$this->server->getBaseUri());
$this->server->httpRequest = ($request);
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/octet-stream',
'Content-Length' => 13,
'Last-Modified' => HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt'))),
),
$this->response->headers
);
$this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
$this->assertEquals('Test contents', stream_get_contents($this->response->body));
}
function testBaseUriAddSlash() {
$tests = array(
'/' => '/',
'/foo' => '/foo/',
'/foo/' => '/foo/',
'/foo/bar' => '/foo/bar/',
'/foo/bar/' => '/foo/bar/',
);
foreach($tests as $test=>$result) {
$this->server->setBaseUri($test);
$this->assertEquals($result, $this->server->getBaseUri());
}
}
function testCalculateUri() {
$uris = array(
'http://www.example.org/root/somepath',
'/root/somepath',
'/root/somepath/',
);
$this->server->setBaseUri('/root/');
foreach($uris as $uri) {
$this->assertEquals('somepath',$this->server->calculateUri($uri));
}
$this->server->setBaseUri('/root');
foreach($uris as $uri) {
$this->assertEquals('somepath',$this->server->calculateUri($uri));
}
$this->assertEquals('', $this->server->calculateUri('/root'));
}
function testCalculateUriSpecialChars() {
$uris = array(
'http://www.example.org/root/%C3%A0fo%C3%B3',
'/root/%C3%A0fo%C3%B3',
'/root/%C3%A0fo%C3%B3/'
);
$this->server->setBaseUri('/root/');
foreach($uris as $uri) {
$this->assertEquals("\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri));
}
$this->server->setBaseUri('/root');
foreach($uris as $uri) {
$this->assertEquals("\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri));
}
$this->server->setBaseUri('/');
foreach($uris as $uri) {
$this->assertEquals("root/\xc3\xa0fo\xc3\xb3",$this->server->calculateUri($uri));
}
}
function testBaseUriCheck() {
$uris = array(
'http://www.example.org/root/somepath',
'/root/somepath',
'/root/somepath/'
);
try {
$this->server->setBaseUri('root/');
$this->server->calculateUri('/root/testuri');
$this->fail('Expected an exception');
} catch (Exception\Forbidden $e) {
// This was expected
}
}
/**
* @covers \Sabre\DAV\Server::guessBaseUri
*/
function testGuessBaseUri() {
$serverVars = array(
'REQUEST_URI' => '/index.php/root',
'PATH_INFO' => '/root',
);
$httpRequest = new HTTP\Request($serverVars);
$server = new Server();
$server->httpRequest = $httpRequest;
$this->assertEquals('/index.php/', $server->guessBaseUri());
}
/**
* @depends testGuessBaseUri
* @covers Sabre\DAV\Server::guessBaseUri
*/
function testGuessBaseUriPercentEncoding() {
$serverVars = array(
'REQUEST_URI' => '/index.php/dir/path2/path%20with%20spaces',
'PATH_INFO' => '/dir/path2/path with spaces',
);
$httpRequest = new HTTP\Request($serverVars);
$server = new Server();
$server->httpRequest = $httpRequest;
$this->assertEquals('/index.php/', $server->guessBaseUri());
}
/**
* @depends testGuessBaseUri
* @covers \Sabre\DAV\Server::guessBaseUri
*/
/*
function testGuessBaseUriPercentEncoding2() {
$this->markTestIncomplete('This behaviour is not yet implemented');
$serverVars = array(
'REQUEST_URI' => '/some%20directory+mixed/index.php/dir/path2/path%20with%20spaces',
'PATH_INFO' => '/dir/path2/path with spaces',
);
$httpRequest = new HTTP\Request($serverVars);
$server = new Server();
$server->httpRequest = $httpRequest;
$this->assertEquals('/some%20directory+mixed/index.php/', $server->guessBaseUri());
}*/
function testGuessBaseUri2() {
$serverVars = array(
'REQUEST_URI' => '/index.php/root/',
'PATH_INFO' => '/root/',
);
$httpRequest = new HTTP\Request($serverVars);
$server = new Server();
$server->httpRequest = $httpRequest;
$this->assertEquals('/index.php/', $server->guessBaseUri());
}
function testGuessBaseUriNoPathInfo() {
$serverVars = array(
'REQUEST_URI' => '/index.php/root',
);
$httpRequest = new HTTP\Request($serverVars);
$server = new Server();
$server->httpRequest = $httpRequest;
$this->assertEquals('/', $server->guessBaseUri());
}
function testGuessBaseUriNoPathInfo2() {
$serverVars = array(
'REQUEST_URI' => '/a/b/c/test.php',
);
$httpRequest = new HTTP\Request($serverVars);
$server = new Server();
$server->httpRequest = $httpRequest;
$this->assertEquals('/', $server->guessBaseUri());
}
/**
* @covers \Sabre\DAV\Server::guessBaseUri
* @depends testGuessBaseUri
*/
function testGuessBaseUriQueryString() {
$serverVars = array(
'REQUEST_URI' => '/index.php/root?query_string=blabla',
'PATH_INFO' => '/root',
);
$httpRequest = new HTTP\Request($serverVars);
$server = new Server();
$server->httpRequest = $httpRequest;
$this->assertEquals('/index.php/', $server->guessBaseUri());
}
/**
* @covers \Sabre\DAV\Server::guessBaseUri
* @depends testGuessBaseUri
* @expectedException \Sabre\DAV\Exception
*/
function testGuessBaseUriBadConfig() {
$serverVars = array(
'REQUEST_URI' => '/index.php/root/heyyy',
'PATH_INFO' => '/root',
);
$httpRequest = new HTTP\Request($serverVars);
$server = new Server();
$server->httpRequest = $httpRequest;
$server->guessBaseUri();
}
function testTriggerException() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'FOO',
);
$httpRequest = new HTTP\Request($serverVars);
$this->server->httpRequest = $httpRequest;
$this->server->subscribeEvent('beforeMethod',array($this,'exceptionTrigger'));
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/xml; charset=utf-8',
),$this->response->headers);
$this->assertEquals('HTTP/1.1 500 Internal Server Error',$this->response->status);
}
function exceptionTrigger() {
throw new Exception('Hola');
}
function testReportNotFound() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'REPORT',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->httpRequest->setBody('<?xml version="1.0"?><bla:myreport xmlns:bla="http://www.rooftopsolutions.nl/NS"></bla:myreport>');
$this->server->exec();
$this->assertEquals(array(
'Content-Type' => 'application/xml; charset=utf-8',
),
$this->response->headers
);
$this->assertEquals('HTTP/1.1 403 Forbidden',$this->response->status,'We got an incorrect status back. Full response body follows: ' . $this->response->body);
}
function testReportIntercepted() {
$serverVars = array(
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'REPORT',
);
$request = new HTTP\Request($serverVars);
$this->server->httpRequest = ($request);
$this->server->httpRequest->setBody('<?xml version="1.0"?><bla:myreport xmlns:bla="http://www.rooftopsolutions.nl/NS"></bla:myreport>');
$this->server->subscribeEvent('report',array($this,'reportHandler'));
$this->server->exec();
$this->assertEquals(array(
'testheader' => 'testvalue',
),
$this->response->headers
);
$this->assertEquals('HTTP/1.1 418 I\'m a teapot',$this->response->status,'We got an incorrect status back. Full response body follows: ' . $this->response->body);
}
function reportHandler($reportName) {
if ($reportName=='{http://www.rooftopsolutions.nl/NS}myreport') {
$this->server->httpResponse->sendStatus(418);
$this->server->httpResponse->setHeader('testheader','testvalue');
return false;
}
else return;
}
function testGetPropertiesForChildren() {
$result = $this->server->getPropertiesForChildren('',array(
'{DAV:}getcontentlength',
));
$expected = array(
'test.txt' => array('{DAV:}getcontentlength' => 13),
'dir/' => array(),
);
$this->assertEquals($expected,$result);
}
}