ILIAS  trunk Revision v11.0_alpha-2658-ge2404539063
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;
54 
59  protected function setUp(): void
60  {
61  parent::setUp();
62 
63  $this->filesystemMock = Mockery::mock(FilesystemOperator::class);
64  $adapterMock = Mockery::mock(FilesystemAdapter::class);
65  $this->subject = new FlySystemFileAccess($this->filesystemMock);
66  }
67 
68  public function testReadWhichShouldSucceed(): void
69  {
70  $file_content = 'Test file content.';
71  $path = '/path/to/your/file';
72 
73  $this->filesystemMock->shouldReceive('has')
74  ->once()
75  ->with(ltrim($path, '/'))
76  ->andReturn(true);
77 
78  $this->filesystemMock->shouldReceive('read')
79  ->with(ltrim($path, '/'))
80  ->once()
81  ->andReturn($file_content);
82 
83 
84  $actualContent = $this->subject->read($path);
85  $this->assertSame($file_content, $actualContent);
86  }
87 
89  {
90  $path = '/path/to/your/file';
91 
92  $this->filesystemMock->shouldReceive('has')
93  ->once()
94  ->with(ltrim($path, '/'))
95  ->andReturn(true);
96 
97  $this->filesystemMock->shouldReceive('read')
98  ->with(ltrim($path, '/'))
99  ->once()
100  ->andReturn(false);
101 
102 
103  $this->expectException(IOException::class);
104  $this->expectExceptionMessage('File "' . ltrim($path, '/') . '" not found.');
105  $actualContent = $this->subject->read($path);
106  }
107 
109  {
110 
111  $path = '/path/to/your/file';
112 
113  $this->filesystemMock->shouldReceive('has')
114  ->once()
115  ->with(ltrim($path, '/'))
116  ->andReturn(false);
117 
118  $this->filesystemMock->shouldReceive('read')
119  ->never();
120 
121 
122  $this->expectException(IOException::class);
123  $this->expectExceptionMessage('File "' . ltrim($path, '/') . '" not found.');
124  $actualContent = $this->subject->read($path);
125  }
126 
127  public function testGetMimeTypeWhichShouldSucceed(): void
128  {
129  $mimeType = 'image/jpeg';
130  $this->filesystemMock->shouldReceive('mimeType')
131  ->once()
132  ->andReturn($mimeType);
133 
134  $actualMimeType = $this->subject->getMimeType('/path/to/your/file');
135  $this->assertSame($mimeType, $actualMimeType);
136  }
137 
138  public function testPutContentExistingFile(): void
139  {
140  $content = 'Test file content.';
141  $this->filesystemMock->shouldReceive('has')
142  ->once()
143  ->andReturn(true);
144  $this->filesystemMock->shouldReceive('write')
145  ->with('/path/to/your/file', $content)
146  ->once()
147  ->andReturn(true);
148 
149  $this->subject->put('/path/to/your/file', $content);
150  }
151 
152  public function testPutContentNonExistingFile(): void
153  {
154  $content = 'Test file content.';
155  $this->filesystemMock->shouldReceive('has')
156  ->twice()
157  ->andReturn(false);
158 
159  $this->filesystemMock->shouldReceive('write')
160  ->with('/path/to/your/file', $content)
161  ->once()
162  ->andReturn(true);
163 
164  $this->subject->put('/path/to/your/file', $content);
165  }
166 
167 
169  {
170  $path = '/path/to/your/file';
171  $this->filesystemMock->shouldReceive('mimeType')
172  ->with($path)
173  ->once()
174  ->andReturn('');
175 
176  $this->expectException(IOException::class);
177  $this->expectExceptionMessage("Could not determine the MIME type of the file \"$path\".");
178 
179  $this->subject->getMimeType($path);
180  }
181 
183  {
184  $path = '/path/to/your/file';
185  $this->filesystemMock->shouldReceive('mimeType')
186  ->once()
187  ->with($path)
188  ->andThrow(UnableToRetrieveMetadata::class);
189 
190  $this->expectException(IOException::class);
191  $this->expectExceptionMessage("File \"$path\" not found.");
192 
193  $this->subject->getMimeType($path);
194  }
195 
196  public function testGetTimestampWhichShouldSucceed(): void
197  {
198  $datetime = '2012-02-06';
199  $timestamp = strtotime($datetime);
200  $this->filesystemMock
201  ->shouldReceive('lastModified')
202  ->once()
203  ->andReturn($timestamp);
204 
205  $actualTimestamp = $this->subject->getTimestamp('/path/to/your/file');
206 
207  /*
208  * needs to be equals instead of same because == checks if the object content is the same and === seems to check the reference too
209  * eg.
210  * $a == $b => true
211  * $a === $b => false
212  * $a === $a => true
213  * $b === $b => true
214  *
215  * Danger; this is only the observed behaviour and was not documented at least the part with the === operator.
216  * Tested with DateTime objects (PHP 7.1.6)
217  */
218  $this->assertEquals(new \DateTime($datetime), $actualTimestamp);
219  }
220 
222  {
223  $path = '/path/to/your/file';
224  $this->filesystemMock
225  ->shouldReceive('lastModified')
226  ->with($path)
227  ->once()
228  ->andThrow(UnableToRetrieveMetadata::class);
229 
230  $this->expectException(IOException::class);
231  $this->expectExceptionMessage("Could not lookup timestamp of the file \"$path\".");
232 
233  $this->subject->getTimestamp($path);
234  }
235 
237  {
238  $path = '/path/to/your/file';
239  $this->filesystemMock
240  ->shouldReceive('lastModified')
241  ->once()
242  ->with($path)
243  ->andThrow(UnableToReadFile::class);
244 
245  $this->expectException(IOException::class);
246  $this->expectExceptionMessage("File \"$path\" not found.");
247 
248  $this->subject->getTimestamp($path);
249  }
250 
251  public function testGetSizeWhichShouldSucceed(): void
252  {
253  $rawSize = 1024;
254  $size = new DataSize($rawSize, DataSize::KiB); //floating point is never that precise.
255 
256  $this->filesystemMock->shouldReceive('fileSize')
257  ->once()
258  ->andReturn($rawSize);
259 
260  $actualSize = $this->subject->getSize('/path/to/your/file', DataSize::KiB);
261  $this->assertSame($size->getSize(), $actualSize->getSize(), '');
262  }
263 
265  {
266  $path = '/path/to/your/file';
267  $this->filesystemMock
268  ->shouldReceive('fileSize')
269  ->with($path)
270  ->once()
271  ->andThrow(UnableToRetrieveMetadata::class);
272 
273  $this->expectException(IOException::class);
274  $this->expectExceptionMessage("File \"$path\" not found.");
275 
276  $this->subject->getSize($path, DataSize::MiB);
277  }
278 
280  {
281  $path = '/path/to/your/file';
282  $this->filesystemMock
283  ->shouldReceive('fileSize')
284  ->once()
285  ->with($path)
286  ->andThrow(UnableToRetrieveMetadata::class);
287 
288  $this->expectException(IOException::class);
289  $this->expectExceptionMessage("File \"$path\" not found.");
290 
291  $this->subject->getSize($path, DataSize::GiB);
292  }
293 
294  public function testSetVisibilityWhichShouldSucceed(): void
295  {
296  $path = '/path/to/your/file';
297  $visibility = "private";
298 
299  $this->filesystemMock->shouldReceive('has')
300  ->once()
301  ->with($path)
302  ->andReturn(true);
303 
304  $this->filesystemMock->shouldReceive('setVisibility')
305  ->once()
306  ->withArgs([$path, $visibility])
307  ->andReturn(true);
308 
309  $operationSuccessful = $this->subject->setVisibility($path, $visibility);
310  $this->assertTrue($operationSuccessful);
311  }
312 
314  {
315  $path = '/path/to/your/file';
316  $visibility = "private";
317 
318  $this->filesystemMock->shouldReceive('has')
319  ->once()
320  ->with($path)
321  ->andReturn(true);
322 
323  $this->filesystemMock->shouldReceive('setVisibility')
324  ->once()
325  ->withArgs([$path, $visibility])
326  ->andThrow(UnableToSetVisibility::class);
327 
328  $operationSuccessful = $this->subject->setVisibility($path, $visibility);
329  $this->assertFalse($operationSuccessful);
330  }
331 
332  #[Test]
333 
335  {
336  $path = '/path/to/your/file';
337  $visibility = "private";
338 
339  $this->filesystemMock->shouldReceive('has')
340  ->once()
341  ->with($path)
342  ->andReturn(false);
343 
344  $this->expectException(FileNotFoundException::class);
345  $this->expectExceptionMessage("Path \"$path\" not found.");
346 
347  $this->subject->setVisibility($path, $visibility);
348  }
349 
350  #[Test]
351 
353  {
354  $path = '/path/to/your/file';
355  $visibility = "not valid";
356 
357  $this->filesystemMock->shouldReceive('has')
358  ->once()
359  ->with($path)
360  ->andReturn(true);
361 
362  $this->expectException(\InvalidArgumentException::class);
363  $this->expectExceptionMessage("The access must be 'public' or 'private' but '$visibility' was given.");
364 
365  $this->subject->setVisibility($path, $visibility);
366  }
367 
368  #[Test]
369 
370  public function testGetVisibilityWhichShouldSucceed(): void
371  {
372  $path = '/path/to/your/file';
373  $visibility = "private";
374 
375  $this->filesystemMock->shouldReceive('has')
376  ->once()
377  ->with($path)
378  ->andReturn(true);
379 
380  $this->filesystemMock->shouldReceive('getVisibility')
381  ->once()
382  ->with($path)
383  ->andReturn($visibility);
384 
385  $actualVisibility = $this->subject->getVisibility($path);
386  $this->assertSame($visibility, $actualVisibility);
387  }
388 
389  #[Test]
390 
392  {
393  $path = '/path/to/your/file';
394 
395  $this->filesystemMock->shouldReceive('has')
396  ->once()
397  ->with($path)
398  ->andReturn(false);
399 
400  $this->expectException(FileNotFoundException::class);
401  $this->expectExceptionMessage("Path \"$path\" not found.");
402 
403  $this->subject->getVisibility($path);
404  }
405 
406  #[Test]
407 
409  {
410  $path = '/path/to/your/file';
411 
412  $this->filesystemMock->shouldReceive('has')
413  ->once()
414  ->with($path)
415  ->andReturn(true);
416 
417  $this->filesystemMock->shouldReceive('getVisibility')
418  ->once()
419  ->with($path)
420  ->andReturn(false);
421 
422  $this->expectException(IOException::class);
423  $this->expectExceptionMessage("Could not determine visibility for path '$path'.");
424 
425  $this->subject->getVisibility($path);
426  }
427 
428  #[Test]
429 
430  public function testWriteWhichShouldSucceed(): void
431  {
432  $path = '/path/to/your/file';
433  $content = "some awesome content";
434 
435  $this->filesystemMock
436  ->shouldReceive('has')
437  ->once()
438  ->with($path)
439  ->andReturn(false)
440  ->getMock()
441  ->shouldReceive('write')
442  ->once()
443  ->withArgs([$path, $content]);
444 
445  $this->subject->write($path, $content);
446  }
447 
448  #[Test]
449 
451  {
452  $path = '/path/to/your/file';
453  $content = "some awesome content";
454 
455  $this->filesystemMock
456  ->shouldReceive('has')
457  ->once()
458  ->with($path)
459  ->andReturn(true)
460  ->shouldReceive('write')
461  ->never()
462  ->withArgs([$path, $content])
463  ->andThrow(UnableToWriteFile::class);
464 
465  $this->expectException(FileAlreadyExistsException::class);
466  $this->expectExceptionMessage("File \"$path\" already exists.");
467 
468  $this->subject->write($path, $content);
469  }
470 
471  #[Test]
472 
474  {
475  $path = '/path/to/your/file';
476  $content = "some awesome content";
477 
478  $this->filesystemMock
479  ->shouldReceive('has')
480  ->once()
481  ->with($path)
482  ->andReturn(false)
483  ->getMock()
484  ->shouldReceive('write')
485  ->once()
486  ->withArgs([$path, $content])
487  ->andThrow(UnableToWriteFile::class);
488 
489  $this->expectException(IOException::class);
490  $this->expectExceptionMessage(
491  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
492  );
493 
494  $this->subject->write($path, $content);
495  }
496 
497  #[Test]
498 
499  public function testUpdateWhichShouldSucceed(): void
500  {
501  $path = '/path/to/your/file';
502  $content = "some awesome content";
503 
504  $this->filesystemMock->shouldReceive('write')
505  ->once()
506  ->withArgs([$path, $content])
507  ->andReturn(true);
508 
509  $this->subject->update($path, $content);
510  }
511 
512  #[Test]
513 
515  {
516  $path = '/path/to/your/file';
517  $content = "some awesome content";
518 
519  $this->filesystemMock->shouldReceive('write')
520  ->once()
521  ->withArgs([$path, $content])
522  ->andThrow(UnableToWriteFile::class);
523 
524  $this->expectException(IOException::class);
525  $this->expectExceptionMessage(
526  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
527  );
528 
529  $this->subject->update($path, $content);
530  }
531 
532  #[Test]
533 
535  {
536  $path = '/path/to/your/file';
537  $content = "some awesome content";
538 
539  $this->filesystemMock
540  ->shouldReceive('write')
541  ->once()
542  ->withArgs([$path, $content])
543  ->andThrow(UnableToWriteFile::class);
544 
545  $this->expectException(IOException::class);
546  $this->expectExceptionMessage(
547  "Could not write to file \"$path\" because a general IO error occurred. Please check that your destination is writable."
548  );
549 
550  $this->subject->update($path, $content);
551  }
552 
553  #[Test]
554 
555  public function testDeleteWhichShouldSucceed(): void
556  {
557  $path = '/path/to/your/file';
558 
559  $this->filesystemMock->shouldReceive('delete')
560  ->once()
561  ->with($path)
562  ->andReturn(true);
563 
564  $this->subject->delete($path);
565  }
566 
567  #[Test]
568 
570  {
571  $path = '/path/to/your/file';
572 
573  $this->filesystemMock->shouldReceive('delete')
574  ->once()
575  ->with($path)
576  ->andThrow(UnableToDeleteFile::class);
577 
578  $this->expectException(IOException::class);
579  $this->expectExceptionMessage(
580  "Could not delete file \"$path\" because a general IO error occurred. Please check that your target is writable."
581  );
582 
583  $this->subject->delete($path);
584  }
585 
586  #[Test]
587 
589  {
590  $path = '/path/to/your/file';
591 
592  $this->filesystemMock->shouldReceive('delete')
593  ->once()
594  ->with($path)
595  ->andThrow(UnableToRetrieveMetadata::class);
596 
597  $this->expectException(FileNotFoundException::class);
598  $this->expectExceptionMessage("File \"$path\" was not found delete operation failed.");
599 
600  $this->subject->delete($path);
601  }
602 
603  #[Test]
604 
605  public function testReadAndDeleteWhichShouldSucceed(): void
606  {
607  $path = '/path/to/your/file';
608  $content = "awesome content";
609 
610  //partially mock the subject to intercept the method calls of the own object.
611  $this->subject = Mockery::mock(FlySystemFileAccess::class, [$this->filesystemMock])->makePartial();
612 
613  $this->subject
614  ->shouldReceive('read')
615  ->once()
616  ->with($path)
617  ->andReturn($content)
618  ->getMock()
619  ->shouldReceive('delete')
620  ->once()
621  ->with($path);
622 
623  $this->subject->readAndDelete($path);
624  }
625 
626  #[Test]
627 
628  public function testRenameWhichShouldSucceed(): void
629  {
630  $source = '/source/path';
631  $destination = '/dest/path';
632 
633  $this->filesystemMock
634  ->shouldReceive('has')
635  ->once()
636  ->with($destination)
637  ->andReturn(false)
638  ->getMock()
639  ->shouldReceive('move')
640  ->once()
641  ->withArgs([$source, $destination])
642  ->andReturn(true);
643 
644  $this->subject->rename($source, $destination);
645  }
646 
647  #[Test]
648 
650  {
651  $source = '/source/path';
652  $destination = '/dest/path';
653 
654  $this->filesystemMock
655  ->shouldReceive('has')
656  ->once()
657  ->with($destination)
658  ->andReturn(false)
659  ->getMock()
660  ->shouldReceive('move')
661  ->once()
662  ->withArgs([$source, $destination])
663  ->andThrow(UnableToRetrieveMetadata::class);
664 
665  $this->expectException(FileNotFoundException::class);
666  $this->expectExceptionMessage("File \"$source\" not found.");
667 
668  $this->subject->rename($source, $destination);
669  }
670 
671  #[Test]
672 
674  {
675  $source = '/source/path';
676  $destination = '/dest/path';
677 
678  $this->filesystemMock
679  ->shouldReceive('has')
680  ->once()
681  ->with($destination)
682  ->andReturn(true)
683  ->getMock()
684  ->shouldReceive('move')
685  ->never()
686  ->withArgs([$source, $destination])
687  ->andThrow(UnableToMoveFile::class);
688 
689  $this->expectException(IOException::class);
690  $this->expectExceptionMessage("File \"$destination\" already exists.");
691 
692  $this->subject->rename($source, $destination);
693  }
694 
695  #[Test]
696 
698  {
699  $source = '/source/path';
700  $destination = '/dest/path';
701 
702  $this->filesystemMock
703  ->shouldReceive('has')
704  ->once()
705  ->with($destination)
706  ->andReturn(false)
707  ->getMock()
708  ->shouldReceive('move')
709  ->once()
710  ->withArgs([$source, $destination])
711  ->andThrow(UnableToMoveFile::class);
712 
713  $this->expectException(IOException::class);
714  $this->expectExceptionMessage("Could not move file from \"$source\" to \"$destination\".");
715 
716  $this->subject->rename($source, $destination);
717  }
718 
719  #[Test]
720 
721  public function testCopyWhichShouldSucceed(): void
722  {
723  $sourcePath = '/path/to/your/source/file';
724  $destinationPath = '/path/to/your/destination/file';
725 
726  $this->filesystemMock
727  ->shouldReceive('has')
728  ->once()
729  ->with($destinationPath)
730  ->andReturn(false)
731  ->getMock()
732  ->shouldReceive('copy')
733  ->once()
734  ->withArgs([$sourcePath, $destinationPath])
735  ->andReturn(true);
736 
737  $this->subject->copy($sourcePath, $destinationPath);
738  }
739 
740  #[Test]
741 
743  {
744  $sourcePath = '/path/to/your/source/file';
745  $destinationPath = '/path/to/your/destination/file';
746 
747  $this->filesystemMock
748  ->shouldReceive('has')
749  ->once()
750  ->with($destinationPath)
751  ->andReturn(false)
752  ->getMock()
753  ->shouldReceive('copy')
754  ->once()
755  ->withArgs([$sourcePath, $destinationPath])
756  ->andThrow(UnableToCopyFile::class);
757 
758  $this->expectException(IOException::class);
759  $this->expectExceptionMessage(
760  "Could not copy file \"$sourcePath\" to destination \"$destinationPath\" because a general IO error occurred. Please check that your destination is writable."
761  );
762 
763  $this->subject->copy($sourcePath, $destinationPath);
764  }
765 
766  #[Test]
767 
769  {
770  $sourcePath = '/path/to/your/source/file';
771  $destinationPath = '/path/to/your/destination/file';
772 
773  $this->filesystemMock
774  ->shouldReceive('has')
775  ->once()
776  ->with($destinationPath)
777  ->andReturn(false)
778  ->getMock()
779  ->shouldReceive('copy')
780  ->once()
781  ->withArgs([$sourcePath, $destinationPath])
782  ->andThrow(UnableToRetrieveMetadata::class);
783 
784  $this->expectException(FileNotFoundException::class);
785  $this->expectExceptionMessage("File source \"$sourcePath\" was not found copy failed.");
786 
787  $this->subject->copy($sourcePath, $destinationPath);
788  }
789 
790  #[Test]
791 
793  {
794  $sourcePath = '/path/to/your/source/file';
795  $destinationPath = '/path/to/your/destination/file';
796 
797  $this->filesystemMock
798  ->shouldReceive('has')
799  ->once()
800  ->with($destinationPath)
801  ->andReturn(true)
802  ->getMock()
803  ->shouldReceive('copy')
804  ->never()
805  ->withArgs([$sourcePath, $destinationPath])
806  ->andThrow(UnableToCopyFile::class);
807 
808  $this->expectException(FileAlreadyExistsException::class);
809  $this->expectExceptionMessage("File \"$destinationPath\" already exists.");
810 
811  $this->subject->copy($sourcePath, $destinationPath);
812  }
813 }
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