StoragesControllerTest.php 11 KB

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