MountManagerTests.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. use League\Flysystem\Adapter\Local;
  3. use League\Flysystem\AdapterInterface;
  4. use League\Flysystem\Filesystem;
  5. use League\Flysystem\FilesystemInterface;
  6. use League\Flysystem\MountManager;
  7. use League\Flysystem\Plugin\ListWith;
  8. use League\Flysystem\Stub\FilesystemSpy;
  9. use PHPUnit\Framework\TestCase;
  10. use Prophecy\Argument;
  11. class MountManagerTests extends TestCase
  12. {
  13. public function testInstantiable()
  14. {
  15. $instance = new MountManager();
  16. $this->assertInstanceOf(MountManager::class, $instance);
  17. }
  18. public function testConstructorInjection()
  19. {
  20. $mock = $this->prophesize(FilesystemInterface::class)->reveal();
  21. $manager = new MountManager([
  22. 'prefix' => $mock,
  23. ]);
  24. $this->assertEquals($mock, $manager->getFilesystem('prefix'));
  25. }
  26. public function testInvalidPrefix()
  27. {
  28. $this->expectException(InvalidArgumentException::class);
  29. $filesystem = $this->prophesize(FilesystemInterface::class)->reveal();
  30. $manager = new MountManager();
  31. $manager->mountFilesystem(false, $filesystem);
  32. }
  33. public function testUndefinedFilesystem()
  34. {
  35. $this->expectException(LogicException::class);
  36. $manager = new MountManager();
  37. $manager->getFilesystem('prefix');
  38. }
  39. public function invalidCallProvider()
  40. {
  41. return [
  42. [[], 'LogicException'],
  43. [[false], 'InvalidArgumentException'],
  44. [['path/without/protocol'], 'InvalidArgumentException'],
  45. ];
  46. }
  47. /**
  48. * @dataProvider invalidCallProvider
  49. */
  50. public function testInvalidArguments($arguments, $exception)
  51. {
  52. $this->expectException($exception);
  53. $manager = new MountManager();
  54. $manager->filterPrefix($arguments);
  55. }
  56. public function testCopyBetweenFilesystems()
  57. {
  58. $manager = new MountManager();
  59. $fs1 = $this->prophesize('League\Flysystem\FilesystemInterface');
  60. $fs2 = $this->prophesize('League\Flysystem\FilesystemInterface');
  61. $manager->mountFilesystem('fs1', $fs1->reveal());
  62. $manager->mountFilesystem('fs2', $fs2->reveal());
  63. $filename = 'test1.txt';
  64. $buffer = tmpfile();
  65. $fs1->readStream($filename)->willReturn($buffer)->shouldBeCalledTimes(1);
  66. $fs2->writeStream($filename, $buffer, [])->willReturn(true)->shouldBeCalledTimes(1);
  67. $response = $manager->copy("fs1://{$filename}", "fs2://{$filename}");
  68. $this->assertTrue($response);
  69. // test failed status
  70. $filename = 'test2.txt';
  71. $fs1->readStream($filename)->willReturn(false)->shouldBeCalledTimes(1);
  72. $status = $manager->copy("fs1://{$filename}", "fs2://{$filename}");
  73. $this->assertFalse($status);
  74. $filename = 'test3.txt';
  75. $fs1->readStream($filename)->willReturn($buffer)->shouldBeCalledTimes(1);
  76. $fs2->writeStream($filename, $buffer, [])->willReturn(false)->shouldBeCalledTimes(1);
  77. $status = $manager->copy("fs1://{$filename}", "fs2://{$filename}");
  78. $this->assertFalse($status);
  79. $filename = 'test4.txt';
  80. $fs1->readStream($filename)->willReturn($buffer)->shouldBeCalledTimes(1);
  81. $fs2->writeStream($filename, $buffer, [])->willReturn(true)->shouldBeCalledTimes(1);
  82. $status = $manager->copy("fs1://{$filename}", "fs2://{$filename}");
  83. $this->assertTrue($status);
  84. }
  85. public function testMoveBetweenFilesystemsCanFail()
  86. {
  87. $manager = new MountManager();
  88. $fs1 = $this->prophesize('League\Flysystem\FilesystemInterface');
  89. $fs2 = $this->prophesize('League\Flysystem\FilesystemInterface');
  90. $manager->mountFilesystem('fs1', $fs1->reveal());
  91. $manager->mountFilesystem('fs2', $fs2->reveal());
  92. $filename = 'test.txt';
  93. $buffer = tmpfile();
  94. $fs1->readStream($filename)->willReturn($buffer);
  95. $fs2->writeStream($filename, $buffer, [])->willReturn(false);
  96. $result = $manager->move("fs1://{$filename}", "fs2://{$filename}");
  97. $this->assertFalse($result);
  98. }
  99. public function testMoveBetweenFilesystemsCanSucceed()
  100. {
  101. $manager = new MountManager();
  102. $fs1 = $this->prophesize('League\Flysystem\FilesystemInterface');
  103. $fs2 = $this->prophesize('League\Flysystem\FilesystemInterface');
  104. $manager->mountFilesystem('fs1', $fs1->reveal());
  105. $manager->mountFilesystem('fs2', $fs2->reveal());
  106. $filename = 'test.txt';
  107. $buffer = tmpfile();
  108. $fs1->readStream($filename)->willReturn($buffer);
  109. $fs2->writeStream($filename, $buffer, [])->willReturn(true);
  110. $fs1->delete($filename)->willReturn(true);
  111. $result = $manager->move("fs1://{$filename}", "fs2://{$filename}");
  112. $this->assertTrue($result);
  113. }
  114. public function testMoveSameFilesystems()
  115. {
  116. $manager = new MountManager();
  117. $fs = $this->prophesize('League\Flysystem\FilesystemInterface');
  118. $manager->mountFilesystem('fs1', $fs->reveal());
  119. $config = ['visibility' => 'private'];
  120. $fs->rename('old.txt', 'new.txt')->willReturn(true);
  121. $fs->setVisibility('new.txt', 'private')->willReturn(true);
  122. $this->assertTrue($manager->move('fs1://old.txt', 'fs1://new.txt'));
  123. $this->assertTrue($manager->move('fs1://old.txt', 'fs1://new.txt', $config));
  124. }
  125. protected function mockFilesystem()
  126. {
  127. $mock = $this->prophesize('League\Flysystem\FilesystemInterface');
  128. $mock->listContents(Argument::type('string'), false)->willReturn([
  129. ['path' => 'path.txt', 'type' => 'file'],
  130. ['path' => 'dirname/path.txt', 'type' => 'file'],
  131. ]);
  132. return $mock->reveal();
  133. }
  134. public function testFileWithAliasWithMountManager()
  135. {
  136. $fs = $this->mockFilesystem();
  137. $fs2 = $this->mockFilesystem();
  138. $mountManager = new MountManager();
  139. $mountManager->mountFilesystem('local', $fs);
  140. $mountManager->mountFilesystem('huge', $fs2);
  141. $results = $mountManager->listContents("local://tests/files");
  142. foreach ($results as $result) {
  143. $this->assertArrayHasKey('filesystem', $result);
  144. $this->assertEquals($result['filesystem'], 'local');
  145. }
  146. $results = $mountManager->listContents("huge://tests/files");
  147. foreach ($results as $result) {
  148. $this->assertArrayHasKey('filesystem', $result);
  149. $this->assertEquals($result['filesystem'], 'huge');
  150. }
  151. }
  152. public function testListWith()
  153. {
  154. $manager = new MountManager();
  155. $fs = new Filesystem(new Local(__DIR__ . '/files'));
  156. $fs->deleteDir('dirname');
  157. $fs->addPlugin(new ListWith());
  158. $fs->write('dirname/file.txt', 'contents');
  159. $listing = $fs->listWith(['timestamp'], 'dirname', false);
  160. $manager->mountFilesystem('prot', $fs);
  161. $this->assertEquals($listing, $manager->listWith(['timestamp'], 'prot://dirname', false));
  162. $fs->deleteDir('dirname');
  163. }
  164. public function provideMountSchemas()
  165. {
  166. return [
  167. ['with.dot'],
  168. ['with-dash'],
  169. ['with+plus'],
  170. ['with:colon']
  171. ];
  172. }
  173. /**
  174. * @dataProvider provideMountSchemas
  175. */
  176. public function testMountSchemaTypes($schema)
  177. {
  178. $manager = new MountManager();
  179. $mock = $this->prophesize(FilesystemInterface::class);
  180. $mock->read('file.ext')->willReturn('a result');
  181. $manager->mountFilesystem($schema, $mock->reveal());
  182. $this->assertEquals($manager->read($schema . '://file.ext'), 'a result');
  183. }
  184. /**
  185. * @dataProvider methodForwardingProvider
  186. */
  187. public function testMethodForwarding($method, array $arguments)
  188. {
  189. $mountManager = new MountManager();
  190. $filesystem = new FilesystemSpy();
  191. $mountManager->mountFilesystem('local', $filesystem);
  192. $expectedCall = FilesystemSpy::class . '::' . $method;
  193. $callingArguments = $arguments;
  194. $callingArguments[0] = "local://{$callingArguments[0]}";
  195. call_user_func_array([$mountManager, $method], $callingArguments);
  196. $this->assertEquals([$expectedCall, $arguments], $filesystem->lastCall);
  197. }
  198. public function methodForwardingProvider()
  199. {
  200. return [
  201. ['write', ['path.txt', 'contents', []]],
  202. ['writeStream', ['path.txt', 'contents', []]],
  203. ['update', ['path.txt', 'contents', []]],
  204. ['updateStream', ['path.txt', 'contents', []]],
  205. ['put', ['path.txt', 'contents', []]],
  206. ['putStream', ['path.txt', 'contents', []]],
  207. ['read', ['path.txt']],
  208. ['readStream', ['path.txt']],
  209. ['readAndDelete', ['path.txt']],
  210. ['get', ['path.txt']],
  211. ['has', ['path.txt']],
  212. ['getMetadata', ['path.txt']],
  213. ['getMimetype', ['path.txt']],
  214. ['getTimestamp', ['path.txt']],
  215. ['getSize', ['path.txt']],
  216. ['delete', ['path.txt']],
  217. ['deleteDir', ['dirname']],
  218. ['createDir', ['dirname']],
  219. ['rename', ['name', 'other-name']],
  220. ['setVisibility', ['name', AdapterInterface::VISIBILITY_PUBLIC]],
  221. ['getVisibility', ['name']],
  222. ];
  223. }
  224. }