ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
FlySystemFileAccessTest.php
Go to the documentation of this file.
1 <?php
2 
20 
31 use Mockery;
43 
48 class FlySystemFileAccessTest extends TestCase
49 {
51 
52  private \ILIAS\Filesystem\Provider\FlySystem\FlySystemFileAccess $subject;
53  private \League\Flysystem\Filesystem|\Mockery\MockInterface $filesystemMock;
57  private \Mockery\LegacyMockInterface $adapterMock;
58 
63  protected function setUp(): void
64  {
65  parent::setUp();
66 
67  $this->filesystemMock = Mockery::mock(FilesystemOperator::class);
68  $this->adapterMock = Mockery::mock(FilesystemAdapter::class);
69  $this->subject = new FlySystemFileAccess($this->filesystemMock);
70  }
71 
72  public function testReadWhichShouldSucceed(): void
73  {
74  $file_content = 'Test file content.';
75  $path = '/path/to/your/file';
76 
77  $this->filesystemMock->shouldReceive('has')
78  ->once()
79  ->with(ltrim($path, '/'))
80  ->andReturn(true);
81 
82  $this->filesystemMock->shouldReceive('read')
83  ->with(ltrim($path, '/'))
84  ->once()
85  ->andReturn($file_content);
86 
87 
88  $actualContent = $this->subject->read($path);
89  $this->assertSame($file_content, $actualContent);
90  }
91 
93  {
94  $path = '/path/to/your/file';
95 
96  $this->filesystemMock->shouldReceive('has')
97  ->once()
98  ->with(ltrim($path, '/'))
99  ->andReturn(true);
100 
101  $this->filesystemMock->shouldReceive('read')
102  ->with(ltrim($path, '/'))
103  ->once()
104  ->andReturn(false);
105 
106 
107  $this->expectException(IOException::class);
108  $this->expectExceptionMessage('File "' . ltrim($path, '/') . '" not found.');
109  $actualContent = $this->subject->read($path);
110  }
111 
113  {
114 
115  $path = '/path/to/your/file';
116 
117  $this->filesystemMock->shouldReceive('has')
118  ->once()
119  ->with(ltrim($path, '/'))
120  ->andReturn(false);
121 
122  $this->filesystemMock->shouldReceive('read')
123  ->never();
124 
125 
126  $this->expectException(IOException::class);
127  $this->expectExceptionMessage('File "' . ltrim($path, '/') . '" not found.');
128  $actualContent = $this->subject->read($path);
129  }
130 
131  public function testGetMimeTypeWhichShouldSucceed(): void
132  {
133  $mimeType = 'image/jpeg';
134  $this->filesystemMock->shouldReceive('mimeType')
135  ->once()
136  ->andReturn($mimeType);
137 
138  $actualMimeType = $this->subject->getMimeType('/path/to/your/file');
139  $this->assertSame($mimeType, $actualMimeType);
140  }
141 
142  public function testPutContentExistingFile(): void
143  {
144  $content = 'Test file content.';
145  $this->filesystemMock->shouldReceive('has')
146  ->once()
147  ->andReturn(true);
148  $this->filesystemMock->shouldReceive('write')
149  ->with('/path/to/your/file', $content)
150  ->once()
151  ->andReturn(true);
152 
153  $this->subject->put('/path/to/your/file', $content);
154  }
155 
156  public function testPutContentNonExistingFile(): void
157  {
158  $content = 'Test file content.';
159  $this->filesystemMock->shouldReceive('has')
160  ->twice()
161  ->andReturn(false);
162 
163  $this->filesystemMock->shouldReceive('write')
164  ->with('/path/to/your/file', $content)
165  ->once()
166  ->andReturn(true);
167 
168  $this->subject->put('/path/to/your/file', $content);
169  }
170 
171 
173  {
174  $path = '/path/to/your/file';
175  $this->filesystemMock->shouldReceive('mimeType')
176  ->with($path)
177  ->once()
178  ->andReturn('');
179 
180  $this->expectException(IOException::class);
181  $this->expectExceptionMessage("Could not determine the MIME type of the file \"$path\".");
182 
183  $this->subject->getMimeType($path);
184  }
185 
187  {
188  $path = '/path/to/your/file';
189  $this->filesystemMock->shouldReceive('mimeType')
190  ->once()
191  ->with($path)
192  ->andThrow(UnableToRetrieveMetadata::class);
193 
194  $this->expectException(IOException::class);
195  $this->expectExceptionMessage("File \"$path\" not found.");
196 
197  $this->subject->getMimeType($path);
198  }
199 
200  public function testGetTimestampWhichShouldSucceed(): void
201  {
202  $datetime = '2012-02-06';
203  $timestamp = strtotime($datetime);
204  $this->filesystemMock
205  ->shouldReceive('lastModified')
206  ->once()
207  ->andReturn($timestamp);
208 
209  $actualTimestamp = $this->subject->getTimestamp('/path/to/your/file');
210 
211  /*
212  * needs to be equals instead of same because == checks if the object content is the same and === seems to check the reference too
213  * eg.
214  * $a == $b => true
215  * $a === $b => false
216  * $a === $a => true
217  * $b === $b => true
218  *
219  * Danger; this is only the observed behaviour and was not documented at least the part with the === operator.
220  * Tested with DateTime objects (PHP 7.1.6)
221  */
222  $this->assertEquals(new \DateTime($datetime), $actualTimestamp);
223  }
224 
226  {
227  $path = '/path/to/your/file';
228  $this->filesystemMock
229  ->shouldReceive('lastModified')
230  ->with($path)
231  ->once()
232  ->andThrow(UnableToRetrieveMetadata::class);
233 
234  $this->expectException(IOException::class);
235  $this->expectExceptionMessage("Could not lookup timestamp of the file \"$path\".");
236 
237  $this->subject->getTimestamp($path);
238  }
239 
241  {
242  $path = '/path/to/your/file';
243  $this->filesystemMock
244  ->shouldReceive('lastModified')
245  ->once()
246  ->with($path)
247  ->andThrow(UnableToReadFile::class);
248 
249  $this->expectException(IOException::class);
250  $this->expectExceptionMessage("File \"$path\" not found.");
251 
252  $this->subject->getTimestamp($path);
253  }
254 
255  public function testGetSizeWhichShouldSucceed(): void
256  {
257  $rawSize = 1024;
258  $size = new DataSize($rawSize, DataSize::KiB); //floating point is never that precise.
259 
260  $this->filesystemMock->shouldReceive('fileSize')
261  ->once()
262  ->andReturn($rawSize);
263 
264  $actualSize = $this->subject->getSize('/path/to/your/file', DataSize::KiB);
265  $this->assertSame($size->getSize(), $actualSize->getSize(), '');
266  }
267 
269  {
270  $path = '/path/to/your/file';
271  $this->filesystemMock
272  ->shouldReceive('fileSize')
273  ->with($path)
274  ->once()
275  ->andThrow(UnableToRetrieveMetadata::class);
276 
277  $this->expectException(IOException::class);
278  $this->expectExceptionMessage("File \"$path\" not found.");
279 
280  $this->subject->getSize($path, DataSize::MiB);
281  }
282 
284  {
285  $path = '/path/to/your/file';
286  $this->filesystemMock
287  ->shouldReceive('fileSize')
288  ->once()
289  ->with($path)
290  ->andThrow(UnableToRetrieveMetadata::class);
291 
292  $this->expectException(IOException::class);
293  $this->expectExceptionMessage("File \"$path\" not found.");
294 
295  $this->subject->getSize($path, DataSize::GiB);
296  }
297 
298  public function testSetVisibilityWhichShouldSucceed(): void
299  {
300  $path = '/path/to/your/file';
301  $visibility = "private";
302 
303  $this->filesystemMock->shouldReceive('has')
304  ->once()
305  ->with($path)
306  ->andReturn(true);
307 
308  $this->filesystemMock->shouldReceive('setVisibility')
309  ->once()
310  ->withArgs([$path, $visibility])
311  ->andReturn(true);
312 
313  $operationSuccessful = $this->subject->setVisibility($path, $visibility);
314  $this->assertTrue($operationSuccessful);
315  }
316 
318  {
319  $path = '/path/to/your/file';
320  $visibility = "private";
321 
322  $this->filesystemMock->shouldReceive('has')
323  ->once()
324  ->with($path)
325  ->andReturn(true);
326 
327  $this->filesystemMock->shouldReceive('setVisibility')
328  ->once()
329  ->withArgs([$path, $visibility])
330  ->andThrow(UnableToSetVisibility::class);
331 
332  $operationSuccessful = $this->subject->setVisibility($path, $visibility);
333  $this->assertFalse($operationSuccessful);
334  }
335 
341  {
342  $path = '/path/to/your/file';
343  $visibility = "private";
344 
345  $this->filesystemMock->shouldReceive('has')
346  ->once()
347  ->with($path)
348  ->andReturn(false);
349 
350  $this->expectException(\ILIAS\Filesystem\Exception\FileNotFoundException::class);
351  $this->expectExceptionMessage("Path \"$path\" not found.");
352 
353  $this->subject->setVisibility($path, $visibility);
354  }
355 
361  {
362  $path = '/path/to/your/file';
363  $visibility = "not valid";
364 
365  $this->filesystemMock->shouldReceive('has')
366  ->once()
367  ->with($path)
368  ->andReturn(true);
369 
370  $this->expectException(\InvalidArgumentException::class);
371  $this->expectExceptionMessage("The access must be 'public' or 'private' but '$visibility' was given.");
372 
373  $this->subject->setVisibility($path, $visibility);
374  }
375 
380  public function testGetVisibilityWhichShouldSucceed(): void
381  {
382  $path = '/path/to/your/file';
383  $visibility = "private";
384 
385  $this->filesystemMock->shouldReceive('has')
386  ->once()
387  ->with($path)
388  ->andReturn(true);
389 
390  $this->filesystemMock->shouldReceive('getVisibility')
391  ->once()
392  ->with($path)
393  ->andReturn($visibility);
394 
395  $actualVisibility = $this->subject->getVisibility($path);
396  $this->assertSame($visibility, $actualVisibility);
397  }
398 
404  {
405  $path = '/path/to/your/file';
406 
407  $this->filesystemMock->shouldReceive('has')
408  ->once()
409  ->with($path)
410  ->andReturn(false);
411 
412  $this->expectException(\ILIAS\Filesystem\Exception\FileNotFoundException::class);
413  $this->expectExceptionMessage("Path \"$path\" not found.");
414 
415  $this->subject->getVisibility($path);
416  }
417 
423  {
424  $path = '/path/to/your/file';
425 
426  $this->filesystemMock->shouldReceive('has')
427  ->once()
428  ->with($path)
429  ->andReturn(true);
430 
431  $this->filesystemMock->shouldReceive('getVisibility')
432  ->once()
433  ->with($path)
434  ->andReturn(false);
435 
436  $this->expectException(IOException::class);
437  $this->expectExceptionMessage("Could not determine visibility for path '$path'.");
438 
439  $this->subject->getVisibility($path);
440  }
441 
446  public function testWriteWhichShouldSucceed(): void
447  {
448  $path = '/path/to/your/file';
449  $content = "some awesome content";
450 
451  $this->filesystemMock
452  ->shouldReceive('has')
453  ->once()
454  ->with($path)
455  ->andReturn(false)
456  ->getMock()
457  ->shouldReceive('write')
458  ->once()
459  ->withArgs([$path, $content]);
460 
461  $this->subject->write($path, $content);
462  }
463 
469  {
470  $path = '/path/to/your/file';
471  $content = "some awesome content";
472 
473  $this->filesystemMock
474  ->shouldReceive('has')
475  ->once()
476  ->with($path)
477  ->andReturn(true)
478  ->shouldReceive('write')
479  ->never()
480  ->withArgs([$path, $content])
481  ->andThrow(UnableToWriteFile::class);
482 
483  $this->expectException(FileAlreadyExistsException::class);
484  $this->expectExceptionMessage("File \"$path\" already exists.");
485 
486  $this->subject->write($path, $content);
487  }
488 
494  {
495  $path = '/path/to/your/file';
496  $content = "some awesome content";
497 
498  $this->filesystemMock
499  ->shouldReceive('has')
500  ->once()
501  ->with($path)
502  ->andReturn(false)
503  ->getMock()
504  ->shouldReceive('write')
505  ->once()
506  ->withArgs([$path, $content])
507  ->andThrow(UnableToWriteFile::class);
508 
509  $this->expectException(IOException::class);
510  $this->expectExceptionMessage(
511  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
512  );
513 
514  $this->subject->write($path, $content);
515  }
516 
521  public function testUpdateWhichShouldSucceed(): void
522  {
523  $path = '/path/to/your/file';
524  $content = "some awesome content";
525 
526  $this->filesystemMock->shouldReceive('write')
527  ->once()
528  ->withArgs([$path, $content])
529  ->andReturn(true);
530 
531  $this->subject->update($path, $content);
532  }
533 
539  {
540  $path = '/path/to/your/file';
541  $content = "some awesome content";
542 
543  $this->filesystemMock->shouldReceive('write')
544  ->once()
545  ->withArgs([$path, $content])
546  ->andThrow(UnableToWriteFile::class);
547 
548  $this->expectException(IOException::class);
549  $this->expectExceptionMessage(
550  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
551  );
552 
553  $this->subject->update($path, $content);
554  }
555 
561  {
562  $path = '/path/to/your/file';
563  $content = "some awesome content";
564 
565  $this->filesystemMock
566  ->shouldReceive('write')
567  ->once()
568  ->withArgs([$path, $content])
569  ->andThrow(UnableToWriteFile::class);
570 
571  $this->expectException(IOException::class);
572  $this->expectExceptionMessage(
573  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
574  );
575 
576  $this->subject->update($path, $content);
577  }
578 
583  public function testDeleteWhichShouldSucceed(): void
584  {
585  $path = '/path/to/your/file';
586 
587  $this->filesystemMock->shouldReceive('delete')
588  ->once()
589  ->with($path)
590  ->andReturn(true);
591 
592  $this->subject->delete($path);
593  }
594 
600  {
601  $path = '/path/to/your/file';
602 
603  $this->filesystemMock->shouldReceive('delete')
604  ->once()
605  ->with($path)
606  ->andThrow(UnableToDeleteFile::class);
607 
608  $this->expectException(IOException::class);
609  $this->expectExceptionMessage(
610  "Could not delete file \"$path\" because a general IO error occurred. Please check that your target is writable."
611  );
612 
613  $this->subject->delete($path);
614  }
615 
621  {
622  $path = '/path/to/your/file';
623 
624  $this->filesystemMock->shouldReceive('delete')
625  ->once()
626  ->with($path)
627  ->andThrow(UnableToRetrieveMetadata::class);
628 
629  $this->expectException(\ILIAS\Filesystem\Exception\FileNotFoundException::class);
630  $this->expectExceptionMessage("File \"$path\" was not found delete operation failed.");
631 
632  $this->subject->delete($path);
633  }
634 
640  public function testReadAndDeleteWhichShouldSucceed(): void
641  {
642  $path = '/path/to/your/file';
643  $content = "awesome content";
644 
645  //partially mock the subject to intercept the method calls of the own object.
646  $this->subject = Mockery::mock(FlySystemFileAccess::class, [$this->filesystemMock])->makePartial();
647 
648  $this->subject
649  ->shouldReceive('read')
650  ->once()
651  ->with($path)
652  ->andReturn($content)
653  ->getMock()
654  ->shouldReceive('delete')
655  ->once()
656  ->with($path);
657 
658  $this->subject->readAndDelete($path);
659  }
660 
665  public function testRenameWhichShouldSucceed(): void
666  {
667  $source = '/source/path';
668  $destination = '/dest/path';
669 
670  $this->filesystemMock
671  ->shouldReceive('has')
672  ->once()
673  ->with($destination)
674  ->andReturn(false)
675  ->getMock()
676  ->shouldReceive('move')
677  ->once()
678  ->withArgs([$source, $destination])
679  ->andReturn(true);
680 
681  $this->subject->rename($source, $destination);
682  }
683 
689  {
690  $source = '/source/path';
691  $destination = '/dest/path';
692 
693  $this->filesystemMock
694  ->shouldReceive('has')
695  ->once()
696  ->with($destination)
697  ->andReturn(false)
698  ->getMock()
699  ->shouldReceive('move')
700  ->once()
701  ->withArgs([$source, $destination])
702  ->andThrow(UnableToRetrieveMetadata::class);
703 
704  $this->expectException(\ILIAS\Filesystem\Exception\FileNotFoundException::class);
705  $this->expectExceptionMessage("File \"$source\" not found.");
706 
707  $this->subject->rename($source, $destination);
708  }
709 
715  {
716  $source = '/source/path';
717  $destination = '/dest/path';
718 
719  $this->filesystemMock
720  ->shouldReceive('has')
721  ->once()
722  ->with($destination)
723  ->andReturn(true)
724  ->getMock()
725  ->shouldReceive('move')
726  ->never()
727  ->withArgs([$source, $destination])
728  ->andThrow(UnableToMoveFile::class);
729 
730  $this->expectException(IOException::class);
731  $this->expectExceptionMessage("File \"$destination\" already exists.");
732 
733  $this->subject->rename($source, $destination);
734  }
735 
741  {
742  $source = '/source/path';
743  $destination = '/dest/path';
744 
745  $this->filesystemMock
746  ->shouldReceive('has')
747  ->once()
748  ->with($destination)
749  ->andReturn(false)
750  ->getMock()
751  ->shouldReceive('move')
752  ->once()
753  ->withArgs([$source, $destination])
754  ->andThrow(UnableToMoveFile::class);
755 
756  $this->expectException(IOException::class);
757  $this->expectExceptionMessage("Could not move file from \"$source\" to \"$destination\".");
758 
759  $this->subject->rename($source, $destination);
760  }
761 
766  public function testCopyWhichShouldSucceed(): void
767  {
768  $sourcePath = '/path/to/your/source/file';
769  $destinationPath = '/path/to/your/destination/file';
770 
771  $this->filesystemMock
772  ->shouldReceive('has')
773  ->once()
774  ->with($destinationPath)
775  ->andReturn(false)
776  ->getMock()
777  ->shouldReceive('copy')
778  ->once()
779  ->withArgs([$sourcePath, $destinationPath])
780  ->andReturn(true);
781 
782  $this->subject->copy($sourcePath, $destinationPath);
783  }
784 
790  {
791  $sourcePath = '/path/to/your/source/file';
792  $destinationPath = '/path/to/your/destination/file';
793 
794  $this->filesystemMock
795  ->shouldReceive('has')
796  ->once()
797  ->with($destinationPath)
798  ->andReturn(false)
799  ->getMock()
800  ->shouldReceive('copy')
801  ->once()
802  ->withArgs([$sourcePath, $destinationPath])
803  ->andThrow(UnableToCopyFile::class);
804 
805  $this->expectException(IOException::class);
806  $this->expectExceptionMessage(
807  "Could not copy file \"$sourcePath\" to destination \"$destinationPath\" because a general IO error occurred. Please check that your destination is writable."
808  );
809 
810  $this->subject->copy($sourcePath, $destinationPath);
811  }
812 
818  {
819  $sourcePath = '/path/to/your/source/file';
820  $destinationPath = '/path/to/your/destination/file';
821 
822  $this->filesystemMock
823  ->shouldReceive('has')
824  ->once()
825  ->with($destinationPath)
826  ->andReturn(false)
827  ->getMock()
828  ->shouldReceive('copy')
829  ->once()
830  ->withArgs([$sourcePath, $destinationPath])
831  ->andThrow(UnableToRetrieveMetadata::class);
832 
833  $this->expectException(\ILIAS\Filesystem\Exception\FileNotFoundException::class);
834  $this->expectExceptionMessage("File source \"$sourcePath\" was not found copy failed.");
835 
836  $this->subject->copy($sourcePath, $destinationPath);
837  }
838 
844  {
845  $sourcePath = '/path/to/your/source/file';
846  $destinationPath = '/path/to/your/destination/file';
847 
848  $this->filesystemMock
849  ->shouldReceive('has')
850  ->once()
851  ->with($destinationPath)
852  ->andReturn(true)
853  ->getMock()
854  ->shouldReceive('copy')
855  ->never()
856  ->withArgs([$sourcePath, $destinationPath])
857  ->andThrow(UnableToCopyFile::class);
858 
859  $this->expectException(FileAlreadyExistsException::class);
860  $this->expectExceptionMessage("File \"$destinationPath\" already exists.");
861 
862  $this->subject->copy($sourcePath, $destinationPath);
863  }
864 }
Class ChatMainBarProvider .
This class provides the data size with additional information to remove the work to calculate the siz...
Definition: DataSize.php:30
$datetime
setUp()
Sets up the fixture, for example, open a network connection.
$path
Definition: ltiservices.php:32
League Flysystem Filesystem Mockery MockInterface $filesystemMock
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ILIAS Filesystem Provider FlySystem FlySystemFileAccess $subject
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:70