Skip to content

Commit 3a73b31

Browse files
authored
Merge pull request #418 from magento/MQE-1561
CreateData action must be able to parse Data entity which references another data
2 parents a626fb8 + 466f92c commit 3a73b31

File tree

5 files changed

+262
-3
lines changed

5 files changed

+262
-3
lines changed

src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Magento\FunctionalTestingFramework\DataGenerator\Objects;
88

99
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
10+
use Magento\FunctionalTestingFramework\DataGenerator\Util\GenerationDataReferenceResolver;
1011
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
1112
use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;
1213

@@ -160,6 +161,7 @@ public function getAllData()
160161
* @param integer $uniquenessFormat
161162
* @return string|null
162163
* @throws TestFrameworkException
164+
* @SuppressWarnings(PHPMD)
163165
*/
164166
public function getDataByName($name, $uniquenessFormat)
165167
{
@@ -181,13 +183,36 @@ public function getDataByName($name, $uniquenessFormat)
181183
return null;
182184
}
183185

186+
$dataReferenceResolver = new GenerationDataReferenceResolver();
184187
if (array_key_exists($name_lower, $this->data)) {
185-
$uniquenessData = $this->getUniquenessDataByName($name_lower);
188+
if (is_array($this->data[$name_lower])) {
189+
return $this->data[$name_lower];
190+
}
191+
$uniquenessData = $this->getUniquenessDataByName($name_lower) === null
192+
? $dataReferenceResolver->getDataUniqueness(
193+
$this->data[$name_lower],
194+
$this->name . '.' . $name
195+
)
196+
: $this->getUniquenessDataByName($name_lower);
197+
if ($uniquenessData !== null) {
198+
$this->uniquenessData[$name] = $uniquenessData;
199+
}
200+
$this->data[$name_lower] = $dataReferenceResolver->getDataReference(
201+
$this->data[$name_lower],
202+
$this->name . '.' . $name
203+
);
186204
if (null === $uniquenessData || $uniquenessFormat == self::NO_UNIQUE_PROCESS) {
187205
return $this->data[$name_lower];
188206
}
189207
return $this->formatUniqueData($name_lower, $uniquenessData, $uniquenessFormat);
190208
} elseif (array_key_exists($name, $this->data)) {
209+
if (is_array($this->data[$name_lower])) {
210+
return $this->data[$name];
211+
}
212+
$this->data[$name] = $dataReferenceResolver->getDataReference(
213+
$this->data[$name],
214+
$this->name . '.' . $name
215+
);
191216
// Data returned by the API may be camelCase so we need to check for the original $name also.
192217
return $this->data[$name];
193218
} else {

src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject;
1212
use Magento\FunctionalTestingFramework\DataGenerator\Objects\OperationElement;
1313
use Magento\FunctionalTestingFramework\DataGenerator\Util\OperationElementExtractor;
14+
use Magento\FunctionalTestingFramework\DataGenerator\Util\RuntimeDataReferenceResolver;
1415
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
1516

1617
class OperationDataArrayResolver
@@ -65,8 +66,7 @@ public function __construct($dependentEntities = null)
6566
* @param boolean $fromArray
6667
* @return array
6768
* @throws \Exception
68-
* @SuppressWarnings(PHPMD.NPathComplexity)
69-
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
69+
* @SuppressWarnings(PHPMD)
7070
*/
7171
public function resolveOperationDataArray($entityObject, $operationMetadata, $operation, $fromArray = false)
7272
{
@@ -121,6 +121,17 @@ public function resolveOperationDataArray($entityObject, $operationMetadata, $op
121121
}
122122
}
123123

124+
$dataReferenceResolver = new RuntimeDataReferenceResolver();
125+
foreach ($operationDataArray as $key => $operationDataValue) {
126+
if (is_array($operationDataValue)) {
127+
continue;
128+
}
129+
$operationDataArray[$key] = $dataReferenceResolver->getDataReference(
130+
$operationDataValue,
131+
$entityObject->getName()
132+
);
133+
}
134+
124135
return $operationDataArray;
125136
}
126137

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\FunctionalTestingFramework\DataGenerator\Util;
8+
9+
interface DataReferenceResolverInterface
10+
{
11+
const REFERENCE_REGEX_PATTERN = "/(?<reference>{{[\w]+\..+}})/";
12+
13+
/**
14+
* @param string $data
15+
* @param string $originalDataEntity
16+
* @return mixed
17+
*/
18+
public function getDataReference(string $data, string $originalDataEntity);
19+
20+
/**
21+
* @param string $data
22+
* @param string $originalDataEntity
23+
* @return mixed
24+
*/
25+
public function getDataUniqueness(string $data, string $originalDataEntity);
26+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\FunctionalTestingFramework\DataGenerator\Util;
8+
9+
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler;
10+
use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException;
11+
use Magento\FunctionalTestingFramework\Test\Objects\ActionObject;
12+
13+
/**
14+
* Class resolves data references in data entities while generating static test files.
15+
*/
16+
class GenerationDataReferenceResolver implements DataReferenceResolverInterface
17+
{
18+
/**
19+
* Returns data uniqueness for data entity field.
20+
*
21+
*
22+
* @param string $data
23+
* @param string $originalDataEntity
24+
* @return string|null
25+
* @throws TestReferenceException
26+
*/
27+
public function getDataUniqueness(string $data, string $originalDataEntity)
28+
{
29+
preg_match(
30+
ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN,
31+
$data,
32+
$matches
33+
);
34+
35+
if (empty($matches['reference'])) {
36+
return null;
37+
}
38+
39+
$strippedReference = str_replace(['{{', '}}'], '', $matches['reference']);
40+
list($entity, $var) = explode('.', $strippedReference);
41+
$entityObject = DataObjectHandler::getInstance()->getObject($entity);
42+
if ($entityObject === null) {
43+
throw new TestReferenceException(
44+
"Could not resolve entity reference \"{$matches['reference']}\" "
45+
. "in Data entity \"{$originalDataEntity}\""
46+
);
47+
}
48+
49+
return $entityObject->getUniquenessDataByName($var);
50+
}
51+
52+
/**
53+
* Returns data by reference if reference exist.
54+
*
55+
* @param string $data
56+
* @param string $originalDataEntity
57+
* @return string|null
58+
* @throws TestReferenceException
59+
*/
60+
public function getDataReference(string $data, string $originalDataEntity)
61+
{
62+
$result = null;
63+
preg_match(self::REFERENCE_REGEX_PATTERN, $data, $matches);
64+
65+
if (empty($matches['reference'])) {
66+
return $data;
67+
}
68+
69+
$strippedReference = str_replace(['{{', '}}'], '', $matches['reference']);
70+
list($entity, $var) = explode('.', $strippedReference);
71+
switch ($entity) {
72+
case ActionObject::__ENV:
73+
case ActionObject::__CREDS:
74+
$result = $data;
75+
break;
76+
default:
77+
$entityObject = DataObjectHandler::getInstance()->getObject($entity);
78+
if ($entityObject === null) {
79+
throw new TestReferenceException(
80+
"Could not find data entity by name \"{$entityObject}\" "
81+
. "referenced in Data entity \"{$originalDataEntity}\"" . PHP_EOL
82+
);
83+
}
84+
$entityData = $entityObject->getAllData();
85+
if (!isset($entityData[$var])) {
86+
throw new TestReferenceException(
87+
"Could not resolve entity reference \"{$matches['reference']}\" "
88+
. "in Data entity \"{$originalDataEntity}\"" . PHP_EOL
89+
);
90+
}
91+
$result = $entityData[$var];
92+
}
93+
94+
return $result;
95+
}
96+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\FunctionalTestingFramework\DataGenerator\Util;
8+
9+
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\CredentialStore;
10+
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler;
11+
use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException;
12+
use Magento\FunctionalTestingFramework\Test\Objects\ActionObject;
13+
14+
/**
15+
* Class resolves data references in data entities at the runtime of tests.
16+
*/
17+
class RuntimeDataReferenceResolver implements DataReferenceResolverInterface
18+
{
19+
/**
20+
* Returns data by reference if reference exist.
21+
*
22+
* @param string $data
23+
* @param string $originalDataEntity
24+
* @return array|false|string|null
25+
* @throws TestReferenceException
26+
* @throws \Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException
27+
*/
28+
public function getDataReference(string $data, string $originalDataEntity)
29+
{
30+
$result = null;
31+
preg_match(self::REFERENCE_REGEX_PATTERN, $data, $matches);
32+
33+
if (empty($matches['reference'])) {
34+
return $data;
35+
}
36+
37+
$strippedReference = str_replace(['{{', '}}'], '', $matches['reference']);
38+
list($entity, $var) = explode('.', $strippedReference);
39+
switch ($entity) {
40+
case ActionObject::__ENV:
41+
$result = str_replace($matches['reference'], getenv($var), $data);
42+
break;
43+
case ActionObject::__CREDS:
44+
$value = CredentialStore::getInstance()->getSecret($var);
45+
$result = CredentialStore::getInstance()->decryptSecretValue($value);
46+
$result = str_replace($matches['reference'], $result, $data);
47+
break;
48+
default:
49+
$entityObject = DataObjectHandler::getInstance()->getObject($entity);
50+
if ($entityObject === null) {
51+
throw new TestReferenceException(
52+
"Could not find data entity by name \"{$entityObject}\" "
53+
. "referenced in Data entity \"{$originalDataEntity}\"" . PHP_EOL
54+
);
55+
}
56+
$entityData = $entityObject->getAllData();
57+
if (!isset($entityData[$var])) {
58+
throw new TestReferenceException(
59+
"Could not resolve entity reference \"{$matches['reference']}\" "
60+
. "in Data entity \"{$originalDataEntity}\"" . PHP_EOL
61+
);
62+
}
63+
$result = $entityData[$var];
64+
}
65+
66+
return $result;
67+
}
68+
69+
/**
70+
* Returns data uniqueness for data entity field.
71+
*
72+
* @param string $data
73+
* @param string $originalDataEntity
74+
* @return string|null
75+
* @throws TestReferenceException
76+
*/
77+
public function getDataUniqueness(string $data, string $originalDataEntity)
78+
{
79+
preg_match(
80+
ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN,
81+
$data,
82+
$matches
83+
);
84+
85+
if (empty($matches['reference'])) {
86+
return null;
87+
}
88+
89+
$strippedReference = str_replace(['{{', '}}'], '', $matches['reference']);
90+
list($entity, $var) = explode('.', $strippedReference);
91+
$entityObject = DataObjectHandler::getInstance()->getObject($entity);
92+
if ($entityObject === null) {
93+
throw new TestReferenceException(
94+
"Could not resolve entity reference \"{$matches['reference']}\" "
95+
. "in Data entity \"{$originalDataEntity}\""
96+
);
97+
}
98+
99+
return $entityObject->getUniquenessDataByName($var);
100+
}
101+
}

0 commit comments

Comments
 (0)