ConfigFixture.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Implementation of the @magentoConfigFixture DocBlock annotation
  8. */
  9. namespace Magento\TestFramework\Annotation;
  10. use Magento\Framework\App\Config\ScopeConfigInterface;
  11. /**
  12. * Handler which works with magentoConfigFixture annotations
  13. *
  14. * @package Magento\TestFramework\Annotation
  15. */
  16. class ConfigFixture
  17. {
  18. /**
  19. * Test instance that is available between 'startTest' and 'stopTest' events
  20. *
  21. * @var \PHPUnit\Framework\TestCase
  22. */
  23. protected $_currentTest;
  24. /**
  25. * Original values for global configuration options that need to be restored
  26. *
  27. * @var array
  28. */
  29. private $_globalConfigValues = [];
  30. /**
  31. * Original values for store-scoped configuration options that need to be restored
  32. *
  33. * @var array
  34. */
  35. private $_storeConfigValues = [];
  36. /**
  37. * Retrieve configuration node value
  38. *
  39. * @param string $configPath
  40. * @param string|bool|null $scopeCode
  41. * @return string
  42. */
  43. protected function _getConfigValue($configPath, $scopeCode = null)
  44. {
  45. $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  46. $result = null;
  47. if ($scopeCode !== false) {
  48. /** @var \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig */
  49. $scopeConfig = $objectManager->get(\Magento\Framework\App\Config\ScopeConfigInterface::class);
  50. $result = $scopeConfig->getValue(
  51. $configPath,
  52. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  53. $scopeCode
  54. );
  55. }
  56. return $result;
  57. }
  58. /**
  59. * Assign configuration node value
  60. *
  61. * @param string $configPath
  62. * @param string $value
  63. * @param string|bool|null $storeCode
  64. */
  65. protected function _setConfigValue($configPath, $value, $storeCode = false)
  66. {
  67. $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  68. if ($storeCode === false) {
  69. if (strpos($configPath, 'default/') === 0) {
  70. $configPath = substr($configPath, 8);
  71. $objectManager->get(
  72. \Magento\Framework\App\Config\MutableScopeConfigInterface::class
  73. )->setValue(
  74. $configPath,
  75. $value,
  76. ScopeConfigInterface::SCOPE_TYPE_DEFAULT
  77. );
  78. }
  79. } else {
  80. \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
  81. \Magento\Framework\App\Config\MutableScopeConfigInterface::class
  82. )->setValue(
  83. $configPath,
  84. $value,
  85. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  86. $storeCode
  87. );
  88. }
  89. }
  90. /**
  91. * Assign required config values and save original ones
  92. *
  93. * @param \PHPUnit\Framework\TestCase $test
  94. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  95. */
  96. protected function _assignConfigData(\PHPUnit\Framework\TestCase $test)
  97. {
  98. $annotations = $test->getAnnotations();
  99. if (!isset($annotations['method']['magentoConfigFixture'])) {
  100. return;
  101. }
  102. foreach ($annotations['method']['magentoConfigFixture'] as $configPathAndValue) {
  103. if (preg_match('/^.+?(?=_store\s)/', $configPathAndValue, $matches)) {
  104. /* Store-scoped config value */
  105. $storeCode = $matches[0] != 'current' ? $matches[0] : null;
  106. $parts = preg_split('/\s+/', $configPathAndValue, 3);
  107. list($configScope, $configPath, $requiredValue) = $parts + ['', '', ''];
  108. $originalValue = $this->_getConfigValue($configPath, $storeCode);
  109. $this->_storeConfigValues[$storeCode][$configPath] = $originalValue;
  110. $this->_setConfigValue($configPath, $requiredValue, $storeCode);
  111. } else {
  112. /* Global config value */
  113. list($configPath, $requiredValue) = preg_split('/\s+/', $configPathAndValue, 2);
  114. $originalValue = $this->_getConfigValue($configPath);
  115. $this->_globalConfigValues[$configPath] = $originalValue;
  116. $this->_setConfigValue($configPath, $requiredValue);
  117. }
  118. }
  119. }
  120. /**
  121. * Restore original values for changed config options
  122. */
  123. protected function _restoreConfigData()
  124. {
  125. /* Restore global values */
  126. foreach ($this->_globalConfigValues as $configPath => $originalValue) {
  127. $this->_setConfigValue($configPath, $originalValue);
  128. }
  129. $this->_globalConfigValues = [];
  130. /* Restore store-scoped values */
  131. foreach ($this->_storeConfigValues as $storeCode => $originalData) {
  132. foreach ($originalData as $configPath => $originalValue) {
  133. if (empty($storeCode)) {
  134. $storeCode = null;
  135. }
  136. $this->_setConfigValue($configPath, $originalValue, $storeCode);
  137. }
  138. }
  139. $this->_storeConfigValues = [];
  140. }
  141. /**
  142. * Handler for 'startTest' event
  143. *
  144. * @param \PHPUnit\Framework\TestCase $test
  145. */
  146. public function startTest(\PHPUnit\Framework\TestCase $test)
  147. {
  148. $this->_currentTest = $test;
  149. $this->_assignConfigData($test);
  150. }
  151. /**
  152. * Handler for 'endTest' event
  153. *
  154. * @param \PHPUnit\Framework\TestCase $test
  155. *
  156. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  157. */
  158. public function endTest(\PHPUnit\Framework\TestCase $test)
  159. {
  160. $this->_currentTest = null;
  161. $this->_restoreConfigData();
  162. }
  163. /**
  164. * Reassign configuration data whenever application is reset
  165. */
  166. public function initStoreAfter()
  167. {
  168. /* process events triggered from within a test only */
  169. if ($this->_currentTest) {
  170. $this->_assignConfigData($this->_currentTest);
  171. }
  172. }
  173. }