TranslateTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\Framework\Test\Unit;
  8. use Magento\Framework\Serialize\SerializerInterface;
  9. use Magento\Framework\Translate;
  10. /**
  11. * @SuppressWarnings(PHPMD.TooManyFields)
  12. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  13. */
  14. class TranslateTest extends \PHPUnit\Framework\TestCase
  15. {
  16. /** @var Translate */
  17. protected $translate;
  18. /** @var \Magento\Framework\View\DesignInterface|\PHPUnit_Framework_MockObject_MockObject */
  19. protected $viewDesign;
  20. /** @var \Magento\Framework\Cache\FrontendInterface|\PHPUnit_Framework_MockObject_MockObject */
  21. protected $cache;
  22. /** @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject */
  23. protected $viewFileSystem;
  24. /** @var \Magento\Framework\Module\ModuleList|\PHPUnit_Framework_MockObject_MockObject */
  25. protected $moduleList;
  26. /** @var \Magento\Framework\Module\Dir\Reader|\PHPUnit_Framework_MockObject_MockObject */
  27. protected $modulesReader;
  28. /** @var \Magento\Framework\App\ScopeResolverInterface|\PHPUnit_Framework_MockObject_MockObject */
  29. protected $scopeResolver;
  30. /** @var \Magento\Framework\Translate\ResourceInterface|\PHPUnit_Framework_MockObject_MockObject */
  31. protected $resource;
  32. /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject */
  33. protected $locale;
  34. /** @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject */
  35. protected $appState;
  36. /** @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject */
  37. protected $filesystem;
  38. /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
  39. protected $request;
  40. /** @var \Magento\Framework\File\Csv|\PHPUnit_Framework_MockObject_MockObject */
  41. protected $csvParser;
  42. /** @var \Magento\Framework\App\Language\Dictionary|\PHPUnit_Framework_MockObject_MockObject */
  43. protected $packDictionary;
  44. /** @var \Magento\Framework\Filesystem\Directory\ReadInterface|\PHPUnit_Framework_MockObject_MockObject */
  45. protected $directory;
  46. /** @var \Magento\Framework\Filesystem\DriverInterface|\PHPUnit_Framework_MockObject_MockObject */
  47. protected $fileDriver;
  48. protected function setUp(): void
  49. {
  50. $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
  51. $this->viewDesign = $this->createMock(\Magento\Framework\View\DesignInterface::class);
  52. $this->cache = $this->createMock(\Magento\Framework\Cache\FrontendInterface::class);
  53. $this->viewFileSystem = $this->createMock(\Magento\Framework\View\FileSystem::class);
  54. $this->moduleList = $this->createMock(\Magento\Framework\Module\ModuleList::class);
  55. $this->modulesReader = $this->createMock(\Magento\Framework\Module\Dir\Reader::class);
  56. $this->scopeResolver = $this->createMock(\Magento\Framework\App\ScopeResolverInterface::class);
  57. $this->resource = $this->createMock(\Magento\Framework\Translate\ResourceInterface::class);
  58. $this->locale = $this->createMock(\Magento\Framework\Locale\ResolverInterface::class);
  59. $this->appState = $this->createMock(\Magento\Framework\App\State::class);
  60. $this->request = $this->getMockForAbstractClass(
  61. \Magento\Framework\App\RequestInterface::class,
  62. [],
  63. '',
  64. false,
  65. false,
  66. true,
  67. ['getParam', 'getControllerModule']
  68. );
  69. $this->csvParser = $this->createMock(\Magento\Framework\File\Csv::class);
  70. $this->packDictionary = $this->createMock(\Magento\Framework\App\Language\Dictionary::class);
  71. $this->directory = $this->createMock(\Magento\Framework\Filesystem\Directory\ReadInterface::class);
  72. $filesystem = $this->createMock(\Magento\Framework\Filesystem::class);
  73. $filesystem->expects($this->once())->method('getDirectoryRead')->will($this->returnValue($this->directory));
  74. $this->fileDriver = $this->createMock(\Magento\Framework\Filesystem\DriverInterface::class);
  75. $this->translate = new Translate(
  76. $this->viewDesign,
  77. $this->cache,
  78. $this->viewFileSystem,
  79. $this->moduleList,
  80. $this->modulesReader,
  81. $this->scopeResolver,
  82. $this->resource,
  83. $this->locale,
  84. $this->appState,
  85. $filesystem,
  86. $this->request,
  87. $this->csvParser,
  88. $this->packDictionary,
  89. $this->fileDriver
  90. );
  91. $serializerMock = $this->createMock(SerializerInterface::class);
  92. $serializerMock->method('serialize')
  93. ->willReturnCallback(function ($data) {
  94. return json_encode($data);
  95. });
  96. $serializerMock->method('unserialize')
  97. ->willReturnCallback(function ($string) {
  98. return json_decode($string, true);
  99. });
  100. $objectManager->setBackwardCompatibleProperty(
  101. $this->translate,
  102. 'serializer',
  103. $serializerMock
  104. );
  105. }
  106. /**
  107. * @param string $area
  108. * @param bool $forceReload
  109. * @param array $cachedData
  110. * @dataProvider dataProviderLoadDataCachedTranslation
  111. */
  112. public function testLoadDataCachedTranslation($area, $forceReload, $cachedData): void
  113. {
  114. $this->expectsSetConfig('Magento/luma');
  115. $this->cache->expects($this->once())
  116. ->method('load')
  117. ->will($this->returnValue(json_encode($cachedData)));
  118. $this->appState->expects($this->exactly($area ? 0 : 1))
  119. ->method('getAreaCode')
  120. ->will($this->returnValue('frontend'));
  121. $this->translate->loadData($area, $forceReload);
  122. $this->assertEquals($cachedData, $this->translate->getData());
  123. }
  124. /**
  125. * @return array
  126. */
  127. public function dataProviderLoadDataCachedTranslation(): array
  128. {
  129. $cachedData = ['cached 1' => 'translated 1', 'cached 2' => 'translated 2'];
  130. return [
  131. ['adminhtml', false, $cachedData],
  132. ['frontend', false, $cachedData],
  133. [null, false, $cachedData],
  134. ];
  135. }
  136. /**
  137. * @param string $area
  138. * @param bool $forceReload
  139. * @dataProvider dataProviderForTestLoadData
  140. * @SuppressWarnings(PHPMD.NPathComplexity)
  141. */
  142. public function testLoadData($area, $forceReload): void
  143. {
  144. $this->expectsSetConfig('Magento/luma');
  145. $this->appState->expects($this->exactly($area ? 0 : 1))
  146. ->method('getAreaCode')
  147. ->will($this->returnValue('frontend'));
  148. $this->cache->expects($this->exactly($forceReload ? 0 : 1))
  149. ->method('load')
  150. ->will($this->returnValue(false));
  151. $this->directory->expects($this->any())->method('isExist')->will($this->returnValue(true));
  152. // _loadModuleTranslation()
  153. $modules = ['some_module', 'other_module', 'another_module', 'current_module'];
  154. $this->request->expects($this->any())
  155. ->method('getControllerModule')
  156. ->willReturn('current_module');
  157. $this->moduleList->expects($this->once())->method('getNames')->will($this->returnValue($modules));
  158. $moduleData = [
  159. 'module original' => 'module translated',
  160. 'module theme' => 'module-theme original translated',
  161. 'module pack' => 'module-pack original translated',
  162. 'module db' => 'module-db original translated',
  163. ];
  164. $this->modulesReader->expects($this->any())->method('getModuleDir')->will($this->returnValue('/app/module'));
  165. $themeData = [
  166. 'theme original' => 'theme translated',
  167. 'module theme' => 'theme translated overwrite',
  168. 'module pack' => 'theme-pack translated overwrite',
  169. 'module db' => 'theme-db translated overwrite',
  170. ];
  171. $this->csvParser->expects($this->any())
  172. ->method('getDataPairs')
  173. ->will(
  174. $this->returnValueMap(
  175. [
  176. ['/app/module/en_US.csv', 0, 1, $moduleData],
  177. ['/app/module/en_GB.csv', 0, 1, $moduleData],
  178. ['/theme.csv', 0, 1, $themeData],
  179. ]
  180. )
  181. );
  182. $this->fileDriver->expects($this->any())
  183. ->method('isExists')
  184. ->will(
  185. $this->returnValueMap(
  186. [
  187. ['/app/module/en_US.csv', true],
  188. ['/app/module/en_GB.csv', true],
  189. ['/theme.csv', true],
  190. ]
  191. )
  192. );
  193. // _loadPackTranslation
  194. $packData = [
  195. 'pack original' => 'pack translated',
  196. 'module pack' => 'pack translated overwrite',
  197. 'module db' => 'pack-db translated overwrite',
  198. ];
  199. $this->packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue($packData));
  200. // _loadThemeTranslation()
  201. $this->viewFileSystem->expects($this->any())
  202. ->method('getLocaleFileName')
  203. ->will($this->returnValue('/theme.csv'));
  204. // _loadDbTranslation()
  205. $dbData = [
  206. 'db original' => 'db translated',
  207. 'module db' => 'db translated overwrite',
  208. ];
  209. $this->resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue($dbData));
  210. $this->cache->expects($this->exactly($forceReload ? 0 : 1))->method('save');
  211. $this->translate->loadData($area, $forceReload);
  212. $expected = [
  213. 'module original' => 'module translated',
  214. 'module theme' => 'theme translated overwrite',
  215. 'module pack' => 'theme-pack translated overwrite',
  216. 'module db' => 'db translated overwrite',
  217. 'theme original' => 'theme translated',
  218. 'pack original' => 'pack translated',
  219. 'db original' => 'db translated',
  220. ];
  221. $this->assertEquals($expected, $this->translate->getData());
  222. }
  223. /**
  224. * @return array
  225. */
  226. public function dataProviderForTestLoadData(): array
  227. {
  228. return [
  229. ['adminhtml', true],
  230. ['adminhtml', false],
  231. ['frontend', true],
  232. ['frontend', false],
  233. [null, true],
  234. [null, false]
  235. ];
  236. }
  237. /**
  238. * @param $data
  239. * @param $result
  240. * @dataProvider dataProviderForTestGetData
  241. */
  242. public function testGetData($data, $result): void
  243. {
  244. $this->cache->expects($this->once())
  245. ->method('load')
  246. ->will($this->returnValue(json_encode($data)));
  247. $this->expectsSetConfig('themeId');
  248. $this->translate->loadData('frontend');
  249. $this->assertEquals($result, $this->translate->getData());
  250. }
  251. /**
  252. * @return array
  253. */
  254. public function dataProviderForTestGetData(): array
  255. {
  256. $data = ['original 1' => 'translated 1', 'original 2' => 'translated 2'];
  257. return [
  258. [$data, $data],
  259. [null, []]
  260. ];
  261. }
  262. public function testGetLocale(): void
  263. {
  264. $this->locale->expects($this->once())->method('getLocale')->will($this->returnValue('en_US'));
  265. $this->assertEquals('en_US', $this->translate->getLocale());
  266. $this->locale->expects($this->never())->method('getLocale');
  267. $this->assertEquals('en_US', $this->translate->getLocale());
  268. $this->locale->expects($this->never())->method('getLocale');
  269. $this->translate->setLocale('en_GB');
  270. $this->assertEquals('en_GB', $this->translate->getLocale());
  271. }
  272. public function testSetLocale(): void
  273. {
  274. $this->translate->setLocale('en_GB');
  275. $this->locale->expects($this->never())->method('getLocale');
  276. $this->assertEquals('en_GB', $this->translate->getLocale());
  277. }
  278. public function testGetTheme(): void
  279. {
  280. $this->request->expects($this->at(0))->method('getParam')->with('theme')->will($this->returnValue(''));
  281. $requestTheme = ['theme_title' => 'Theme Title'];
  282. $this->request->expects($this->at(1))->method('getParam')->with('theme')
  283. ->will($this->returnValue($requestTheme));
  284. $this->assertEquals('theme', $this->translate->getTheme());
  285. $this->assertEquals('themeTheme Title', $this->translate->getTheme());
  286. }
  287. public function testLoadDataNoTheme(): void
  288. {
  289. $forceReload = true;
  290. $this->expectsSetConfig(null, null);
  291. $this->moduleList->expects($this->once())->method('getNames')->will($this->returnValue([]));
  292. $this->appState->expects($this->once())->method('getAreaCode')->will($this->returnValue('frontend'));
  293. $this->packDictionary->expects($this->once())->method('getDictionary')->will($this->returnValue([]));
  294. $this->resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue([]));
  295. $this->assertEquals($this->translate, $this->translate->loadData(null, $forceReload));
  296. }
  297. /**
  298. * Declare calls expectation for setConfig() method
  299. */
  300. protected function expectsSetConfig($themeId, $localeCode = 'en_US'): void
  301. {
  302. $this->locale->expects($this->any())->method('getLocale')->will($this->returnValue($localeCode));
  303. $scope = new \Magento\Framework\DataObject(['code' => 'frontendCode', 'id' => 1]);
  304. $scopeAdmin = new \Magento\Framework\DataObject(['code' => 'adminCode', 'id' => 0]);
  305. $this->scopeResolver->expects($this->any())
  306. ->method('getScope')
  307. ->will(
  308. $this->returnValueMap(
  309. [
  310. [null, $scope],
  311. ['admin', $scopeAdmin],
  312. ]
  313. )
  314. );
  315. $designTheme = $this->getMockBuilder(\Magento\Theme\Model\Theme::class)
  316. ->disableOriginalConstructor()
  317. ->getMock();
  318. $designTheme->expects($this->once())
  319. ->method('getThemePath')
  320. ->willReturn($themeId);
  321. $this->viewDesign->expects($this->any())->method('getDesignTheme')->will($this->returnValue($designTheme));
  322. }
  323. }