AppManagerTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. <?php
  2. /**
  3. * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test\App;
  9. use OC\App\AppManager;
  10. use OC\AppConfig;
  11. use OC\Group\Group;
  12. use OC\User\User;
  13. use OCP\App\AppPathNotFoundException;
  14. use OCP\App\IAppManager;
  15. use OCP\ICache;
  16. use OCP\ICacheFactory;
  17. use OCP\IGroup;
  18. use OCP\IGroupManager;
  19. use OCP\ILogger;
  20. use OCP\IUser;
  21. use OCP\IUserSession;
  22. use OCP\IAppConfig;
  23. use OCP\IConfig;
  24. use OCP\IURLGenerator;
  25. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  26. use Test\TestCase;
  27. /**
  28. * Class AppManagerTest
  29. *
  30. * @package Test\App
  31. */
  32. class AppManagerTest extends TestCase {
  33. /**
  34. * @return AppConfig|\PHPUnit_Framework_MockObject_MockObject
  35. */
  36. protected function getAppConfig() {
  37. $appConfig = array();
  38. $config = $this->createMock(AppConfig::class);
  39. $config->expects($this->any())
  40. ->method('getValue')
  41. ->will($this->returnCallback(function ($app, $key, $default) use (&$appConfig) {
  42. return (isset($appConfig[$app]) and isset($appConfig[$app][$key])) ? $appConfig[$app][$key] : $default;
  43. }));
  44. $config->expects($this->any())
  45. ->method('setValue')
  46. ->will($this->returnCallback(function ($app, $key, $value) use (&$appConfig) {
  47. if (!isset($appConfig[$app])) {
  48. $appConfig[$app] = array();
  49. }
  50. $appConfig[$app][$key] = $value;
  51. }));
  52. $config->expects($this->any())
  53. ->method('getValues')
  54. ->will($this->returnCallback(function ($app, $key) use (&$appConfig) {
  55. if ($app) {
  56. return $appConfig[$app];
  57. } else {
  58. $values = array();
  59. foreach ($appConfig as $appid => $appData) {
  60. if (isset($appData[$key])) {
  61. $values[$appid] = $appData[$key];
  62. }
  63. }
  64. return $values;
  65. }
  66. }));
  67. return $config;
  68. }
  69. /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
  70. protected $userSession;
  71. /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
  72. protected $groupManager;
  73. /** @var AppConfig|\PHPUnit_Framework_MockObject_MockObject */
  74. protected $appConfig;
  75. /** @var ICache|\PHPUnit_Framework_MockObject_MockObject */
  76. protected $cache;
  77. /** @var ICacheFactory|\PHPUnit_Framework_MockObject_MockObject */
  78. protected $cacheFactory;
  79. /** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
  80. protected $eventDispatcher;
  81. /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
  82. protected $logger;
  83. /** @var IAppManager */
  84. protected $manager;
  85. protected function setUp() {
  86. parent::setUp();
  87. $this->userSession = $this->createMock(IUserSession::class);
  88. $this->groupManager = $this->createMock(IGroupManager::class);
  89. $this->appConfig = $this->getAppConfig();
  90. $this->cacheFactory = $this->createMock(ICacheFactory::class);
  91. $this->cache = $this->createMock(ICache::class);
  92. $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);
  93. $this->logger = $this->createMock(ILogger::class);
  94. $this->cacheFactory->expects($this->any())
  95. ->method('createDistributed')
  96. ->with('settings')
  97. ->willReturn($this->cache);
  98. $this->manager = new AppManager($this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger);
  99. }
  100. protected function expectClearCache() {
  101. $this->cache->expects($this->once())
  102. ->method('clear')
  103. ->with('listApps');
  104. }
  105. public function testEnableApp() {
  106. $this->expectClearCache();
  107. // making sure "files_trashbin" is disabled
  108. if ($this->manager->isEnabledForUser('files_trashbin')) {
  109. $this->manager->disableApp('files_trashbin');
  110. }
  111. $this->manager->enableApp('files_trashbin');
  112. $this->assertEquals('yes', $this->appConfig->getValue('files_trashbin', 'enabled', 'no'));
  113. }
  114. public function testDisableApp() {
  115. $this->expectClearCache();
  116. $this->manager->disableApp('files_trashbin');
  117. $this->assertEquals('no', $this->appConfig->getValue('files_trashbin', 'enabled', 'no'));
  118. }
  119. public function testNotEnableIfNotInstalled() {
  120. try {
  121. $this->manager->enableApp('some_random_name_which_i_hope_is_not_an_app');
  122. $this->assertFalse(true, 'If this line is reached the expected exception is not thrown.');
  123. } catch (AppPathNotFoundException $e) {
  124. // Exception is expected
  125. $this->assertEquals('Could not find path for some_random_name_which_i_hope_is_not_an_app', $e->getMessage());
  126. }
  127. $this->assertEquals('no', $this->appConfig->getValue(
  128. 'some_random_name_which_i_hope_is_not_an_app', 'enabled', 'no'
  129. ));
  130. }
  131. public function testEnableAppForGroups() {
  132. $group1 = $this->createMock(IGroup::class);
  133. $group1->method('getGID')
  134. ->willReturn('group1');
  135. $group2 = $this->createMock(IGroup::class);
  136. $group2->method('getGID')
  137. ->willReturn('group2');
  138. $groups = [$group1, $group2];
  139. $this->expectClearCache();
  140. /** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
  141. $manager = $this->getMockBuilder(AppManager::class)
  142. ->setConstructorArgs([
  143. $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
  144. ])
  145. ->setMethods([
  146. 'getAppPath',
  147. ])
  148. ->getMock();
  149. $manager->expects($this->exactly(2))
  150. ->method('getAppPath')
  151. ->with('test')
  152. ->willReturn('apps/test');
  153. $manager->enableAppForGroups('test', $groups);
  154. $this->assertEquals('["group1","group2"]', $this->appConfig->getValue('test', 'enabled', 'no'));
  155. }
  156. public function dataEnableAppForGroupsAllowedTypes() {
  157. return [
  158. [[]],
  159. [[
  160. 'types' => [],
  161. ]],
  162. [[
  163. 'types' => ['nickvergessen'],
  164. ]],
  165. ];
  166. }
  167. /**
  168. * @dataProvider dataEnableAppForGroupsAllowedTypes
  169. *
  170. * @param array $appInfo
  171. */
  172. public function testEnableAppForGroupsAllowedTypes(array $appInfo) {
  173. $group1 = $this->createMock(IGroup::class);
  174. $group1->method('getGID')
  175. ->willReturn('group1');
  176. $group2 = $this->createMock(IGroup::class);
  177. $group2->method('getGID')
  178. ->willReturn('group2');
  179. $groups = [$group1, $group2];
  180. $this->expectClearCache();
  181. /** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
  182. $manager = $this->getMockBuilder(AppManager::class)
  183. ->setConstructorArgs([
  184. $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
  185. ])
  186. ->setMethods([
  187. 'getAppPath',
  188. 'getAppInfo',
  189. ])
  190. ->getMock();
  191. $manager->expects($this->once())
  192. ->method('getAppPath')
  193. ->with('test')
  194. ->willReturn(null);
  195. $manager->expects($this->once())
  196. ->method('getAppInfo')
  197. ->with('test')
  198. ->willReturn($appInfo);
  199. $manager->enableAppForGroups('test', $groups);
  200. $this->assertEquals('["group1","group2"]', $this->appConfig->getValue('test', 'enabled', 'no'));
  201. }
  202. public function dataEnableAppForGroupsForbiddenTypes() {
  203. return [
  204. ['filesystem'],
  205. ['prelogin'],
  206. ['authentication'],
  207. ['logging'],
  208. ['prevent_group_restriction'],
  209. ];
  210. }
  211. /**
  212. * @dataProvider dataEnableAppForGroupsForbiddenTypes
  213. *
  214. * @param string $type
  215. *
  216. * @expectedException \Exception
  217. * @expectedExceptionMessage test can't be enabled for groups.
  218. */
  219. public function testEnableAppForGroupsForbiddenTypes($type) {
  220. $group1 = $this->createMock(IGroup::class);
  221. $group1->method('getGID')
  222. ->willReturn('group1');
  223. $group2 = $this->createMock(IGroup::class);
  224. $group2->method('getGID')
  225. ->willReturn('group2');
  226. $groups = [$group1, $group2];
  227. /** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
  228. $manager = $this->getMockBuilder(AppManager::class)
  229. ->setConstructorArgs([
  230. $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
  231. ])
  232. ->setMethods([
  233. 'getAppPath',
  234. 'getAppInfo',
  235. ])
  236. ->getMock();
  237. $manager->expects($this->once())
  238. ->method('getAppPath')
  239. ->with('test')
  240. ->willReturn(null);
  241. $manager->expects($this->once())
  242. ->method('getAppInfo')
  243. ->with('test')
  244. ->willReturn([
  245. 'types' => [$type],
  246. ]);
  247. $manager->enableAppForGroups('test', $groups);
  248. }
  249. public function testIsInstalledEnabled() {
  250. $this->appConfig->setValue('test', 'enabled', 'yes');
  251. $this->assertTrue($this->manager->isInstalled('test'));
  252. }
  253. public function testIsInstalledDisabled() {
  254. $this->appConfig->setValue('test', 'enabled', 'no');
  255. $this->assertFalse($this->manager->isInstalled('test'));
  256. }
  257. public function testIsInstalledEnabledForGroups() {
  258. $this->appConfig->setValue('test', 'enabled', '["foo"]');
  259. $this->assertTrue($this->manager->isInstalled('test'));
  260. }
  261. private function newUser($uid) {
  262. $user = $this->createMock(IUser::class);
  263. $user->method('getUID')
  264. ->willReturn($uid);
  265. return $user;
  266. }
  267. public function testIsEnabledForUserEnabled() {
  268. $this->appConfig->setValue('test', 'enabled', 'yes');
  269. $user = $this->newUser('user1');
  270. $this->assertTrue($this->manager->isEnabledForUser('test', $user));
  271. }
  272. public function testIsEnabledForUserDisabled() {
  273. $this->appConfig->setValue('test', 'enabled', 'no');
  274. $user = $this->newUser('user1');
  275. $this->assertFalse($this->manager->isEnabledForUser('test', $user));
  276. }
  277. public function testGetAppPath() {
  278. $this->assertEquals(\OC::$SERVERROOT . '/apps/files', $this->manager->getAppPath('files'));
  279. }
  280. public function testGetAppPathFail() {
  281. $this->expectException(AppPathNotFoundException::class);
  282. $this->manager->getAppPath('testnotexisting');
  283. }
  284. public function testIsEnabledForUserEnabledForGroup() {
  285. $user = $this->newUser('user1');
  286. $this->groupManager->expects($this->once())
  287. ->method('getUserGroupIds')
  288. ->with($user)
  289. ->will($this->returnValue(array('foo', 'bar')));
  290. $this->appConfig->setValue('test', 'enabled', '["foo"]');
  291. $this->assertTrue($this->manager->isEnabledForUser('test', $user));
  292. }
  293. public function testIsEnabledForUserDisabledForGroup() {
  294. $user = $this->newUser('user1');
  295. $this->groupManager->expects($this->once())
  296. ->method('getUserGroupIds')
  297. ->with($user)
  298. ->will($this->returnValue(array('bar')));
  299. $this->appConfig->setValue('test', 'enabled', '["foo"]');
  300. $this->assertFalse($this->manager->isEnabledForUser('test', $user));
  301. }
  302. public function testIsEnabledForUserLoggedOut() {
  303. $this->appConfig->setValue('test', 'enabled', '["foo"]');
  304. $this->assertFalse($this->manager->isEnabledForUser('test'));
  305. }
  306. public function testIsEnabledForUserLoggedIn() {
  307. $user = $this->newUser('user1');
  308. $this->userSession->expects($this->once())
  309. ->method('getUser')
  310. ->will($this->returnValue($user));
  311. $this->groupManager->expects($this->once())
  312. ->method('getUserGroupIds')
  313. ->with($user)
  314. ->will($this->returnValue(array('foo', 'bar')));
  315. $this->appConfig->setValue('test', 'enabled', '["foo"]');
  316. $this->assertTrue($this->manager->isEnabledForUser('test'));
  317. }
  318. public function testGetInstalledApps() {
  319. $this->appConfig->setValue('test1', 'enabled', 'yes');
  320. $this->appConfig->setValue('test2', 'enabled', 'no');
  321. $this->appConfig->setValue('test3', 'enabled', '["foo"]');
  322. $apps = [
  323. 'cloud_federation_api',
  324. 'dav',
  325. 'federatedfilesharing',
  326. 'files',
  327. 'lookup_server_connector',
  328. 'oauth2',
  329. 'provisioning_api',
  330. 'test1',
  331. 'test3',
  332. 'twofactor_backupcodes',
  333. 'workflowengine',
  334. ];
  335. $this->assertEquals($apps, $this->manager->getInstalledApps());
  336. }
  337. public function testGetAppsForUser() {
  338. $user = $this->newUser('user1');
  339. $this->groupManager->expects($this->any())
  340. ->method('getUserGroupIds')
  341. ->with($user)
  342. ->will($this->returnValue(array('foo', 'bar')));
  343. $this->appConfig->setValue('test1', 'enabled', 'yes');
  344. $this->appConfig->setValue('test2', 'enabled', 'no');
  345. $this->appConfig->setValue('test3', 'enabled', '["foo"]');
  346. $this->appConfig->setValue('test4', 'enabled', '["asd"]');
  347. $enabled = [
  348. 'cloud_federation_api',
  349. 'dav',
  350. 'federatedfilesharing',
  351. 'files',
  352. 'lookup_server_connector',
  353. 'oauth2',
  354. 'provisioning_api',
  355. 'test1',
  356. 'test3',
  357. 'twofactor_backupcodes',
  358. 'workflowengine',
  359. ];
  360. $this->assertEquals($enabled, $this->manager->getEnabledAppsForUser($user));
  361. }
  362. public function testGetAppsNeedingUpgrade() {
  363. /** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
  364. $manager = $this->getMockBuilder(AppManager::class)
  365. ->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger])
  366. ->setMethods(['getAppInfo'])
  367. ->getMock();
  368. $appInfos = [
  369. 'cloud_federation_api' => ['id' => 'cloud_federation_api'],
  370. 'dav' => ['id' => 'dav'],
  371. 'files' => ['id' => 'files'],
  372. 'federatedfilesharing' => ['id' => 'federatedfilesharing'],
  373. 'provisioning_api' => ['id' => 'provisioning_api'],
  374. 'lookup_server_connector' => ['id' => 'lookup_server_connector'],
  375. 'test1' => ['id' => 'test1', 'version' => '1.0.1', 'requiremax' => '9.0.0'],
  376. 'test2' => ['id' => 'test2', 'version' => '1.0.0', 'requiremin' => '8.2.0'],
  377. 'test3' => ['id' => 'test3', 'version' => '1.2.4', 'requiremin' => '9.0.0'],
  378. 'test4' => ['id' => 'test4', 'version' => '3.0.0', 'requiremin' => '8.1.0'],
  379. 'testnoversion' => ['id' => 'testnoversion', 'requiremin' => '8.2.0'],
  380. 'twofactor_backupcodes' => ['id' => 'twofactor_backupcodes'],
  381. 'workflowengine' => ['id' => 'workflowengine'],
  382. 'oauth2' => ['id' => 'oauth2'],
  383. ];
  384. $manager->expects($this->any())
  385. ->method('getAppInfo')
  386. ->will($this->returnCallback(
  387. function($appId) use ($appInfos) {
  388. return $appInfos[$appId];
  389. }
  390. ));
  391. $this->appConfig->setValue('test1', 'enabled', 'yes');
  392. $this->appConfig->setValue('test1', 'installed_version', '1.0.0');
  393. $this->appConfig->setValue('test2', 'enabled', 'yes');
  394. $this->appConfig->setValue('test2', 'installed_version', '1.0.0');
  395. $this->appConfig->setValue('test3', 'enabled', 'yes');
  396. $this->appConfig->setValue('test3', 'installed_version', '1.0.0');
  397. $this->appConfig->setValue('test4', 'enabled', 'yes');
  398. $this->appConfig->setValue('test4', 'installed_version', '2.4.0');
  399. $apps = $manager->getAppsNeedingUpgrade('8.2.0');
  400. $this->assertCount(2, $apps);
  401. $this->assertEquals('test1', $apps[0]['id']);
  402. $this->assertEquals('test4', $apps[1]['id']);
  403. }
  404. public function testGetIncompatibleApps() {
  405. /** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
  406. $manager = $this->getMockBuilder(AppManager::class)
  407. ->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger])
  408. ->setMethods(['getAppInfo'])
  409. ->getMock();
  410. $appInfos = [
  411. 'cloud_federation_api' => ['id' => 'cloud_federation_api'],
  412. 'dav' => ['id' => 'dav'],
  413. 'files' => ['id' => 'files'],
  414. 'federatedfilesharing' => ['id' => 'federatedfilesharing'],
  415. 'provisioning_api' => ['id' => 'provisioning_api'],
  416. 'lookup_server_connector' => ['id' => 'lookup_server_connector'],
  417. 'test1' => ['id' => 'test1', 'version' => '1.0.1', 'requiremax' => '8.0.0'],
  418. 'test2' => ['id' => 'test2', 'version' => '1.0.0', 'requiremin' => '8.2.0'],
  419. 'test3' => ['id' => 'test3', 'version' => '1.2.4', 'requiremin' => '9.0.0'],
  420. 'testnoversion' => ['id' => 'testnoversion', 'requiremin' => '8.2.0'],
  421. 'twofactor_backupcodes' => ['id' => 'twofactor_backupcodes'],
  422. 'workflowengine' => ['id' => 'workflowengine'],
  423. 'oauth2' => ['id' => 'oauth2'],
  424. ];
  425. $manager->expects($this->any())
  426. ->method('getAppInfo')
  427. ->will($this->returnCallback(
  428. function($appId) use ($appInfos) {
  429. return $appInfos[$appId];
  430. }
  431. ));
  432. $this->appConfig->setValue('test1', 'enabled', 'yes');
  433. $this->appConfig->setValue('test2', 'enabled', 'yes');
  434. $this->appConfig->setValue('test3', 'enabled', 'yes');
  435. $apps = $manager->getIncompatibleApps('8.2.0');
  436. $this->assertCount(2, $apps);
  437. $this->assertEquals('test1', $apps[0]['id']);
  438. $this->assertEquals('test3', $apps[1]['id']);
  439. }
  440. public function testGetEnabledAppsForGroup() {
  441. $group = $this->createMock(IGroup::class);
  442. $group->expects($this->any())
  443. ->method('getGID')
  444. ->will($this->returnValue('foo'));
  445. $this->appConfig->setValue('test1', 'enabled', 'yes');
  446. $this->appConfig->setValue('test2', 'enabled', 'no');
  447. $this->appConfig->setValue('test3', 'enabled', '["foo"]');
  448. $this->appConfig->setValue('test4', 'enabled', '["asd"]');
  449. $enabled = [
  450. 'cloud_federation_api',
  451. 'dav',
  452. 'federatedfilesharing',
  453. 'files',
  454. 'lookup_server_connector',
  455. 'oauth2',
  456. 'provisioning_api',
  457. 'test1',
  458. 'test3',
  459. 'twofactor_backupcodes',
  460. 'workflowengine',
  461. ];
  462. $this->assertEquals($enabled, $this->manager->getEnabledAppsForGroup($group));
  463. }
  464. public function testGetAppRestriction() {
  465. $this->appConfig->setValue('test1', 'enabled', 'yes');
  466. $this->appConfig->setValue('test2', 'enabled', 'no');
  467. $this->appConfig->setValue('test3', 'enabled', '["foo"]');
  468. $this->assertEquals([], $this->manager->getAppRestriction('test1'));
  469. $this->assertEquals([], $this->manager->getAppRestriction('test2'));
  470. $this->assertEquals(['foo'], $this->manager->getAppRestriction('test3'));
  471. }
  472. }