1
0

FactoryTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. <?php
  2. /**
  3. * Copyright (c) 2016 Joas Schilling <nickvergessen@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\L10N;
  9. use OC\L10N\Factory;
  10. use OC\L10N\LanguageNotFoundException;
  11. use OCP\IConfig;
  12. use OCP\IRequest;
  13. use OCP\IUser;
  14. use OCP\IUserSession;
  15. use Test\TestCase;
  16. /**
  17. * Class FactoryTest
  18. *
  19. * @package Test\L10N
  20. */
  21. class FactoryTest extends TestCase {
  22. /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
  23. protected $config;
  24. /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
  25. protected $request;
  26. /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
  27. protected $userSession;
  28. /** @var string */
  29. protected $serverRoot;
  30. public function setUp() {
  31. parent::setUp();
  32. $this->config = $this->getMockBuilder(IConfig::class)
  33. ->disableOriginalConstructor()
  34. ->getMock();
  35. $this->request = $this->getMockBuilder(IRequest::class)
  36. ->disableOriginalConstructor()
  37. ->getMock();
  38. $this->userSession = $this->getMockBuilder(IUserSession::class)
  39. ->disableOriginalConstructor()
  40. ->getMock();
  41. $this->serverRoot = \OC::$SERVERROOT;
  42. }
  43. /**
  44. * @param array $methods
  45. * @param bool $mockRequestGetHeaderMethod
  46. * @return Factory|\PHPUnit_Framework_MockObject_MockObject
  47. */
  48. protected function getFactory(array $methods = [], $mockRequestGetHeaderMethod = false) {
  49. if ($mockRequestGetHeaderMethod) {
  50. $this->request->expects($this->any())
  51. ->method('getHeader')
  52. ->willReturn('');
  53. }
  54. if (!empty($methods)) {
  55. return $this->getMockBuilder(Factory::class)
  56. ->setConstructorArgs([
  57. $this->config,
  58. $this->request,
  59. $this->userSession,
  60. $this->serverRoot,
  61. ])
  62. ->setMethods($methods)
  63. ->getMock();
  64. } else {
  65. return new Factory($this->config, $this->request, $this->userSession, $this->serverRoot);
  66. }
  67. }
  68. public function dataFindAvailableLanguages() {
  69. return [
  70. [null],
  71. ['files'],
  72. ];
  73. }
  74. public function testFindLanguageWithExistingRequestLanguageAndNoApp() {
  75. $factory = $this->getFactory(['languageExists']);
  76. $this->invokePrivate($factory, 'requestLanguage', ['de']);
  77. $factory->expects($this->once())
  78. ->method('languageExists')
  79. ->with(null, 'de')
  80. ->willReturn(true);
  81. $this->assertSame('de', $factory->findLanguage());
  82. }
  83. public function testFindLanguageWithExistingRequestLanguageAndApp() {
  84. $factory = $this->getFactory(['languageExists']);
  85. $this->invokePrivate($factory, 'requestLanguage', ['de']);
  86. $factory->expects($this->once())
  87. ->method('languageExists')
  88. ->with('MyApp', 'de')
  89. ->willReturn(true);
  90. $this->assertSame('de', $factory->findLanguage('MyApp'));
  91. }
  92. public function testFindLanguageWithNotExistingRequestLanguageAndExistingStoredUserLanguage() {
  93. $factory = $this->getFactory(['languageExists']);
  94. $this->invokePrivate($factory, 'requestLanguage', ['de']);
  95. $factory->expects($this->at(0))
  96. ->method('languageExists')
  97. ->with('MyApp', 'de')
  98. ->willReturn(false);
  99. $this->config
  100. ->expects($this->at(0))
  101. ->method('getSystemValue')
  102. ->with('force_language', false)
  103. ->willReturn(false);
  104. $this->config
  105. ->expects($this->at(1))
  106. ->method('getSystemValue')
  107. ->with('installed', false)
  108. ->willReturn(true);
  109. $user = $this->getMockBuilder(IUser::class)
  110. ->getMock();
  111. $user->expects($this->once())
  112. ->method('getUID')
  113. ->willReturn('MyUserUid');
  114. $this->userSession
  115. ->expects($this->exactly(2))
  116. ->method('getUser')
  117. ->willReturn($user);
  118. $this->config
  119. ->expects($this->once())
  120. ->method('getUserValue')
  121. ->with('MyUserUid', 'core', 'lang', null)
  122. ->willReturn('jp');
  123. $factory->expects($this->at(1))
  124. ->method('languageExists')
  125. ->with('MyApp', 'jp')
  126. ->willReturn(true);
  127. $this->assertSame('jp', $factory->findLanguage('MyApp'));
  128. }
  129. public function testFindLanguageWithNotExistingRequestLanguageAndNotExistingStoredUserLanguage() {
  130. $factory = $this->getFactory(['languageExists'], true);
  131. $this->invokePrivate($factory, 'requestLanguage', ['de']);
  132. $factory->expects($this->at(0))
  133. ->method('languageExists')
  134. ->with('MyApp', 'de')
  135. ->willReturn(false);
  136. $this->config
  137. ->expects($this->at(0))
  138. ->method('getSystemValue')
  139. ->with('force_language', false)
  140. ->willReturn(false);
  141. $this->config
  142. ->expects($this->at(1))
  143. ->method('getSystemValue')
  144. ->with('installed', false)
  145. ->willReturn(true);
  146. $user = $this->getMockBuilder(IUser::class)
  147. ->getMock();
  148. $user->expects($this->once())
  149. ->method('getUID')
  150. ->willReturn('MyUserUid');
  151. $this->userSession
  152. ->expects($this->exactly(2))
  153. ->method('getUser')
  154. ->willReturn($user);
  155. $this->config
  156. ->expects($this->once())
  157. ->method('getUserValue')
  158. ->with('MyUserUid', 'core', 'lang', null)
  159. ->willReturn('jp');
  160. $factory->expects($this->at(1))
  161. ->method('languageExists')
  162. ->with('MyApp', 'jp')
  163. ->willReturn(false);
  164. $this->config
  165. ->expects($this->at(3))
  166. ->method('getSystemValue')
  167. ->with('default_language', false)
  168. ->willReturn('es');
  169. $factory->expects($this->at(2))
  170. ->method('languageExists')
  171. ->with('MyApp', 'es')
  172. ->willReturn(true);
  173. $this->assertSame('es', $factory->findLanguage('MyApp'));
  174. }
  175. public function testFindLanguageWithNotExistingRequestLanguageAndNotExistingStoredUserLanguageAndNotExistingDefault() {
  176. $factory = $this->getFactory(['languageExists'], true);
  177. $this->invokePrivate($factory, 'requestLanguage', ['de']);
  178. $factory->expects($this->at(0))
  179. ->method('languageExists')
  180. ->with('MyApp', 'de')
  181. ->willReturn(false);
  182. $this->config
  183. ->expects($this->at(0))
  184. ->method('getSystemValue')
  185. ->with('force_language', false)
  186. ->willReturn(false);
  187. $this->config
  188. ->expects($this->at(1))
  189. ->method('getSystemValue')
  190. ->with('installed', false)
  191. ->willReturn(true);
  192. $user = $this->getMockBuilder(IUser::class)
  193. ->getMock();
  194. $user->expects($this->once())
  195. ->method('getUID')
  196. ->willReturn('MyUserUid');
  197. $this->userSession
  198. ->expects($this->exactly(2))
  199. ->method('getUser')
  200. ->willReturn($user);
  201. $this->config
  202. ->expects($this->once())
  203. ->method('getUserValue')
  204. ->with('MyUserUid', 'core', 'lang', null)
  205. ->willReturn('jp');
  206. $factory->expects($this->at(1))
  207. ->method('languageExists')
  208. ->with('MyApp', 'jp')
  209. ->willReturn(false);
  210. $this->config
  211. ->expects($this->at(3))
  212. ->method('getSystemValue')
  213. ->with('default_language', false)
  214. ->willReturn('es');
  215. $factory->expects($this->at(2))
  216. ->method('languageExists')
  217. ->with('MyApp', 'es')
  218. ->willReturn(false);
  219. $this->config
  220. ->expects($this->never())
  221. ->method('setUserValue');
  222. $this->assertSame('en', $factory->findLanguage('MyApp'));
  223. }
  224. public function testFindLanguageWithNotExistingRequestLanguageAndNotExistingStoredUserLanguageAndNotExistingDefaultAndNoAppInScope() {
  225. $factory = $this->getFactory(['languageExists'], true);
  226. $this->invokePrivate($factory, 'requestLanguage', ['de']);
  227. $factory->expects($this->at(0))
  228. ->method('languageExists')
  229. ->with('MyApp', 'de')
  230. ->willReturn(false);
  231. $this->config
  232. ->expects($this->at(0))
  233. ->method('getSystemValue')
  234. ->with('force_language', false)
  235. ->willReturn(false);
  236. $this->config
  237. ->expects($this->at(1))
  238. ->method('getSystemValue')
  239. ->with('installed', false)
  240. ->willReturn(true);
  241. $user = $this->getMockBuilder(IUser::class)
  242. ->getMock();
  243. $user->expects($this->once())
  244. ->method('getUID')
  245. ->willReturn('MyUserUid');
  246. $this->userSession
  247. ->expects($this->exactly(2))
  248. ->method('getUser')
  249. ->willReturn($user);
  250. $this->config
  251. ->expects($this->once())
  252. ->method('getUserValue')
  253. ->with('MyUserUid', 'core', 'lang', null)
  254. ->willReturn('jp');
  255. $factory->expects($this->at(1))
  256. ->method('languageExists')
  257. ->with('MyApp', 'jp')
  258. ->willReturn(false);
  259. $this->config
  260. ->expects($this->at(3))
  261. ->method('getSystemValue')
  262. ->with('default_language', false)
  263. ->willReturn('es');
  264. $factory->expects($this->at(2))
  265. ->method('languageExists')
  266. ->with('MyApp', 'es')
  267. ->willReturn(false);
  268. $this->config
  269. ->expects($this->never())
  270. ->method('setUserValue')
  271. ->with('MyUserUid', 'core', 'lang', 'en');
  272. $this->assertSame('en', $factory->findLanguage('MyApp'));
  273. }
  274. public function testFindLanguageWithForcedLanguage() {
  275. $factory = $this->getFactory(['languageExists']);
  276. $this->config
  277. ->expects($this->at(0))
  278. ->method('getSystemValue')
  279. ->with('force_language', false)
  280. ->willReturn('de');
  281. $factory->expects($this->once())
  282. ->method('languageExists')
  283. ->with('MyApp', 'de')
  284. ->willReturn(true);
  285. $this->assertSame('de', $factory->findLanguage('MyApp'));
  286. }
  287. /**
  288. * @dataProvider dataFindAvailableLanguages
  289. *
  290. * @param string|null $app
  291. */
  292. public function testFindAvailableLanguages($app) {
  293. $factory = $this->getFactory(['findL10nDir']);
  294. $factory->expects($this->once())
  295. ->method('findL10nDir')
  296. ->with($app)
  297. ->willReturn(\OC::$SERVERROOT . '/tests/data/l10n/');
  298. $this->assertEquals(['cs', 'de', 'en', 'ru'], $factory->findAvailableLanguages($app), '', 0.0, 10, true);
  299. }
  300. public function dataLanguageExists() {
  301. return [
  302. [null, 'en', [], true],
  303. [null, 'de', [], false],
  304. [null, 'de', ['ru'], false],
  305. [null, 'de', ['ru', 'de'], true],
  306. ['files', 'en', [], true],
  307. ['files', 'de', [], false],
  308. ['files', 'de', ['ru'], false],
  309. ['files', 'de', ['de', 'ru'], true],
  310. ];
  311. }
  312. public function testFindAvailableLanguagesWithThemes() {
  313. $this->serverRoot .= '/tests/data';
  314. $app = 'files';
  315. $factory = $this->getFactory(['findL10nDir']);
  316. $factory->expects($this->once())
  317. ->method('findL10nDir')
  318. ->with($app)
  319. ->willReturn($this->serverRoot . '/apps/files/l10n/');
  320. $this->config
  321. ->expects($this->once())
  322. ->method('getSystemValue')
  323. ->with('theme')
  324. ->willReturn('abc');
  325. $this->assertEquals(['en', 'zz'], $factory->findAvailableLanguages($app), '', 0.0, 10, true);
  326. }
  327. /**
  328. * @dataProvider dataLanguageExists
  329. *
  330. * @param string|null $app
  331. * @param string $lang
  332. * @param string[] $availableLanguages
  333. * @param string $expected
  334. */
  335. public function testLanguageExists($app, $lang, array $availableLanguages, $expected) {
  336. $factory = $this->getFactory(['findAvailableLanguages']);
  337. $factory->expects(($lang === 'en') ? $this->never() : $this->once())
  338. ->method('findAvailableLanguages')
  339. ->with($app)
  340. ->willReturn($availableLanguages);
  341. $this->assertSame($expected, $factory->languageExists($app, $lang));
  342. }
  343. public function dataSetLanguageFromRequest() {
  344. return [
  345. // Language is available
  346. [null, 'de', ['de'], 'de'],
  347. [null, 'de,en', ['de'], 'de'],
  348. [null, 'de-DE,en-US;q=0.8,en;q=0.6', ['de'], 'de'],
  349. // Language is not available
  350. [null, 'de', ['ru'], new LanguageNotFoundException()],
  351. [null, 'de,en', ['ru', 'en'], 'en'],
  352. [null, 'de-DE,en-US;q=0.8,en;q=0.6', ['ru', 'en'], 'en'],
  353. // Language for app
  354. ['files_pdfviewer', 'de', ['de'], 'de'],
  355. ['files_pdfviewer', 'de,en', ['de'], 'de'],
  356. ['files_pdfviewer', 'de-DE,en-US;q=0.8,en;q=0.6', ['de'], 'de'],
  357. // Language for app is not available
  358. ['files_pdfviewer', 'de', ['ru'], new LanguageNotFoundException()],
  359. ['files_pdfviewer', 'de,en', ['ru', 'en'], 'en'],
  360. ['files_pdfviewer', 'de-DE,en-US;q=0.8,en;q=0.6', ['ru', 'en'], 'en'],
  361. ];
  362. }
  363. /**
  364. * @dataProvider dataSetLanguageFromRequest
  365. *
  366. * @param string|null $app
  367. * @param string $header
  368. * @param string[] $availableLanguages
  369. * @param string $expected
  370. */
  371. public function testGetLanguageFromRequest($app, $header, array $availableLanguages, $expected) {
  372. $factory = $this->getFactory(['findAvailableLanguages', 'respectDefaultLanguage']);
  373. $factory->expects($this->once())
  374. ->method('findAvailableLanguages')
  375. ->with($app)
  376. ->willReturn($availableLanguages);
  377. $factory->expects($this->any())
  378. ->method('respectDefaultLanguage')->willReturnCallback(function($app, $lang) {
  379. return $lang;
  380. });
  381. $this->request->expects($this->once())
  382. ->method('getHeader')
  383. ->with('ACCEPT_LANGUAGE')
  384. ->willReturn($header);
  385. if ($expected instanceof LanguageNotFoundException) {
  386. $this->expectException(LanguageNotFoundException::class);
  387. self::invokePrivate($factory, 'getLanguageFromRequest', [$app]);
  388. } else {
  389. $this->assertSame($expected, self::invokePrivate($factory, 'getLanguageFromRequest', [$app]), 'Asserting returned language');
  390. }
  391. }
  392. public function dataGetL10nFilesForApp() {
  393. return [
  394. [null, 'de', [\OC::$SERVERROOT . '/core/l10n/de.json']],
  395. ['core', 'ru', [\OC::$SERVERROOT . '/core/l10n/ru.json']],
  396. ['lib', 'ru', [\OC::$SERVERROOT . '/lib/l10n/ru.json']],
  397. ['settings', 'de', [\OC::$SERVERROOT . '/settings/l10n/de.json']],
  398. ['files', 'de', [\OC::$SERVERROOT . '/apps/files/l10n/de.json']],
  399. ['files', '_lang_never_exists_', []],
  400. ['_app_never_exists_', 'de', [\OC::$SERVERROOT . '/core/l10n/de.json']],
  401. ];
  402. }
  403. /**
  404. * @dataProvider dataGetL10nFilesForApp
  405. *
  406. * @param string|null $app
  407. * @param string $expected
  408. */
  409. public function testGetL10nFilesForApp($app, $lang, $expected) {
  410. $factory = $this->getFactory();
  411. $this->assertSame($expected, $this->invokePrivate($factory, 'getL10nFilesForApp', [$app, $lang]));
  412. }
  413. public function dataFindL10NDir() {
  414. return [
  415. [null, \OC::$SERVERROOT . '/core/l10n/'],
  416. ['core', \OC::$SERVERROOT . '/core/l10n/'],
  417. ['lib', \OC::$SERVERROOT . '/lib/l10n/'],
  418. ['settings', \OC::$SERVERROOT . '/settings/l10n/'],
  419. ['files', \OC::$SERVERROOT . '/apps/files/l10n/'],
  420. ['_app_never_exists_', \OC::$SERVERROOT . '/core/l10n/'],
  421. ];
  422. }
  423. /**
  424. * @dataProvider dataFindL10NDir
  425. *
  426. * @param string|null $app
  427. * @param string $expected
  428. */
  429. public function testFindL10NDir($app, $expected) {
  430. $factory = $this->getFactory();
  431. $this->assertSame($expected, $this->invokePrivate($factory, 'findL10nDir', [$app]));
  432. }
  433. public function dataFindLanguage() {
  434. return [
  435. // Not logged in
  436. [false, [], 'en'],
  437. [false, ['fr'], 'fr'],
  438. [false, ['de', 'fr'], 'de'],
  439. [false, ['nl', 'de', 'fr'], 'de'],
  440. [true, [], 'en'],
  441. [true, ['fr'], 'fr'],
  442. [true, ['de', 'fr'], 'de'],
  443. [true, ['nl', 'de', 'fr'], 'nl'],
  444. ];
  445. }
  446. /**
  447. * @dataProvider dataFindLanguage
  448. *
  449. * @param bool $loggedIn
  450. * @param array $availableLang
  451. * @param string $expected
  452. */
  453. public function testFindLanguage($loggedIn, $availableLang, $expected) {
  454. $userLang = 'nl';
  455. $browserLang = 'de';
  456. $defaultLang = 'fr';
  457. $this->config->expects($this->any())
  458. ->method('getSystemValue')
  459. ->will($this->returnCallback(function($var, $default) use ($defaultLang) {
  460. if ($var === 'installed') {
  461. return true;
  462. } else if ($var === 'default_language') {
  463. return $defaultLang;
  464. } else {
  465. return $default;
  466. }
  467. }));
  468. if ($loggedIn) {
  469. $user = $this->getMockBuilder(IUser::class)
  470. ->getMock();
  471. $user->expects($this->any())
  472. ->method('getUID')
  473. ->willReturn('MyUserUid');
  474. $this->userSession
  475. ->expects($this->any())
  476. ->method('getUser')
  477. ->willReturn($user);
  478. $this->config->expects($this->any())
  479. ->method('getUserValue')
  480. ->with('MyUserUid', 'core', 'lang', null)
  481. ->willReturn($userLang);
  482. } else {
  483. $this->userSession
  484. ->expects($this->any())
  485. ->method('getUser')
  486. ->willReturn(null);
  487. }
  488. $this->request->expects($this->any())
  489. ->method('getHeader')
  490. ->with($this->equalTo('ACCEPT_LANGUAGE'))
  491. ->willReturn($browserLang);
  492. $factory = $this->getFactory(['languageExists', 'findAvailableLanguages', 'respectDefaultLanguage']);
  493. $factory->expects($this->any())
  494. ->method('languageExists')
  495. ->will($this->returnCallback(function ($app, $lang) use ($availableLang) {
  496. return in_array($lang, $availableLang);
  497. }));
  498. $factory->expects($this->any())
  499. ->method('findAvailableLanguages')
  500. ->will($this->returnCallback(function ($app) use ($availableLang) {
  501. return $availableLang;
  502. }));
  503. $factory->expects($this->any())
  504. ->method('respectDefaultLanguage')->willReturnCallback(function($app, $lang) {
  505. return $lang;
  506. });
  507. $lang = $factory->findLanguage(null);
  508. $this->assertSame($expected, $lang);
  509. }
  510. public function dataTestRespectDefaultLanguage() {
  511. return [
  512. ['de', 'de_DE', true, 'de_DE'],
  513. ['de', 'de', true, 'de'],
  514. ['de', false, true, 'de'],
  515. ['fr', 'de_DE', true, 'fr'],
  516. ];
  517. }
  518. /**
  519. * test if we respect default language if possible
  520. *
  521. * @dataProvider dataTestRespectDefaultLanguage
  522. *
  523. * @param string $lang
  524. * @param string $defaultLanguage
  525. * @param bool $langExists
  526. * @param string $expected
  527. */
  528. public function testRespectDefaultLanguage($lang, $defaultLanguage, $langExists, $expected) {
  529. $factory = $this->getFactory(['languageExists']);
  530. $factory->expects($this->any())
  531. ->method('languageExists')->willReturn($langExists);
  532. $this->config->expects($this->any())
  533. ->method('getSystemValue')->with('default_language', false)->willReturn($defaultLanguage);
  534. $result = $this->invokePrivate($factory, 'respectDefaultLanguage', ['app', $lang]);
  535. $this->assertSame($expected, $result);
  536. }
  537. }