This commit is contained in:
2026-09-15 10:26:34 +08:00
commit ecf36afa56
10493 changed files with 1404888 additions and 0 deletions
@@ -0,0 +1,221 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\TestFramework\Annotation;
use Magento\Config\Model\ResourceModel\Config as ConfigResource;
use Magento\Framework\App\Config\MutableScopeConfigInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\TestFramework\App\ApiMutableScopeConfig;
use Magento\TestFramework\Config\Model\ConfigStorage;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
/**
* @inheritDoc
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
class ApiConfigFixture extends ConfigFixture
{
/**
* Values need to be deleted form the database
*
* @var array
*/
private $valuesToDeleteFromDatabase = [];
/**
* Put Poison Pill
*
* @return void
* @throws \Exception
*/
private function putPill(): void
{
Bootstrap::getObjectManager()
->get(\Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface::class)
->put();
}
/**
* @inheritdoc
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
protected function setStoreConfigValue(array $matches, $configPathAndValue): void
{
$storeCode = $matches[0];
$parts = preg_split('/\s+/', $configPathAndValue, 3);
[$configScope, $configPath, $requiredValue] = $parts + ['', '', ''];
/** @var ConfigStorage $configStorage */
$configStorage = Bootstrap::getObjectManager()->get(ConfigStorage::class);
if (!$configStorage->checkIsRecordExist($configPath, ScopeInterface::SCOPE_STORES, $storeCode)) {
$this->valuesToDeleteFromDatabase[$storeCode][$configPath ?? ''] = $requiredValue ?? '';
}
parent::setStoreConfigValue($matches, $configPathAndValue);
}
/**
* @inheritDoc
*/
protected function _assignConfigData(TestCase $test)
{
parent::_assignConfigData($test);
$needUpdates = !empty($this->globalConfigValues)
|| !empty($this->storeConfigValues)
|| !empty($this->websiteConfigValues);
if ($needUpdates) {
$this->putPill();
}
}
/**
* @inheritdoc
*/
protected function setGlobalConfigValue($configPathAndValue): void
{
[$configPath, $requiredValue] = preg_split('/\s+/', $configPathAndValue, 2);
$configPath = str_starts_with($configPath, 'default/') ? substr($configPath, 8) : $configPath;
/** @var ConfigStorage $configStorage */
$configStorage = Bootstrap::getObjectManager()->get(ConfigStorage::class);
if (!$configStorage->checkIsRecordExist($configPath)) {
$this->valuesToDeleteFromDatabase['global'][$configPath] = $requiredValue;
}
$originalValue = $this->getScopeConfigValue($configPath, ScopeConfigInterface::SCOPE_TYPE_DEFAULT);
$this->globalConfigValues[$configPath] = $originalValue;
$this->_setConfigValue($configPath, $requiredValue);
}
/**
* @inheritdoc
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
protected function setWebsiteConfigValue(array $matches, $configPathAndValue): void
{
$websiteCode = $matches[0];
$parts = preg_split('/\s+/', $configPathAndValue, 3);
[$configScope, $configPath, $requiredValue] = $parts + ['', '', ''];
/** @var ConfigStorage $configStorage */
$configStorage = Bootstrap::getObjectManager()->get(ConfigStorage::class);
if (!$configStorage->checkIsRecordExist($configPath, ScopeInterface::SCOPE_WEBSITES, $websiteCode)) {
$this->valuesToDeleteFromDatabase[$websiteCode][$configPath ?? ''] = $requiredValue ?? '';
}
parent::setWebsiteConfigValue($matches, $configPathAndValue);
}
/**
* @inheritDoc
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
protected function _restoreConfigData()
{
$needUpdates = !empty($this->globalConfigValues)
|| !empty($this->storeConfigValues)
|| !empty($this->websiteConfigValues);
/** @var ConfigResource $configResource */
$configResource = Bootstrap::getObjectManager()->get(ConfigResource::class);
/* Restore global values */
foreach ($this->globalConfigValues as $configPath => $originalValue) {
if (isset($this->valuesToDeleteFromDatabase['global'][$configPath])) {
$configResource->deleteConfig($configPath);
} else {
$this->_setConfigValue($configPath, $originalValue);
}
}
$this->globalConfigValues = [];
/* Restore store-scoped values */
foreach ($this->storeConfigValues as $storeCode => $originalData) {
foreach ($originalData as $configPath => $originalValue) {
$storeCode = $storeCode ?: null;
if (isset($this->valuesToDeleteFromDatabase[$storeCode][$configPath])) {
$scopeId = $this->getIdByScopeType(ScopeInterface::SCOPE_STORES, $storeCode);
$configResource->deleteConfig($configPath, ScopeInterface::SCOPE_STORES, $scopeId);
} else {
$this->setScopeConfigValue(
$configPath,
(string)$originalValue,
ScopeInterface::SCOPE_STORES,
$storeCode
);
}
}
}
$this->storeConfigValues = [];
/* Restore website-scoped values */
foreach ($this->websiteConfigValues as $websiteCode => $originalData) {
foreach ($originalData as $configPath => $originalValue) {
$websiteCode = $websiteCode ?: null;
if (isset($this->valuesToDeleteFromDatabase[$websiteCode][$configPath])) {
$scopeId = $this->getIdByScopeType(ScopeInterface::SCOPE_WEBSITES, $websiteCode);
$configResource->deleteConfig($configPath, ScopeInterface::SCOPE_WEBSITES, $scopeId);
} else {
$this->setScopeConfigValue(
$configPath,
$originalValue,
ScopeInterface::SCOPE_WEBSITES,
$websiteCode
);
}
}
}
$this->websiteConfigValues = [];
if ($needUpdates) {
$this->putPill();
}
}
/**
* @inheritdoc
*/
protected function getMutableScopeConfig(): MutableScopeConfigInterface
{
return Bootstrap::getObjectManager()
->get(ApiMutableScopeConfig::class);
}
/**
* @inheritdoc
*/
protected function getScopeConfigValue(string $configPath, string $scopeType, string $scopeCode = null): ?string
{
/** @var ConfigStorage $configStorage */
$configStorage = Bootstrap::getObjectManager()->get(ConfigStorage::class);
$result = $configStorage->getValueFromDb($configPath, $scopeType, $scopeCode);
return $result ?: null;
}
/**
* Get id by code
*
* @param string $scopeType
* @param string|null $scopeId
* @return int
*/
private function getIdByScopeType(string $scopeType, ?string $scopeId): int
{
$id = 0;
/** @var StoreManagerInterface $storeManager */
$storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
switch ($scopeType) {
case ScopeInterface::SCOPE_WEBSITES:
$id = (int)$storeManager->getWebsite($scopeId)->getId();
break;
case ScopeInterface::SCOPE_STORES:
$id = (int)$storeManager->getStore($scopeId)->getId();
break;
default:
break;
}
return $id;
}
}
@@ -0,0 +1,96 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\TestFramework\Annotation;
use Magento\Customer\Model\Metadata\AttributeMetadataCache;
use Magento\TestFramework\Event\Param\Transaction;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
/**
* Implementation of the @magentoApiDataFixture DocBlock annotation.
*/
class ApiDataFixture extends DataFixture
{
public const ANNOTATION = 'magentoApiDataFixture';
/**
* Handler for 'startTest' event
*
* @param TestCase $test
*/
public function startTest(TestCase $test)
{
Bootstrap::getInstance()->reinitialize();
$this->_applyFixtures($this->_getFixtures($test), $test);
}
/**
* Handler for 'endTest' event
*
* @param TestCase $test
*/
public function endTest(TestCase $test)
{
$this->_revertFixtures($test);
$objectManager = Bootstrap::getObjectManager();
$objectManager->get(AttributeMetadataCache::class)->clean();
}
/**
* @inheritdoc
*/
protected function getAnnotation(): string
{
return self::ANNOTATION;
}
/**
* @inheritdoc
*/
protected function getDbIsolationState(TestCase $test)
{
return parent::getDbIsolationState($test) ?: ['disabled'];
}
/**
* @inheritdoc
*/
public function startTestTransactionRequest(TestCase $test, Transaction $param): void
{
Bootstrap::getInstance()->reinitialize();
parent::startTestTransactionRequest($test, $param);
}
/**
* @inheritdoc
*/
public function endTestTransactionRequest(TestCase $test, Transaction $param): void
{
parent::endTestTransactionRequest($test, $param);
$objectManager = Bootstrap::getObjectManager();
$objectManager->get(AttributeMetadataCache::class)->clean();
}
/**
* @inheritdoc
*/
protected function getParsers(): array
{
$parsers = [];
// Add magentoDataFixture annotations
$parsers[] = Bootstrap::getObjectManager()->create(
\Magento\TestFramework\Annotation\Parser\DataFixture::class,
['annotation' => DataFixture::ANNOTATION]
);
return array_merge(
parent::getParsers(),
$parsers
);
}
}