Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*/
class ActionObjectTest extends MagentoTestCase
{
const STUB_PAGE_URL_WITH_NO_ATTRIBUTE = '{{PageObject}}/some/path';

/**
* Before test functionality
* @return void
Expand Down Expand Up @@ -227,16 +229,17 @@ public function testResolveUrl()
}

/**
* {{PageObject}} should not be replaced and should elicit a warning in console
* {{PageObject}} should not be replaced and should throw an exception!
*
* @throws /Exception
*/
public function testResolveUrlWithNoAttribute()
{
// Set up mocks
// Given
$actionObject = new ActionObject('merge123', 'amOnPage', [
'url' => '{{PageObject}}'
'url' => self::STUB_PAGE_URL_WITH_NO_ATTRIBUTE
]);

$pageObject = new PageObject('PageObject', '/replacement/url.html', 'Test', [], false, "test");
$pageObjectList = ["PageObject" => $pageObject];
$instance = AspectMock::double(
Expand All @@ -245,20 +248,14 @@ public function testResolveUrlWithNoAttribute()
)->make(); // bypass the private constructor
AspectMock::double(PageObjectHandler::class, ['getInstance' => $instance]);

// Call the method under test
$actionObject->resolveReferences();

// Expect this warning to get generated
TestLoggingUtil::getInstance()->validateMockLogStatement(
"warning",
"page url attribute not found and is required",
['action' => $actionObject->getType(), 'url' => '{{PageObject}}', 'stepKey' => $actionObject->getStepKey()]
);

// Verify
// Expect
$this->expectExceptionMessage('Can not resolve replacements: "{{PageObject}}"');
$expected = [
'url' => '{{PageObject}}'
'url' => self::STUB_PAGE_URL_WITH_NO_ATTRIBUTE
];

// When
$actionObject->resolveReferences();
$this->assertEquals($expected, $actionObject->getCustomActionAttributes());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class ActionObject
const ACTION_ATTRIBUTE_USERINPUT = 'userInput';
const ACTION_TYPE_COMMENT = 'comment';
const INVISIBLE_STEP_ACTIONS = ['retrieveEntityField', 'getSecret'];
const REGEX_SINGLE_GROUP = '[\w]+';
const REGEX_WITH_INDEX = '[\w]+\.[\w\[\]]+';
const REGEX_WITH_PARAM = '[\w]+\.[\w]+\((?(?!}}).)+\)';

/**
* The unique identifier for the action
Expand Down Expand Up @@ -415,6 +418,14 @@ private function resolveUrlReference()
$url = $this->actionAttributes[ActionObject::ACTION_ATTRIBUTE_URL];

$replacement = $this->findAndReplaceReferences(PageObjectHandler::getInstance(), $url);

$missingReferences = $this->getMissingReferences($replacement);
if (!empty($missingReferences)) {
throw new TestReferenceException(
sprintf('Can not resolve replacements: "%s"', implode('", "', $missingReferences))
);
}

if ($replacement) {
$this->resolvedCustomAttributes[ActionObject::ACTION_ATTRIBUTE_URL] = $replacement;
$allPages = PageObjectHandler::getInstance()->getAllObjects();
Expand All @@ -428,6 +439,27 @@ private function resolveUrlReference()
}
}

/**
* Returns array of missing references
*
* @param string $replacement
* @return array
*/
private function getMissingReferences($replacement): array
{
$matchPatterns = [
self::REGEX_SINGLE_GROUP,
self::REGEX_WITH_INDEX,
self::REGEX_WITH_PARAM
];

preg_match_all($this->getMustachePattern($matchPatterns), $replacement, $matches);

return array_filter($matches[1], function ($match) {
return !empty($match) && false === strpos($match, '_ENV.');
});
}

/**
* Look up the value for EntityDataObjectName.Key and set it as the corresponding attribute in the resolved custom
* attributes.
Expand Down Expand Up @@ -521,10 +553,12 @@ private function stripAndReturnParameters($reference)
*/
private function findAndReplaceReferences($objectHandler, $inputString)
{
//look for parameter area, if so use different regex
$regex = ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN;
$matchPatterns = [
self::REGEX_WITH_INDEX,
self::REGEX_WITH_PARAM
];

preg_match_all($regex, $inputString, $matches);
preg_match_all($this->getMustachePattern($matchPatterns), $inputString, $matches);

$outputString = $inputString;

Expand Down Expand Up @@ -722,7 +756,11 @@ private function resolveParameterization($isParameterized, $replacement, $match,
*/
private function matchParameterReferences($reference, $parameters)
{
preg_match_all('/{{[\w.]+}}/', $reference, $varMatches);
$matchPatterns = [
self::REGEX_SINGLE_GROUP
];

preg_match_all($this->getMustachePattern($matchPatterns), $reference, $varMatches);
$varMatches[0] = array_unique($varMatches[0]);
$this->checkParameterCount($varMatches[0], $parameters, $reference);

Expand Down Expand Up @@ -793,6 +831,17 @@ private function checkParameterCount($matches, $parameters, $reference)
}
}

/**
* Returns Mustache regex pattern
*
* @param array|null $patterns
* @return string
*/
private function getMustachePattern(array $patterns = []): string
{
return '/({{' .implode('}})|({{', $patterns).'}})/';
}

/**
* Returns array of deprecated usages in Action.
*
Expand Down