Passed
Push — master ( 51cba3...dc9091 )
by Peter
03:11
created

testFileExistsUsesTheFirstCheckedFilesystem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 16
nc 1
nop 0
dl 0
loc 28
rs 9.7333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Framework\Assets\CacheManager;
6
7
use League\Flysystem\DirectoryListing;
8
use League\Flysystem\Filesystem;
9
use League\Flysystem\FilesystemOperator;
10
use League\Flysystem\UnableToReadFile;
11
use League\Flysystem\UnableToWriteFile;
12
use PHPUnit\Framework\MockObject\MockObject;
13
use PHPUnit\Framework\TestCase;
14
15
class FlysystemTest extends TestCase
16
{
17
    /** @var Flysystem - System Under Test */
18
    protected $sut;
19
20
    public function setUp(): void
21
    {
22
        $this->sut = new Flysystem();
23
24
        parent::setUp();
25
    }
26
27
    /**
28
     * @return FilesystemOperator|MockObject
29
     */
30
    protected function createFilesystemMock()
31
    {
32
        return $this->createMock(Filesystem::class);
33
    }
34
35
    public function testHasThrowsExceptionWhenThereAreNoFilesystemsRegistered()
36
    {
37
        $this->expectException(\InvalidArgumentException::class);
38
39
        $path = 'foo.ext';
40
41
        $this->sut->fileExists($path);
42
    }
43
44
    public function testHasThrowsExceptionWhenNoMatchingFilesystemIsFound()
45
    {
46
        $this->expectException(\InvalidArgumentException::class);
47
48
        $fs = $this->createFilesystemMock();
49
50
        $this->sut->registerFilesystem(
51
            $fs,
52
            function () {
53
                return false;
54
            }
55
        );
56
57
        $path = 'foo.ext';
58
59
        $this->sut->fileExists($path);
60
    }
61
62
    public function testFileExistsUsesTheFirstCheckedFilesystem()
63
    {
64
        $expectedResult = true;
65
66
        $fs1 = $this->createFilesystemMock();
67
        $fs2 = $this->createFilesystemMock();
68
69
        $this->sut->registerFilesystem(
70
            $fs1,
71
            function () {
72
                return false;
73
            }
74
        );
75
        $this->sut->registerFilesystem(
76
            $fs2,
77
            function () {
78
                return true;
79
            }
80
        );
81
82
        $path = 'foo.ext';
83
84
        $fs1->expects($this->never())->method('read')->willThrowException(new UnableToReadFile($path));
85
        $fs2->expects($this->once())->method('fileExists')->willReturn($expectedResult);
86
87
        $actualResult = $this->sut->fileExists($path);
88
89
        $this->assertEquals($expectedResult, $actualResult);
90
    }
91
92
    public function testReadThrowsExceptionWhenThereAreNoFilesystemsRegistered()
93
    {
94
        $this->expectException(\InvalidArgumentException::class);
95
96
        $path = 'foo.ext';
97
98
        $this->sut->read($path);
99
    }
100
101
    public function testReadThrowsExceptionWhenNoMatchingFilesystemIsFound()
102
    {
103
        $this->expectException(\InvalidArgumentException::class);
104
105
        $fs = $this->createFilesystemMock();
106
107
        $this->sut->registerFilesystem(
108
            $fs,
109
            function () {
110
                return false;
111
            }
112
        );
113
114
        $path = 'foo.ext';
115
116
        $this->sut->read($path);
117
    }
118
119
    public function testReadReturnsNullIfPathDoesNotExist()
120
    {
121
        $fs = $this->createFilesystemMock();
122
        $fs->expects($this->once())->method('fileExists')->willReturn(false);
123
        $this->sut->registerFilesystem($fs);
124
125
        $path = 'foo.ext';
126
127
        $actualResult = $this->sut->read($path);
128
129
        $this->assertNull($actualResult);
130
    }
131
132
    public function testReadReturnsNullIfFileCanNotBeRead()
133
    {
134
        $path = 'foo.ext';
135
136
        $fs = $this->createFilesystemMock();
137
        $fs->expects($this->any())->method('fileExists')->willReturn(true);
138
        $fs->expects($this->once())->method('read')->willThrowException(new UnableToReadFile($path));
139
        $this->sut->registerFilesystem($fs);
140
141
        $actualResult = $this->sut->read($path);
142
143
        $this->assertNull($actualResult);
144
    }
145
146
    public function testReadReturnsContentIfFileIsReadable()
147
    {
148
        $expectedResult = 'bar';
149
150
        $fs = $this->createFilesystemMock();
151
        $fs->expects($this->any())->method('fileExists')->willReturn(true);
152
        $fs->expects($this->once())->method('read')->willReturn($expectedResult);
153
        $this->sut->registerFilesystem($fs);
154
155
        $path = 'foo.ext';
156
157
        $actualResult = $this->sut->read($path);
158
159
        $this->assertEquals($expectedResult, $actualResult);
160
    }
161
162
    public function testReadUsesTheFirstCheckedFilesystem()
163
    {
164
        $expectedResult = 'bar';
165
166
        $fs1 = $this->createFilesystemMock();
167
        $fs2 = $this->createFilesystemMock();
168
169
        $this->sut->registerFilesystem(
170
            $fs1,
171
            function () {
172
                return false;
173
            }
174
        );
175
        $this->sut->registerFilesystem(
176
            $fs2,
177
            function () {
178
                return true;
179
            }
180
        );
181
182
        $path = 'foo.ext';
183
184
        $fs1->expects($this->never())->method('read')->willThrowException(new UnableToReadFile($path));
185
        $fs2->expects($this->once())->method('fileExists')->willReturn(true);
186
        $fs2->expects($this->once())->method('read')->willReturn($expectedResult);
187
188
        $actualResult = $this->sut->read($path);
189
190
        $this->assertEquals($expectedResult, $actualResult);
191
    }
192
193
    public function testWriteThrowsExceptionWhenThereAreNoFilesystemsRegistered()
194
    {
195
        $this->expectException(\InvalidArgumentException::class);
196
197
        $path    = 'foo.ext';
198
        $content = 'bar';
199
200
        $this->sut->write($path, $content);
201
    }
202
203
    public function testWriteThrowsExceptionWhenNoMatchingFilesystemIsFound()
204
    {
205
        $this->expectException(\InvalidArgumentException::class);
206
207
        $fs = $this->createFilesystemMock();
208
209
        $this->sut->registerFilesystem(
210
            $fs,
211
            function () {
212
                return false;
213
            }
214
        );
215
216
        $path    = 'foo.ext';
217
        $content = 'bar';
218
219
        $this->sut->write($path, $content);
220
    }
221
222
    public function testWriteReturnsFalseIfWritingFails()
223
    {
224
        $fs = $this->createFilesystemMock();
225
226
        $path    = 'foo.ext';
227
        $content = 'bar';
228
229
        $this->sut->registerFilesystem($fs);
230
231
        $fs->expects($this->once())->method('write')->willThrowException(new UnableToWriteFile($path));
232
233
        $this->sut->write($path, $content);
234
    }
235
236
    public function testWriteReturnsTrueOnSuccess()
237
    {
238
        $fs = $this->createFilesystemMock();
239
240
        $path    = 'foo.ext';
241
        $content = 'bar';
242
243
        $this->sut->registerFilesystem($fs);
244
245
        $fs->expects($this->once())->method('write');
246
247
        $actualResult = $this->sut->write($path, $content);
248
249
        $this->assertTrue($actualResult);
250
    }
251
252
    public function testWriteUsesTheFirstCheckedFilesystem()
253
    {
254
        $fs1 = $this->createFilesystemMock();
255
        $fs2 = $this->createFilesystemMock();
256
257
        $this->sut->registerFilesystem(
258
            $fs1,
259
            function () {
260
                return false;
261
            }
262
        );
263
        $this->sut->registerFilesystem(
264
            $fs2,
265
            function () {
266
                return true;
267
            }
268
        );
269
270
        $path    = 'foo.ext';
271
        $content = 'bar';
272
273
        $fs1->expects($this->never())->method('write')->willThrowException(new UnableToWriteFile($path));
274
        $fs2->expects($this->once())->method('write');
275
276
        $actualResult = $this->sut->write($path, $content);
277
278
        $this->assertTrue($actualResult);
279
    }
280
281
    public function testWriteReturnsFalseOnFileExistExceptionIfWritingIsNotForced()
282
    {
283
        $fs = $this->createFilesystemMock();
284
285
        $this->sut->registerFilesystem($fs);
286
287
        $path    = 'foo.ext';
288
        $content = 'bar';
289
290
        $fs->expects($this->once())->method('write')->willThrowException(new UnableToWriteFile($path));
291
292
        $actualResult = $this->sut->write($path, $content, false);
293
294
        $this->assertFalse($actualResult);
295
    }
296
297
    public function testWriteTriesToDeleteExistingFileIfWritingIsForcedAndFileExists()
298
    {
299
        $expectedResult = true;
300
301
        $fs = $this->createFilesystemMock();
302
303
        $this->sut->registerFilesystem($fs);
304
305
        $path    = 'foo.ext';
306
        $content = 'bar';
307
308
        $fs->expects($this->once())->method('fileExists')->with($path)->willReturn(true);
309
        $fs->expects($this->once())->method('delete');
310
        $fs->expects($this->once())->method('write')->with($path, $content);
311
312
        $actualResult = $this->sut->write($path, $content);
313
314
        $this->assertSame($expectedResult, $actualResult);
315
    }
316
317
    public function testGetWebPath()
318
    {
319
        $path      = 'foo.ext';
320
        $timestamp = time();
321
322
        $fs = $this->createFilesystemMock();
323
324
        $this->sut->registerFilesystem($fs);
325
326
        $fs->expects($this->once())->method('lastModified')->with($path)->willReturn($timestamp);
327
328
        $actualResult = $this->sut->getWebPath($path);
329
330
        $this->assertStringContainsString($path, $actualResult);
331
        $this->assertNotSame($path, $actualResult);
332
    }
333
334
    public function testFlushDeletesAllFlushableFilesInAllRegisteredFilesystems()
335
    {
336
        $fs1 = $this->createFilesystemMock();
337
        $fs2 = $this->createFilesystemMock();
338
339
        $this->sut->registerFilesystem($fs1);
340
        $this->sut->registerFilesystem($fs2);
341
342
        $obj1 = ['path' => 'foo', 'basename' => ''];
343
        $obj2 = ['path' => 'bar', 'basename' => ''];
344
        $obj3 = ['path' => 'baz', 'basename' => ''];
345
        $obj4 = ['path' => 'quix', 'basename' => ''];
346
347
        $fs1->expects($this->once())->method('listContents')->willReturn(new DirectoryListing([$obj1, $obj2]));
348
        $fs2->expects($this->once())->method('listContents')->willReturn(new DirectoryListing([$obj3, $obj4]));
349
350
        $fs1->expects($this->exactly(2))->method('delete');
351
        $fs2->expects($this->exactly(2))->method('delete');
352
353
        $this->sut->flush();
354
    }
355
356
    public function testFlushIgnoresDotGitignoreFiles()
357
    {
358
        $fs = $this->createFilesystemMock();
359
360
        $this->sut->registerFilesystem($fs);
361
362
        $obj1 = ['path' => 'foo', 'basename' => '.gitignore'];
363
364
        $fs->expects($this->once())->method('listContents')->willReturn(new DirectoryListing([$obj1]));
365
366
        $fs->expects($this->never())->method('delete');
367
368
        $this->sut->flush();
369
    }
370
371
    public function testFlushIgnoresPhpFiles()
372
    {
373
        $fs = $this->createFilesystemMock();
374
375
        $this->sut->registerFilesystem($fs);
376
377
        $obj1 = ['path' => 'foo', 'basename' => 'index', 'extension' => 'php'];
378
379
        $fs->expects($this->once())->method('listContents')->willReturn(new DirectoryListing([$obj1]));
380
381
        $fs->expects($this->never())->method('delete');
382
383
        $this->sut->flush();
384
    }
385
386
    public function testFlushUsesSetIsFlushableCallback()
387
    {
388
        $this->sut->setIsFlushable(
389
            function ($obj) {
390
                if ($obj['path'] === 'protected') {
391
                    return false;
392
                }
393
394
                return true;
395
            }
396
        );
397
398
        $fs1 = $this->createFilesystemMock();
399
        $fs2 = $this->createFilesystemMock();
400
401
        $this->sut->registerFilesystem($fs1);
402
        $this->sut->registerFilesystem($fs2);
403
404
        $obj1 = ['path' => 'foo', 'basename' => 'index', 'extension' => 'php'];
405
        $obj2 = ['path' => 'foo', 'basename' => '.gitignore'];
406
        $obj3 = ['path' => 'protected', 'basename' => 'abc'];
407
        $obj4 = ['path' => 'protected', 'basename' => 'cba'];
408
409
        $fs1->expects($this->once())->method('listContents')->willReturn(new DirectoryListing([$obj1, $obj2]));
410
        $fs2->expects($this->once())->method('listContents')->willReturn(new DirectoryListing([$obj3, $obj4]));
411
412
        $fs1->expects($this->exactly(2))->method('delete');
413
        $fs2->expects($this->never())->method('delete');
414
415
        $this->sut->flush();
416
    }
417
}
418