1<?php
2
3namespace Sabre\DAV;
4
5use Sabre\HTTP;
6
7require_once 'Sabre/HTTP/ResponseMock.php';
8
9class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
10
11    /**
12     * @expectedException Sabre\DAV\Exception\PreconditionFailed
13     */
14    function testIfMatchNoNode() {
15
16        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
17        $server = new Server($root);
18        $httpRequest = new HTTP\Request('GET', '/bar', ['If-Match' => '*']);
19        $httpResponse = new HTTP\Response();
20        $server->checkPreconditions($httpRequest, $httpResponse);
21
22    }
23
24    /**
25     */
26    function testIfMatchHasNode() {
27
28        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
29        $server = new Server($root);
30        $httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '*']);
31        $httpResponse = new HTTP\Response();
32        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
33
34    }
35
36    /**
37     * @expectedException Sabre\DAV\Exception\PreconditionFailed
38     */
39    function testIfMatchWrongEtag() {
40
41        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
42        $server = new Server($root);
43        $httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '1234']);
44        $httpResponse = new HTTP\Response();
45        $server->checkPreconditions($httpRequest, $httpResponse);
46
47    }
48
49    /**
50     */
51    function testIfMatchCorrectEtag() {
52
53        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
54        $server = new Server($root);
55        $httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '"abc123"']);
56        $httpResponse = new HTTP\Response();
57        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
58
59    }
60
61    /**
62     * Evolution sometimes uses \" instead of " for If-Match headers.
63     *
64     * @depends testIfMatchCorrectEtag
65     */
66    function testIfMatchEvolutionEtag() {
67
68        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
69        $server = new Server($root);
70        $httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '\\"abc123\\"']);
71        $httpResponse = new HTTP\Response();
72        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
73
74    }
75
76    /**
77     */
78    function testIfMatchMultiple() {
79
80        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
81        $server = new Server($root);
82        $httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '"hellothere", "abc123"']);
83        $httpResponse = new HTTP\Response();
84        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
85
86    }
87
88    /**
89     */
90    function testIfNoneMatchNoNode() {
91
92        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
93        $server = new Server($root);
94        $httpRequest = new HTTP\Request('GET', '/bar', ['If-None-Match' => '*']);
95        $httpResponse = new HTTP\Response();
96        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
97
98    }
99
100    /**
101     * @expectedException Sabre\DAV\Exception\PreconditionFailed
102     */
103    function testIfNoneMatchHasNode() {
104
105        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
106        $server = new Server($root);
107        $httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '*']);
108        $httpResponse = new HTTP\Response();
109        $server->checkPreconditions($httpRequest, $httpResponse);
110
111    }
112
113    /**
114     */
115    function testIfNoneMatchWrongEtag() {
116
117        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
118        $server = new Server($root);
119        $httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '"1234"']);
120        $httpResponse = new HTTP\Response();
121        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
122
123    }
124
125    /**
126     */
127    function testIfNoneMatchWrongEtagMultiple() {
128
129        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
130        $server = new Server($root);
131        $httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '"1234", "5678"']);
132        $httpResponse = new HTTP\Response();
133        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
134
135    }
136
137    /**
138     * @expectedException Sabre\DAV\Exception\PreconditionFailed
139     */
140    public function testIfNoneMatchCorrectEtag() {
141
142        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
143        $server = new Server($root);
144        $httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '"abc123"']);
145        $httpResponse = new HTTP\Response();
146        $server->checkPreconditions($httpRequest, $httpResponse);
147
148    }
149
150    /**
151     * @expectedException Sabre\DAV\Exception\PreconditionFailed
152     */
153    public function testIfNoneMatchCorrectEtagMultiple() {
154
155        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
156        $server = new Server($root);
157        $httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '"1234, "abc123"']);
158        $httpResponse = new HTTP\Response();
159        $server->checkPreconditions($httpRequest, $httpResponse);
160
161    }
162
163    /**
164     */
165    public function testIfNoneMatchCorrectEtagAsGet() {
166
167        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
168        $server = new Server($root);
169        $httpRequest = new HTTP\Request('GET', '/foo', ['If-None-Match' => '"abc123"']);
170        $server->httpResponse = new HTTP\ResponseMock();
171
172        $this->assertFalse($server->checkPreconditions($httpRequest, $server->httpResponse));
173        $this->assertEquals(304, $server->httpResponse->getStatus());
174        $this->assertEquals(['ETag' => ['"abc123"']], $server->httpResponse->getHeaders());
175
176    }
177
178    /**
179     * This was a test written for issue #515.
180     */
181    public function testNoneMatchCorrectEtagEnsureSapiSent() {
182
183        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
184        $server = new Server($root);
185        $server->sapi = new HTTP\SapiMock();
186        HTTP\SapiMock::$sent = 0;
187        $httpRequest = new HTTP\Request('GET', '/foo', ['If-None-Match' => '"abc123"']);
188        $server->httpRequest = $httpRequest;
189        $server->httpResponse = new HTTP\ResponseMock();
190
191        $server->exec();
192
193        $this->assertFalse($server->checkPreconditions($httpRequest, $server->httpResponse));
194        $this->assertEquals(304, $server->httpResponse->getStatus());
195        $this->assertEquals([
196            'ETag' => ['"abc123"'],
197            'X-Sabre-Version' => [Version::VERSION],
198        ], $server->httpResponse->getHeaders());
199        $this->assertEquals(1, HTTP\SapiMock::$sent);
200
201    }
202
203    /**
204     */
205    public function testIfModifiedSinceUnModified() {
206
207        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
208        $server = new Server($root);
209        $httpRequest = HTTP\Sapi::createFromServerArray(array(
210            'HTTP_IF_MODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 GMT',
211            'REQUEST_URI'   => '/foo'
212        ));
213        $server->httpResponse = new HTTP\ResponseMock();
214        $this->assertFalse($server->checkPreconditions($httpRequest, $server->httpResponse));
215
216        $this->assertEquals(304, $server->httpResponse->status);
217        $this->assertEquals(array(
218            'Last-Modified' => ['Sat, 06 Apr 1985 23:30:00 GMT'],
219        ), $server->httpResponse->getHeaders());
220
221    }
222
223
224    /**
225     */
226    public function testIfModifiedSinceModified() {
227
228        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
229        $server = new Server($root);
230        $httpRequest = HTTP\Sapi::createFromServerArray(array(
231            'HTTP_IF_MODIFIED_SINCE' => 'Tue, 06 Nov 1984 08:49:37 GMT',
232            'REQUEST_URI'   => '/foo'
233        ));
234
235        $httpRequest = $httpRequest;
236        $httpResponse = new HTTP\ResponseMock();
237        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
238
239    }
240
241    /**
242     */
243    public function testIfModifiedSinceInvalidDate() {
244
245        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
246        $server = new Server($root);
247        $httpRequest = HTTP\Sapi::createFromServerArray(array(
248            'HTTP_IF_MODIFIED_SINCE' => 'Your mother',
249            'REQUEST_URI'   => '/foo'
250        ));
251        $httpRequest = $httpRequest;
252        $httpResponse = new HTTP\ResponseMock();
253
254        // Invalid dates must be ignored, so this should return true
255        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
256
257    }
258
259    /**
260     */
261    public function testIfModifiedSinceInvalidDate2() {
262
263        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
264        $server = new Server($root);
265        $httpRequest = HTTP\Sapi::createFromServerArray(array(
266            'HTTP_IF_MODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 EST',
267            'REQUEST_URI'   => '/foo'
268        ));
269        $httpResponse = new HTTP\ResponseMock();
270        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
271
272    }
273
274
275    /**
276     */
277    public function testIfUnmodifiedSinceUnModified() {
278
279        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
280        $server = new Server($root);
281        $httpRequest = HTTP\Sapi::createFromServerArray(array(
282            'HTTP_IF_UNMODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 GMT',
283            'REQUEST_URI'   => '/foo'
284        ));
285        $httpResponse = new HTTP\Response();
286        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
287
288    }
289
290
291    /**
292     * @expectedException Sabre\DAV\Exception\PreconditionFailed
293     */
294    public function testIfUnmodifiedSinceModified() {
295
296        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
297        $server = new Server($root);
298        $httpRequest = HTTP\Sapi::createFromServerArray(array(
299            'HTTP_IF_UNMODIFIED_SINCE' => 'Tue, 06 Nov 1984 08:49:37 GMT',
300            'REQUEST_URI'   => '/foo'
301        ));
302        $httpResponse = new HTTP\ResponseMock();
303        $server->checkPreconditions($httpRequest, $httpResponse);
304
305    }
306
307    /**
308     */
309    public function testIfUnmodifiedSinceInvalidDate() {
310
311        $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
312        $server = new Server($root);
313        $httpRequest = HTTP\Sapi::createFromServerArray(array(
314            'HTTP_IF_UNMODIFIED_SINCE' => 'Sun, 06 Nov 1984 08:49:37 CET',
315            'REQUEST_URI'   => '/foo'
316        ));
317        $httpResponse = new HTTP\ResponseMock();
318        $this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
319
320    }
321
322
323}
324
325class ServerPreconditionsNode extends File {
326
327    function getETag() {
328
329        return '"abc123"';
330
331    }
332
333    function getLastModified() {
334
335        /* my birthday & time, I believe */
336        return strtotime('1985-04-07 01:30 +02:00');
337
338    }
339
340    function getName() {
341
342        return 'foo';
343
344    }
345
346}
347