ILIAS  trunk Revision v11.0_alpha-1843-g9e1fad99175
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
FlySystemFileAccessTestTBD.php
Go to the documentation of this file.
1 <?php
2 
20 
31 use Mockery;
43 
48 class FlySystemFileAccessTest extends TestCase
49 {
51 
53  private Filesystem|MockInterface $filesystemMock;
57  private 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 
336  #[Test]
337 
339  {
340  $path = '/path/to/your/file';
341  $visibility = "private";
342 
343  $this->filesystemMock->shouldReceive('has')
344  ->once()
345  ->with($path)
346  ->andReturn(false);
347 
348  $this->expectException(FileNotFoundException::class);
349  $this->expectExceptionMessage("Path \"$path\" not found.");
350 
351  $this->subject->setVisibility($path, $visibility);
352  }
353 
354  #[Test]
355 
357  {
358  $path = '/path/to/your/file';
359  $visibility = "not valid";
360 
361  $this->filesystemMock->shouldReceive('has')
362  ->once()
363  ->with($path)
364  ->andReturn(true);
365 
366  $this->expectException(\InvalidArgumentException::class);
367  $this->expectExceptionMessage("The access must be 'public' or 'private' but '$visibility' was given.");
368 
369  $this->subject->setVisibility($path, $visibility);
370  }
371 
372  #[Test]
373 
374  public function testGetVisibilityWhichShouldSucceed(): void
375  {
376  $path = '/path/to/your/file';
377  $visibility = "private";
378 
379  $this->filesystemMock->shouldReceive('has')
380  ->once()
381  ->with($path)
382  ->andReturn(true);
383 
384  $this->filesystemMock->shouldReceive('getVisibility')
385  ->once()
386  ->with($path)
387  ->andReturn($visibility);
388 
389  $actualVisibility = $this->subject->getVisibility($path);
390  $this->assertSame($visibility, $actualVisibility);
391  }
392 
393  #[Test]
394 
396  {
397  $path = '/path/to/your/file';
398 
399  $this->filesystemMock->shouldReceive('has')
400  ->once()
401  ->with($path)
402  ->andReturn(false);
403 
404  $this->expectException(FileNotFoundException::class);
405  $this->expectExceptionMessage("Path \"$path\" not found.");
406 
407  $this->subject->getVisibility($path);
408  }
409 
410  #[Test]
411 
413  {
414  $path = '/path/to/your/file';
415 
416  $this->filesystemMock->shouldReceive('has')
417  ->once()
418  ->with($path)
419  ->andReturn(true);
420 
421  $this->filesystemMock->shouldReceive('getVisibility')
422  ->once()
423  ->with($path)
424  ->andReturn(false);
425 
426  $this->expectException(IOException::class);
427  $this->expectExceptionMessage("Could not determine visibility for path '$path'.");
428 
429  $this->subject->getVisibility($path);
430  }
431 
432  #[Test]
433 
434  public function testWriteWhichShouldSucceed(): void
435  {
436  $path = '/path/to/your/file';
437  $content = "some awesome content";
438 
439  $this->filesystemMock
440  ->shouldReceive('has')
441  ->once()
442  ->with($path)
443  ->andReturn(false)
444  ->getMock()
445  ->shouldReceive('write')
446  ->once()
447  ->withArgs([$path, $content]);
448 
449  $this->subject->write($path, $content);
450  }
451 
452  #[Test]
453 
455  {
456  $path = '/path/to/your/file';
457  $content = "some awesome content";
458 
459  $this->filesystemMock
460  ->shouldReceive('has')
461  ->once()
462  ->with($path)
463  ->andReturn(true)
464  ->shouldReceive('write')
465  ->never()
466  ->withArgs([$path, $content])
467  ->andThrow(UnableToWriteFile::class);
468 
469  $this->expectException(FileAlreadyExistsException::class);
470  $this->expectExceptionMessage("File \"$path\" already exists.");
471 
472  $this->subject->write($path, $content);
473  }
474 
475  #[Test]
476 
478  {
479  $path = '/path/to/your/file';
480  $content = "some awesome content";
481 
482  $this->filesystemMock
483  ->shouldReceive('has')
484  ->once()
485  ->with($path)
486  ->andReturn(false)
487  ->getMock()
488  ->shouldReceive('write')
489  ->once()
490  ->withArgs([$path, $content])
491  ->andThrow(UnableToWriteFile::class);
492 
493  $this->expectException(IOException::class);
494  $this->expectExceptionMessage(
495  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
496  );
497 
498  $this->subject->write($path, $content);
499  }
500 
501  #[Test]
502 
503  public function testUpdateWhichShouldSucceed(): void
504  {
505  $path = '/path/to/your/file';
506  $content = "some awesome content";
507 
508  $this->filesystemMock->shouldReceive('write')
509  ->once()
510  ->withArgs([$path, $content])
511  ->andReturn(true);
512 
513  $this->subject->update($path, $content);
514  }
515 
516  #[Test]
517 
519  {
520  $path = '/path/to/your/file';
521  $content = "some awesome content";
522 
523  $this->filesystemMock->shouldReceive('write')
524  ->once()
525  ->withArgs([$path, $content])
526  ->andThrow(UnableToWriteFile::class);
527 
528  $this->expectException(IOException::class);
529  $this->expectExceptionMessage(
530  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
531  );
532 
533  $this->subject->update($path, $content);
534  }
535 
536  #[Test]
537 
539  {
540  $path = '/path/to/your/file';
541  $content = "some awesome content";
542 
543  $this->filesystemMock
544  ->shouldReceive('write')
545  ->once()
546  ->withArgs([$path, $content])
547  ->andThrow(UnableToWriteFile::class);
548 
549  $this->expectException(IOException::class);
550  $this->expectExceptionMessage(
551  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
552  );
553 
554  $this->subject->update($path, $content);
555  }
556 
557  #[Test]
558 
559  public function testDeleteWhichShouldSucceed(): void
560  {
561  $path = '/path/to/your/file';
562 
563  $this->filesystemMock->shouldReceive('delete')
564  ->once()
565  ->with($path)
566  ->andReturn(true);
567 
568  $this->subject->delete($path);
569  }
570 
571  #[Test]
572 
574  {
575  $path = '/path/to/your/file';
576 
577  $this->filesystemMock->shouldReceive('delete')
578  ->once()
579  ->with($path)
580  ->andThrow(UnableToDeleteFile::class);
581 
582  $this->expectException(IOException::class);
583  $this->expectExceptionMessage(
584  "Could not delete file \"$path\" because a general IO error occurred. Please check that your target is writable."
585  );
586 
587  $this->subject->delete($path);
588  }
589 
590  #[Test]
591 
593  {
594  $path = '/path/to/your/file';
595 
596  $this->filesystemMock->shouldReceive('delete')
597  ->once()
598  ->with($path)
599  ->andThrow(UnableToRetrieveMetadata::class);
600 
601  $this->expectException(FileNotFoundException::class);
602  $this->expectExceptionMessage("File \"$path\" was not found delete operation failed.");
603 
604  $this->subject->delete($path);
605  }
606 
607  #[Test]
608 
609  public function testReadAndDeleteWhichShouldSucceed(): void
610  {
611  $path = '/path/to/your/file';
612  $content = "awesome content";
613 
614  //partially mock the subject to intercept the method calls of the own object.
615  $this->subject = Mockery::mock(FlySystemFileAccess::class, [$this->filesystemMock])->makePartial();
616 
617  $this->subject
618  ->shouldReceive('read')
619  ->once()
620  ->with($path)
621  ->andReturn($content)
622  ->getMock()
623  ->shouldReceive('delete')
624  ->once()
625  ->with($path);
626 
627  $this->subject->readAndDelete($path);
628  }
629 
630  #[Test]
631 
632  public function testRenameWhichShouldSucceed(): void
633  {
634  $source = '/source/path';
635  $destination = '/dest/path';
636 
637  $this->filesystemMock
638  ->shouldReceive('has')
639  ->once()
640  ->with($destination)
641  ->andReturn(false)
642  ->getMock()
643  ->shouldReceive('move')
644  ->once()
645  ->withArgs([$source, $destination])
646  ->andReturn(true);
647 
648  $this->subject->rename($source, $destination);
649  }
650 
651  #[Test]
652 
654  {
655  $source = '/source/path';
656  $destination = '/dest/path';
657 
658  $this->filesystemMock
659  ->shouldReceive('has')
660  ->once()
661  ->with($destination)
662  ->andReturn(false)
663  ->getMock()
664  ->shouldReceive('move')
665  ->once()
666  ->withArgs([$source, $destination])
667  ->andThrow(UnableToRetrieveMetadata::class);
668 
669  $this->expectException(FileNotFoundException::class);
670  $this->expectExceptionMessage("File \"$source\" not found.");
671 
672  $this->subject->rename($source, $destination);
673  }
674 
675  #[Test]
676 
678  {
679  $source = '/source/path';
680  $destination = '/dest/path';
681 
682  $this->filesystemMock
683  ->shouldReceive('has')
684  ->once()
685  ->with($destination)
686  ->andReturn(true)
687  ->getMock()
688  ->shouldReceive('move')
689  ->never()
690  ->withArgs([$source, $destination])
691  ->andThrow(UnableToMoveFile::class);
692 
693  $this->expectException(IOException::class);
694  $this->expectExceptionMessage("File \"$destination\" already exists.");
695 
696  $this->subject->rename($source, $destination);
697  }
698 
699  #[Test]
700 
702  {
703  $source = '/source/path';
704  $destination = '/dest/path';
705 
706  $this->filesystemMock
707  ->shouldReceive('has')
708  ->once()
709  ->with($destination)
710  ->andReturn(false)
711  ->getMock()
712  ->shouldReceive('move')
713  ->once()
714  ->withArgs([$source, $destination])
715  ->andThrow(UnableToMoveFile::class);
716 
717  $this->expectException(IOException::class);
718  $this->expectExceptionMessage("Could not move file from \"$source\" to \"$destination\".");
719 
720  $this->subject->rename($source, $destination);
721  }
722 
723  #[Test]
724 
725  public function testCopyWhichShouldSucceed(): void
726  {
727  $sourcePath = '/path/to/your/source/file';
728  $destinationPath = '/path/to/your/destination/file';
729 
730  $this->filesystemMock
731  ->shouldReceive('has')
732  ->once()
733  ->with($destinationPath)
734  ->andReturn(false)
735  ->getMock()
736  ->shouldReceive('copy')
737  ->once()
738  ->withArgs([$sourcePath, $destinationPath])
739  ->andReturn(true);
740 
741  $this->subject->copy($sourcePath, $destinationPath);
742  }
743 
744  #[Test]
745 
747  {
748  $sourcePath = '/path/to/your/source/file';
749  $destinationPath = '/path/to/your/destination/file';
750 
751  $this->filesystemMock
752  ->shouldReceive('has')
753  ->once()
754  ->with($destinationPath)
755  ->andReturn(false)
756  ->getMock()
757  ->shouldReceive('copy')
758  ->once()
759  ->withArgs([$sourcePath, $destinationPath])
760  ->andThrow(UnableToCopyFile::class);
761 
762  $this->expectException(IOException::class);
763  $this->expectExceptionMessage(
764  "Could not copy file \"$sourcePath\" to destination \"$destinationPath\" because a general IO error occurred. Please check that your destination is writable."
765  );
766 
767  $this->subject->copy($sourcePath, $destinationPath);
768  }
769 
770  #[Test]
771 
773  {
774  $sourcePath = '/path/to/your/source/file';
775  $destinationPath = '/path/to/your/destination/file';
776 
777  $this->filesystemMock
778  ->shouldReceive('has')
779  ->once()
780  ->with($destinationPath)
781  ->andReturn(false)
782  ->getMock()
783  ->shouldReceive('copy')
784  ->once()
785  ->withArgs([$sourcePath, $destinationPath])
786  ->andThrow(UnableToRetrieveMetadata::class);
787 
788  $this->expectException(FileNotFoundException::class);
789  $this->expectExceptionMessage("File source \"$sourcePath\" was not found copy failed.");
790 
791  $this->subject->copy($sourcePath, $destinationPath);
792  }
793 
794  #[Test]
795 
797  {
798  $sourcePath = '/path/to/your/source/file';
799  $destinationPath = '/path/to/your/destination/file';
800 
801  $this->filesystemMock
802  ->shouldReceive('has')
803  ->once()
804  ->with($destinationPath)
805  ->andReturn(true)
806  ->getMock()
807  ->shouldReceive('copy')
808  ->never()
809  ->withArgs([$sourcePath, $destinationPath])
810  ->andThrow(UnableToCopyFile::class);
811 
812  $this->expectException(FileAlreadyExistsException::class);
813  $this->expectExceptionMessage("File \"$destinationPath\" already exists.");
814 
815  $this->subject->copy($sourcePath, $destinationPath);
816  }
817 }
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:29
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:70