1<?php
2
3namespace Sabre\DAV;
4use Sabre\HTTP;
5
6require_once 'Sabre/HTTP/ResponseMock.php';
7require_once 'Sabre/DAV/AbstractServer.php';
8
9class ServerPropsTest extends AbstractServer {
10
11    protected function getRootNode() {
12
13        return new FSExt\Directory(SABRE_TEMPDIR);
14
15    }
16
17    function setUp() {
18
19        if (file_exists(SABRE_TEMPDIR.'../.sabredav')) unlink(SABRE_TEMPDIR.'../.sabredav');
20        parent::setUp();
21        file_put_contents(SABRE_TEMPDIR . '/test2.txt', 'Test contents2');
22        mkdir(SABRE_TEMPDIR . '/col');
23        file_put_contents(SABRE_TEMPDIR . 'col/test.txt', 'Test contents');
24        $this->server->addPlugin(new Locks\Plugin(new Locks\Backend\File(SABRE_TEMPDIR . '/.locksdb')));
25
26    }
27
28    function tearDown() {
29
30        parent::tearDown();
31        if (file_exists(SABRE_TEMPDIR.'../.locksdb')) unlink(SABRE_TEMPDIR.'../.locksdb');
32
33    }
34
35    private function sendRequest($body, $path = '/', $headers = ['Depth' => '0']) {
36
37        $request = new HTTP\Request('PROPFIND', $path, $headers, $body);
38
39        $this->server->httpRequest = $request;
40        $this->server->exec();
41
42    }
43
44    function testPropFindEmptyBody() {
45
46        $this->sendRequest("");
47        $this->assertEquals(207, $this->response->status);
48
49        $this->assertEquals(array(
50                'X-Sabre-Version' => [Version::VERSION],
51                'Content-Type' => ['application/xml; charset=utf-8'],
52                'DAV' => ['1, 3, extended-mkcol, 2'],
53                'Vary' => ['Brief,Prefer'],
54            ),
55            $this->response->getHeaders()
56         );
57
58        $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
59        $xml = simplexml_load_string($body);
60        $xml->registerXPathNamespace('d','urn:DAV');
61
62        list($data) = $xml->xpath('/d:multistatus/d:response/d:href');
63        $this->assertEquals('/',(string)$data,'href element should have been /');
64
65        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:resourcetype');
66        $this->assertEquals(1,count($data));
67
68    }
69
70    function testPropFindEmptyBodyFile() {
71
72        $this->sendRequest("", '/test2.txt', []);
73        $this->assertEquals(207, $this->response->status);
74
75        $this->assertEquals(array(
76                'X-Sabre-Version' => [Version::VERSION],
77                'Content-Type' => ['application/xml; charset=utf-8'],
78                'DAV' => ['1, 3, extended-mkcol, 2'],
79                'Vary' => ['Brief,Prefer'],
80            ),
81            $this->response->getHeaders()
82         );
83
84        $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
85        $xml = simplexml_load_string($body);
86        $xml->registerXPathNamespace('d','urn:DAV');
87
88        list($data) = $xml->xpath('/d:multistatus/d:response/d:href');
89        $this->assertEquals('/test2.txt',(string)$data,'href element should have been /');
90
91        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength');
92        $this->assertEquals(1,count($data));
93
94    }
95
96    function testSupportedLocks() {
97
98        $xml = '<?xml version="1.0"?>
99<d:propfind xmlns:d="DAV:">
100  <d:prop>
101    <d:supportedlock />
102  </d:prop>
103</d:propfind>';
104
105        $this->sendRequest($xml);
106
107        $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
108        $xml = simplexml_load_string($body);
109        $xml->registerXPathNamespace('d','urn:DAV');
110
111        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry');
112        $this->assertEquals(2,count($data),'We expected two \'d:lockentry\' tags');
113
114        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope');
115        $this->assertEquals(2,count($data),'We expected two \'d:lockscope\' tags');
116
117        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:locktype');
118        $this->assertEquals(2,count($data),'We expected two \'d:locktype\' tags');
119
120        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope/d:shared');
121        $this->assertEquals(1,count($data),'We expected a \'d:shared\' tag');
122
123        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:lockscope/d:exclusive');
124        $this->assertEquals(1,count($data),'We expected a \'d:exclusive\' tag');
125
126        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:supportedlock/d:lockentry/d:locktype/d:write');
127        $this->assertEquals(2,count($data),'We expected two \'d:write\' tags');
128    }
129
130    function testLockDiscovery() {
131
132        $xml = '<?xml version="1.0"?>
133<d:propfind xmlns:d="DAV:">
134  <d:prop>
135    <d:lockdiscovery />
136  </d:prop>
137</d:propfind>';
138
139        $this->sendRequest($xml);
140
141        $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
142        $xml = simplexml_load_string($body);
143        $xml->registerXPathNamespace('d','urn:DAV');
144
145        $data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:lockdiscovery');
146        $this->assertEquals(1,count($data),'We expected a \'d:lockdiscovery\' tag');
147
148    }
149
150    function testUnknownProperty() {
151
152        $xml = '<?xml version="1.0"?>
153<d:propfind xmlns:d="DAV:">
154  <d:prop>
155    <d:macaroni />
156  </d:prop>
157</d:propfind>';
158
159        $this->sendRequest($xml);
160        $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
161        $xml = simplexml_load_string($body);
162        $xml->registerXPathNamespace('d','urn:DAV');
163        $pathTests = array(
164            '/d:multistatus',
165            '/d:multistatus/d:response',
166            '/d:multistatus/d:response/d:propstat',
167            '/d:multistatus/d:response/d:propstat/d:status',
168            '/d:multistatus/d:response/d:propstat/d:prop',
169            '/d:multistatus/d:response/d:propstat/d:prop/d:macaroni',
170        );
171        foreach($pathTests as $test) {
172            $this->assertTrue(count($xml->xpath($test))==true,'We expected the ' . $test . ' element to appear in the response, we got: ' . $body);
173        }
174
175        $val = $xml->xpath('/d:multistatus/d:response/d:propstat/d:status');
176        $this->assertEquals(1,count($val),$body);
177        $this->assertEquals('HTTP/1.1 404 Not Found',(string)$val[0]);
178
179    }
180
181    function testParsePropPatchRequest() {
182
183        $body = '<?xml version="1.0"?>
184<d:propertyupdate xmlns:d="DAV:" xmlns:s="http://sabredav.org/NS/test">
185  <d:set><d:prop><s:someprop>somevalue</s:someprop></d:prop></d:set>
186  <d:remove><d:prop><s:someprop2 /></d:prop></d:remove>
187  <d:set><d:prop><s:someprop3>removeme</s:someprop3></d:prop></d:set>
188  <d:remove><d:prop><s:someprop3 /></d:prop></d:remove>
189</d:propertyupdate>';
190
191        $result = $this->server->xml->parse($body);
192        $this->assertEquals([
193            '{http://sabredav.org/NS/test}someprop' => 'somevalue',
194            '{http://sabredav.org/NS/test}someprop2' => null,
195            '{http://sabredav.org/NS/test}someprop3' => null,
196        ], $result->properties);
197
198    }
199
200}
201