DesignTest.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Theme\Model;
  7. use Magento\Backend\Block\Widget\Grid\Serializer;
  8. use Magento\Framework\Serialize\SerializerInterface;
  9. class DesignTest extends \PHPUnit\Framework\TestCase
  10. {
  11. /**
  12. * @var \Magento\Theme\Model\Design
  13. */
  14. protected $_model;
  15. protected function setUp()
  16. {
  17. $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  18. \Magento\Theme\Model\Design::class
  19. );
  20. }
  21. public function testLoadChange()
  22. {
  23. $this->_model->loadChange(1);
  24. $this->assertNull($this->_model->getId());
  25. }
  26. /**
  27. * @magentoDataFixture Magento/Theme/_files/design_change.php
  28. */
  29. public function testChangeDesign()
  30. {
  31. \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class)
  32. ->setAreaCode('frontend');
  33. $design = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  34. \Magento\Framework\View\DesignInterface::class
  35. );
  36. $storeId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  37. \Magento\Store\Model\StoreManagerInterface::class
  38. )->getDefaultStoreView()->getId();
  39. // fixture design_change
  40. $designChange = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  41. \Magento\Theme\Model\Design::class
  42. );
  43. $designChange->loadChange($storeId)->changeDesign($design);
  44. $this->assertEquals('Magento/luma', $design->getDesignTheme()->getThemePath());
  45. }
  46. public function testCRUD()
  47. {
  48. $this->_model->setData(
  49. [
  50. 'store_id' => 1,
  51. 'design' => 'Magento/blank',
  52. 'date_from' => date('Y-m-d', strtotime('-1 day')),
  53. 'date_to' => date('Y-m-d', strtotime('+1 day')),
  54. ]
  55. );
  56. $this->_model->save();
  57. $this->assertNotEmpty($this->_model->getId());
  58. try {
  59. $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  60. \Magento\Theme\Model\Design::class
  61. );
  62. $model->loadChange(1);
  63. $this->assertEquals($this->_model->getId(), $model->getId());
  64. /* Design change that intersects with existing ones should not be saved, so exception is expected */
  65. try {
  66. $model->setId(null);
  67. $model->save();
  68. $this->fail('A validation failure is expected.');
  69. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  70. }
  71. $this->_model->delete();
  72. } catch (\Exception $e) {
  73. $this->_model->delete();
  74. throw $e;
  75. }
  76. $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  77. \Magento\Theme\Model\Design::class
  78. );
  79. $model->loadChange(1);
  80. $this->assertEmpty($model->getId());
  81. }
  82. public function testCollection()
  83. {
  84. $collection = $this->_model->getCollection()->joinStore()->addDateFilter();
  85. /**
  86. * @todo fix and add addStoreFilter method
  87. */
  88. $this->assertEmpty($collection->getItems());
  89. }
  90. /**
  91. * @magentoDataFixture Magento/Theme/_files/design_change.php
  92. * @magentoConfigFixture current_store general/locale/timezone UTC
  93. */
  94. public function testLoadChangeCache()
  95. {
  96. $date = (new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
  97. $storeId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  98. \Magento\Store\Model\StoreManagerInterface::class
  99. )->getDefaultStoreView()->getId();
  100. // fixture design_change
  101. $cacheId = 'design_change_' . md5($storeId . $date);
  102. /** @var \Magento\Theme\Model\Design $design */
  103. $design = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  104. \Magento\Theme\Model\Design::class
  105. );
  106. $design->loadChange($storeId, $date);
  107. $cachedDesign = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  108. \Magento\Framework\App\CacheInterface::class
  109. )->load(
  110. $cacheId
  111. );
  112. $serializer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(SerializerInterface::class);
  113. $cachedDesign = $serializer->unserialize($cachedDesign);
  114. $this->assertInternalType('array', $cachedDesign);
  115. $this->assertArrayHasKey('design', $cachedDesign);
  116. $this->assertEquals($cachedDesign['design'], $design->getDesign());
  117. $design->setDesign('Magento/blank')->save();
  118. $design = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  119. \Magento\Theme\Model\Design::class
  120. );
  121. $design->loadChange($storeId, $date);
  122. $cachedDesign = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  123. \Magento\Framework\App\CacheInterface::class
  124. )->load(
  125. $cacheId
  126. );
  127. $cachedDesign = $serializer->unserialize($cachedDesign);
  128. $this->assertTrue(is_array($cachedDesign));
  129. $this->assertEquals($cachedDesign['design'], $design->getDesign());
  130. }
  131. /**
  132. * @magentoAppIsolation enabled
  133. * @magentoDataFixture Magento/Theme/_files/design_change_timezone.php
  134. * @dataProvider loadChangeTimezoneDataProvider
  135. */
  136. public function testLoadChangeTimezone($storeCode, $storeTimezone, $storeUtcOffset)
  137. {
  138. if (date_default_timezone_get() != 'UTC') {
  139. $this->markTestSkipped('Test requires UTC to be the default timezone.');
  140. }
  141. $utcDatetime = time();
  142. $utcDate = date('Y-m-d', $utcDatetime);
  143. $storeDatetime = strtotime($storeUtcOffset, $utcDatetime);
  144. $storeDate = date('Y-m-d', $storeDatetime);
  145. if ($storeDate == $utcDate) {
  146. $expectedDesign = "{$storeCode}_today_design";
  147. } else {
  148. if ($storeDatetime > $utcDatetime) {
  149. $expectedDesign = "{$storeCode}_tomorrow_design";
  150. } else {
  151. $expectedDesign = "{$storeCode}_yesterday_design";
  152. }
  153. }
  154. $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  155. \Magento\Store\Model\StoreManagerInterface::class
  156. )->getStore(
  157. $storeCode
  158. );
  159. $defaultTimeZonePath = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  160. \Magento\Framework\Stdlib\DateTime\TimezoneInterface::class
  161. )->getDefaultTimezonePath();
  162. $store->setConfig($defaultTimeZonePath, $storeTimezone);
  163. $storeId = $store->getId();
  164. /** @var $locale \Magento\Framework\Stdlib\DateTime\TimezoneInterface */
  165. $locale = $this->createMock(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class);
  166. $locale->expects(
  167. $this->once()
  168. )->method(
  169. 'scopeTimeStamp'
  170. )->with(
  171. $storeId
  172. )->will(
  173. $this->returnValue($storeDatetime)
  174. );
  175. // store time must stay unchanged during test execution
  176. $design = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  177. \Magento\Theme\Model\Design::class,
  178. ['localeDate' => $locale]
  179. );
  180. $design->loadChange($storeId);
  181. $actualDesign = $design->getDesign();
  182. $this->assertEquals($expectedDesign, $actualDesign);
  183. }
  184. public function loadChangeTimezoneDataProvider()
  185. {
  186. /**
  187. * Depending on the current UTC time, either UTC-12:00, or UTC+12:00 timezone points to the different date.
  188. * If UTC time is between 00:00 and 12:00, UTC+12:00 points to the same day, and UTC-12:00 to the previous day.
  189. * If UTC time is between 12:00 and 24:00, UTC-12:00 points to the same day, and UTC+12:00 to the next day.
  190. * Testing the design change with both UTC-12:00 and UTC+12:00 store timezones guarantees
  191. * that the proper design change is chosen for the timezone with the date different from the UTC.
  192. */
  193. return [
  194. 'default store - UTC+12:00' => ['default', 'Etc/GMT-12', '+12 hours'],
  195. 'default store - UTC-12:00' => ['default', 'Etc/GMT+12', '-12 hours'],
  196. 'admin store - UTC+12:00' => ['admin', 'Etc/GMT-12', '+12 hours'],
  197. 'admin store - UTC-12:00' => ['admin', 'Etc/GMT+12', '-12 hours']
  198. ];
  199. }
  200. }