FactoryTest.php 15 KB

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