StoragesControllerTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\Files_External\Tests\Controller;
  8. use OCA\Files_External\Controller\GlobalStoragesController;
  9. use OCA\Files_External\Lib\Auth\AuthMechanism;
  10. use OCA\Files_External\Lib\Backend\Backend;
  11. use OCA\Files_External\Lib\StorageConfig;
  12. use OCA\Files_External\MountConfig;
  13. use OCA\Files_External\NotFoundException;
  14. use OCA\Files_External\Service\GlobalStoragesService;
  15. use OCA\Files_External\Service\UserStoragesService;
  16. use OCP\AppFramework\Http;
  17. use PHPUnit\Framework\MockObject\MockObject;
  18. abstract class StoragesControllerTest extends \Test\TestCase {
  19. /**
  20. * @var GlobalStoragesController
  21. */
  22. protected $controller;
  23. /**
  24. * @var GlobalStoragesService|UserStoragesService|MockObject
  25. */
  26. protected $service;
  27. protected function setUp(): void {
  28. MountConfig::$skipTest = true;
  29. }
  30. protected function tearDown(): void {
  31. MountConfig::$skipTest = false;
  32. }
  33. /**
  34. * @return \OCA\Files_External\Lib\Backend\Backend|MockObject
  35. */
  36. protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OCA\Files_External\Lib\Storage\SMB') {
  37. $backend = $this->getMockBuilder(Backend::class)
  38. ->disableOriginalConstructor()
  39. ->getMock();
  40. $backend->method('getStorageClass')
  41. ->willReturn($storageClass);
  42. $backend->method('getIdentifier')
  43. ->willReturn('identifier:' . $class);
  44. $backend->method('getParameters')
  45. ->willReturn([]);
  46. return $backend;
  47. }
  48. /**
  49. * @return AuthMechanism|MockObject
  50. */
  51. protected function getAuthMechMock($scheme = 'null', $class = '\OCA\Files_External\Lib\Auth\NullMechanism') {
  52. $authMech = $this->getMockBuilder(AuthMechanism::class)
  53. ->disableOriginalConstructor()
  54. ->getMock();
  55. $authMech->method('getScheme')
  56. ->willReturn($scheme);
  57. $authMech->method('getIdentifier')
  58. ->willReturn('identifier:' . $class);
  59. $authMech->method('getParameters')
  60. ->willReturn([]);
  61. return $authMech;
  62. }
  63. public function testAddStorage(): void {
  64. $authMech = $this->getAuthMechMock();
  65. $authMech->method('validateStorage')
  66. ->willReturn(true);
  67. $authMech->method('isVisibleFor')
  68. ->willReturn(true);
  69. $backend = $this->getBackendMock();
  70. $backend->method('validateStorage')
  71. ->willReturn(true);
  72. $backend->method('isVisibleFor')
  73. ->willReturn(true);
  74. $storageConfig = new StorageConfig(1);
  75. $storageConfig->setMountPoint('mount');
  76. $storageConfig->setBackend($backend);
  77. $storageConfig->setAuthMechanism($authMech);
  78. $storageConfig->setBackendOptions([]);
  79. $this->service->expects($this->once())
  80. ->method('createStorage')
  81. ->willReturn($storageConfig);
  82. $this->service->expects($this->once())
  83. ->method('addStorage')
  84. ->willReturn($storageConfig);
  85. $response = $this->controller->create(
  86. 'mount',
  87. '\OCA\Files_External\Lib\Storage\SMB',
  88. '\OCA\Files_External\Lib\Auth\NullMechanism',
  89. [],
  90. [],
  91. [],
  92. [],
  93. null
  94. );
  95. $data = $response->getData();
  96. $this->assertEquals(Http::STATUS_CREATED, $response->getStatus());
  97. $this->assertEquals($storageConfig->jsonSerialize(), $data);
  98. }
  99. public function testAddLocalStorageWhenDisabled(): void {
  100. $authMech = $this->getAuthMechMock();
  101. $backend = $this->getBackendMock();
  102. $storageConfig = new StorageConfig(1);
  103. $storageConfig->setMountPoint('mount');
  104. $storageConfig->setBackend($backend);
  105. $storageConfig->setAuthMechanism($authMech);
  106. $storageConfig->setBackendOptions([]);
  107. $this->service->expects($this->never())
  108. ->method('createStorage');
  109. $this->service->expects($this->never())
  110. ->method('addStorage');
  111. $response = $this->controller->create(
  112. 'mount',
  113. 'local',
  114. '\OCA\Files_External\Lib\Auth\NullMechanism',
  115. [],
  116. [],
  117. [],
  118. [],
  119. null
  120. );
  121. $data = $response->getData();
  122. $this->assertEquals(Http::STATUS_FORBIDDEN, $response->getStatus());
  123. }
  124. public function testUpdateStorage(): void {
  125. $authMech = $this->getAuthMechMock();
  126. $authMech->method('validateStorage')
  127. ->willReturn(true);
  128. $authMech->method('isVisibleFor')
  129. ->willReturn(true);
  130. $backend = $this->getBackendMock();
  131. $backend->method('validateStorage')
  132. ->willReturn(true);
  133. $backend->method('isVisibleFor')
  134. ->willReturn(true);
  135. $storageConfig = new StorageConfig(1);
  136. $storageConfig->setMountPoint('mount');
  137. $storageConfig->setBackend($backend);
  138. $storageConfig->setAuthMechanism($authMech);
  139. $storageConfig->setBackendOptions([]);
  140. $this->service->expects($this->once())
  141. ->method('createStorage')
  142. ->willReturn($storageConfig);
  143. $this->service->expects($this->once())
  144. ->method('updateStorage')
  145. ->willReturn($storageConfig);
  146. $response = $this->controller->update(
  147. 1,
  148. 'mount',
  149. '\OCA\Files_External\Lib\Storage\SMB',
  150. '\OCA\Files_External\Lib\Auth\NullMechanism',
  151. [],
  152. [],
  153. [],
  154. [],
  155. null
  156. );
  157. $data = $response->getData();
  158. $this->assertEquals(Http::STATUS_OK, $response->getStatus());
  159. $this->assertEquals($storageConfig->jsonSerialize(), $data);
  160. }
  161. public function mountPointNamesProvider() {
  162. return [
  163. [''],
  164. ['/'],
  165. ['//'],
  166. ];
  167. }
  168. /**
  169. * @dataProvider mountPointNamesProvider
  170. */
  171. public function testAddOrUpdateStorageInvalidMountPoint($mountPoint): void {
  172. $storageConfig = new StorageConfig(1);
  173. $storageConfig->setMountPoint($mountPoint);
  174. $storageConfig->setBackend($this->getBackendMock());
  175. $storageConfig->setAuthMechanism($this->getAuthMechMock());
  176. $storageConfig->setBackendOptions([]);
  177. $this->service->expects($this->exactly(2))
  178. ->method('createStorage')
  179. ->willReturn($storageConfig);
  180. $this->service->expects($this->never())
  181. ->method('addStorage');
  182. $this->service->expects($this->never())
  183. ->method('updateStorage');
  184. $response = $this->controller->create(
  185. $mountPoint,
  186. '\OCA\Files_External\Lib\Storage\SMB',
  187. '\OCA\Files_External\Lib\Auth\NullMechanism',
  188. [],
  189. [],
  190. [],
  191. [],
  192. null
  193. );
  194. $this->assertEquals(Http::STATUS_UNPROCESSABLE_ENTITY, $response->getStatus());
  195. $response = $this->controller->update(
  196. 1,
  197. $mountPoint,
  198. '\OCA\Files_External\Lib\Storage\SMB',
  199. '\OCA\Files_External\Lib\Auth\NullMechanism',
  200. [],
  201. [],
  202. [],
  203. [],
  204. null
  205. );
  206. $this->assertEquals(Http::STATUS_UNPROCESSABLE_ENTITY, $response->getStatus());
  207. }
  208. public function testAddOrUpdateStorageInvalidBackend(): void {
  209. $this->service->expects($this->exactly(2))
  210. ->method('createStorage')
  211. ->will($this->throwException(new \InvalidArgumentException()));
  212. $this->service->expects($this->never())
  213. ->method('addStorage');
  214. $this->service->expects($this->never())
  215. ->method('updateStorage');
  216. $response = $this->controller->create(
  217. 'mount',
  218. '\OC\Files\Storage\InvalidStorage',
  219. '\OCA\Files_External\Lib\Auth\NullMechanism',
  220. [],
  221. [],
  222. [],
  223. [],
  224. null
  225. );
  226. $this->assertEquals(Http::STATUS_UNPROCESSABLE_ENTITY, $response->getStatus());
  227. $response = $this->controller->update(
  228. 1,
  229. 'mount',
  230. '\OC\Files\Storage\InvalidStorage',
  231. '\OCA\Files_External\Lib\Auth\NullMechanism',
  232. [],
  233. [],
  234. [],
  235. [],
  236. null
  237. );
  238. $this->assertEquals(Http::STATUS_UNPROCESSABLE_ENTITY, $response->getStatus());
  239. }
  240. public function testUpdateStorageNonExisting(): void {
  241. $authMech = $this->getAuthMechMock();
  242. $authMech->method('validateStorage')
  243. ->willReturn(true);
  244. $authMech->method('isVisibleFor')
  245. ->willReturn(true);
  246. $backend = $this->getBackendMock();
  247. $backend->method('validateStorage')
  248. ->willReturn(true);
  249. $backend->method('isVisibleFor')
  250. ->willReturn(true);
  251. $storageConfig = new StorageConfig(255);
  252. $storageConfig->setMountPoint('mount');
  253. $storageConfig->setBackend($backend);
  254. $storageConfig->setAuthMechanism($authMech);
  255. $storageConfig->setBackendOptions([]);
  256. $this->service->expects($this->once())
  257. ->method('createStorage')
  258. ->willReturn($storageConfig);
  259. $this->service->expects($this->once())
  260. ->method('updateStorage')
  261. ->will($this->throwException(new NotFoundException()));
  262. $response = $this->controller->update(
  263. 255,
  264. 'mount',
  265. '\OCA\Files_External\Lib\Storage\SMB',
  266. '\OCA\Files_External\Lib\Auth\NullMechanism',
  267. [],
  268. [],
  269. [],
  270. [],
  271. null
  272. );
  273. $this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus());
  274. }
  275. public function testDeleteStorage(): void {
  276. $this->service->expects($this->once())
  277. ->method('removeStorage');
  278. $response = $this->controller->destroy(1);
  279. $this->assertEquals(Http::STATUS_NO_CONTENT, $response->getStatus());
  280. }
  281. public function testDeleteStorageNonExisting(): void {
  282. $this->service->expects($this->once())
  283. ->method('removeStorage')
  284. ->will($this->throwException(new NotFoundException()));
  285. $response = $this->controller->destroy(255);
  286. $this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus());
  287. }
  288. public function testGetStorage(): void {
  289. $backend = $this->getBackendMock();
  290. $authMech = $this->getAuthMechMock();
  291. $storageConfig = new StorageConfig(1);
  292. $storageConfig->setMountPoint('test');
  293. $storageConfig->setBackend($backend);
  294. $storageConfig->setAuthMechanism($authMech);
  295. $storageConfig->setBackendOptions(['user' => 'test', 'password', 'password123']);
  296. $storageConfig->setMountOptions(['priority' => false]);
  297. $this->service->expects($this->once())
  298. ->method('getStorage')
  299. ->with(1)
  300. ->willReturn($storageConfig);
  301. $response = $this->controller->show(1);
  302. $this->assertEquals(Http::STATUS_OK, $response->getStatus());
  303. $expected = $storageConfig->jsonSerialize();
  304. $expected['can_edit'] = false;
  305. $this->assertEquals($expected, $response->getData());
  306. }
  307. public function validateStorageProvider() {
  308. return [
  309. [true, true, true],
  310. [false, true, false],
  311. [true, false, false],
  312. [false, false, false]
  313. ];
  314. }
  315. /**
  316. * @dataProvider validateStorageProvider
  317. */
  318. public function testValidateStorage($backendValidate, $authMechValidate, $expectSuccess): void {
  319. $backend = $this->getBackendMock();
  320. $backend->method('validateStorage')
  321. ->willReturn($backendValidate);
  322. $backend->method('isVisibleFor')
  323. ->willReturn(true);
  324. $authMech = $this->getAuthMechMock();
  325. $authMech->method('validateStorage')
  326. ->willReturn($authMechValidate);
  327. $authMech->method('isVisibleFor')
  328. ->willReturn(true);
  329. $storageConfig = new StorageConfig();
  330. $storageConfig->setMountPoint('mount');
  331. $storageConfig->setBackend($backend);
  332. $storageConfig->setAuthMechanism($authMech);
  333. $storageConfig->setBackendOptions([]);
  334. $this->service->expects($this->once())
  335. ->method('createStorage')
  336. ->willReturn($storageConfig);
  337. if ($expectSuccess) {
  338. $this->service->expects($this->once())
  339. ->method('addStorage')
  340. ->with($storageConfig)
  341. ->willReturn($storageConfig);
  342. } else {
  343. $this->service->expects($this->never())
  344. ->method('addStorage');
  345. }
  346. $response = $this->controller->create(
  347. 'mount',
  348. '\OCA\Files_External\Lib\Storage\SMB',
  349. '\OCA\Files_External\Lib\Auth\NullMechanism',
  350. [],
  351. [],
  352. [],
  353. [],
  354. null
  355. );
  356. if ($expectSuccess) {
  357. $this->assertEquals(Http::STATUS_CREATED, $response->getStatus());
  358. } else {
  359. $this->assertEquals(Http::STATUS_UNPROCESSABLE_ENTITY, $response->getStatus());
  360. }
  361. }
  362. }