]> git.mxchange.org Git - friendica-addons.git/blob - dav/SabreDAV/tests/Sabre/DAV/Locks/PluginTest.php
Merge remote branch 'upstream/master'
[friendica-addons.git] / dav / SabreDAV / tests / Sabre / DAV / Locks / PluginTest.php
1 <?php
2
3 require_once 'Sabre/DAV/AbstractServer.php';
4
5 class Sabre_DAV_Locks_PluginTest extends Sabre_DAV_AbstractServer {
6
7     /**
8      * @var Sabre_DAV_Locks_Plugin
9      */
10     protected $locksPlugin;
11
12     function setUp() {
13
14         parent::setUp();
15         $locksBackend = new Sabre_DAV_Locks_Backend_File(SABRE_TEMPDIR . '/locksdb');
16         $locksPlugin = new Sabre_DAV_Locks_Plugin($locksBackend);
17         $this->server->addPlugin($locksPlugin);
18         $this->locksPlugin = $locksPlugin;
19
20     }
21
22     function testGetFeatures() {
23
24         $this->assertEquals(array(2),$this->locksPlugin->getFeatures());
25
26     }
27
28     function testGetHTTPMethods() {
29
30         $this->assertEquals(array('LOCK','UNLOCK'),$this->locksPlugin->getHTTPMethods(''));
31
32     }
33
34     function testGetHTTPMethodsNoBackend() {
35
36         $locksPlugin = new Sabre_DAV_Locks_Plugin();
37         $this->server->addPlugin($locksPlugin);
38         $this->assertEquals(array(),$locksPlugin->getHTTPMethods(''));
39
40     }
41
42     function testUnknownMethodPassthough() {
43
44         $this->assertNull($this->locksPlugin->unknownMethod('BLA','/'));
45
46     }
47
48     function testLockNoBody() {
49
50         $serverVars = array(
51             'REQUEST_URI'    => '/test.txt',
52             'REQUEST_METHOD' => 'LOCK',
53         );
54
55         $request = new Sabre_HTTP_Request($serverVars);
56         $request->setBody('');
57         $this->server->httpRequest = ($request);
58         $this->server->exec();
59
60         $this->assertEquals(array(
61             'Content-Type' => 'application/xml; charset=utf-8',
62             ),
63             $this->response->headers
64          );
65
66         $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status);
67
68     }
69
70     function testLock() {
71
72         $serverVars = array(
73             'REQUEST_URI'    => '/test.txt',
74             'REQUEST_METHOD' => 'LOCK',
75         );
76
77         $request = new Sabre_HTTP_Request($serverVars);
78         $request->setBody('<?xml version="1.0"?>
79 <D:lockinfo xmlns:D="DAV:">
80     <D:lockscope><D:exclusive/></D:lockscope>
81     <D:locktype><D:write/></D:locktype>
82     <D:owner>
83         <D:href>http://example.org/~ejw/contact.html</D:href>
84     </D:owner>
85 </D:lockinfo>');
86
87         $this->server->httpRequest = $request;
88         $this->server->exec();
89
90         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
91         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
92
93         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'Got an incorrect status back. Response body: ' . $this->response->body);
94
95         $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"DAV:\"",$this->response->body);
96         $xml = simplexml_load_string($body);
97         $xml->registerXPathNamespace('d','DAV:');
98
99         $elements = array(
100             '/d:prop',
101             '/d:prop/d:lockdiscovery',
102             '/d:prop/d:lockdiscovery/d:activelock',
103             '/d:prop/d:lockdiscovery/d:activelock/d:locktype',
104             '/d:prop/d:lockdiscovery/d:activelock/d:lockroot',
105             '/d:prop/d:lockdiscovery/d:activelock/d:lockroot/d:href',
106             '/d:prop/d:lockdiscovery/d:activelock/d:locktype/d:write',
107             '/d:prop/d:lockdiscovery/d:activelock/d:lockscope',
108             '/d:prop/d:lockdiscovery/d:activelock/d:lockscope/d:exclusive',
109             '/d:prop/d:lockdiscovery/d:activelock/d:depth',
110             '/d:prop/d:lockdiscovery/d:activelock/d:owner',
111             '/d:prop/d:lockdiscovery/d:activelock/d:timeout',
112             '/d:prop/d:lockdiscovery/d:activelock/d:locktoken',
113             '/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href',
114         );
115
116         foreach($elements as $elem) {
117             $data = $xml->xpath($elem);
118             $this->assertEquals(1,count($data),'We expected 1 match for the xpath expression "' . $elem . '". ' . count($data) . ' were found. Full response body: ' . $this->response->body);
119         }
120
121         $depth = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:depth');
122         $this->assertEquals('infinity',(string)$depth[0]);
123
124         $token = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href');
125         $this->assertEquals($this->response->headers['Lock-Token'],'<' . (string)$token[0] . '>','Token in response body didn\'t match token in response header.');
126
127     }
128
129     /**
130      * @depends testLock
131      */
132     function testDoubleLock() {
133
134         $serverVars = array(
135             'REQUEST_URI'    => '/test.txt',
136             'REQUEST_METHOD' => 'LOCK',
137         );
138
139         $request = new Sabre_HTTP_Request($serverVars);
140         $request->setBody('<?xml version="1.0"?>
141 <D:lockinfo xmlns:D="DAV:">
142     <D:lockscope><D:exclusive/></D:lockscope>
143     <D:locktype><D:write/></D:locktype>
144     <D:owner>
145         <D:href>http://example.org/~ejw/contact.html</D:href>
146     </D:owner>
147 </D:lockinfo>');
148
149         $this->server->httpRequest = $request;
150         $this->server->exec();
151
152         $this->response = new Sabre_HTTP_ResponseMock();
153         $this->server->httpResponse = $this->response;
154
155         $this->server->exec();
156
157         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
158
159         $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status);
160
161     }
162
163     /**
164      * @depends testLock
165      */
166     function testLockRefresh() {
167
168         $serverVars = array(
169             'REQUEST_URI'    => '/test.txt',
170             'REQUEST_METHOD' => 'LOCK',
171         );
172
173         $request = new Sabre_HTTP_Request($serverVars);
174         $request->setBody('<?xml version="1.0"?>
175 <D:lockinfo xmlns:D="DAV:">
176     <D:lockscope><D:exclusive/></D:lockscope>
177     <D:locktype><D:write/></D:locktype>
178     <D:owner>
179         <D:href>http://example.org/~ejw/contact.html</D:href>
180     </D:owner>
181 </D:lockinfo>');
182
183         $this->server->httpRequest = $request;
184         $this->server->exec();
185
186         $lockToken = $this->response->headers['Lock-Token'];
187
188         $this->response = new Sabre_HTTP_ResponseMock();
189         $this->server->httpResponse = $this->response;
190
191         $serverVars = array(
192             'REQUEST_URI' => '/test.txt',
193             'REQUEST_METHOD' => 'LOCK',
194             'HTTP_IF' => '(' . $lockToken . ')',
195         );
196         $request = new Sabre_HTTP_Request($serverVars);
197         $request->setBody('');
198         $this->server->httpRequest = $request;
199
200         $this->server->exec();
201
202         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
203
204         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status,'We received an incorrect status code. Full response body: ' . $this->response->body);
205
206     }
207
208     /**
209      * @depends testLock
210      */
211     function testLockNoFile() {
212
213         $serverVars = array(
214             'REQUEST_URI'    => '/notfound.txt',
215             'REQUEST_METHOD' => 'LOCK',
216         );
217
218         $request = new Sabre_HTTP_Request($serverVars);
219         $request->setBody('<?xml version="1.0"?>
220 <D:lockinfo xmlns:D="DAV:">
221     <D:lockscope><D:exclusive/></D:lockscope>
222     <D:locktype><D:write/></D:locktype>
223     <D:owner>
224         <D:href>http://example.org/~ejw/contact.html</D:href>
225     </D:owner>
226 </D:lockinfo>');
227
228         $this->server->httpRequest = $request;
229         $this->server->exec();
230
231         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
232         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
233
234         $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
235
236     }
237
238     /**
239      * @depends testLock
240      */
241     function testUnlockNoToken() {
242
243         $serverVars = array(
244             'REQUEST_URI'    => '/test.txt',
245             'REQUEST_METHOD' => 'UNLOCK',
246         );
247
248         $request = new Sabre_HTTP_Request($serverVars);
249         $this->server->httpRequest = ($request);
250         $this->server->exec();
251
252         $this->assertEquals(array(
253             'Content-Type' => 'application/xml; charset=utf-8',
254             ),
255             $this->response->headers
256          );
257
258         $this->assertEquals('HTTP/1.1 400 Bad request',$this->response->status);
259
260     }
261
262     /**
263      * @depends testLock
264      */
265     function testUnlockBadToken() {
266
267         $serverVars = array(
268             'REQUEST_URI'     => '/test.txt',
269             'REQUEST_METHOD'  => 'UNLOCK',
270             'HTTP_LOCK_TOKEN' => '<opaquelocktoken:blablabla>',
271         );
272
273         $request = new Sabre_HTTP_Request($serverVars);
274         $this->server->httpRequest = ($request);
275         $this->server->exec();
276
277         $this->assertEquals(array(
278             'Content-Type' => 'application/xml; charset=utf-8',
279             ),
280             $this->response->headers
281          );
282
283         $this->assertEquals('HTTP/1.1 409 Conflict',$this->response->status,'Got an incorrect status code. Full response body: ' . $this->response->body);
284
285     }
286
287     /**
288      * @depends testLock
289      */
290     function testLockPutNoToken() {
291
292         $serverVars = array(
293             'REQUEST_URI'    => '/test.txt',
294             'REQUEST_METHOD' => 'LOCK',
295         );
296
297         $request = new Sabre_HTTP_Request($serverVars);
298         $request->setBody('<?xml version="1.0"?>
299 <D:lockinfo xmlns:D="DAV:">
300     <D:lockscope><D:exclusive/></D:lockscope>
301     <D:locktype><D:write/></D:locktype>
302     <D:owner>
303         <D:href>http://example.org/~ejw/contact.html</D:href>
304     </D:owner>
305 </D:lockinfo>');
306
307         $this->server->httpRequest = $request;
308         $this->server->exec();
309
310         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
311         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
312
313         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
314
315         $serverVars = array(
316             'REQUEST_URI'    => '/test.txt',
317             'REQUEST_METHOD' => 'PUT',
318         );
319
320         $request = new Sabre_HTTP_Request($serverVars);
321         $request->setBody('newbody');
322         $this->server->httpRequest = $request;
323         $this->server->exec();
324
325         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
326         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
327
328         $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status);
329
330     }
331
332     /**
333      * @depends testLock
334      */
335     function testUnlock() {
336
337         $request = new Sabre_HTTP_Request(array());
338         $this->server->httpRequest = $request;
339
340         $request->setBody('<?xml version="1.0"?>
341 <D:lockinfo xmlns:D="DAV:">
342     <D:lockscope><D:exclusive/></D:lockscope>
343     <D:locktype><D:write/></D:locktype>
344     <D:owner>
345         <D:href>http://example.org/~ejw/contact.html</D:href>
346     </D:owner>
347 </D:lockinfo>');
348
349         $this->server->invokeMethod('LOCK','test.txt');
350         $lockToken = $this->server->httpResponse->headers['Lock-Token'];
351
352         $serverVars = array(
353             'HTTP_LOCK_TOKEN' => $lockToken,
354         );
355
356         $request = new Sabre_HTTP_Request($serverVars);
357         $this->server->httpRequest = ($request);
358         $this->server->httpResponse = new Sabre_HTTP_ResponseMock();
359         $this->server->invokeMethod('UNLOCK', 'test.txt');
360
361         $this->assertEquals('HTTP/1.1 204 No Content',$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body);
362         $this->assertEquals(array(
363             'Content-Length' => '0',
364             ),
365             $this->server->httpResponse->headers
366          );
367
368
369     }
370
371     /**
372      * @depends testLock
373      */
374     function testUnlockWindowsBug() {
375
376         $request = new Sabre_HTTP_Request(array());
377         $this->server->httpRequest = $request;
378
379         $request->setBody('<?xml version="1.0"?>
380 <D:lockinfo xmlns:D="DAV:">
381     <D:lockscope><D:exclusive/></D:lockscope>
382     <D:locktype><D:write/></D:locktype>
383     <D:owner>
384         <D:href>http://example.org/~ejw/contact.html</D:href>
385     </D:owner>
386 </D:lockinfo>');
387
388         $this->server->invokeMethod('LOCK','test.txt');
389         $lockToken = $this->server->httpResponse->headers['Lock-Token'];
390
391         // See Issue 123
392         $lockToken = trim($lockToken,'<>');
393
394         $serverVars = array(
395             'HTTP_LOCK_TOKEN' => $lockToken,
396         );
397
398         $request = new Sabre_HTTP_Request($serverVars);
399         $this->server->httpRequest = ($request);
400         $this->server->httpResponse = new Sabre_HTTP_ResponseMock();
401         $this->server->invokeMethod('UNLOCK', 'test.txt');
402
403         $this->assertEquals('HTTP/1.1 204 No Content',$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body);
404         $this->assertEquals(array(
405             'Content-Length' => '0',
406             ),
407             $this->server->httpResponse->headers
408          );
409
410
411     }
412
413     /**
414      * @depends testLock
415      */
416     function testLockRetainOwner() {
417
418         $request = new Sabre_HTTP_Request(array());
419         $this->server->httpRequest = $request;
420
421         $request->setBody('<?xml version="1.0"?>
422 <D:lockinfo xmlns:D="DAV:">
423     <D:lockscope><D:exclusive/></D:lockscope>
424     <D:locktype><D:write/></D:locktype>
425     <D:owner>Evert</D:owner>
426 </D:lockinfo>');
427
428         $this->server->invokeMethod('LOCK','test.txt');
429         $lockToken = $this->server->httpResponse->headers['Lock-Token'];
430
431         $locks = $this->locksPlugin->getLocks('test.txt');
432         $this->assertEquals(1,count($locks));
433         $this->assertEquals('Evert',$locks[0]->owner);
434
435
436     }
437
438     /**
439      * @depends testLock
440      */
441     function testLockPutBadToken() {
442
443         $serverVars = array(
444             'REQUEST_URI'    => '/test.txt',
445             'REQUEST_METHOD' => 'LOCK',
446         );
447
448         $request = new Sabre_HTTP_Request($serverVars);
449         $request->setBody('<?xml version="1.0"?>
450 <D:lockinfo xmlns:D="DAV:">
451     <D:lockscope><D:exclusive/></D:lockscope>
452     <D:locktype><D:write/></D:locktype>
453     <D:owner>
454         <D:href>http://example.org/~ejw/contact.html</D:href>
455     </D:owner>
456 </D:lockinfo>');
457
458         $this->server->httpRequest = $request;
459         $this->server->exec();
460
461         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
462         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
463
464         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
465
466         $serverVars = array(
467             'REQUEST_URI'    => '/test.txt',
468             'REQUEST_METHOD' => 'PUT',
469             'HTTP_IF' => '(<opaquelocktoken:token1>)',
470         );
471
472         $request = new Sabre_HTTP_Request($serverVars);
473         $request->setBody('newbody');
474         $this->server->httpRequest = $request;
475         $this->server->exec();
476
477         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
478         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
479
480         $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status);
481
482     }
483
484     /**
485      * @depends testLock
486      */
487     function testLockDeleteParent() {
488
489         $serverVars = array(
490             'REQUEST_URI'    => '/dir/child.txt',
491             'REQUEST_METHOD' => 'LOCK',
492         );
493
494         $request = new Sabre_HTTP_Request($serverVars);
495         $request->setBody('<?xml version="1.0"?>
496 <D:lockinfo xmlns:D="DAV:">
497     <D:lockscope><D:exclusive/></D:lockscope>
498     <D:locktype><D:write/></D:locktype>
499     <D:owner>
500         <D:href>http://example.org/~ejw/contact.html</D:href>
501     </D:owner>
502 </D:lockinfo>');
503
504         $this->server->httpRequest = $request;
505         $this->server->exec();
506
507         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
508         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
509
510         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
511
512         $serverVars = array(
513             'REQUEST_URI'    => '/dir',
514             'REQUEST_METHOD' => 'DELETE',
515         );
516
517         $request = new Sabre_HTTP_Request($serverVars);
518         $this->server->httpRequest = $request;
519         $this->server->exec();
520
521         $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status);
522         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
523
524     }
525     /**
526      * @depends testLock
527      */
528     function testLockDeleteSucceed() {
529
530         $serverVars = array(
531             'REQUEST_URI'    => '/dir/child.txt',
532             'REQUEST_METHOD' => 'LOCK',
533         );
534
535         $request = new Sabre_HTTP_Request($serverVars);
536         $request->setBody('<?xml version="1.0"?>
537 <D:lockinfo xmlns:D="DAV:">
538     <D:lockscope><D:exclusive/></D:lockscope>
539     <D:locktype><D:write/></D:locktype>
540     <D:owner>
541         <D:href>http://example.org/~ejw/contact.html</D:href>
542     </D:owner>
543 </D:lockinfo>');
544
545         $this->server->httpRequest = $request;
546         $this->server->exec();
547
548         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
549         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
550
551         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
552
553         $serverVars = array(
554             'REQUEST_URI'    => '/dir/child.txt',
555             'REQUEST_METHOD' => 'DELETE',
556             'HTTP_IF' => '(' . $this->response->headers['Lock-Token'] . ')',
557         );
558
559         $request = new Sabre_HTTP_Request($serverVars);
560         $this->server->httpRequest = $request;
561         $this->server->exec();
562
563         $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
564         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
565
566     }
567
568     /**
569      * @depends testLock
570      */
571     function testLockCopyLockSource() {
572
573         $serverVars = array(
574             'REQUEST_URI'    => '/dir/child.txt',
575             'REQUEST_METHOD' => 'LOCK',
576         );
577
578         $request = new Sabre_HTTP_Request($serverVars);
579         $request->setBody('<?xml version="1.0"?>
580 <D:lockinfo xmlns:D="DAV:">
581     <D:lockscope><D:exclusive/></D:lockscope>
582     <D:locktype><D:write/></D:locktype>
583     <D:owner>
584         <D:href>http://example.org/~ejw/contact.html</D:href>
585     </D:owner>
586 </D:lockinfo>');
587
588         $this->server->httpRequest = $request;
589         $this->server->exec();
590
591         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
592         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
593
594         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
595
596         $serverVars = array(
597             'REQUEST_URI'    => '/dir/child.txt',
598             'REQUEST_METHOD' => 'COPY',
599             'HTTP_DESTINATION' => '/dir/child2.txt',
600         );
601
602         $request = new Sabre_HTTP_Request($serverVars);
603         $this->server->httpRequest = $request;
604         $this->server->exec();
605
606         $this->assertEquals('HTTP/1.1 201 Created',$this->response->status,'Copy must succeed if only the source is locked, but not the destination');
607         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
608
609     }
610     /**
611      * @depends testLock
612      */
613     function testLockCopyLockDestination() {
614
615         $serverVars = array(
616             'REQUEST_URI'    => '/dir/child2.txt',
617             'REQUEST_METHOD' => 'LOCK',
618         );
619
620         $request = new Sabre_HTTP_Request($serverVars);
621         $request->setBody('<?xml version="1.0"?>
622 <D:lockinfo xmlns:D="DAV:">
623     <D:lockscope><D:exclusive/></D:lockscope>
624     <D:locktype><D:write/></D:locktype>
625     <D:owner>
626         <D:href>http://example.org/~ejw/contact.html</D:href>
627     </D:owner>
628 </D:lockinfo>');
629
630         $this->server->httpRequest = $request;
631         $this->server->exec();
632
633         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
634         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
635
636         $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
637
638         $serverVars = array(
639             'REQUEST_URI'    => '/dir/child.txt',
640             'REQUEST_METHOD' => 'COPY',
641             'HTTP_DESTINATION' => '/dir/child2.txt',
642         );
643
644         $request = new Sabre_HTTP_Request($serverVars);
645         $this->server->httpRequest = $request;
646         $this->server->exec();
647
648         $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination');
649         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
650
651     }
652
653     /**
654      * @depends testLock
655      */
656     function testLockMoveLockSourceLocked() {
657
658         $serverVars = array(
659             'REQUEST_URI'    => '/dir/child.txt',
660             'REQUEST_METHOD' => 'LOCK',
661         );
662
663         $request = new Sabre_HTTP_Request($serverVars);
664         $request->setBody('<?xml version="1.0"?>
665 <D:lockinfo xmlns:D="DAV:">
666     <D:lockscope><D:exclusive/></D:lockscope>
667     <D:locktype><D:write/></D:locktype>
668     <D:owner>
669         <D:href>http://example.org/~ejw/contact.html</D:href>
670     </D:owner>
671 </D:lockinfo>');
672
673         $this->server->httpRequest = $request;
674         $this->server->exec();
675
676         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
677         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
678
679         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
680
681         $serverVars = array(
682             'REQUEST_URI'    => '/dir/child.txt',
683             'REQUEST_METHOD' => 'MOVE',
684             'HTTP_DESTINATION' => '/dir/child2.txt',
685         );
686
687         $request = new Sabre_HTTP_Request($serverVars);
688         $this->server->httpRequest = $request;
689         $this->server->exec();
690
691         $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination');
692         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
693
694     }
695
696     /**
697      * @depends testLock
698      */
699     function testLockMoveLockSourceSucceed() {
700
701         $serverVars = array(
702             'REQUEST_URI'    => '/dir/child.txt',
703             'REQUEST_METHOD' => 'LOCK',
704         );
705
706         $request = new Sabre_HTTP_Request($serverVars);
707         $request->setBody('<?xml version="1.0"?>
708 <D:lockinfo xmlns:D="DAV:">
709     <D:lockscope><D:exclusive/></D:lockscope>
710     <D:locktype><D:write/></D:locktype>
711     <D:owner>
712         <D:href>http://example.org/~ejw/contact.html</D:href>
713     </D:owner>
714 </D:lockinfo>');
715
716         $this->server->httpRequest = $request;
717         $this->server->exec();
718
719         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
720         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
721
722         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
723
724         $serverVars = array(
725             'REQUEST_URI'    => '/dir/child.txt',
726             'REQUEST_METHOD' => 'MOVE',
727             'HTTP_DESTINATION' => '/dir/child2.txt',
728             'HTTP_IF' => '(' . $this->response->headers['Lock-Token'] . ')',
729         );
730
731         $request = new Sabre_HTTP_Request($serverVars);
732         $this->server->httpRequest = $request;
733         $this->server->exec();
734
735         $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);
736
737     }
738
739     /**
740      * @depends testLock
741      */
742     function testLockMoveLockDestination() {
743
744         $serverVars = array(
745             'REQUEST_URI'    => '/dir/child2.txt',
746             'REQUEST_METHOD' => 'LOCK',
747         );
748
749         $request = new Sabre_HTTP_Request($serverVars);
750         $request->setBody('<?xml version="1.0"?>
751 <D:lockinfo xmlns:D="DAV:">
752     <D:lockscope><D:exclusive/></D:lockscope>
753     <D:locktype><D:write/></D:locktype>
754     <D:owner>
755         <D:href>http://example.org/~ejw/contact.html</D:href>
756     </D:owner>
757 </D:lockinfo>');
758
759         $this->server->httpRequest = $request;
760         $this->server->exec();
761
762         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
763         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
764
765         $this->assertEquals('HTTP/1.1 201 Created',$this->response->status);
766
767         $serverVars = array(
768             'REQUEST_URI'    => '/dir/child.txt',
769             'REQUEST_METHOD' => 'MOVE',
770             'HTTP_DESTINATION' => '/dir/child2.txt',
771         );
772
773         $request = new Sabre_HTTP_Request($serverVars);
774         $this->server->httpRequest = $request;
775         $this->server->exec();
776
777         $this->assertEquals('HTTP/1.1 423 Locked',$this->response->status,'Copy must succeed if only the source is locked, but not the destination');
778         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
779
780     }
781     /**
782      * @depends testLock
783      */
784     function testLockMoveLockParent() {
785
786         $serverVars = array(
787             'REQUEST_URI'    => '/dir',
788             'REQUEST_METHOD' => 'LOCK',
789             'HTTP_DEPTH' => 'infinite',
790         );
791
792         $request = new Sabre_HTTP_Request($serverVars);
793         $request->setBody('<?xml version="1.0"?>
794 <D:lockinfo xmlns:D="DAV:">
795     <D:lockscope><D:exclusive/></D:lockscope>
796     <D:locktype><D:write/></D:locktype>
797     <D:owner>
798         <D:href>http://example.org/~ejw/contact.html</D:href>
799     </D:owner>
800 </D:lockinfo>');
801
802         $this->server->httpRequest = $request;
803         $this->server->exec();
804
805         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
806         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
807
808         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
809
810         $serverVars = array(
811             'REQUEST_URI'    => '/dir/child.txt',
812             'REQUEST_METHOD' => 'MOVE',
813             'HTTP_DESTINATION' => '/dir/child2.txt',
814             'HTTP_IF' => '</dir> (' . $this->response->headers['Lock-Token'] . ')',
815         );
816
817         $request = new Sabre_HTTP_Request($serverVars);
818         $this->server->httpRequest = $request;
819         $this->server->exec();
820
821         $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.');
822         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
823
824     }
825
826     /**
827      * @depends testLock
828      */
829     function testLockPutGoodToken() {
830
831         $serverVars = array(
832             'REQUEST_URI'    => '/test.txt',
833             'REQUEST_METHOD' => 'LOCK',
834         );
835
836         $request = new Sabre_HTTP_Request($serverVars);
837         $request->setBody('<?xml version="1.0"?>
838 <D:lockinfo xmlns:D="DAV:">
839     <D:lockscope><D:exclusive/></D:lockscope>
840     <D:locktype><D:write/></D:locktype>
841     <D:owner>
842         <D:href>http://example.org/~ejw/contact.html</D:href>
843     </D:owner>
844 </D:lockinfo>');
845
846         $this->server->httpRequest = $request;
847         $this->server->exec();
848
849         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
850         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
851
852         $this->assertEquals('HTTP/1.1 200 OK',$this->response->status);
853
854         $serverVars = array(
855             'REQUEST_URI'    => '/test.txt',
856             'REQUEST_METHOD' => 'PUT',
857             'HTTP_IF' => '('.$this->response->headers['Lock-Token'].')',
858         );
859
860         $request = new Sabre_HTTP_Request($serverVars);
861         $request->setBody('newbody');
862         $this->server->httpRequest = $request;
863         $this->server->exec();
864
865         $this->assertEquals('application/xml; charset=utf-8',$this->response->headers['Content-Type']);
866         $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->headers['Lock-Token'])===1,'We did not get a valid Locktoken back (' . $this->response->headers['Lock-Token'] . ')');
867
868         $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status);
869
870     }
871
872     function testPutWithIncorrectETag() {
873
874         $serverVars = array(
875             'REQUEST_URI'    => '/test.txt',
876             'REQUEST_METHOD' => 'PUT',
877             'HTTP_IF' => '(["etag1"])',
878         );
879
880         $request = new Sabre_HTTP_Request($serverVars);
881         $request->setBody('newbody');
882         $this->server->httpRequest = $request;
883         $this->server->exec();
884         $this->assertEquals('HTTP/1.1 412 Precondition failed',$this->response->status);
885
886     }
887
888     /**
889      * @depends testPutWithIncorrectETag
890      */
891     function testPutWithCorrectETag() {
892
893         // We need an etag-enabled file node.
894         $tree = new Sabre_DAV_ObjectTree(new Sabre_DAV_FSExt_Directory(SABRE_TEMPDIR));
895         $this->server->tree = $tree;
896
897         $etag = md5(file_get_contents(SABRE_TEMPDIR . '/test.txt'));
898         $serverVars = array(
899             'REQUEST_URI'    => '/test.txt',
900             'REQUEST_METHOD' => 'PUT',
901             'HTTP_IF' => '(["'.$etag.'"])',
902         );
903
904         $request = new Sabre_HTTP_Request($serverVars);
905         $request->setBody('newbody');
906         $this->server->httpRequest = $request;
907         $this->server->exec();
908         $this->assertEquals('HTTP/1.1 204 No Content',$this->response->status, 'Incorrect status received. Full response body:' . $this->response->body);
909
910     }
911
912     function testGetTimeoutHeader() {
913
914         $request = new Sabre_HTTP_Request(array(
915             'HTTP_TIMEOUT' => 'second-100',
916         ));
917
918         $this->server->httpRequest = $request;
919         $this->assertEquals(100, $this->locksPlugin->getTimeoutHeader());
920
921     }
922
923
924     function testGetTimeoutHeaderNotSet() {
925
926         $request = new Sabre_HTTP_Request(array(
927         ));
928
929         $this->server->httpRequest = $request;
930         $this->assertEquals(0, $this->locksPlugin->getTimeoutHeader());
931
932     }
933
934
935     function testGetTimeoutHeaderInfinite() {
936
937         $request = new Sabre_HTTP_Request(array(
938             'HTTP_TIMEOUT' => 'infinite',
939         ));
940
941         $this->server->httpRequest = $request;
942         $this->assertEquals(Sabre_DAV_Locks_LockInfo::TIMEOUT_INFINITE, $this->locksPlugin->getTimeoutHeader());
943
944     }
945
946     /**
947      * @expectedException Sabre_DAV_Exception_BadRequest
948      */
949     function testGetTimeoutHeaderInvalid() {
950
951         $request = new Sabre_HTTP_Request(array(
952             'HTTP_TIMEOUT' => 'yourmom',
953         ));
954
955         $this->server->httpRequest = $request;
956         $this->locksPlugin->getTimeoutHeader();
957
958     }
959
960
961 }