AppConfigControllerTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
  4. *
  5. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  6. * @author Joas Schilling <coding@schilljs.com>
  7. * @author Morris Jobke <hey@morrisjobke.de>
  8. * @author Roeland Jago Douma <roeland@famdouma.nl>
  9. *
  10. * @license GNU AGPL version 3 or any later version
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Affero General Public License as
  14. * published by the Free Software Foundation, either version 3 of the
  15. * License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Affero General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Affero General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. *
  25. */
  26. namespace OCA\Provisioning_API\Tests\Controller;
  27. use OC\AppConfig;
  28. use OCA\Provisioning_API\Controller\AppConfigController;
  29. use OCP\AppFramework\Http;
  30. use OCP\AppFramework\Http\DataResponse;
  31. use OCP\IAppConfig;
  32. use OCP\IGroupManager;
  33. use OCP\IL10N;
  34. use OCP\IRequest;
  35. use OCP\IUser;
  36. use OCP\IUserSession;
  37. use OCP\Settings\IManager;
  38. use Test\TestCase;
  39. /**
  40. * Class AppConfigControllerTest
  41. *
  42. * @package OCA\Provisioning_API\Tests
  43. */
  44. class AppConfigControllerTest extends TestCase {
  45. /** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
  46. private $appConfig;
  47. /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
  48. private $userSession;
  49. /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
  50. private $l10n;
  51. /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
  52. private $settingManager;
  53. /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
  54. private $groupManager;
  55. protected function setUp(): void {
  56. parent::setUp();
  57. $this->appConfig = $this->createMock(AppConfig::class);
  58. $this->userSession = $this->createMock(IUserSession::class);
  59. $this->l10n = $this->createMock(IL10N::class);
  60. $this->groupManager = $this->createMock(IGroupManager::class);
  61. $this->settingManager = $this->createMock(IManager::class);
  62. }
  63. /**
  64. * @param string[] $methods
  65. * @return AppConfigController|\PHPUnit\Framework\MockObject\MockObject
  66. */
  67. protected function getInstance(array $methods = []) {
  68. $request = $this->createMock(IRequest::class);
  69. if (empty($methods)) {
  70. return new AppConfigController(
  71. 'provisioning_api',
  72. $request,
  73. $this->appConfig,
  74. $this->userSession,
  75. $this->l10n,
  76. $this->groupManager,
  77. $this->settingManager
  78. );
  79. } else {
  80. return $this->getMockBuilder(AppConfigController::class)
  81. ->setConstructorArgs([
  82. 'provisioning_api',
  83. $request,
  84. $this->appConfig,
  85. $this->userSession,
  86. $this->l10n,
  87. $this->groupManager,
  88. $this->settingManager
  89. ])
  90. ->setMethods($methods)
  91. ->getMock();
  92. }
  93. }
  94. public function testGetApps() {
  95. $this->appConfig->expects($this->once())
  96. ->method('getApps')
  97. ->willReturn(['apps']);
  98. $result = $this->getInstance()->getApps();
  99. $this->assertInstanceOf(DataResponse::class, $result);
  100. $this->assertSame(Http::STATUS_OK, $result->getStatus());
  101. $this->assertEquals(['data' => ['apps']], $result->getData());
  102. }
  103. public function dataGetKeys() {
  104. return [
  105. ['app1 ', null, new \InvalidArgumentException('error'), Http::STATUS_FORBIDDEN],
  106. ['app2', ['keys'], null, Http::STATUS_OK],
  107. ];
  108. }
  109. /**
  110. * @dataProvider dataGetKeys
  111. * @param string $app
  112. * @param array|null $keys
  113. * @param \Exception|null $throws
  114. * @param int $status
  115. */
  116. public function testGetKeys($app, $keys, $throws, $status) {
  117. $api = $this->getInstance(['verifyAppId']);
  118. if ($throws instanceof \Exception) {
  119. $api->expects($this->once())
  120. ->method('verifyAppId')
  121. ->with($app)
  122. ->willThrowException($throws);
  123. $this->appConfig->expects($this->never())
  124. ->method('getKeys');
  125. } else {
  126. $api->expects($this->once())
  127. ->method('verifyAppId')
  128. ->with($app);
  129. $this->appConfig->expects($this->once())
  130. ->method('getKeys')
  131. ->with($app)
  132. ->willReturn($keys);
  133. }
  134. $result = $api->getKeys($app);
  135. $this->assertInstanceOf(DataResponse::class, $result);
  136. $this->assertSame($status, $result->getStatus());
  137. if ($throws instanceof \Exception) {
  138. $this->assertEquals(['data' => ['message' => $throws->getMessage()]], $result->getData());
  139. } else {
  140. $this->assertEquals(['data' => $keys], $result->getData());
  141. }
  142. }
  143. public function dataGetValue() {
  144. return [
  145. ['app1', 'key', 'default', null, new \InvalidArgumentException('error'), Http::STATUS_FORBIDDEN],
  146. ['app2', 'key', 'default', 'return', null, Http::STATUS_OK],
  147. ];
  148. }
  149. /**
  150. * @dataProvider dataGetValue
  151. * @param string $app
  152. * @param string|null $key
  153. * @param string|null $default
  154. * @param string|null $return
  155. * @param \Exception|null $throws
  156. * @param int $status
  157. */
  158. public function testGetValue($app, $key, $default, $return, $throws, $status) {
  159. $api = $this->getInstance(['verifyAppId']);
  160. if ($throws instanceof \Exception) {
  161. $api->expects($this->once())
  162. ->method('verifyAppId')
  163. ->with($app)
  164. ->willThrowException($throws);
  165. } else {
  166. $api->expects($this->once())
  167. ->method('verifyAppId')
  168. ->with($app);
  169. $this->appConfig->expects($this->once())
  170. ->method('getValueMixed')
  171. ->with($app, $key, $default)
  172. ->willReturn($return);
  173. }
  174. $result = $api->getValue($app, $key, $default);
  175. $this->assertInstanceOf(DataResponse::class, $result);
  176. $this->assertSame($status, $result->getStatus());
  177. if ($throws instanceof \Exception) {
  178. $this->assertEquals(['data' => ['message' => $throws->getMessage()]], $result->getData());
  179. } else {
  180. $this->assertEquals(['data' => $return], $result->getData());
  181. }
  182. }
  183. public function dataSetValue() {
  184. return [
  185. ['app1', 'key', 'default', new \InvalidArgumentException('error1'), null, Http::STATUS_FORBIDDEN],
  186. ['app2', 'key', 'default', null, new \InvalidArgumentException('error2'), Http::STATUS_FORBIDDEN],
  187. ['app2', 'key', 'default', null, null, Http::STATUS_OK],
  188. ];
  189. }
  190. /**
  191. * @dataProvider dataSetValue
  192. * @param string $app
  193. * @param string|null $key
  194. * @param string|null $value
  195. * @param \Exception|null $appThrows
  196. * @param \Exception|null $keyThrows
  197. * @param int $status
  198. */
  199. public function testSetValue($app, $key, $value, $appThrows, $keyThrows, $status) {
  200. $adminUser = $this->createMock(IUser::class);
  201. $adminUser->expects($this->once())
  202. ->method('getUid')
  203. ->willReturn('admin');
  204. $this->userSession->expects($this->once())
  205. ->method('getUser')
  206. ->willReturn($adminUser);
  207. $this->groupManager->expects($this->once())
  208. ->method('isAdmin')
  209. ->with('admin')
  210. ->willReturn(true);
  211. $api = $this->getInstance(['verifyAppId', 'verifyConfigKey']);
  212. if ($appThrows instanceof \Exception) {
  213. $api->expects($this->once())
  214. ->method('verifyAppId')
  215. ->with($app)
  216. ->willThrowException($appThrows);
  217. $api->expects($this->never())
  218. ->method('verifyConfigKey');
  219. $this->appConfig->expects($this->never())
  220. ->method('setValueMixed');
  221. } elseif ($keyThrows instanceof \Exception) {
  222. $api->expects($this->once())
  223. ->method('verifyAppId')
  224. ->with($app);
  225. $api->expects($this->once())
  226. ->method('verifyConfigKey')
  227. ->with($app, $key)
  228. ->willThrowException($keyThrows);
  229. $this->appConfig->expects($this->never())
  230. ->method('setValueMixed');
  231. } else {
  232. $api->expects($this->once())
  233. ->method('verifyAppId')
  234. ->with($app);
  235. $api->expects($this->once())
  236. ->method('verifyConfigKey')
  237. ->with($app, $key);
  238. $this->appConfig->expects($this->once())
  239. ->method('setValueMixed')
  240. ->with($app, $key, $value);
  241. }
  242. $result = $api->setValue($app, $key, $value);
  243. $this->assertInstanceOf(DataResponse::class, $result);
  244. $this->assertSame($status, $result->getStatus());
  245. if ($appThrows instanceof \Exception) {
  246. $this->assertEquals(['data' => ['message' => $appThrows->getMessage()]], $result->getData());
  247. } elseif ($keyThrows instanceof \Exception) {
  248. $this->assertEquals(['data' => ['message' => $keyThrows->getMessage()]], $result->getData());
  249. } else {
  250. $this->assertEquals([], $result->getData());
  251. }
  252. }
  253. public function dataDeleteValue() {
  254. return [
  255. ['app1', 'key', new \InvalidArgumentException('error1'), null, Http::STATUS_FORBIDDEN],
  256. ['app2', 'key', null, new \InvalidArgumentException('error2'), Http::STATUS_FORBIDDEN],
  257. ['app2', 'key', null, null, Http::STATUS_OK],
  258. ];
  259. }
  260. /**
  261. * @dataProvider dataDeleteValue
  262. * @param string $app
  263. * @param string|null $key
  264. * @param \Exception|null $appThrows
  265. * @param \Exception|null $keyThrows
  266. * @param int $status
  267. */
  268. public function testDeleteValue($app, $key, $appThrows, $keyThrows, $status) {
  269. $api = $this->getInstance(['verifyAppId', 'verifyConfigKey']);
  270. if ($appThrows instanceof \Exception) {
  271. $api->expects($this->once())
  272. ->method('verifyAppId')
  273. ->with($app)
  274. ->willThrowException($appThrows);
  275. $api->expects($this->never())
  276. ->method('verifyConfigKey');
  277. $this->appConfig->expects($this->never())
  278. ->method('deleteKey');
  279. } elseif ($keyThrows instanceof \Exception) {
  280. $api->expects($this->once())
  281. ->method('verifyAppId')
  282. ->with($app);
  283. $api->expects($this->once())
  284. ->method('verifyConfigKey')
  285. ->with($app, $key)
  286. ->willThrowException($keyThrows);
  287. $this->appConfig->expects($this->never())
  288. ->method('deleteKey');
  289. } else {
  290. $api->expects($this->once())
  291. ->method('verifyAppId')
  292. ->with($app);
  293. $api->expects($this->once())
  294. ->method('verifyConfigKey')
  295. ->with($app, $key);
  296. $this->appConfig->expects($this->once())
  297. ->method('deleteKey')
  298. ->with($app, $key);
  299. }
  300. $result = $api->deleteKey($app, $key);
  301. $this->assertInstanceOf(DataResponse::class, $result);
  302. $this->assertSame($status, $result->getStatus());
  303. if ($appThrows instanceof \Exception) {
  304. $this->assertEquals(['data' => ['message' => $appThrows->getMessage()]], $result->getData());
  305. } elseif ($keyThrows instanceof \Exception) {
  306. $this->assertEquals(['data' => ['message' => $keyThrows->getMessage()]], $result->getData());
  307. } else {
  308. $this->assertEquals([], $result->getData());
  309. }
  310. }
  311. public function testVerifyAppId() {
  312. $api = $this->getInstance();
  313. $this->invokePrivate($api, 'verifyAppId', ['activity']);
  314. $this->addToAssertionCount(1);
  315. }
  316. public function dataVerifyAppIdThrows() {
  317. return [
  318. ['activity..'],
  319. ['activity/'],
  320. ['activity\\'],
  321. ['activity\0'],
  322. ];
  323. }
  324. /**
  325. * @dataProvider dataVerifyAppIdThrows
  326. * @param string $app
  327. */
  328. public function testVerifyAppIdThrows($app) {
  329. $this->expectException(\InvalidArgumentException::class);
  330. $api = $this->getInstance();
  331. $this->invokePrivate($api, 'verifyAppId', [$app]);
  332. }
  333. public function dataVerifyConfigKey() {
  334. return [
  335. ['activity', 'abc', ''],
  336. ['dav', 'public_route', ''],
  337. ['files', 'remote_route', ''],
  338. ['core', 'encryption_enabled', 'yes'],
  339. ];
  340. }
  341. /**
  342. * @dataProvider dataVerifyConfigKey
  343. * @param string $app
  344. * @param string $key
  345. * @param string $value
  346. */
  347. public function testVerifyConfigKey($app, $key, $value) {
  348. $api = $this->getInstance();
  349. $this->invokePrivate($api, 'verifyConfigKey', [$app, $key, $value]);
  350. $this->addToAssertionCount(1);
  351. }
  352. public function dataVerifyConfigKeyThrows() {
  353. return [
  354. ['activity', 'installed_version', ''],
  355. ['calendar', 'enabled', ''],
  356. ['contacts', 'types', ''],
  357. ['core', 'encryption_enabled', 'no'],
  358. ['core', 'encryption_enabled', ''],
  359. ['core', 'public_files', ''],
  360. ['core', 'public_dav', ''],
  361. ['core', 'remote_files', ''],
  362. ['core', 'remote_dav', ''],
  363. ];
  364. }
  365. /**
  366. * @dataProvider dataVerifyConfigKeyThrows
  367. * @param string $app
  368. * @param string $key
  369. * @param string $value
  370. */
  371. public function testVerifyConfigKeyThrows($app, $key, $value) {
  372. $this->expectException(\InvalidArgumentException::class);
  373. $api = $this->getInstance();
  374. $this->invokePrivate($api, 'verifyConfigKey', [$app, $key, $value]);
  375. }
  376. }