From 3a9b868966430f4a5401d5d881aeb121b96ad948 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk Date: Mon, 12 Aug 2019 13:42:46 -0500 Subject: [PATCH 1/5] MQE-1561: CreateData action must be able to parse Data entity which references another data --- .../Objects/EntityDataObject.php | 28 ++++-- .../Persist/OperationDataArrayResolver.php | 12 +++ .../Util/DataReferenceResolverInterface.php | 26 ++++++ .../Util/GenerationDataReferenceResolver.php | 82 +++++++++++++++++ .../Util/RuntimeDataReferenceResolver.php | 88 +++++++++++++++++++ 5 files changed, 231 insertions(+), 5 deletions(-) create mode 100644 src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php create mode 100644 src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php create mode 100644 src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php index 09c95df9e..3fb511d3b 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; @@ -81,14 +82,14 @@ class EntityDataObject /** * Constructor * - * @param string $name - * @param string $type + * @param string $name + * @param string $type * @param string[] $data * @param string[] $linkedEntities * @param string[] $uniquenessData * @param string[] $vars - * @param string $parentEntity - * @param string $filename + * @param string $parentEntity + * @param string $filename */ public function __construct( $name, @@ -181,13 +182,30 @@ public function getDataByName($name, $uniquenessFormat) return null; } + $dataReferenceResolver = new GenerationDataReferenceResolver(); if (array_key_exists($name_lower, $this->data)) { - $uniquenessData = $this->getUniquenessDataByName($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)) { + $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..7a76c54d1 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 @@ -121,6 +122,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..488a87bfe --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php @@ -0,0 +1,26 @@ +{{[\w]+\.[\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..bea84b7a9 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php @@ -0,0 +1,82 @@ +getObject($entity); + if ($entityObject === null) { + throw new TestReferenceException( + "Could not resolve entity reference \"{$matches['reference']}\" " + . "in Data entity \"{$originalDataEntity}\"" + ); + } + $entityData = $entityObject->getAllData(); + $result = $entityData[$var]; + } + + return $result; + } + + /** + * @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); + } +} diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php new file mode 100644 index 000000000..68f083cad --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php @@ -0,0 +1,88 @@ +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 resolve entity reference \"{$matches['reference']}\" " + . "in Data entity \"{$originalDataEntity}\"" + ); + } + $entityData = $entityObject->getAllData(); + $result = $entityData[$var]; + } + + return $result; + } + + /** + * @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); + } +} From 124e1069f285287348d5fc473343a9ff503b6e1e Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk Date: Mon, 12 Aug 2019 15:00:45 -0500 Subject: [PATCH 2/5] MQE-1561: CreateData action must be able to parse Data entity which references another data - fix an issue when data is an array --- .../DataGenerator/Objects/EntityDataObject.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php index 3fb511d3b..59e02d09d 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php @@ -184,6 +184,9 @@ public function getDataByName($name, $uniquenessFormat) $dataReferenceResolver = new GenerationDataReferenceResolver(); if (array_key_exists($name_lower, $this->data)) { + if (is_array($this->data[$name_lower])) { + return $this->data[$name_lower]; + } $uniquenessData = $this->getUniquenessDataByName($name_lower) === null ? $dataReferenceResolver->getDataUniqueness( $this->data[$name_lower], @@ -202,6 +205,9 @@ public function getDataByName($name, $uniquenessFormat) } 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 From 37ea58d47aeb9168965837db5f57c3078ebf83aa Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk Date: Tue, 13 Aug 2019 12:01:16 -0500 Subject: [PATCH 3/5] MQE-1561: CreateData action must be able to parse Data entity which references another data - fix static check failures --- .../Objects/EntityDataObject.php | 9 +-- .../Persist/OperationDataArrayResolver.php | 5 +- .../Util/GenerationDataReferenceResolver.php | 62 +++++++++---------- .../Util/RuntimeDataReferenceResolver.php | 4 +- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php index 59e02d09d..110869187 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php @@ -82,14 +82,14 @@ class EntityDataObject /** * Constructor * - * @param string $name - * @param string $type + * @param string $name + * @param string $type * @param string[] $data * @param string[] $linkedEntities * @param string[] $uniquenessData * @param string[] $vars - * @param string $parentEntity - * @param string $filename + * @param string $parentEntity + * @param string $filename */ public function __construct( $name, @@ -161,6 +161,7 @@ public function getAllData() * @param integer $uniquenessFormat * @return string|null * @throws TestFrameworkException + * @SuppressWarnings(PHPMD) */ public function getDataByName($name, $uniquenessFormat) { diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php index 7a76c54d1..6d1ebc3fc 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php @@ -66,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) { @@ -124,7 +123,7 @@ public function resolveOperationDataArray($entityObject, $operationMetadata, $op $dataReferenceResolver = new RuntimeDataReferenceResolver(); foreach ($operationDataArray as $key => $operationDataValue) { - if (is_array($operationDataValue)){ + if (is_array($operationDataValue)) { continue; } $operationDataArray[$key] = $dataReferenceResolver->getDataReference( diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php index bea84b7a9..903dcdf29 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php @@ -12,6 +12,37 @@ class GenerationDataReferenceResolver implements DataReferenceResolverInterface { + /** + * @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); + } + /** * @param string $data * @param string $originalDataEntity @@ -48,35 +79,4 @@ public function getDataReference(string $data, string $originalDataEntity) return $result; } - - /** - * @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); - } } diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php index 68f083cad..a8bb4154e 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php @@ -63,7 +63,8 @@ public function getDataReference(string $data, string $originalDataEntity) */ public function getDataUniqueness(string $data, string $originalDataEntity) { - preg_match(ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN, + preg_match( + ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN, $data, $matches ); @@ -80,7 +81,6 @@ public function getDataUniqueness(string $data, string $originalDataEntity) "Could not resolve entity reference \"{$matches['reference']}\" " . "in Data entity \"{$originalDataEntity}\"" ); - } return $entityObject->getUniquenessDataByName($var); From 32967a2cfb07724bdc98c269cca2a5e1598d2c62 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk Date: Tue, 13 Aug 2019 15:09:24 -0500 Subject: [PATCH 4/5] MQE-1561: CreateData action must be able to parse Data entity which references another data - fix regex to match all paths --- .../DataGenerator/Util/DataReferenceResolverInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php index 488a87bfe..4c7070646 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/DataReferenceResolverInterface.php @@ -8,7 +8,7 @@ interface DataReferenceResolverInterface { - const REFERENCE_REGEX_PATTERN = "/(?{{[\w]+\.[\w\[\]]+}})/"; + const REFERENCE_REGEX_PATTERN = "/(?{{[\w]+\..+}})/"; /** * @param string $data From dd2da2e13efa2afb8f7744c3bda0e5a2f0cf204f Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk Date: Thu, 15 Aug 2019 14:37:28 -0500 Subject: [PATCH 5/5] MQE-1561: CreateData action must be able to parse Data entity which references another data - Added phpdoc blocks --- .../Util/GenerationDataReferenceResolver.php | 18 ++++++++++++++++-- .../Util/RuntimeDataReferenceResolver.php | 17 +++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php index 903dcdf29..c9e0bd9a9 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/GenerationDataReferenceResolver.php @@ -10,9 +10,15 @@ use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException; use Magento\FunctionalTestingFramework\Test\Objects\ActionObject; +/** + * Class resolves data references in data entities while generating static test files. + */ class GenerationDataReferenceResolver implements DataReferenceResolverInterface { /** + * Returns data uniqueness for data entity field. + * + * * @param string $data * @param string $originalDataEntity * @return string|null @@ -44,6 +50,8 @@ public function getDataUniqueness(string $data, string $originalDataEntity) } /** + * Returns data by reference if reference exist. + * * @param string $data * @param string $originalDataEntity * @return string|null @@ -69,11 +77,17 @@ public function getDataReference(string $data, string $originalDataEntity) $entityObject = DataObjectHandler::getInstance()->getObject($entity); if ($entityObject === null) { throw new TestReferenceException( - "Could not resolve entity reference \"{$matches['reference']}\" " - . "in Data entity \"{$originalDataEntity}\"" + "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]; } diff --git a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php index a8bb4154e..a09afd01a 100644 --- a/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php +++ b/src/Magento/FunctionalTestingFramework/DataGenerator/Util/RuntimeDataReferenceResolver.php @@ -11,9 +11,14 @@ use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException; use Magento\FunctionalTestingFramework\Test\Objects\ActionObject; +/** + * Class resolves data references in data entities at the runtime of tests. + */ class RuntimeDataReferenceResolver implements DataReferenceResolverInterface { /** + * Returns data by reference if reference exist. + * * @param string $data * @param string $originalDataEntity * @return array|false|string|null @@ -44,11 +49,17 @@ public function getDataReference(string $data, string $originalDataEntity) $entityObject = DataObjectHandler::getInstance()->getObject($entity); if ($entityObject === null) { throw new TestReferenceException( - "Could not resolve entity reference \"{$matches['reference']}\" " - . "in Data entity \"{$originalDataEntity}\"" + "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]; } @@ -56,6 +67,8 @@ public function getDataReference(string $data, string $originalDataEntity) } /** + * Returns data uniqueness for data entity field. + * * @param string $data * @param string $originalDataEntity * @return string|null