ILIAS  release_8 Revision v8.24
FlySystemDirectoryAccessTest.php
Go to the documentation of this file.
1<?php
2
4
5\Hamcrest\Util::registerGlobalFunctions();
6
12use League\Flysystem\FilesystemInterface;
13use League\Flysystem\RootViolationException;
14use Mockery;
15use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
16use Mockery\MockInterface;
17use PHPUnit\Framework\TestCase;
18
19/******************************************************************************
20 *
21 * This file is part of ILIAS, a powerful learning management system.
22 *
23 * ILIAS is licensed with the GPL-3.0, you should have received a copy
24 * of said license along with the source code.
25 *
26 * If this is not the case or you just want to try ILIAS, you'll find
27 * us at:
28 * https://www.ilias.de
29 * https://github.com/ILIAS-eLearning
30 *
31 *****************************************************************************/
40class FlySystemDirectoryAccessTest extends TestCase
41{
42 use MockeryPHPUnitIntegration;
43
47 private $subject;
56
60 protected function setUp(): void
61 {
62 parent::setUp();
63
64 $this->filesystemMock = Mockery::mock(FilesystemInterface::class);
65 $this->fileAccessMock = Mockery::mock(FlySystemFileAccess::class);
66
67 $this->subject = new FlySystemDirectoryAccess($this->filesystemMock, $this->fileAccessMock);
68 }
69
74 public function testHasDirWhichShouldSucceed(): void
75 {
76 $path = '/path/to/dir';
77 $metadata = [
78 'type' => 'dir',
79 'path' => $path,
80 'timestamp' => 10_000_000
81 ];
82
83 $this->filesystemMock
84 ->shouldReceive('has')
85 ->with($path)
86 ->andReturn(true)
87 ->getMock()
88 ->shouldReceive('getMetadata')
89 ->once()
90 ->andReturn($metadata);
91
92 $exists = $this->subject->hasDir($path);
93 $this->assertTrue($exists);
94 }
95
101 {
102 $path = '/path/to/file';
103 $metadata = [
104 'type' => 'file',
105 'path' => $path,
106 'timestamp' => 10_000_000
107 ];
108
109 $this->filesystemMock
110 ->shouldReceive('has')
111 ->with($path)
112 ->andReturn(true)
113 ->getMock()
114 ->shouldReceive('getMetadata')
115 ->once()
116 ->andReturn($metadata);
117
118 $exists = $this->subject->hasDir($path);
119 $this->assertFalse($exists);
120 }
121
127 {
128 $path = '/path/to/file';
129 $metadata = [
130 'path' => $path,
131 'timestamp' => 10_000_000
132 ];
133
134 $this->filesystemMock
135 ->shouldReceive('has')
136 ->with($path)
137 ->andReturn(true)
138 ->getMock()
139 ->shouldReceive('getMetadata')
140 ->once()
141 ->andReturn($metadata);
142
143 $this->expectException(IOException::class);
144 $this->expectExceptionMessage("Could not evaluate path type: \"$path\"");
145
146 $exists = $this->subject->hasDir($path);
147 $this->assertFalse($exists);
148 }
149
155 {
156 $path = '/path/to/dir';
157
158 $this->filesystemMock
159 ->shouldReceive('has')
160 ->with($path)
161 ->andReturn(false);
162
163 $exists = $this->subject->hasDir($path);
164 $this->assertFalse($exists);
165 }
166
171 public function testListContentsWhichShouldSucceed(): void
172 {
173 $path = '/path/to/dir';
174 $file = ['type' => 'file', 'path' => $path];
175 $dir = ['type' => 'dir', 'path' => $path];
176
177 $contentList = [
178 $file,
179 $dir
180 ];
181
182 $this->filesystemMock
183 ->shouldReceive('listContents')
184 ->once()
185 ->withArgs([$path, \boolValue()])
186 ->andReturn($contentList)
187 ->getMock()
188 ->shouldReceive('has')
189 ->once()
190 ->with($path)
191 ->andReturn(true)
192 ->getMock()
193 ->shouldReceive('getMetadata')
194 ->once()
195 ->with($path)
196 ->andReturn($dir);
197
201 $content = $this->subject->listContents($path);
202
203 $this->assertSame($contentList[0]['type'], $content[0]->getType());
204 $this->assertSame($contentList[0]['path'], $content[0]->getPath());
205 $this->assertTrue($content[0]->isFile());
206 $this->assertFalse($content[0]->isDir());
207 $this->assertSame($contentList[1]['type'], $content[1]->getType());
208 $this->assertSame($contentList[1]['path'], $content[1]->getPath());
209 $this->assertTrue($content[1]->isDir());
210 $this->assertFalse($content[1]->isFile());
211 }
212
218 {
219 $path = '/path/to/dir';
220
221 $this->filesystemMock
222 ->shouldReceive('has')
223 ->once()
224 ->andReturn(false);
225
226 $this->expectException(DirectoryNotFoundException::class);
227 $this->expectExceptionMessage("Directory \"$path\" not found.");
228
229 $this->subject->listContents($path);
230 }
231
237 {
238 $path = '/path/to/dir';
239 $file = ['type' => 'file', 'path' => $path];
240 $dir = ['type' => 'dir'];
241
242 $contentList = [
243 $file,
244 $dir,
245 $file
246 ];
247
248 $this->filesystemMock
249 ->shouldReceive('listContents')
250 ->once()
251 ->andReturn($contentList)
252 ->getMock()
253 ->shouldReceive('has')
254 ->once()
255 ->andReturn(true)
256 ->getMock()
257 ->shouldReceive('getMetadata')
258 ->once()
259 ->andReturn($dir);
260
261 $this->expectException(IOException::class);
262 $this->expectExceptionMessage("Invalid metadata received for path \"$path\"");
263
264 $this->subject->listContents($path);
265 }
266
271 public function testCreateDirWhichShouldSucceed(): void
272 {
273 $path = '/path/to/dir';
275
276 $this->filesystemMock
277 ->shouldReceive('createDir')
278 ->once()
279 ->withArgs([$path, ['visibility' => $access]])
280 ->andReturn(true);
281
282 $this->subject->createDir($path, $access);
283 }
284
290 {
291 $path = '/path/to/dir';
293
294 $this->filesystemMock
295 ->shouldReceive('createDir')
296 ->once()
297 ->withArgs([$path, ['visibility' => $access]])
298 ->andReturn(false);
299
300 $this->expectException(IOException::class);
301 $this->expectExceptionMessage("Could not create directory \"$path\"");
302
303 $this->subject->createDir($path, $access);
304 }
305
311 {
312 $path = '/path/to/dir';
313 $access = 'invalid';
314
315 $this->expectException(\InvalidArgumentException::class);
316 $this->expectExceptionMessage("Invalid visibility expected public or private but got \"$access\".");
317
318 $this->subject->createDir($path, $access);
319 }
320
325 public function testCopyDirWhichShouldSucceed(): void
326 {
327 $srcPath = '/source/path/to/dir';
328 $destPath = '/dest/path/to/dir';
329
333 $fileSourceList = [
334 new Metadata("$srcPath/hello1", MetadataType::FILE),
335 new Metadata("$srcPath/helloDir", MetadataType::DIRECTORY),
336 new Metadata("$srcPath/hello2", MetadataType::FILE),
337 new Metadata("$srcPath/hello/subhello1", MetadataType::FILE),
338 new Metadata("$srcPath/helloDir2", MetadataType::DIRECTORY),
339 new Metadata("$srcPath/hello3", MetadataType::FILE),
340 new Metadata("$srcPath/hello/subhello2", MetadataType::FILE),
341 ];
342
343 $fileDestinationList = [];
344
345 $subjectMock = Mockery::mock(
346 FlySystemDirectoryAccess::class . '[listContents, hasDir]',
347 [$this->filesystemMock, $this->fileAccessMock]
348 );
349 $subjectMock
350 ->shouldReceive('listContents')
351 ->withArgs([$srcPath, true])
352 ->once()
353 ->andReturn($fileSourceList)
354 ->getMock()
355 ->shouldReceive('listContents')
356 ->withArgs([$destPath, true])
357 ->once()
358 ->andReturn($fileDestinationList);
359
360 $subjectMock
361 ->shouldReceive('hasDir')
362 ->with($srcPath)
363 ->once()
364 ->andReturn(true);
365
366 $this->fileAccessMock
367 ->shouldReceive('copy')
368 ->withArgs([$fileSourceList[0]->getPath(), "$destPath/hello1"])
369 ->once()
370 ->getMock()
371 ->shouldReceive('copy')
372 ->withArgs([$fileSourceList[2]->getPath(), "$destPath/hello2"])
373 ->once()
374 ->getMock()
375 ->shouldReceive('copy')
376 ->withArgs([$fileSourceList[3]->getPath(), "$destPath/hello/subhello1"])
377 ->once()
378 ->getMock()
379 ->shouldReceive('copy')
380 ->withArgs([$fileSourceList[5]->getPath(), "$destPath/hello3"])
381 ->once()
382 ->getMock()
383 ->shouldReceive('copy')
384 ->withArgs([$fileSourceList[6]->getPath(), "$destPath/hello/subhello2"])
385 ->once()
386 ->getMock();
387
388 $subjectMock->copyDir($srcPath, $destPath);
389 }
390
395 public function testCopyDirWithDestinationListContentErrorWhichShouldSucceed(): void
396 {
397 $srcPath = '/source/path/to/dir';
398 $destPath = '/dest/path/to/dir';
399
403 $fileSourceList = [
404 new Metadata("$srcPath/hello1", MetadataType::FILE),
405 new Metadata("$srcPath/helloDir", MetadataType::DIRECTORY),
406 new Metadata("$srcPath/hello2", MetadataType::FILE),
407 new Metadata("$srcPath/hello/subhello1", MetadataType::FILE),
408 new Metadata("$srcPath/helloDir2", MetadataType::DIRECTORY),
409 new Metadata("$srcPath/hello3", MetadataType::FILE),
410 new Metadata("$srcPath/hello/subhello2", MetadataType::FILE),
411 ];
412
413 $subjectMock = Mockery::mock(
414 FlySystemDirectoryAccess::class . '[listContents, hasDir]',
415 [$this->filesystemMock, $this->fileAccessMock]
416 );
417 $subjectMock
418 ->shouldReceive('listContents')
419 ->withArgs([$srcPath, true])
420 ->once()
421 ->andReturn($fileSourceList)
422 ->getMock()
423 ->shouldReceive('listContents')
424 ->withArgs([$destPath, true])
425 ->once()
426 ->andThrow(DirectoryNotFoundException::class);
427
428 $subjectMock
429 ->shouldReceive('hasDir')
430 ->with($srcPath)
431 ->once()
432 ->andReturn(true);
433
434 $this->fileAccessMock
435 ->shouldReceive('copy')
436 ->withArgs([$fileSourceList[0]->getPath(), "$destPath/hello1"])
437 ->once()
438 ->getMock()
439 ->shouldReceive('copy')
440 ->withArgs([$fileSourceList[2]->getPath(), "$destPath/hello2"])
441 ->once()
442 ->getMock()
443 ->shouldReceive('copy')
444 ->withArgs([$fileSourceList[3]->getPath(), "$destPath/hello/subhello1"])
445 ->once()
446 ->getMock()
447 ->shouldReceive('copy')
448 ->withArgs([$fileSourceList[5]->getPath(), "$destPath/hello3"])
449 ->once()
450 ->getMock()
451 ->shouldReceive('copy')
452 ->withArgs([$fileSourceList[6]->getPath(), "$destPath/hello/subhello2"])
453 ->once()
454 ->getMock();
455
456 $subjectMock->copyDir($srcPath, $destPath);
457 }
458
463 public function testCopyDirWithFullDestinationDirWhichShouldFail(): void
464 {
465 $srcPath = '/source/path/to/dir';
466 $destPath = '/dest/path/to/dir';
467
471 $fileDestinationList = [
472 new Metadata("$srcPath/hello1", MetadataType::FILE),
473 new Metadata("$srcPath/helloDir", MetadataType::DIRECTORY),
474 new Metadata("$srcPath/hello2", MetadataType::FILE),
475 new Metadata("$srcPath/hello/subhello1", MetadataType::FILE),
476 new Metadata("$srcPath/helloDir2", MetadataType::DIRECTORY),
477 new Metadata("$srcPath/hello3", MetadataType::FILE),
478 new Metadata("$srcPath/hello/subhello2", MetadataType::FILE),
479 ];
480
481 $subjectMock = Mockery::mock(
482 FlySystemDirectoryAccess::class . '[listContents, hasDir]',
483 [$this->filesystemMock, $this->fileAccessMock]
484 );
485 $subjectMock
486 ->shouldReceive('listContents')
487 ->withArgs([$destPath, true])
488 ->once()
489 ->andReturn($fileDestinationList);
490
491 $subjectMock
492 ->shouldReceive('hasDir')
493 ->with($srcPath)
494 ->once()
495 ->andReturn(true);
496
497 $this->expectException(IOException::class);
498 $this->expectExceptionMessage("Destination \"$destPath\" is not empty can not copy files.");
499
500 $subjectMock->copyDir($srcPath, $destPath);
501 }
502
508 {
509 $srcPath = '/source/path/to/dir';
510 $destPath = '/dest/path/to/dir';
511
512 $subjectMock = Mockery::mock(
513 FlySystemDirectoryAccess::class . '[hasDir]',
514 [$this->filesystemMock, $this->fileAccessMock]
515 );
516 $subjectMock
517 ->shouldReceive('hasDir')
518 ->with($srcPath)
519 ->once()
520 ->andReturn(false);
521
522 $this->expectException(DirectoryNotFoundException::class);
523 $this->expectExceptionMessage("Directory \"$srcPath\" not found");
524
525 $subjectMock->copyDir($srcPath, $destPath);
526 }
527
532 public function testDeleteDirWhichShouldSucceed(): void
533 {
534 $path = '/directory/which/should/be/removed';
535
536 $this->filesystemMock
537 ->shouldReceive('deleteDir')
538 ->once()
539 ->with($path)
540 ->andReturn(true);
541
542 $this->subject->deleteDir($path);
543 }
544
550 {
551 $path = '';
552
553 $this->filesystemMock
554 ->shouldReceive('deleteDir')
555 ->once()
556 ->with($path)
557 ->andThrow(RootViolationException::class);
558
559 $this->expectException(IOException::class);
560 $this->expectExceptionMessage('The filesystem root must not be deleted.');
561
562 $this->subject->deleteDir($path);
563 }
564
570 {
571 $path = '/directory/which/should/be/removed';
572
573 $this->filesystemMock
574 ->shouldReceive('deleteDir')
575 ->once()
576 ->with($path)
577 ->andReturn(false);
578
579 $this->expectException(IOException::class);
580 $this->expectExceptionMessage("Could not delete directory \"$path\".");
581
582 $this->subject->deleteDir($path);
583 }
584}
const FILE
The subject is file.
const DIRECTORY
The subject is a directory.
Interface Visibility.
Definition: Visibility.php:32
const PRIVATE_ACCESS
Private file visibility.
Definition: Visibility.php:42
$path
Definition: ltiservices.php:32