1<?php 2 3namespace Elgg\Filesystem; 4 5/** 6 * @group UnitTests 7 */ 8abstract class DirectoryUnitTest extends \Elgg\UnitTestCase { 9 10 /** 11 * Returns an array of one-element arrays. Those elements should 12 * be fresh (empty) directory instances that use the relevant implementation. 13 * 14 * @return array 15 */ 16 abstract public function emptyDirectoryProvider(); 17 18 public function up() { 19 20 } 21 22 public function down() { 23 24 } 25 26 /** 27 * @dataProvider emptyDirectoryProvider 28 */ 29 public function testListFilesAndDirsInTheDirectory(Directory $directory) { 30 $directory->putContents('/foo/bar/bar.php', 'bar'); 31 $directory->putContents('/foo/baz/baz.php', 'baz'); 32 $directory->putContents('/foo/foo.php', 'foo'); 33 $directory->putContents('/qux.php', 'qux'); 34 35 $this->assertEquals(4, count($directory->getFiles())); 36 $this->assertEquals(1, count($directory->getFiles('', false))); 37 38 $this->assertEquals(3, count($directory->getDirectories())); 39 $this->assertEquals(1, count($directory->getDirectories('', false))); 40 } 41 42 /** 43 * @dataProvider emptyDirectoryProvider 44 */ 45 public function testListFilesAndDirsInASubdirectory(Directory $directory) { 46 $directory->putContents('/foo/bar/bar.php', 'bar'); 47 $directory->putContents('/foo/baz/baz.php', 'baz'); 48 $directory->putContents('/foo/baz/bing/foo.php', 'foo'); 49 $directory->putContents('/foo/foo.php', 'foo'); 50 $directory->putContents('/qux.php', 'qux'); 51 52 foreach (['foo', '/foo', 'foo/', '/foo/'] as $path) { 53 $this->assertEquals(4, count($directory->getFiles($path))); 54 $this->assertEquals(1, count($directory->getFiles($path, false))); 55 56 $this->assertEquals(3, count($directory->getDirectories($path))); 57 $this->assertEquals(2, count($directory->getDirectories($path, false))); 58 } 59 } 60 61 /** 62 * @dataProvider emptyDirectoryProvider 63 */ 64 public function testChrootReturnsANewDirectoryThatOnlyHasAccessToTheGivenSubdir(Directory $directory) { 65 $directory->putContents('/foo/bar/bar.php', 'bar'); 66 $directory->putContents('/foo/baz/baz.php', 'baz'); 67 $directory->putContents('/foo/foo.php', 'foo'); 68 $directory->putContents('/qux.php', 'qux'); 69 70 $this->assertEquals(3, count($directory->chroot('/foo/')->getFiles())); 71 $this->assertEquals(3, count($directory->chroot('foo/')->getFiles())); 72 $this->assertEquals(3, count($directory->chroot('/foo')->getFiles())); 73 $this->assertEquals(3, count($directory->chroot('foo')->getFiles())); 74 75 $this->assertEquals(1, count($directory->chroot('/foo/bar/')->getFiles())); 76 $this->assertEquals(1, count($directory->chroot('foo/bar/')->getFiles())); 77 $this->assertEquals(1, count($directory->chroot('/foo/bar')->getFiles())); 78 $this->assertEquals(1, count($directory->chroot('foo/bar')->getFiles())); 79 } 80 81 /** 82 * @dataProvider emptyDirectoryProvider 83 */ 84 public function testCanGetAnyFileInThisDirectoryEvenIfTheFileDoesNotExistYet(Directory $directory) { 85 $this->assertFalse($directory->getFile('foo.php')->exists()); 86 } 87 88 /** 89 * @dataProvider emptyDirectoryProvider 90 */ 91 public function testPathsCannotContainDots(Directory $directory) { 92 $funcs = [ 93 function () use ($directory) { 94 $directory->chroot('.'); 95 }, 96 function () use ($directory) { 97 $directory->chroot('..'); 98 }, 99 function () use ($directory) { 100 $directory->getFile('.'); 101 }, 102 function () use ($directory) { 103 $directory->getFile('..'); 104 }, 105 ]; 106 107 foreach ($funcs as $i => $f) { 108 try { 109 $f(); 110 $this->fail("A path was allowed to contain . or .. in function #$i"); 111 } catch (\InvalidArgumentException $e) { 112 113 } 114 } 115 } 116 117 /** 118 * @dataProvider emptyDirectoryProvider 119 */ 120 public function testCanGetFileInsideItself(Directory $directory) { 121 $directory->putContents('/foo/bar.php', 'bar'); 122 123 $file = $directory->chroot('foo')->getFile('bar.php'); 124 125 $this->assertInstanceOf(File::class, $file); 126 127 $this->assertEquals('bar', $file->getContents()); 128 } 129 130 /** 131 * @dataProvider emptyDirectoryProvider 132 */ 133 public function testCanGetDirectoryInsideItself(Directory $directory) { 134 $directory->putContents('/foo/bar/bang.php', 'bang'); 135 $directory->putContents('/foo/boom/bang.php', 'bang'); 136 137 $dirs = $directory->getDirectories('foo'); 138 $this->assertCount(2, $dirs); 139 foreach ($dirs as $dir) { 140 $this->assertInstanceOf(Directory::class, $dir); 141 $this->assertEquals('bang', $dir->getFile('bang.php')->getContents()); 142 } 143 } 144 145} 146