AppConfigControllerTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  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 OCA\Provisioning_API\Controller\AppConfigController;
  28. use OCP\AppFramework\Http;
  29. use OCP\AppFramework\Http\DataResponse;
  30. use OCP\IAppConfig;
  31. use OCP\IConfig;
  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 IConfig|\PHPUnit\Framework\MockObject\MockObject */
  46. private $config;
  47. /** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
  48. private $appConfig;
  49. /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
  50. private $userSession;
  51. /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
  52. private $l10n;
  53. /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
  54. private $settingManager;
  55. /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
  56. private $groupManager;
  57. protected function setUp(): void {
  58. parent::setUp();
  59. $this->config = $this->createMock(IConfig::class);
  60. $this->appConfig = $this->createMock(IAppConfig::class);
  61. $this->userSession = $this->createMock(IUserSession::class);
  62. $this->l10n = $this->createMock(IL10N::class);
  63. $this->groupManager = $this->createMock(IGroupManager::class);
  64. $this->settingManager = $this->createMock(IManager::class);
  65. }
  66. /**
  67. * @param string[] $methods
  68. * @return AppConfigController|\PHPUnit\Framework\MockObject\MockObject
  69. */
  70. protected function getInstance(array $methods = []) {
  71. $request = $this->createMock(IRequest::class);
  72. if (empty($methods)) {
  73. return new AppConfigController(
  74. 'provisioning_api',
  75. $request,
  76. $this->config,
  77. $this->appConfig,
  78. $this->userSession,
  79. $this->l10n,
  80. $this->groupManager,
  81. $this->settingManager
  82. );
  83. } else {
  84. return $this->getMockBuilder(AppConfigController::class)
  85. ->setConstructorArgs([
  86. 'provisioning_api',
  87. $request,
  88. $this->config,
  89. $this->appConfig,
  90. $this->userSession,
  91. $this->l10n,
  92. $this->groupManager,
  93. $this->settingManager
  94. ])
  95. ->setMethods($methods)
  96. ->getMock();
  97. }
  98. }
  99. public function testGetApps() {
  100. $this->appConfig->expects($this->once())
  101. ->method('getApps')
  102. ->willReturn(['apps']);
  103. $result = $this->getInstance()->getApps();
  104. $this->assertInstanceOf(DataResponse::class, $result);
  105. $this->assertSame(Http::STATUS_OK, $result->getStatus());
  106. $this->assertEquals(['data' => ['apps']], $result->getData());
  107. }
  108. public function dataGetKeys() {
  109. return [
  110. ['app1 ', null, new \InvalidArgumentException('error'), Http::STATUS_FORBIDDEN],
  111. ['app2', ['keys'], null, Http::STATUS_OK],
  112. ];
  113. }
  114. /**
  115. * @dataProvider dataGetKeys
  116. * @param string $app
  117. * @param array|null $keys
  118. * @param \Exception|null $throws
  119. * @param int $status
  120. */
  121. public function testGetKeys($app, $keys, $throws, $status) {
  122. $api = $this->getInstance(['verifyAppId']);
  123. if ($throws instanceof \Exception) {
  124. $api->expects($this->once())
  125. ->method('verifyAppId')
  126. ->with($app)
  127. ->willThrowException($throws);
  128. $this->config->expects($this->never())
  129. ->method('getAppKeys');
  130. } else {
  131. $api->expects($this->once())
  132. ->method('verifyAppId')
  133. ->with($app);
  134. $this->config->expects($this->once())
  135. ->method('getAppKeys')
  136. ->with($app)
  137. ->willReturn($keys);
  138. }
  139. $result = $api->getKeys($app);
  140. $this->assertInstanceOf(DataResponse::class, $result);
  141. $this->assertSame($status, $result->getStatus());
  142. if ($throws instanceof \Exception) {
  143. $this->assertEquals(['data' => ['message' => $throws->getMessage()]], $result->getData());
  144. } else {
  145. $this->assertEquals(['data' => $keys], $result->getData());
  146. }
  147. }
  148. public function dataGetValue() {
  149. return [
  150. ['app1', 'key', 'default', null, new \InvalidArgumentException('error'), Http::STATUS_FORBIDDEN],
  151. ['app2', 'key', 'default', 'return', null, Http::STATUS_OK],
  152. ];
  153. }
  154. /**
  155. * @dataProvider dataGetValue
  156. * @param string $app
  157. * @param string|null $key
  158. * @param string|null $default
  159. * @param string|null $return
  160. * @param \Exception|null $throws
  161. * @param int $status
  162. */
  163. public function testGetValue($app, $key, $default, $return, $throws, $status) {
  164. $api = $this->getInstance(['verifyAppId']);
  165. if ($throws instanceof \Exception) {
  166. $api->expects($this->once())
  167. ->method('verifyAppId')
  168. ->with($app)
  169. ->willThrowException($throws);
  170. $this->config->expects($this->never())
  171. ->method('getAppValue');
  172. } else {
  173. $api->expects($this->once())
  174. ->method('verifyAppId')
  175. ->with($app);
  176. $this->config->expects($this->once())
  177. ->method('getAppValue')
  178. ->with($app, $key, $default)
  179. ->willReturn($return);
  180. }
  181. $result = $api->getValue($app, $key, $default);
  182. $this->assertInstanceOf(DataResponse::class, $result);
  183. $this->assertSame($status, $result->getStatus());
  184. if ($throws instanceof \Exception) {
  185. $this->assertEquals(['data' => ['message' => $throws->getMessage()]], $result->getData());
  186. } else {
  187. $this->assertEquals(['data' => $return], $result->getData());
  188. }
  189. }
  190. public function dataSetValue() {
  191. return [
  192. ['app1', 'key', 'default', new \InvalidArgumentException('error1'), null, Http::STATUS_FORBIDDEN],
  193. ['app2', 'key', 'default', null, new \InvalidArgumentException('error2'), Http::STATUS_FORBIDDEN],
  194. ['app2', 'key', 'default', null, null, Http::STATUS_OK],
  195. ];
  196. }
  197. /**
  198. * @dataProvider dataSetValue
  199. * @param string $app
  200. * @param string|null $key
  201. * @param string|null $value
  202. * @param \Exception|null $appThrows
  203. * @param \Exception|null $keyThrows
  204. * @param int $status
  205. */
  206. public function testSetValue($app, $key, $value, $appThrows, $keyThrows, $status) {
  207. $adminUser = $this->createMock(IUser::class);
  208. $adminUser->expects($this->once())
  209. ->method('getUid')
  210. ->willReturn('admin');
  211. $this->userSession->expects($this->once())
  212. ->method('getUser')
  213. ->willReturn($adminUser);
  214. $this->groupManager->expects($this->once())
  215. ->method('isAdmin')
  216. ->with('admin')
  217. ->willReturn(true);
  218. $api = $this->getInstance(['verifyAppId', 'verifyConfigKey']);
  219. if ($appThrows instanceof \Exception) {
  220. $api->expects($this->once())
  221. ->method('verifyAppId')
  222. ->with($app)
  223. ->willThrowException($appThrows);
  224. $api->expects($this->never())
  225. ->method('verifyConfigKey');
  226. $this->config->expects($this->never())
  227. ->method('setAppValue');
  228. } elseif ($keyThrows instanceof \Exception) {
  229. $api->expects($this->once())
  230. ->method('verifyAppId')
  231. ->with($app);
  232. $api->expects($this->once())
  233. ->method('verifyConfigKey')
  234. ->with($app, $key)
  235. ->willThrowException($keyThrows);
  236. $this->config->expects($this->never())
  237. ->method('setAppValue');
  238. } else {
  239. $api->expects($this->once())
  240. ->method('verifyAppId')
  241. ->with($app);
  242. $api->expects($this->once())
  243. ->method('verifyConfigKey')
  244. ->with($app, $key);
  245. $this->config->expects($this->once())
  246. ->method('setAppValue')
  247. ->with($app, $key, $value);
  248. }
  249. $result = $api->setValue($app, $key, $value);
  250. $this->assertInstanceOf(DataResponse::class, $result);
  251. $this->assertSame($status, $result->getStatus());
  252. if ($appThrows instanceof \Exception) {
  253. $this->assertEquals(['data' => ['message' => $appThrows->getMessage()]], $result->getData());
  254. } elseif ($keyThrows instanceof \Exception) {
  255. $this->assertEquals(['data' => ['message' => $keyThrows->getMessage()]], $result->getData());
  256. } else {
  257. $this->assertEquals([], $result->getData());
  258. }
  259. }
  260. public function dataDeleteValue() {
  261. return [
  262. ['app1', 'key', new \InvalidArgumentException('error1'), null, Http::STATUS_FORBIDDEN],
  263. ['app2', 'key', null, new \InvalidArgumentException('error2'), Http::STATUS_FORBIDDEN],
  264. ['app2', 'key', null, null, Http::STATUS_OK],
  265. ];
  266. }
  267. /**
  268. * @dataProvider dataDeleteValue
  269. * @param string $app
  270. * @param string|null $key
  271. * @param \Exception|null $appThrows
  272. * @param \Exception|null $keyThrows
  273. * @param int $status
  274. */
  275. public function testDeleteValue($app, $key, $appThrows, $keyThrows, $status) {
  276. $api = $this->getInstance(['verifyAppId', 'verifyConfigKey']);
  277. if ($appThrows instanceof \Exception) {
  278. $api->expects($this->once())
  279. ->method('verifyAppId')
  280. ->with($app)
  281. ->willThrowException($appThrows);
  282. $api->expects($this->never())
  283. ->method('verifyConfigKey');
  284. $this->config->expects($this->never())
  285. ->method('deleteAppValue');
  286. } elseif ($keyThrows instanceof \Exception) {
  287. $api->expects($this->once())
  288. ->method('verifyAppId')
  289. ->with($app);
  290. $api->expects($this->once())
  291. ->method('verifyConfigKey')
  292. ->with($app, $key)
  293. ->willThrowException($keyThrows);
  294. $this->config->expects($this->never())
  295. ->method('deleteAppValue');
  296. } else {
  297. $api->expects($this->once())
  298. ->method('verifyAppId')
  299. ->with($app);
  300. $api->expects($this->once())
  301. ->method('verifyConfigKey')
  302. ->with($app, $key);
  303. $this->config->expects($this->once())
  304. ->method('deleteAppValue')
  305. ->with($app, $key);
  306. }
  307. $result = $api->deleteKey($app, $key);
  308. $this->assertInstanceOf(DataResponse::class, $result);
  309. $this->assertSame($status, $result->getStatus());
  310. if ($appThrows instanceof \Exception) {
  311. $this->assertEquals(['data' => ['message' => $appThrows->getMessage()]], $result->getData());
  312. } elseif ($keyThrows instanceof \Exception) {
  313. $this->assertEquals(['data' => ['message' => $keyThrows->getMessage()]], $result->getData());
  314. } else {
  315. $this->assertEquals([], $result->getData());
  316. }
  317. }
  318. public function testVerifyAppId() {
  319. $api = $this->getInstance();
  320. $this->invokePrivate($api, 'verifyAppId', ['activity']);
  321. $this->addToAssertionCount(1);
  322. }
  323. public function dataVerifyAppIdThrows() {
  324. return [
  325. ['activity..'],
  326. ['activity/'],
  327. ['activity\\'],
  328. ['activity\0'],
  329. ];
  330. }
  331. /**
  332. * @dataProvider dataVerifyAppIdThrows
  333. * @param string $app
  334. */
  335. public function testVerifyAppIdThrows($app) {
  336. $this->expectException(\InvalidArgumentException::class);
  337. $api = $this->getInstance();
  338. $this->invokePrivate($api, 'verifyAppId', [$app]);
  339. }
  340. public function dataVerifyConfigKey() {
  341. return [
  342. ['activity', 'abc', ''],
  343. ['dav', 'public_route', ''],
  344. ['files', 'remote_route', ''],
  345. ['core', 'encryption_enabled', 'yes'],
  346. ];
  347. }
  348. /**
  349. * @dataProvider dataVerifyConfigKey
  350. * @param string $app
  351. * @param string $key
  352. * @param string $value
  353. */
  354. public function testVerifyConfigKey($app, $key, $value) {
  355. $api = $this->getInstance();
  356. $this->invokePrivate($api, 'verifyConfigKey', [$app, $key, $value]);
  357. $this->addToAssertionCount(1);
  358. }
  359. public function dataVerifyConfigKeyThrows() {
  360. return [
  361. ['activity', 'installed_version', ''],
  362. ['calendar', 'enabled', ''],
  363. ['contacts', 'types', ''],
  364. ['core', 'encryption_enabled', 'no'],
  365. ['core', 'encryption_enabled', ''],
  366. ['core', 'public_files', ''],
  367. ['core', 'public_dav', ''],
  368. ['core', 'remote_files', ''],
  369. ['core', 'remote_dav', ''],
  370. ];
  371. }
  372. /**
  373. * @dataProvider dataVerifyConfigKeyThrows
  374. * @param string $app
  375. * @param string $key
  376. * @param string $value
  377. */
  378. public function testVerifyConfigKeyThrows($app, $key, $value) {
  379. $this->expectException(\InvalidArgumentException::class);
  380. $api = $this->getInstance();
  381. $this->invokePrivate($api, 'verifyConfigKey', [$app, $key, $value]);
  382. }
  383. }