You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AppTest.php 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Bernhard Posselt <dev@bernhard-posselt.com>
  4. * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
  5. * This file is licensed under the Affero General Public License version 3 or
  6. * later.
  7. * See the COPYING-README file.
  8. */
  9. namespace Test;
  10. use OCP\IAppConfig;
  11. /**
  12. * Class AppTest
  13. *
  14. * @group DB
  15. */
  16. class AppTest extends \Test\TestCase {
  17. const TEST_USER1 = 'user1';
  18. const TEST_USER2 = 'user2';
  19. const TEST_USER3 = 'user3';
  20. const TEST_GROUP1 = 'group1';
  21. const TEST_GROUP2 = 'group2';
  22. function appVersionsProvider() {
  23. return array(
  24. // exact match
  25. array(
  26. '6.0.0.0',
  27. array(
  28. 'requiremin' => '6.0',
  29. 'requiremax' => '6.0',
  30. ),
  31. true
  32. ),
  33. // in-between match
  34. array(
  35. '6.0.0.0',
  36. array(
  37. 'requiremin' => '5.0',
  38. 'requiremax' => '7.0',
  39. ),
  40. true
  41. ),
  42. // app too old
  43. array(
  44. '6.0.0.0',
  45. array(
  46. 'requiremin' => '5.0',
  47. 'requiremax' => '5.0',
  48. ),
  49. false
  50. ),
  51. // app too new
  52. array(
  53. '5.0.0.0',
  54. array(
  55. 'requiremin' => '6.0',
  56. 'requiremax' => '6.0',
  57. ),
  58. false
  59. ),
  60. // only min specified
  61. array(
  62. '6.0.0.0',
  63. array(
  64. 'requiremin' => '6.0',
  65. ),
  66. true
  67. ),
  68. // only min specified fail
  69. array(
  70. '5.0.0.0',
  71. array(
  72. 'requiremin' => '6.0',
  73. ),
  74. false
  75. ),
  76. // only min specified legacy
  77. array(
  78. '6.0.0.0',
  79. array(
  80. 'require' => '6.0',
  81. ),
  82. true
  83. ),
  84. // only min specified legacy fail
  85. array(
  86. '4.0.0.0',
  87. array(
  88. 'require' => '6.0',
  89. ),
  90. false
  91. ),
  92. // only max specified
  93. array(
  94. '5.0.0.0',
  95. array(
  96. 'requiremax' => '6.0',
  97. ),
  98. true
  99. ),
  100. // only max specified fail
  101. array(
  102. '7.0.0.0',
  103. array(
  104. 'requiremax' => '6.0',
  105. ),
  106. false
  107. ),
  108. // variations of versions
  109. // single OC number
  110. array(
  111. '4',
  112. array(
  113. 'require' => '4.0',
  114. ),
  115. true
  116. ),
  117. // multiple OC number
  118. array(
  119. '4.3.1',
  120. array(
  121. 'require' => '4.3',
  122. ),
  123. true
  124. ),
  125. // single app number
  126. array(
  127. '4',
  128. array(
  129. 'require' => '4',
  130. ),
  131. true
  132. ),
  133. // single app number fail
  134. array(
  135. '4.3',
  136. array(
  137. 'require' => '5',
  138. ),
  139. false
  140. ),
  141. // complex
  142. array(
  143. '5.0.0',
  144. array(
  145. 'require' => '4.5.1',
  146. ),
  147. true
  148. ),
  149. // complex fail
  150. array(
  151. '4.3.1',
  152. array(
  153. 'require' => '4.3.2',
  154. ),
  155. false
  156. ),
  157. // two numbers
  158. array(
  159. '4.3.1',
  160. array(
  161. 'require' => '4.4',
  162. ),
  163. false
  164. ),
  165. // one number fail
  166. array(
  167. '4.3.1',
  168. array(
  169. 'require' => '5',
  170. ),
  171. false
  172. ),
  173. // pre-alpha app
  174. array(
  175. '5.0.3',
  176. array(
  177. 'require' => '4.93',
  178. ),
  179. true
  180. ),
  181. // pre-alpha OC
  182. array(
  183. '6.90.0.2',
  184. array(
  185. 'require' => '6.90',
  186. ),
  187. true
  188. ),
  189. // pre-alpha OC max
  190. array(
  191. '6.90.0.2',
  192. array(
  193. 'requiremax' => '7',
  194. ),
  195. true
  196. ),
  197. // expect same major number match
  198. array(
  199. '5.0.3',
  200. array(
  201. 'require' => '5',
  202. ),
  203. true
  204. ),
  205. // expect same major number match
  206. array(
  207. '5.0.3',
  208. array(
  209. 'requiremax' => '5',
  210. ),
  211. true
  212. ),
  213. // dependencies versions before require*
  214. array(
  215. '6.0.0.0',
  216. array(
  217. 'requiremin' => '5.0',
  218. 'requiremax' => '7.0',
  219. 'dependencies' => array(
  220. 'owncloud' => array(
  221. '@attributes' => array(
  222. 'min-version' => '7.0',
  223. 'max-version' => '7.0',
  224. ),
  225. ),
  226. ),
  227. ),
  228. false
  229. ),
  230. array(
  231. '6.0.0.0',
  232. array(
  233. 'requiremin' => '5.0',
  234. 'requiremax' => '7.0',
  235. 'dependencies' => array(
  236. 'owncloud' => array(
  237. '@attributes' => array(
  238. 'min-version' => '5.0',
  239. 'max-version' => '5.0',
  240. ),
  241. ),
  242. ),
  243. ),
  244. false
  245. ),
  246. array(
  247. '6.0.0.0',
  248. array(
  249. 'requiremin' => '5.0',
  250. 'requiremax' => '5.0',
  251. 'dependencies' => array(
  252. 'owncloud' => array(
  253. '@attributes' => array(
  254. 'min-version' => '5.0',
  255. 'max-version' => '7.0',
  256. ),
  257. ),
  258. ),
  259. ),
  260. true
  261. ),
  262. );
  263. }
  264. /**
  265. * @dataProvider appVersionsProvider
  266. */
  267. public function testIsAppCompatible($ocVersion, $appInfo, $expectedResult) {
  268. $this->assertEquals($expectedResult, \OC_App::isAppCompatible($ocVersion, $appInfo));
  269. }
  270. /**
  271. * Test that the isAppCompatible method also supports passing an array
  272. * as $ocVersion
  273. */
  274. public function testIsAppCompatibleWithArray() {
  275. $ocVersion = array(6);
  276. $appInfo = array(
  277. 'requiremin' => '6',
  278. 'requiremax' => '6',
  279. );
  280. $this->assertTrue(\OC_App::isAppCompatible($ocVersion, $appInfo));
  281. }
  282. /**
  283. * Tests that the app order is correct
  284. */
  285. public function testGetEnabledAppsIsSorted() {
  286. $apps = \OC_App::getEnabledApps();
  287. // copy array
  288. $sortedApps = $apps;
  289. sort($sortedApps);
  290. // 'files' is always on top
  291. unset($sortedApps[array_search('files', $sortedApps)]);
  292. array_unshift($sortedApps, 'files');
  293. $this->assertEquals($sortedApps, $apps);
  294. }
  295. /**
  296. * Providers for the app config values
  297. */
  298. function appConfigValuesProvider() {
  299. return array(
  300. // logged in user1
  301. array(
  302. self::TEST_USER1,
  303. array(
  304. 'files',
  305. 'app1',
  306. 'app3',
  307. 'appforgroup1',
  308. 'appforgroup12',
  309. 'dav',
  310. 'federatedfilesharing',
  311. ),
  312. false
  313. ),
  314. // logged in user2
  315. array(
  316. self::TEST_USER2,
  317. array(
  318. 'files',
  319. 'app1',
  320. 'app3',
  321. 'appforgroup12',
  322. 'appforgroup2',
  323. 'dav',
  324. 'federatedfilesharing',
  325. ),
  326. false
  327. ),
  328. // logged in user3
  329. array(
  330. self::TEST_USER3,
  331. array(
  332. 'files',
  333. 'app1',
  334. 'app3',
  335. 'appforgroup1',
  336. 'appforgroup12',
  337. 'appforgroup2',
  338. 'dav',
  339. 'federatedfilesharing',
  340. ),
  341. false
  342. ),
  343. // no user, returns all apps
  344. array(
  345. null,
  346. array(
  347. 'files',
  348. 'app1',
  349. 'app3',
  350. 'appforgroup1',
  351. 'appforgroup12',
  352. 'appforgroup2',
  353. 'dav',
  354. 'federatedfilesharing',
  355. ),
  356. false,
  357. ),
  358. // user given, but ask for all
  359. array(
  360. self::TEST_USER1,
  361. array(
  362. 'files',
  363. 'app1',
  364. 'app3',
  365. 'appforgroup1',
  366. 'appforgroup12',
  367. 'appforgroup2',
  368. 'dav',
  369. 'federatedfilesharing',
  370. ),
  371. true,
  372. ),
  373. );
  374. }
  375. /**
  376. * Test enabled apps
  377. *
  378. * @dataProvider appConfigValuesProvider
  379. */
  380. public function testEnabledApps($user, $expectedApps, $forceAll) {
  381. $userManager = \OC::$server->getUserManager();
  382. $groupManager = \OC::$server->getGroupManager();
  383. $user1 = $userManager->createUser(self::TEST_USER1, self::TEST_USER1);
  384. $user2 = $userManager->createUser(self::TEST_USER2, self::TEST_USER2);
  385. $user3 = $userManager->createUser(self::TEST_USER3, self::TEST_USER3);
  386. $group1 = $groupManager->createGroup(self::TEST_GROUP1);
  387. $group1->addUser($user1);
  388. $group1->addUser($user3);
  389. $group2 = $groupManager->createGroup(self::TEST_GROUP2);
  390. $group2->addUser($user2);
  391. $group2->addUser($user3);
  392. \OC_User::setUserId($user);
  393. $this->setupAppConfigMock()->expects($this->once())
  394. ->method('getValues')
  395. ->will($this->returnValue(
  396. array(
  397. 'app3' => 'yes',
  398. 'app2' => 'no',
  399. 'app1' => 'yes',
  400. 'appforgroup1' => '["group1"]',
  401. 'appforgroup2' => '["group2"]',
  402. 'appforgroup12' => '["group2","group1"]',
  403. )
  404. )
  405. );
  406. $apps = \OC_App::getEnabledApps(false, $forceAll);
  407. $this->restoreAppConfig();
  408. \OC_User::setUserId(null);
  409. $user1->delete();
  410. $user2->delete();
  411. $user3->delete();
  412. $group1->delete();
  413. $group2->delete();
  414. $this->assertEquals($expectedApps, $apps);
  415. }
  416. /**
  417. * Test isEnabledApps() with cache, not re-reading the list of
  418. * enabled apps more than once when a user is set.
  419. */
  420. public function testEnabledAppsCache() {
  421. $userManager = \OC::$server->getUserManager();
  422. $user1 = $userManager->createUser(self::TEST_USER1, self::TEST_USER1);
  423. \OC_User::setUserId(self::TEST_USER1);
  424. $this->setupAppConfigMock()->expects($this->once())
  425. ->method('getValues')
  426. ->will($this->returnValue(
  427. array(
  428. 'app3' => 'yes',
  429. 'app2' => 'no',
  430. )
  431. )
  432. );
  433. $apps = \OC_App::getEnabledApps();
  434. $this->assertEquals(array('files', 'app3', 'dav', 'federatedfilesharing',), $apps);
  435. // mock should not be called again here
  436. $apps = \OC_App::getEnabledApps();
  437. $this->assertEquals(array('files', 'app3', 'dav', 'federatedfilesharing',), $apps);
  438. $this->restoreAppConfig();
  439. \OC_User::setUserId(null);
  440. $user1->delete();
  441. }
  442. private function setupAppConfigMock() {
  443. $appConfig = $this->getMock(
  444. '\OC\AppConfig',
  445. array('getValues'),
  446. array(\OC::$server->getDatabaseConnection()),
  447. '',
  448. false
  449. );
  450. $this->registerAppConfig($appConfig);
  451. return $appConfig;
  452. }
  453. /**
  454. * Register an app config mock for testing purposes.
  455. *
  456. * @param IAppConfig $appConfig app config mock
  457. */
  458. private function registerAppConfig(IAppConfig $appConfig) {
  459. \OC::$server->registerService('AppConfig', function ($c) use ($appConfig) {
  460. return $appConfig;
  461. });
  462. \OC::$server->registerService('AppManager', function (\OC\Server $c) use ($appConfig) {
  463. return new \OC\App\AppManager($c->getUserSession(), $appConfig, $c->getGroupManager(), $c->getMemCacheFactory(), $c->getEventDispatcher());
  464. });
  465. }
  466. /**
  467. * Restore the original app config service.
  468. */
  469. private function restoreAppConfig() {
  470. \OC::$server->registerService('AppConfig', function (\OC\Server $c) {
  471. return new \OC\AppConfig($c->getDatabaseConnection());
  472. });
  473. \OC::$server->registerService('AppManager', function (\OC\Server $c) {
  474. return new \OC\App\AppManager($c->getUserSession(), $c->getAppConfig(), $c->getGroupManager(), $c->getMemCacheFactory(), $c->getEventDispatcher());
  475. });
  476. // Remove the cache of the mocked apps list with a forceRefresh
  477. \OC_App::getEnabledApps();
  478. }
  479. /**
  480. * Providers for the app data values
  481. */
  482. function appDataProvider() {
  483. return [
  484. [
  485. ['description' => " \t This is a multiline \n test with \n \t \n \n some new lines "],
  486. ['description' => "This is a multiline test with\n\nsome new lines"]
  487. ],
  488. [
  489. ['description' => " \t This is a multiline \n test with \n \t some new lines "],
  490. ['description' => "This is a multiline test with some new lines"]
  491. ],
  492. [
  493. ['description' => hex2bin('5065726d657420646520732761757468656e7469666965722064616e732070697769676f20646972656374656d656e74206176656320736573206964656e74696669616e7473206f776e636c6f75642073616e73206c65732072657461706572206574206d657420c3a0206a6f757273206365757820636920656e20636173206465206368616e67656d656e74206465206d6f742064652070617373652e0d0a0d')],
  494. ['description' => "Permet de s'authentifier dans piwigo directement avec ses identifiants owncloud sans les retaper et met à jours ceux ci en cas de changement de mot de passe."]
  495. ],
  496. [
  497. ['not-a-description' => " \t This is a multiline \n test with \n \t some new lines "],
  498. ['not-a-description' => " \t This is a multiline \n test with \n \t some new lines "]
  499. ],
  500. [
  501. ['description' => [100, 'bla']],
  502. ['description' => ""]
  503. ],
  504. ];
  505. }
  506. /**
  507. * Test app info parser
  508. *
  509. * @dataProvider appDataProvider
  510. * @param array $data
  511. * @param array $expected
  512. */
  513. public function testParseAppInfo(array $data, array $expected) {
  514. $this->assertSame($expected, \OC_App::parseAppInfo($data));
  515. }
  516. }