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.

app.php 11KB

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