TemplateTest.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Email\Model;
  7. use Magento\Backend\App\Area\FrontNameResolver as BackendFrontNameResolver;
  8. use Magento\Framework\App\Area;
  9. use Magento\Framework\App\Filesystem\DirectoryList;
  10. use Magento\Framework\App\TemplateTypesInterface;
  11. use Magento\Framework\View\DesignInterface;
  12. use Magento\Store\Model\ScopeInterface;
  13. use Magento\Store\Model\Store;
  14. use Magento\TestFramework\Helper\Bootstrap;
  15. /**
  16. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  17. */
  18. class TemplateTest extends \PHPUnit\Framework\TestCase
  19. {
  20. /**
  21. * @var Template|\PHPUnit_Framework_MockObject_MockObject
  22. */
  23. protected $model;
  24. /**
  25. * @var \Zend_Mail|\PHPUnit_Framework_MockObject_MockObject
  26. */
  27. protected $mail;
  28. /**
  29. * @var \Magento\Framework\ObjectManagerInterface
  30. */
  31. protected $objectManager;
  32. protected function setUp()
  33. {
  34. $this->objectManager = Bootstrap::getObjectManager();
  35. }
  36. protected function mockModel($filesystem = null)
  37. {
  38. if (!$filesystem) {
  39. $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
  40. }
  41. $this->mail = $this->getMockBuilder(\Zend_Mail::class)
  42. ->setMethods(['send', 'addTo', 'addBcc', 'setReturnPath', 'setReplyTo'])
  43. ->setConstructorArgs(['utf-8'])
  44. ->getMock();
  45. $this->model = $this->getMockBuilder(\Magento\Email\Model\Template::class)
  46. ->setMethods(['_getMail'])
  47. ->setConstructorArgs([
  48. $this->objectManager->get(\Magento\Framework\Model\Context::class),
  49. $this->objectManager->get(\Magento\Framework\View\DesignInterface::class),
  50. $this->objectManager->get(\Magento\Framework\Registry::class),
  51. $this->objectManager->get(\Magento\Store\Model\App\Emulation::class),
  52. $this->objectManager->get(\Magento\Store\Model\StoreManager::class),
  53. $this->objectManager->create(\Magento\Framework\View\Asset\Repository::class),
  54. $filesystem,
  55. $this->objectManager->create(\Magento\Framework\App\Config\ScopeConfigInterface::class),
  56. $this->objectManager->get(\Magento\Email\Model\Template\Config::class),
  57. $this->objectManager->get(\Magento\Email\Model\TemplateFactory::class),
  58. $this->objectManager->get(\Magento\Framework\Filter\FilterManager::class),
  59. $this->objectManager->get(\Magento\Framework\UrlInterface::class),
  60. $this->objectManager->get(\Magento\Email\Model\Template\FilterFactory::class),
  61. ])
  62. ->getMock();
  63. $this->objectManager->get(\Magento\Framework\App\State::class)->setAreaCode('frontend');
  64. $this->model->expects($this->any())->method('_getMail')->will($this->returnCallback([$this, 'getMail']));
  65. $this->model->setSenderName('sender')->setSenderEmail('sender@example.com')->setTemplateSubject('Subject');
  66. }
  67. /**
  68. * Return a disposable \Zend_Mail instance
  69. *
  70. * @return \PHPUnit_Framework_MockObject_MockObject|\Zend_Mail
  71. */
  72. public function getMail()
  73. {
  74. return clone $this->mail;
  75. }
  76. public function testSetGetTemplateFilter()
  77. {
  78. $this->mockModel();
  79. $filter = $this->model->getTemplateFilter();
  80. $this->assertSame($filter, $this->model->getTemplateFilter());
  81. $this->assertEquals(
  82. $this->objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->getStore()->getId(),
  83. $filter->getStoreId()
  84. );
  85. $filter = $this->objectManager->create(\Magento\Email\Model\Template\Filter::class);
  86. $this->model->setTemplateFilter($filter);
  87. $this->assertSame($filter, $this->model->getTemplateFilter());
  88. }
  89. public function testLoadDefault()
  90. {
  91. $this->mockModel();
  92. $this->model->loadDefault('customer_create_account_email_template');
  93. $this->assertNotEmpty($this->model->getTemplateText());
  94. $this->assertNotEmpty($this->model->getTemplateSubject());
  95. $this->assertNotEmpty($this->model->getOrigTemplateVariables());
  96. $this->assertInternalType('array', json_decode($this->model->getOrigTemplateVariables(), true));
  97. }
  98. /**
  99. * @magentoAppIsolation enabled
  100. * @magentoDataFixture Magento/Store/_files/core_fixturestore.php
  101. */
  102. public function testGetProcessedTemplate()
  103. {
  104. $this->mockModel();
  105. $this->objectManager->get(\Magento\Framework\App\AreaList::class)
  106. ->getArea(Area::AREA_FRONTEND)
  107. ->load();
  108. $expectedViewUrl = '/frontend/Magento/blank/en_US/Magento_Theme/favicon.ico';
  109. $this->model->setDesignConfig([
  110. 'area' => 'frontend',
  111. 'store' => $this->objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)
  112. ->getStore('fixturestore')
  113. ->getId(),
  114. ]);
  115. $this->model->setTemplateText('{{view url="Magento_Theme::favicon.ico"}}');
  116. $this->setNotDefaultThemeForFixtureStore();
  117. $this->assertStringEndsNotWith($expectedViewUrl, $this->model->getProcessedTemplate());
  118. $this->setDefaultThemeForFixtureStore();
  119. $this->assertStringEndsWith($expectedViewUrl, $this->model->getProcessedTemplate());
  120. }
  121. /**
  122. * Test template directive to ensure that templates can be loaded from modules
  123. *
  124. * @param string $area
  125. * @param string $templateId
  126. * @param string $expectedOutput
  127. * @param bool $mockThemeFallback
  128. *
  129. * @magentoDataFixture Magento/Store/_files/core_fixturestore.php
  130. * @magentoComponentsDir Magento/Email/Model/_files/design
  131. * @magentoAppIsolation enabled
  132. * @magentoDbIsolation enabled
  133. * @dataProvider templateFallbackDataProvider
  134. */
  135. public function testTemplateFallback($area, $templateId, $expectedOutput, $mockThemeFallback = false)
  136. {
  137. $this->mockModel();
  138. if ($mockThemeFallback == BackendFrontNameResolver::AREA_CODE) {
  139. $this->setUpAdminThemeFallback();
  140. } elseif ($mockThemeFallback == Area::AREA_FRONTEND) {
  141. $this->setUpThemeFallback($area);
  142. }
  143. $this->model->setId($templateId);
  144. $this->assertContains($expectedOutput, $this->model->processTemplate());
  145. }
  146. /**
  147. * @return array
  148. */
  149. public function templateFallbackDataProvider()
  150. {
  151. return [
  152. 'Template from module - admin' => [
  153. BackendFrontNameResolver::AREA_CODE,
  154. 'customer_create_account_email_template',
  155. 'To sign in to our site, use these credentials during checkout',
  156. ],
  157. 'Template from module - frontend' => [
  158. Area::AREA_FRONTEND,
  159. 'customer_create_account_email_template',
  160. 'To sign in to our site, use these credentials during checkout',
  161. ],
  162. 'Template from theme - frontend' => [
  163. Area::AREA_FRONTEND,
  164. 'customer_create_account_email_template',
  165. 'customer_create_account_email_template template from Vendor/custom_theme',
  166. Area::AREA_FRONTEND,
  167. ],
  168. 'Template from parent theme - frontend' => [
  169. Area::AREA_FRONTEND,
  170. 'customer_create_account_email_confirmation_template',
  171. 'customer_create_account_email_confirmation_template template from Vendor/default',
  172. Area::AREA_FRONTEND,
  173. ],
  174. 'Template from grandparent theme - frontend' => [
  175. Area::AREA_FRONTEND,
  176. 'customer_create_account_email_confirmed_template',
  177. 'customer_create_account_email_confirmed_template template from Magento/default',
  178. Area::AREA_FRONTEND,
  179. ],
  180. 'Template from grandparent theme - adminhtml' => [
  181. BackendFrontNameResolver::AREA_CODE,
  182. 'catalog_productalert_cron_error_email_template',
  183. 'catalog_productalert_cron_error_email_template template from Magento/default',
  184. BackendFrontNameResolver::AREA_CODE,
  185. ],
  186. ];
  187. }
  188. /**
  189. * Test template directive to ensure that templates can be loaded from modules, overridden in backend, and
  190. * overridden in themes
  191. *
  192. * @magentoDataFixture Magento/Store/_files/core_fixturestore.php
  193. * @magentoComponentsDir Magento/Email/Model/_files/design
  194. * @magentoAppIsolation enabled
  195. * @magentoDbIsolation enabled
  196. * @dataProvider templateDirectiveDataProvider
  197. *
  198. * @param string $area
  199. * @param int $templateType
  200. * @param string $templateText
  201. * @param string $assertContains
  202. * @param string $assertNotContains
  203. * @param string $storeConfigPath
  204. * @param bool $mockAdminTheme
  205. */
  206. public function testTemplateDirective(
  207. $area,
  208. $templateType,
  209. $templateText,
  210. $assertContains,
  211. $assertNotContains = null,
  212. $storeConfigPath = null,
  213. $mockAdminTheme = false
  214. ) {
  215. $this->mockModel();
  216. if ($mockAdminTheme) {
  217. $this->setUpAdminThemeFallback();
  218. } else {
  219. $this->setUpThemeFallback($area);
  220. }
  221. $this->model->setTemplateType($templateType);
  222. $this->model->setTemplateText($templateText);
  223. // Allows for testing of templates overridden in backend
  224. if ($storeConfigPath) {
  225. $template = $this->objectManager->create(\Magento\Email\Model\Template::class);
  226. $templateData = [
  227. 'template_code' => 'some_unique_code',
  228. 'template_type' => $templateType,
  229. 'template_text' => $assertContains,
  230. ];
  231. $template->setData($templateData);
  232. $template->save();
  233. // Store the ID of the newly created template in the system config so that this template will be loaded
  234. $this->objectManager->get(\Magento\Framework\App\Config\MutableScopeConfigInterface::class)
  235. ->setValue($storeConfigPath, $template->getId(), ScopeInterface::SCOPE_STORE, 'fixturestore');
  236. }
  237. $this->assertContains($assertContains, $this->model->getProcessedTemplate());
  238. if ($assertNotContains) {
  239. $this->assertNotContains($assertNotContains, $this->model->getProcessedTemplate());
  240. }
  241. }
  242. /**
  243. * @return array
  244. */
  245. public function templateDirectiveDataProvider()
  246. {
  247. return [
  248. 'Template from module folder - adminhtml' => [
  249. BackendFrontNameResolver::AREA_CODE,
  250. TemplateTypesInterface::TYPE_HTML,
  251. '{{template config_path="design/email/footer_template"}}',
  252. "</table>\n<!-- End wrapper table -->",
  253. ],
  254. 'Template from module folder - frontend' => [
  255. Area::AREA_FRONTEND,
  256. TemplateTypesInterface::TYPE_HTML,
  257. '{{template config_path="design/email/footer_template"}}',
  258. "</table>\n<!-- End wrapper table -->",
  259. ],
  260. 'Template from module folder - plaintext' => [
  261. Area::AREA_FRONTEND,
  262. TemplateTypesInterface::TYPE_TEXT,
  263. '{{template config_path="design/email/footer_template"}}',
  264. 'Thank you',
  265. "</table>\n<!-- End wrapper table -->",
  266. ],
  267. 'Template overridden in backend - adminhtml' => [
  268. BackendFrontNameResolver::AREA_CODE,
  269. TemplateTypesInterface::TYPE_HTML,
  270. '{{template config_path="design/email/footer_template"}}',
  271. '<b>Footer configured in backend - email loaded via adminhtml</b>',
  272. null,
  273. 'design/email/footer_template',
  274. ],
  275. 'Template overridden in backend - frontend' => [
  276. Area::AREA_FRONTEND,
  277. TemplateTypesInterface::TYPE_HTML,
  278. '{{template config_path="design/email/footer_template"}}',
  279. '<b>Footer configured in backend - email loaded via frontend</b>',
  280. null,
  281. 'design/email/footer_template',
  282. ],
  283. 'Template from theme - frontend' => [
  284. Area::AREA_FRONTEND,
  285. TemplateTypesInterface::TYPE_HTML,
  286. '{{template config_path="customer/create_account/email_template"}}',
  287. '<strong>customer_create_account_email_template template from Vendor/custom_theme</strong>',
  288. ],
  289. 'Template from parent theme - frontend' => [
  290. Area::AREA_FRONTEND,
  291. TemplateTypesInterface::TYPE_HTML,
  292. '{{template config_path="customer/create_account/email_confirmation_template"}}',
  293. '<strong>customer_create_account_email_confirmation_template template from Vendor/default</strong',
  294. ],
  295. 'Template from grandparent theme - frontend' => [
  296. Area::AREA_FRONTEND,
  297. TemplateTypesInterface::TYPE_HTML,
  298. '{{template config_path="customer/create_account/email_confirmed_template"}}',
  299. '<strong>customer_create_account_email_confirmed_template template from Magento/default</strong',
  300. ],
  301. 'Template from grandparent theme - adminhtml' => [
  302. BackendFrontNameResolver::AREA_CODE,
  303. TemplateTypesInterface::TYPE_HTML,
  304. '{{template config_path="catalog/productalert_cron/error_email_template"}}',
  305. '<strong>catalog_productalert_cron_error_email_template template from Magento/default</strong',
  306. null,
  307. null,
  308. true,
  309. ],
  310. ];
  311. }
  312. /**
  313. * Ensure that the template_styles variable contains styles from either <!--@styles @--> or the "Template Styles"
  314. * textarea in backend, depending on whether template was loaded from filesystem or DB.
  315. *
  316. * @magentoDataFixture Magento/Store/_files/core_fixturestore.php
  317. * @magentoComponentsDir Magento/Email/Model/_files/design
  318. * @magentoAppIsolation enabled
  319. * @magentoDbIsolation enabled
  320. * @dataProvider templateStylesVariableDataProvider
  321. *
  322. * @param string $area
  323. * @param string $expectedOutput
  324. * @param array $unexpectedOutputs
  325. * @param array $templateForDatabase
  326. */
  327. public function testTemplateStylesVariable($area, $expectedOutput, $unexpectedOutputs, $templateForDatabase = [])
  328. {
  329. if (count($templateForDatabase)) {
  330. $this->mockModel();
  331. $this->setUpThemeFallback($area);
  332. $template = $this->objectManager->create(\Magento\Email\Model\Template::class);
  333. $template->setData($templateForDatabase);
  334. $template->save();
  335. $templateId = $template->getId();
  336. $this->model->load($templateId);
  337. } else {
  338. // <!--@styles @--> parsing only via the loadDefault method. Since email template files won't contain
  339. // @styles comments by default, it is necessary to mock an object to return testable contents
  340. $themeDirectory = $this->getMockBuilder(\Magento\Framework\Filesystem\Directory\ReadInterface::class)
  341. ->disableOriginalConstructor()
  342. ->setMethods([
  343. 'readFile',
  344. ])
  345. ->getMockForAbstractClass();
  346. $themeDirectory->expects($this->once())
  347. ->method('readFile')
  348. ->will($this->returnValue('<!--@styles p { color: #111; } @--> {{var template_styles}}'));
  349. $filesystem = $this->getMockBuilder(\Magento\Framework\Filesystem::class)
  350. ->disableOriginalConstructor()
  351. ->setMethods(['getDirectoryRead'])
  352. ->getMock();
  353. $filesystem->expects($this->once())
  354. ->method('getDirectoryRead')
  355. ->with(DirectoryList::ROOT)
  356. ->will($this->returnValue($themeDirectory));
  357. $this->mockModel($filesystem);
  358. $this->model->loadDefault('design_email_header_template');
  359. }
  360. $processedTemplate = $this->model->getProcessedTemplate();
  361. foreach ($unexpectedOutputs as $unexpectedOutput) {
  362. $this->assertNotContains($unexpectedOutput, $processedTemplate);
  363. }
  364. $this->assertContains($expectedOutput, $processedTemplate);
  365. }
  366. /**
  367. * @return array
  368. */
  369. public function templateStylesVariableDataProvider()
  370. {
  371. return [
  372. 'Styles from <!--@styles @--> comment - adminhtml' => [
  373. BackendFrontNameResolver::AREA_CODE,
  374. 'p { color: #111; }',
  375. [
  376. '<!--@styles',
  377. '{{var template_styles}}',
  378. ],
  379. ],
  380. 'Styles from <!--@styles @--> comment - frontend' => [
  381. Area::AREA_FRONTEND,
  382. 'p { color: #111; }',
  383. [
  384. '<!--@styles',
  385. '{{var template_styles}}',
  386. ],
  387. ],
  388. 'Styles from "Template Styles" textarea from backend - adminhtml' => [
  389. BackendFrontNameResolver::AREA_CODE,
  390. 'p { color: #222; }',
  391. ['{{var template_styles}}'],
  392. [
  393. 'template_code' => 'some_unique_code',
  394. 'template_type' => Template::TYPE_HTML,
  395. 'template_text' => 'Footer from database {{var template_styles}}',
  396. 'template_styles' => 'p { color: #222; }',
  397. ],
  398. ],
  399. 'Styles from "Template Styles" textarea from backend - frontend' => [
  400. Area::AREA_FRONTEND,
  401. 'p { color: #333; }',
  402. ['{{var template_styles}}'],
  403. [
  404. 'template_code' => 'some_unique_code',
  405. 'template_type' => Template::TYPE_HTML,
  406. 'template_text' => 'Footer from database {{var template_styles}}',
  407. 'template_styles' => 'p { color: #333; }',
  408. ],
  409. ],
  410. ];
  411. }
  412. /**
  413. * Setup the theme fallback structure and set the Vendor_EmailTest/custom_theme as the current theme for
  414. * 'fixturestore' store
  415. */
  416. protected function setUpAdminThemeFallback()
  417. {
  418. $themes = [BackendFrontNameResolver::AREA_CODE => 'Vendor_EmailTest/custom_theme'];
  419. $design = $this->objectManager->create(\Magento\Theme\Model\View\Design::class, ['themes' => $themes]);
  420. $this->objectManager->addSharedInstance($design, \Magento\Theme\Model\View\Design::class);
  421. /** @var \Magento\Theme\Model\Theme\Registration $registration */
  422. $registration = $this->objectManager->get(
  423. \Magento\Theme\Model\Theme\Registration::class
  424. );
  425. $registration->register();
  426. // The Vendor_EmailTest/custom_theme adminhtml theme is set in the
  427. // dev/tests/integration/testsuite/Magento/Email/Model/_files/design/themes.php file, as it must be set
  428. // before the adminhtml area is loaded below.
  429. Bootstrap::getInstance()->loadArea(BackendFrontNameResolver::AREA_CODE);
  430. /** @var \Magento\Store\Model\Store $adminStore */
  431. $adminStore = $this->objectManager->create(\Magento\Store\Model\Store::class)
  432. ->load(Store::ADMIN_CODE);
  433. $this->model->setDesignConfig([
  434. 'area' => 'adminhtml',
  435. 'store' => $adminStore->getId(),
  436. ]);
  437. }
  438. /**
  439. * Setup the theme fallback structure and set the Vendor_EmailTest/custom_theme as the current theme
  440. * for 'fixturestore' store
  441. *
  442. * @param $area
  443. */
  444. protected function setUpThemeFallback($area)
  445. {
  446. /** @var \Magento\Theme\Model\Theme\Registration $registration */
  447. $registration = $this->objectManager->get(
  448. \Magento\Theme\Model\Theme\Registration::class
  449. );
  450. $registration->register();
  451. // It is important to test from both areas, as emails will get sent from both, so we need to ensure that the
  452. // inline CSS files get loaded properly from both areas.
  453. Bootstrap::getInstance()->loadArea($area);
  454. $collection = $this->objectManager->create(\Magento\Theme\Model\ResourceModel\Theme\Collection::class);
  455. // Hard-coding theme as we want to test the fallback structure to ensure that the parent/grandparent themes of
  456. // Vendor_EmailTest/custom_theme will be checked for CSS files
  457. $themeId = $collection->getThemeByFullPath('frontend/Vendor_EmailTest/custom_theme')->getId();
  458. $this->objectManager->get(\Magento\Framework\App\Config\MutableScopeConfigInterface::class)
  459. ->setValue(
  460. DesignInterface::XML_PATH_THEME_ID,
  461. $themeId,
  462. ScopeInterface::SCOPE_STORE,
  463. 'fixturestore'
  464. );
  465. $this->model->setDesignConfig([
  466. 'area' => 'frontend',
  467. 'store' => $this->objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)
  468. ->getStore('fixturestore')
  469. ->getId(),
  470. ]);
  471. }
  472. /**
  473. * Set 'Magento/luma' for the 'fixturestore' store.
  474. * Application isolation is required, if a test uses this method.
  475. */
  476. protected function setNotDefaultThemeForFixtureStore()
  477. {
  478. /** @var \Magento\Framework\View\Design\ThemeInterface $theme */
  479. $theme = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  480. \Magento\Framework\View\Design\ThemeInterface::class
  481. );
  482. $theme->load('Magento/luma', 'theme_path');
  483. \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  484. \Magento\Framework\App\Config\MutableScopeConfigInterface::class
  485. )->setValue(
  486. \Magento\Framework\View\DesignInterface::XML_PATH_THEME_ID,
  487. $theme->getId(),
  488. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  489. 'fixturestore'
  490. );
  491. }
  492. /**
  493. * Set 'Magento/blank' for the 'fixturestore' store.
  494. * Application isolation is required, if a test uses this method.
  495. */
  496. protected function setDefaultThemeForFixtureStore()
  497. {
  498. /** @var \Magento\Framework\View\Design\ThemeInterface $theme */
  499. $theme = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  500. \Magento\Framework\View\Design\ThemeInterface::class
  501. );
  502. $theme->load('Magento/blank', 'theme_path');
  503. \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  504. \Magento\Framework\App\Config\MutableScopeConfigInterface::class
  505. )->setValue(
  506. \Magento\Framework\View\DesignInterface::XML_PATH_THEME_ID,
  507. $theme->getId(),
  508. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  509. 'fixturestore'
  510. );
  511. }
  512. /**
  513. * @magentoAppIsolation enabled
  514. * @magentoDataFixture Magento/Store/_files/core_fixturestore.php
  515. */
  516. public function testGetProcessedTemplateSubject()
  517. {
  518. $this->mockModel();
  519. $this->objectManager->get(\Magento\Framework\App\AreaList::class)
  520. ->getArea(Area::AREA_FRONTEND)
  521. ->load();
  522. $this->model->setTemplateSubject('{{view url="Magento_Theme::favicon.ico"}}');
  523. $this->model->setDesignConfig([
  524. 'area' => 'frontend',
  525. 'store' => $this->objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)
  526. ->getStore('fixturestore')
  527. ->getId(),
  528. ]);
  529. $this->setNotDefaultThemeForFixtureStore();
  530. $this->assertStringMatchesFormat(
  531. '%s/frontend/Magento/luma/en_US/Magento_Theme/favicon.ico',
  532. $this->model->getProcessedTemplateSubject([])
  533. );
  534. $this->setDefaultThemeForFixtureStore();
  535. $this->assertStringMatchesFormat(
  536. '%s/frontend/Magento/blank/en_US/Magento_Theme/favicon.ico',
  537. $this->model->getProcessedTemplateSubject([])
  538. );
  539. }
  540. /**
  541. * @magentoAppIsolation enabled
  542. */
  543. public function testGetDefaultEmailLogo()
  544. {
  545. $this->mockModel();
  546. $this->objectManager->get(\Magento\Framework\App\AreaList::class)
  547. ->getArea(Area::AREA_FRONTEND)
  548. ->load();
  549. $this->assertStringEndsWith(
  550. '/frontend/Magento/luma/en_US/Magento_Email/logo_email.png',
  551. $this->model->getDefaultEmailLogo()
  552. );
  553. }
  554. /**
  555. * @param $config
  556. * @dataProvider setDesignConfigExceptionDataProvider
  557. * @expectedException \Magento\Framework\Exception\LocalizedException
  558. */
  559. public function testSetDesignConfigException($config)
  560. {
  561. $this->mockModel();
  562. $model = $this->objectManager->create(\Magento\Email\Model\Template::class);
  563. $model->setDesignConfig($config);
  564. }
  565. public function setDesignConfigExceptionDataProvider()
  566. {
  567. $storeId = Bootstrap::getObjectManager()->get(\Magento\Store\Model\StoreManagerInterface::class)
  568. ->getStore()
  569. ->getId();
  570. return [
  571. [[]],
  572. [['area' => 'frontend']],
  573. [['store' => $storeId]],
  574. ];
  575. }
  576. public function testSetAndGetId()
  577. {
  578. $this->mockModel();
  579. $testId = 9999;
  580. $this->model->setId($testId);
  581. $this->assertEquals($testId, $this->model->getId());
  582. }
  583. public function testIsValidForSend()
  584. {
  585. $this->mockModel();
  586. $this->assertTrue($this->model->isValidForSend());
  587. }
  588. /**
  589. * @expectedException \UnexpectedValueException
  590. * @expectedExceptionMessage Email template 'foo' is not defined.
  591. */
  592. public function testGetTypeNonExistentType()
  593. {
  594. $this->mockModel();
  595. $this->model->setId('foo');
  596. $this->model->getType();
  597. }
  598. public function testGetTypeHtml()
  599. {
  600. $this->mockModel();
  601. $this->model->setId('customer_create_account_email_template');
  602. $this->assertEquals(TemplateTypesInterface::TYPE_HTML, $this->model->getType());
  603. }
  604. public function testGetType()
  605. {
  606. $this->mockModel();
  607. $templateTypeId = 'test_template';
  608. $this->model->setTemplateType($templateTypeId);
  609. $this->assertEquals($templateTypeId, $this->model->getType());
  610. }
  611. public function testGetSendingException()
  612. {
  613. $this->mockModel();
  614. $this->assertNull($this->model->getSendingException());
  615. }
  616. public function testGetVariablesOptionArray()
  617. {
  618. $this->mockModel();
  619. $testTemplateVariables = '{"var data.name":"Sender Name","var data.email":"Sender Email"}';
  620. $this->model->setOrigTemplateVariables($testTemplateVariables);
  621. $variablesOptionArray = $this->model->getVariablesOptionArray();
  622. $this->assertEquals('{{var data.name}}', $variablesOptionArray[0]['value']);
  623. $this->assertEquals('Sender Name', $variablesOptionArray[0]['label']->getArguments()[0]);
  624. $this->assertEquals('{{var data.email}}', $variablesOptionArray[1]['value']);
  625. $this->assertEquals('Sender Email', $variablesOptionArray[1]['label']->getArguments()[0]);
  626. }
  627. public function testGetVariablesOptionArrayInGroup()
  628. {
  629. $this->mockModel();
  630. $testTemplateVariables = '{"var data.name":"Sender Name","var data.email":"Sender Email"}';
  631. $this->model->setOrigTemplateVariables($testTemplateVariables);
  632. $variablesOptionArray = $this->model->getVariablesOptionArray(true);
  633. $this->assertEquals('Template Variables', $variablesOptionArray['label']->getText());
  634. $this->assertEquals($this->model->getVariablesOptionArray(), $variablesOptionArray['value']);
  635. }
  636. /**
  637. * @expectedException \Magento\Framework\Exception\MailException
  638. * @expectedExceptionMessage Please enter a template name.
  639. */
  640. public function testBeforeSaveEmptyTemplateCode()
  641. {
  642. $this->mockModel();
  643. $this->model->beforeSave();
  644. }
  645. public function testBeforeSave()
  646. {
  647. $this->mockModel();
  648. $this->model->setTemplateCode('test template code');
  649. $this->model->beforeSave();
  650. }
  651. public function testProcessTemplate()
  652. {
  653. $this->mockModel();
  654. $this->model->setId('customer_create_account_email_template');
  655. $this->assertContains('<body', $this->model->processTemplate());
  656. }
  657. public function testGetSubject()
  658. {
  659. $this->mockModel();
  660. $this->model->setVars(['foo', 'bar', 'baz']);
  661. $this->assertEquals('Subject', $this->model->getSubject());
  662. }
  663. public function testSetOptions()
  664. {
  665. $this->mockModel();
  666. $options = ['area' => 'test area', 'store' => 1];
  667. $this->model->setOptions($options);
  668. $this->assertEquals($options, $this->model->getDesignConfig()->getData());
  669. }
  670. }