1<?php
2
3namespace Sabre\DAV;
4
5class PropPatchTest extends \PHPUnit_Framework_TestCase {
6
7    protected $propPatch;
8
9    public function setUp() {
10
11        $this->propPatch = new PropPatch([
12            '{DAV:}displayname' => 'foo',
13        ]);
14        $this->assertEquals(['{DAV:}displayname' => 'foo'], $this->propPatch->getMutations());
15
16    }
17
18    public function testHandleSingleSuccess() {
19
20        $hasRan = false;
21
22        $this->propPatch->handle('{DAV:}displayname', function($value) use (&$hasRan) {
23            $hasRan = true;
24            $this->assertEquals('foo', $value);
25            return true;
26        });
27
28        $this->assertTrue($this->propPatch->commit());
29        $result = $this->propPatch->getResult();
30        $this->assertEquals(['{DAV:}displayname' => 200], $result);
31
32        $this->assertTrue($hasRan);
33
34    }
35
36    public function testHandleSingleFail() {
37
38        $hasRan = false;
39
40        $this->propPatch->handle('{DAV:}displayname', function($value) use (&$hasRan) {
41            $hasRan = true;
42            $this->assertEquals('foo', $value);
43            return false;
44        });
45
46        $this->assertFalse($this->propPatch->commit());
47        $result = $this->propPatch->getResult();
48        $this->assertEquals(['{DAV:}displayname' => 403], $result);
49
50        $this->assertTrue($hasRan);
51
52    }
53
54    public function testHandleSingleCustomResult() {
55
56        $hasRan = false;
57
58        $this->propPatch->handle('{DAV:}displayname', function($value) use (&$hasRan) {
59            $hasRan = true;
60            $this->assertEquals('foo', $value);
61            return 201;
62        });
63
64        $this->assertTrue($this->propPatch->commit());
65        $result = $this->propPatch->getResult();
66        $this->assertEquals(['{DAV:}displayname' => 201], $result);
67
68        $this->assertTrue($hasRan);
69
70    }
71
72    public function testHandleSingleDeleteSuccess() {
73
74        $hasRan = false;
75
76        $this->propPatch = new PropPatch(['{DAV:}displayname' => null]);
77        $this->propPatch->handle('{DAV:}displayname', function($value) use (&$hasRan) {
78            $hasRan = true;
79            $this->assertNull($value);
80            return true;
81        });
82
83        $this->assertTrue($this->propPatch->commit());
84        $result = $this->propPatch->getResult();
85        $this->assertEquals(['{DAV:}displayname' => 204], $result);
86
87        $this->assertTrue($hasRan);
88
89    }
90
91
92    public function testHandleNothing() {
93
94        $hasRan = false;
95
96        $this->propPatch->handle('{DAV:}foobar', function($value) use (&$hasRan) {
97            $hasRan = true;
98        });
99
100        $this->assertFalse($hasRan);
101
102    }
103
104    /**
105     * @depends testHandleSingleSuccess
106     */
107    public function testHandleRemaining() {
108
109        $hasRan = false;
110
111        $this->propPatch->handleRemaining(function($mutations) use (&$hasRan) {
112            $hasRan = true;
113            $this->assertEquals(['{DAV:}displayname' => 'foo'], $mutations);
114            return true;
115        });
116
117        $this->assertTrue($this->propPatch->commit());
118        $result = $this->propPatch->getResult();
119        $this->assertEquals(['{DAV:}displayname' => 200], $result);
120
121        $this->assertTrue($hasRan);
122
123    }
124    public function testHandleRemainingNothingToDo() {
125
126        $hasRan = false;
127
128        $this->propPatch->handle('{DAV:}displayname', function() {} );
129        $this->propPatch->handleRemaining(function($mutations) use (&$hasRan) {
130            $hasRan = true;
131        });
132
133        $this->assertFalse($hasRan);
134
135    }
136
137    public function testSetResultCode() {
138
139        $this->propPatch->setResultCode('{DAV:}displayname', 201);
140        $this->assertTrue($this->propPatch->commit());
141        $result = $this->propPatch->getResult();
142        $this->assertEquals(['{DAV:}displayname' => 201], $result);
143
144    }
145
146    public function testSetResultCodeFail() {
147
148        $this->propPatch->setResultCode('{DAV:}displayname', 402);
149        $this->assertFalse($this->propPatch->commit());
150        $result = $this->propPatch->getResult();
151        $this->assertEquals(['{DAV:}displayname' => 402], $result);
152
153    }
154
155    public function testSetRemainingResultCode() {
156
157        $this->propPatch->setRemainingResultCode(204);
158        $this->assertTrue($this->propPatch->commit());
159        $result = $this->propPatch->getResult();
160        $this->assertEquals(['{DAV:}displayname' => 204], $result);
161
162    }
163
164    public function testCommitNoHandler() {
165
166        $this->assertFalse($this->propPatch->commit());
167        $result = $this->propPatch->getResult();
168        $this->assertEquals(['{DAV:}displayname' => 403], $result);
169
170    }
171
172    public function testHandlerNotCalled() {
173
174        $hasRan = false;
175
176        $this->propPatch->setResultCode('{DAV:}displayname', 402);
177        $this->propPatch->handle('{DAV:}displayname', function($value) use (&$hasRan) {
178            $hasRan = true;
179        });
180
181        $this->propPatch->commit();
182
183        // The handler is not supposed to have ran
184        $this->assertFalse($hasRan);
185
186    }
187
188    public function testDependencyFail() {
189
190        $propPatch = new PropPatch([
191            '{DAV:}a' => 'foo',
192            '{DAV:}b' => 'bar',
193        ]);
194
195        $calledA = false;
196        $calledB = false;
197
198        $propPatch->handle('{DAV:}a', function() use (&$calledA) {
199            $calledA = true;
200            return false;
201        });
202        $propPatch->handle('{DAV:}b', function() use (&$calledB) {
203            $calledB = true;
204            return false;
205        });
206
207        $result = $propPatch->commit();
208        $this->assertTrue($calledA);
209        $this->assertFalse($calledB);
210
211        $this->assertFalse($result);
212
213        $this->assertEquals([
214            '{DAV:}a' => 403,
215            '{DAV:}b' => 424,
216        ], $propPatch->getResult());
217
218    }
219
220    /**
221     * @expectedException \UnexpectedValueException
222     */
223    public function testHandleSingleBrokenResult() {
224
225        $propPatch = new PropPatch([
226            '{DAV:}a' => 'foo',
227        ]);
228
229        $calledA = false;
230        $calledB = false;
231
232        $propPatch->handle('{DAV:}a', function() use (&$calledA) {
233            return [];
234        });
235        $propPatch->commit();
236
237    }
238
239    public function testHandleMultiValueSuccess() {
240
241        $propPatch = new PropPatch([
242            '{DAV:}a' => 'foo',
243            '{DAV:}b' => 'bar',
244            '{DAV:}c' => null,
245        ]);
246
247        $calledA = false;
248
249        $propPatch->handle(['{DAV:}a', '{DAV:}b', '{DAV:}c'], function($properties) use (&$calledA) {
250            $calledA = true;
251            $this->assertEquals([
252                '{DAV:}a' => 'foo',
253                '{DAV:}b' => 'bar',
254                '{DAV:}c' => null,
255            ], $properties);
256            return true;
257        });
258        $result = $propPatch->commit();
259        $this->assertTrue($calledA);
260        $this->assertTrue($result);
261
262        $this->assertEquals([
263            '{DAV:}a' => 200,
264            '{DAV:}b' => 200,
265            '{DAV:}c' => 204,
266        ], $propPatch->getResult());
267
268    }
269
270
271    public function testHandleMultiValueFail() {
272
273        $propPatch = new PropPatch([
274            '{DAV:}a' => 'foo',
275            '{DAV:}b' => 'bar',
276            '{DAV:}c' => null,
277        ]);
278
279        $calledA = false;
280
281        $propPatch->handle(['{DAV:}a', '{DAV:}b', '{DAV:}c'], function($properties) use (&$calledA) {
282            $calledA = true;
283            $this->assertEquals([
284                '{DAV:}a' => 'foo',
285                '{DAV:}b' => 'bar',
286                '{DAV:}c' => null,
287            ], $properties);
288            return false;
289        });
290        $result = $propPatch->commit();
291        $this->assertTrue($calledA);
292        $this->assertFalse($result);
293
294        $this->assertEquals([
295            '{DAV:}a' => 403,
296            '{DAV:}b' => 403,
297            '{DAV:}c' => 403,
298        ], $propPatch->getResult());
299
300    }
301
302    public function testHandleMultiValueCustomResult() {
303
304        $propPatch = new PropPatch([
305            '{DAV:}a' => 'foo',
306            '{DAV:}b' => 'bar',
307            '{DAV:}c' => null,
308        ]);
309
310        $calledA = false;
311
312        $propPatch->handle(['{DAV:}a', '{DAV:}b', '{DAV:}c'], function($properties) use (&$calledA) {
313            $calledA = true;
314            $this->assertEquals([
315                '{DAV:}a' => 'foo',
316                '{DAV:}b' => 'bar',
317                '{DAV:}c' => null,
318            ], $properties);
319
320            return [
321                '{DAV:}a' => 201,
322                '{DAV:}b' => 204,
323            ];
324            return false;
325        });
326        $result = $propPatch->commit();
327        $this->assertTrue($calledA);
328        $this->assertFalse($result);
329
330        $this->assertEquals([
331            '{DAV:}a' => 201,
332            '{DAV:}b' => 204,
333            '{DAV:}c' => 500,
334        ], $propPatch->getResult());
335
336    }
337
338    /**
339     * @expectedException \UnexpectedValueException
340     */
341    public function testHandleMultiValueBroken() {
342
343        $propPatch = new PropPatch([
344            '{DAV:}a' => 'foo',
345            '{DAV:}b' => 'bar',
346            '{DAV:}c' => null,
347        ]);
348
349        $calledA = false;
350
351        $propPatch->handle(['{DAV:}a', '{DAV:}b', '{DAV:}c'], function($properties) use (&$calledA) {
352            return 'hi';
353        });
354        $propPatch->commit();
355
356    }
357}
358