diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php index 09c95df9e..110869187 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php @@ -7,6 +7,7 @@ namespace Magento\FunctionalTestingFramework\DataGenerator\Objects; use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig; +use Magento\FunctionalTestingFramework\DataGenerator\Util\GenerationDataReferenceResolver; use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException; use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil; @@ -160,6 +161,7 @@ public function getAllData() * @param integer $uniquenessFormat * @return string|null * @throws TestFrameworkException + * @SuppressWarnings(PHPMD) */ public function getDataByName($name, $uniquenessFormat) { @@ -181,13 +183,36 @@ public function getDataByName($name, $uniquenessFormat) return null; } + $dataReferenceResolver = new GenerationDataReferenceResolver(); if (array_key_exists($name_lower, $this->data)) { - $uniquenessData = $this->getUniquenessDataByName($name_lower); + if (is_array($this->data[$name_lower])) { + return $this->data[$name_lower]; + } + $uniquenessData = $this->getUniquenessDataByName($name_lower) === null + ? $dataReferenceResolver->getDataUniqueness( + $this->data[$name_lower], + $this->name . '.' . $name + ) + : $this->getUniquenessDataByName($name_lower); + if ($uniquenessData !== null) { + $this->uniquenessData[$name] = $uniquenessData; + } + $this->data[$name_lower] = $dataReferenceResolver->getDataReference( + $this->data[$name_lower], + $this->name . '.' . $name + ); if (null === $uniquenessData || $uniquenessFormat == self::NO_UNIQUE_PROCESS) { return $this->data[$name_lower]; } return $this->formatUniqueData($name_lower, $uniquenessData, $uniquenessFormat); } elseif (array_key_exists($name, $this->data)) { + if (is_array($this->data[$name_lower])) { + return $this->data[$name]; + } + $this->data[$name] = $dataReferenceResolver->getDataReference( + $this->data[$name], + $this->name . '.' . $name + ); // Data returned by the API may be camelCase so we need to check for the original $name also. return $this->data[$name]; } else { diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php index 4e7915b87..6d1ebc3fc 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php @@ -11,6 +11,7 @@ use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject; use Magento\FunctionalTestingFramework\DataGenerator\Objects\OperationElement; use Magento\FunctionalTestingFramework\DataGenerator\Util\OperationElementExtractor; +use Magento\FunctionalTestingFramework\DataGenerator\Util\RuntimeDataReferenceResolver; use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException; class OperationDataArrayResolver @@ -65,8 +66,7 @@ public function __construct($dependentEntities = null) * @param boolean $fromArray * @return array * @throws \Exception - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD) */ public function resolveOperationDataArray($entityObject, $operationMetadata, $operation, $fromArray = false) { @@ -121,6 +121,17 @@ public function resolveOperationDataArray($entityObject, $operationMetadata, $op } } + $dataReferenceResolver = new RuntimeDataReferenceResolver(); + foreach ($operationDataArray as $key => $operationDataValue) { + if (is_array($operationDataValue)) { + continue; + } + $operationDataArray[$key] = $dataReferenceResolver->getDataReference( + $operationDataValue, + $entityObject->getName() + ); + } + return $operationDataArray; } diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php new file mode 100644 index 000000000..4c7070646 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php @@ -0,0 +1,26 @@ +{{[\w]+\..+}})/"; + + /** + * @param string $data + * @param string $originalDataEntity + * @return mixed + */ + public function getDataReference(string $data, string $originalDataEntity); + + /** + * @param string $data + * @param string $originalDataEntity + * @return mixed + */ + public function getDataUniqueness(string $data, string $originalDataEntity); +} diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php new file mode 100644 index 000000000..c9e0bd9a9 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php @@ -0,0 +1,96 @@ +getObject($entity); + if ($entityObject === null) { + throw new TestReferenceException( + "Could not resolve entity reference \"{$matches['reference']}\" " + . "in Data entity \"{$originalDataEntity}\"" + ); + } + + return $entityObject->getUniquenessDataByName($var); + } + + /** + * Returns data by reference if reference exist. + * + * @param string $data + * @param string $originalDataEntity + * @return string|null + * @throws TestReferenceException + */ + public function getDataReference(string $data, string $originalDataEntity) + { + $result = null; + preg_match(self::REFERENCE_REGEX_PATTERN, $data, $matches); + + if (empty($matches['reference'])) { + return $data; + } + + $strippedReference = str_replace(['{{', '}}'], '', $matches['reference']); + list($entity, $var) = explode('.', $strippedReference); + switch ($entity) { + case ActionObject::__ENV: + case ActionObject::__CREDS: + $result = $data; + break; + default: + $entityObject = DataObjectHandler::getInstance()->getObject($entity); + if ($entityObject === null) { + throw new TestReferenceException( + "Could not find data entity by name \"{$entityObject}\" " + . "referenced in Data entity \"{$originalDataEntity}\"" . PHP_EOL + ); + } + $entityData = $entityObject->getAllData(); + if (!isset($entityData[$var])) { + throw new TestReferenceException( + "Could not resolve entity reference \"{$matches['reference']}\" " + . "in Data entity \"{$originalDataEntity}\"" . PHP_EOL + ); + } + $result = $entityData[$var]; + } + + return $result; + } +} diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php new file mode 100644 index 000000000..a09afd01a --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php @@ -0,0 +1,101 @@ +getSecret($var); + $result = CredentialStore::getInstance()->decryptSecretValue($value); + $result = str_replace($matches['reference'], $result, $data); + break; + default: + $entityObject = DataObjectHandler::getInstance()->getObject($entity); + if ($entityObject === null) { + throw new TestReferenceException( + "Could not find data entity by name \"{$entityObject}\" " + . "referenced in Data entity \"{$originalDataEntity}\"" . PHP_EOL + ); + } + $entityData = $entityObject->getAllData(); + if (!isset($entityData[$var])) { + throw new TestReferenceException( + "Could not resolve entity reference \"{$matches['reference']}\" " + . "in Data entity \"{$originalDataEntity}\"" . PHP_EOL + ); + } + $result = $entityData[$var]; + } + + return $result; + } + + /** + * Returns data uniqueness for data entity field. + * + * @param string $data + * @param string $originalDataEntity + * @return string|null + * @throws TestReferenceException + */ + public function getDataUniqueness(string $data, string $originalDataEntity) + { + preg_match( + ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN, + $data, + $matches + ); + + if (empty($matches['reference'])) { + return null; + } + + $strippedReference = str_replace(['{{', '}}'], '', $matches['reference']); + list($entity, $var) = explode('.', $strippedReference); + $entityObject = DataObjectHandler::getInstance()->getObject($entity); + if ($entityObject === null) { + throw new TestReferenceException( + "Could not resolve entity reference \"{$matches['reference']}\" " + . "in Data entity \"{$originalDataEntity}\"" + ); + } + + return $entityObject->getUniquenessDataByName($var); + } +}