xref: /plugin/davcal/vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\DAV;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse Sabre\DAVServerTest;
6*a1a3b679SAndreas Boehleruse Sabre\HTTP;
7*a1a3b679SAndreas Boehler
8*a1a3b679SAndreas Boehler/**
9*a1a3b679SAndreas Boehler * Tests related to the PUT request.
10*a1a3b679SAndreas Boehler *
11*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
12*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
13*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
14*a1a3b679SAndreas Boehler */
15*a1a3b679SAndreas Boehlerclass HttpPutTest extends DAVServerTest {
16*a1a3b679SAndreas Boehler
17*a1a3b679SAndreas Boehler    /**
18*a1a3b679SAndreas Boehler     * Sets up the DAV tree.
19*a1a3b679SAndreas Boehler     *
20*a1a3b679SAndreas Boehler     * @return void
21*a1a3b679SAndreas Boehler     */
22*a1a3b679SAndreas Boehler    function setUpTree() {
23*a1a3b679SAndreas Boehler
24*a1a3b679SAndreas Boehler        $this->tree = new Mock\Collection('root', [
25*a1a3b679SAndreas Boehler            'file1' => 'foo',
26*a1a3b679SAndreas Boehler        ]);
27*a1a3b679SAndreas Boehler
28*a1a3b679SAndreas Boehler    }
29*a1a3b679SAndreas Boehler
30*a1a3b679SAndreas Boehler    /**
31*a1a3b679SAndreas Boehler     * A successful PUT of a new file.
32*a1a3b679SAndreas Boehler     */
33*a1a3b679SAndreas Boehler    function testPut() {
34*a1a3b679SAndreas Boehler
35*a1a3b679SAndreas Boehler        $request = new HTTP\Request('PUT', '/file2', [], 'hello');
36*a1a3b679SAndreas Boehler
37*a1a3b679SAndreas Boehler        $response = $this->request($request);
38*a1a3b679SAndreas Boehler
39*a1a3b679SAndreas Boehler        $this->assertEquals(201, $response->getStatus(), 'Incorrect status code received. Full response body:' . $response->getBodyAsString());
40*a1a3b679SAndreas Boehler
41*a1a3b679SAndreas Boehler        $this->assertEquals(
42*a1a3b679SAndreas Boehler            'hello',
43*a1a3b679SAndreas Boehler            $this->server->tree->getNodeForPath('file2')->get()
44*a1a3b679SAndreas Boehler        );
45*a1a3b679SAndreas Boehler
46*a1a3b679SAndreas Boehler        $this->assertEquals(
47*a1a3b679SAndreas Boehler            [
48*a1a3b679SAndreas Boehler                'X-Sabre-Version' => [Version::VERSION],
49*a1a3b679SAndreas Boehler                'Content-Length' => ['0'],
50*a1a3b679SAndreas Boehler                'ETag' => ['"' . md5('hello') . '"']
51*a1a3b679SAndreas Boehler            ],
52*a1a3b679SAndreas Boehler            $response->getHeaders()
53*a1a3b679SAndreas Boehler        );
54*a1a3b679SAndreas Boehler
55*a1a3b679SAndreas Boehler    }
56*a1a3b679SAndreas Boehler
57*a1a3b679SAndreas Boehler    /**
58*a1a3b679SAndreas Boehler     * A successful PUT on an existing file.
59*a1a3b679SAndreas Boehler     *
60*a1a3b679SAndreas Boehler     * @depends testPut
61*a1a3b679SAndreas Boehler     */
62*a1a3b679SAndreas Boehler    function testPutExisting() {
63*a1a3b679SAndreas Boehler
64*a1a3b679SAndreas Boehler        $request = new HTTP\Request('PUT', '/file1', [], 'bar');
65*a1a3b679SAndreas Boehler
66*a1a3b679SAndreas Boehler        $response = $this->request($request);
67*a1a3b679SAndreas Boehler
68*a1a3b679SAndreas Boehler        $this->assertEquals(204, $response->getStatus());
69*a1a3b679SAndreas Boehler
70*a1a3b679SAndreas Boehler        $this->assertEquals(
71*a1a3b679SAndreas Boehler            'bar',
72*a1a3b679SAndreas Boehler            $this->server->tree->getNodeForPath('file1')->get()
73*a1a3b679SAndreas Boehler        );
74*a1a3b679SAndreas Boehler
75*a1a3b679SAndreas Boehler        $this->assertEquals(
76*a1a3b679SAndreas Boehler            [
77*a1a3b679SAndreas Boehler                'X-Sabre-Version' => [Version::VERSION],
78*a1a3b679SAndreas Boehler                'Content-Length' => ['0'],
79*a1a3b679SAndreas Boehler                'ETag' => ['"' . md5('bar') . '"']
80*a1a3b679SAndreas Boehler            ],
81*a1a3b679SAndreas Boehler            $response->getHeaders()
82*a1a3b679SAndreas Boehler        );
83*a1a3b679SAndreas Boehler
84*a1a3b679SAndreas Boehler    }
85*a1a3b679SAndreas Boehler
86*a1a3b679SAndreas Boehler    /**
87*a1a3b679SAndreas Boehler     * PUT on existing file with If-Match: *
88*a1a3b679SAndreas Boehler     *
89*a1a3b679SAndreas Boehler     * @depends testPutExisting
90*a1a3b679SAndreas Boehler     */
91*a1a3b679SAndreas Boehler    function testPutExistingIfMatchStar() {
92*a1a3b679SAndreas Boehler
93*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
94*a1a3b679SAndreas Boehler            'PUT',
95*a1a3b679SAndreas Boehler            '/file1',
96*a1a3b679SAndreas Boehler            ['If-Match' => '*'],
97*a1a3b679SAndreas Boehler            'hello'
98*a1a3b679SAndreas Boehler        );
99*a1a3b679SAndreas Boehler
100*a1a3b679SAndreas Boehler        $response = $this->request($request);
101*a1a3b679SAndreas Boehler
102*a1a3b679SAndreas Boehler        $this->assertEquals(204, $response->getStatus());
103*a1a3b679SAndreas Boehler
104*a1a3b679SAndreas Boehler        $this->assertEquals(
105*a1a3b679SAndreas Boehler            'hello',
106*a1a3b679SAndreas Boehler            $this->server->tree->getNodeForPath('file1')->get()
107*a1a3b679SAndreas Boehler        );
108*a1a3b679SAndreas Boehler
109*a1a3b679SAndreas Boehler        $this->assertEquals(
110*a1a3b679SAndreas Boehler            [
111*a1a3b679SAndreas Boehler                'X-Sabre-Version' => [Version::VERSION],
112*a1a3b679SAndreas Boehler                'Content-Length' => ['0'],
113*a1a3b679SAndreas Boehler                'ETag' => ['"' . md5('hello') . '"']
114*a1a3b679SAndreas Boehler            ],
115*a1a3b679SAndreas Boehler            $response->getHeaders()
116*a1a3b679SAndreas Boehler        );
117*a1a3b679SAndreas Boehler
118*a1a3b679SAndreas Boehler    }
119*a1a3b679SAndreas Boehler
120*a1a3b679SAndreas Boehler    /**
121*a1a3b679SAndreas Boehler     * PUT on existing file with If-Match: with a correct etag
122*a1a3b679SAndreas Boehler     *
123*a1a3b679SAndreas Boehler     * @depends testPutExisting
124*a1a3b679SAndreas Boehler     */
125*a1a3b679SAndreas Boehler    function testPutExistingIfMatchCorrect() {
126*a1a3b679SAndreas Boehler
127*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
128*a1a3b679SAndreas Boehler            'PUT',
129*a1a3b679SAndreas Boehler            '/file1',
130*a1a3b679SAndreas Boehler            ['If-Match' => '"' . md5('foo') . '"'],
131*a1a3b679SAndreas Boehler            'hello'
132*a1a3b679SAndreas Boehler        );
133*a1a3b679SAndreas Boehler
134*a1a3b679SAndreas Boehler        $response = $this->request($request);
135*a1a3b679SAndreas Boehler
136*a1a3b679SAndreas Boehler        $this->assertEquals(204, $response->status);
137*a1a3b679SAndreas Boehler
138*a1a3b679SAndreas Boehler        $this->assertEquals(
139*a1a3b679SAndreas Boehler            'hello',
140*a1a3b679SAndreas Boehler            $this->server->tree->getNodeForPath('file1')->get()
141*a1a3b679SAndreas Boehler        );
142*a1a3b679SAndreas Boehler
143*a1a3b679SAndreas Boehler        $this->assertEquals(
144*a1a3b679SAndreas Boehler            [
145*a1a3b679SAndreas Boehler                'X-Sabre-Version' => [Version::VERSION],
146*a1a3b679SAndreas Boehler                'Content-Length' => ['0'],
147*a1a3b679SAndreas Boehler                'ETag' => ['"' . md5('hello') . '"'],
148*a1a3b679SAndreas Boehler            ],
149*a1a3b679SAndreas Boehler            $response->getHeaders()
150*a1a3b679SAndreas Boehler        );
151*a1a3b679SAndreas Boehler
152*a1a3b679SAndreas Boehler    }
153*a1a3b679SAndreas Boehler
154*a1a3b679SAndreas Boehler    /**
155*a1a3b679SAndreas Boehler     * PUT with Content-Range should be rejected.
156*a1a3b679SAndreas Boehler     *
157*a1a3b679SAndreas Boehler     * @depends testPut
158*a1a3b679SAndreas Boehler     */
159*a1a3b679SAndreas Boehler    function testPutContentRange() {
160*a1a3b679SAndreas Boehler
161*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
162*a1a3b679SAndreas Boehler            'PUT',
163*a1a3b679SAndreas Boehler            '/file2',
164*a1a3b679SAndreas Boehler            ['Content-Range' => 'bytes/100-200'],
165*a1a3b679SAndreas Boehler            'hello'
166*a1a3b679SAndreas Boehler        );
167*a1a3b679SAndreas Boehler
168*a1a3b679SAndreas Boehler        $response = $this->request($request);
169*a1a3b679SAndreas Boehler        $this->assertEquals(400, $response->getStatus());
170*a1a3b679SAndreas Boehler
171*a1a3b679SAndreas Boehler    }
172*a1a3b679SAndreas Boehler
173*a1a3b679SAndreas Boehler    /**
174*a1a3b679SAndreas Boehler     * PUT on non-existing file with If-None-Match: * should work.
175*a1a3b679SAndreas Boehler     *
176*a1a3b679SAndreas Boehler     * @depends testPut
177*a1a3b679SAndreas Boehler     */
178*a1a3b679SAndreas Boehler    function testPutIfNoneMatchStar() {
179*a1a3b679SAndreas Boehler
180*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
181*a1a3b679SAndreas Boehler            'PUT',
182*a1a3b679SAndreas Boehler            '/file2',
183*a1a3b679SAndreas Boehler            ['If-None-Match' => '*'],
184*a1a3b679SAndreas Boehler            'hello'
185*a1a3b679SAndreas Boehler        );
186*a1a3b679SAndreas Boehler
187*a1a3b679SAndreas Boehler        $response = $this->request($request);
188*a1a3b679SAndreas Boehler
189*a1a3b679SAndreas Boehler        $this->assertEquals(201, $response->getStatus());
190*a1a3b679SAndreas Boehler
191*a1a3b679SAndreas Boehler        $this->assertEquals(
192*a1a3b679SAndreas Boehler            'hello',
193*a1a3b679SAndreas Boehler            $this->server->tree->getNodeForPath('file2')->get()
194*a1a3b679SAndreas Boehler        );
195*a1a3b679SAndreas Boehler
196*a1a3b679SAndreas Boehler        $this->assertEquals(
197*a1a3b679SAndreas Boehler            [
198*a1a3b679SAndreas Boehler                'X-Sabre-Version' => [Version::VERSION],
199*a1a3b679SAndreas Boehler                'Content-Length' => ['0'],
200*a1a3b679SAndreas Boehler                'ETag' => ['"' . md5('hello') . '"']
201*a1a3b679SAndreas Boehler            ],
202*a1a3b679SAndreas Boehler            $response->getHeaders()
203*a1a3b679SAndreas Boehler        );
204*a1a3b679SAndreas Boehler
205*a1a3b679SAndreas Boehler    }
206*a1a3b679SAndreas Boehler
207*a1a3b679SAndreas Boehler    /**
208*a1a3b679SAndreas Boehler     * PUT on non-existing file with If-Match: * should fail.
209*a1a3b679SAndreas Boehler     *
210*a1a3b679SAndreas Boehler     * @depends testPut
211*a1a3b679SAndreas Boehler     */
212*a1a3b679SAndreas Boehler    function testPutIfMatchStar() {
213*a1a3b679SAndreas Boehler
214*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
215*a1a3b679SAndreas Boehler            'PUT',
216*a1a3b679SAndreas Boehler            '/file2',
217*a1a3b679SAndreas Boehler            ['If-Match' => '*'],
218*a1a3b679SAndreas Boehler            'hello'
219*a1a3b679SAndreas Boehler        );
220*a1a3b679SAndreas Boehler
221*a1a3b679SAndreas Boehler        $response = $this->request($request);
222*a1a3b679SAndreas Boehler
223*a1a3b679SAndreas Boehler        $this->assertEquals(412, $response->getStatus());
224*a1a3b679SAndreas Boehler
225*a1a3b679SAndreas Boehler    }
226*a1a3b679SAndreas Boehler
227*a1a3b679SAndreas Boehler    /**
228*a1a3b679SAndreas Boehler     * PUT on existing file with If-None-Match: * should fail.
229*a1a3b679SAndreas Boehler     *
230*a1a3b679SAndreas Boehler     * @depends testPut
231*a1a3b679SAndreas Boehler     */
232*a1a3b679SAndreas Boehler    function testPutExistingIfNoneMatchStar() {
233*a1a3b679SAndreas Boehler
234*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
235*a1a3b679SAndreas Boehler            'PUT',
236*a1a3b679SAndreas Boehler            '/file1',
237*a1a3b679SAndreas Boehler            ['If-None-Match' => '*'],
238*a1a3b679SAndreas Boehler            'hello'
239*a1a3b679SAndreas Boehler        );
240*a1a3b679SAndreas Boehler        $request->setBody('hello');
241*a1a3b679SAndreas Boehler
242*a1a3b679SAndreas Boehler        $response = $this->request($request);
243*a1a3b679SAndreas Boehler
244*a1a3b679SAndreas Boehler        $this->assertEquals(412, $response->getStatus());
245*a1a3b679SAndreas Boehler
246*a1a3b679SAndreas Boehler    }
247*a1a3b679SAndreas Boehler
248*a1a3b679SAndreas Boehler    /**
249*a1a3b679SAndreas Boehler     * PUT thats created in a non-collection should be rejected.
250*a1a3b679SAndreas Boehler     *
251*a1a3b679SAndreas Boehler     * @depends testPut
252*a1a3b679SAndreas Boehler     */
253*a1a3b679SAndreas Boehler    function testPutNoParent() {
254*a1a3b679SAndreas Boehler
255*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
256*a1a3b679SAndreas Boehler            'PUT',
257*a1a3b679SAndreas Boehler            '/file1/file2',
258*a1a3b679SAndreas Boehler            [],
259*a1a3b679SAndreas Boehler            'hello'
260*a1a3b679SAndreas Boehler        );
261*a1a3b679SAndreas Boehler
262*a1a3b679SAndreas Boehler        $response = $this->request($request);
263*a1a3b679SAndreas Boehler        $this->assertEquals(409, $response->getStatus());
264*a1a3b679SAndreas Boehler
265*a1a3b679SAndreas Boehler    }
266*a1a3b679SAndreas Boehler
267*a1a3b679SAndreas Boehler    /**
268*a1a3b679SAndreas Boehler     * Finder may sometimes make a request, which gets its content-body
269*a1a3b679SAndreas Boehler     * stripped. We can't always prevent this from happening, but in some cases
270*a1a3b679SAndreas Boehler     * we can detected this and return an error instead.
271*a1a3b679SAndreas Boehler     *
272*a1a3b679SAndreas Boehler     * @depends testPut
273*a1a3b679SAndreas Boehler     */
274*a1a3b679SAndreas Boehler    function testFinderPutSuccess() {
275*a1a3b679SAndreas Boehler
276*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
277*a1a3b679SAndreas Boehler            'PUT',
278*a1a3b679SAndreas Boehler            '/file2',
279*a1a3b679SAndreas Boehler            ['X-Expected-Entity-Length' => '5'],
280*a1a3b679SAndreas Boehler            'hello'
281*a1a3b679SAndreas Boehler        );
282*a1a3b679SAndreas Boehler        $response = $this->request($request);
283*a1a3b679SAndreas Boehler
284*a1a3b679SAndreas Boehler        $this->assertEquals(201, $response->getStatus());
285*a1a3b679SAndreas Boehler
286*a1a3b679SAndreas Boehler        $this->assertEquals(
287*a1a3b679SAndreas Boehler            'hello',
288*a1a3b679SAndreas Boehler            $this->server->tree->getNodeForPath('file2')->get()
289*a1a3b679SAndreas Boehler        );
290*a1a3b679SAndreas Boehler
291*a1a3b679SAndreas Boehler        $this->assertEquals(
292*a1a3b679SAndreas Boehler            [
293*a1a3b679SAndreas Boehler                'X-Sabre-Version' => [Version::VERSION],
294*a1a3b679SAndreas Boehler                'Content-Length' => ['0'],
295*a1a3b679SAndreas Boehler                'ETag' => ['"' . md5('hello') . '"'],
296*a1a3b679SAndreas Boehler            ],
297*a1a3b679SAndreas Boehler            $response->getHeaders()
298*a1a3b679SAndreas Boehler        );
299*a1a3b679SAndreas Boehler
300*a1a3b679SAndreas Boehler    }
301*a1a3b679SAndreas Boehler
302*a1a3b679SAndreas Boehler    /**
303*a1a3b679SAndreas Boehler     * Same as the last one, but in this case we're mimicing a failed request.
304*a1a3b679SAndreas Boehler     *
305*a1a3b679SAndreas Boehler     * @depends testFinderPutSuccess
306*a1a3b679SAndreas Boehler     */
307*a1a3b679SAndreas Boehler    function testFinderPutFail() {
308*a1a3b679SAndreas Boehler
309*a1a3b679SAndreas Boehler        $request = new HTTP\Request(
310*a1a3b679SAndreas Boehler            'PUT',
311*a1a3b679SAndreas Boehler            '/file2',
312*a1a3b679SAndreas Boehler            ['X-Expected-Entity-Length' => '5'],
313*a1a3b679SAndreas Boehler            ''
314*a1a3b679SAndreas Boehler        );
315*a1a3b679SAndreas Boehler
316*a1a3b679SAndreas Boehler        $response = $this->request($request);
317*a1a3b679SAndreas Boehler
318*a1a3b679SAndreas Boehler        $this->assertEquals(403, $response->getStatus());
319*a1a3b679SAndreas Boehler
320*a1a3b679SAndreas Boehler    }
321*a1a3b679SAndreas Boehler
322*a1a3b679SAndreas Boehler    /**
323*a1a3b679SAndreas Boehler     * Plugins can intercept PUT. We need to make sure that works.
324*a1a3b679SAndreas Boehler     *
325*a1a3b679SAndreas Boehler     * @depends testPut
326*a1a3b679SAndreas Boehler     */
327*a1a3b679SAndreas Boehler    function testPutIntercept() {
328*a1a3b679SAndreas Boehler
329*a1a3b679SAndreas Boehler        $this->server->on('beforeBind', function($uri) {
330*a1a3b679SAndreas Boehler            $this->server->httpResponse->setStatus(418);
331*a1a3b679SAndreas Boehler            return false;
332*a1a3b679SAndreas Boehler        });
333*a1a3b679SAndreas Boehler
334*a1a3b679SAndreas Boehler        $request = new HTTP\Request('PUT', '/file2', [], 'hello');
335*a1a3b679SAndreas Boehler        $response = $this->request($request);
336*a1a3b679SAndreas Boehler
337*a1a3b679SAndreas Boehler        $this->assertEquals(418, $response->getStatus(), 'Incorrect status code received. Full response body: ' .$response->getBodyAsString());
338*a1a3b679SAndreas Boehler
339*a1a3b679SAndreas Boehler        $this->assertFalse(
340*a1a3b679SAndreas Boehler            $this->server->tree->nodeExists('file2')
341*a1a3b679SAndreas Boehler        );
342*a1a3b679SAndreas Boehler
343*a1a3b679SAndreas Boehler        $this->assertEquals([
344*a1a3b679SAndreas Boehler            'X-Sabre-Version' => [Version::VERSION],
345*a1a3b679SAndreas Boehler        ], $response->getHeaders());
346*a1a3b679SAndreas Boehler
347*a1a3b679SAndreas Boehler    }
348*a1a3b679SAndreas Boehler
349*a1a3b679SAndreas Boehler}
350