Skip to content

Commit 81cfd36

Browse files
authored
Merge pull request #546 from lbajsarowicz/bugfix/55-missing-url-attribute
#55 Throw Exception when cannot resolve URL attribute
2 parents 4462b2c + aff5a79 commit 81cfd36

File tree

2 files changed

+65
-19
lines changed

2 files changed

+65
-19
lines changed

dev/tests/unit/Magento/FunctionalTestFramework/Test/Objects/ActionObjectTest.php

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525
class ActionObjectTest extends MagentoTestCase
2626
{
27+
const STUB_PAGE_URL_WITH_NO_ATTRIBUTE = '{{PageObject}}/some/path';
28+
2729
/**
2830
* Before test functionality
2931
* @return void
@@ -227,16 +229,17 @@ public function testResolveUrl()
227229
}
228230

229231
/**
230-
* {{PageObject}} should not be replaced and should elicit a warning in console
232+
* {{PageObject}} should not be replaced and should throw an exception!
231233
*
232234
* @throws /Exception
233235
*/
234236
public function testResolveUrlWithNoAttribute()
235237
{
236-
// Set up mocks
238+
// Given
237239
$actionObject = new ActionObject('merge123', 'amOnPage', [
238-
'url' => '{{PageObject}}'
240+
'url' => self::STUB_PAGE_URL_WITH_NO_ATTRIBUTE
239241
]);
242+
240243
$pageObject = new PageObject('PageObject', '/replacement/url.html', 'Test', [], false, "test");
241244
$pageObjectList = ["PageObject" => $pageObject];
242245
$instance = AspectMock::double(
@@ -245,20 +248,14 @@ public function testResolveUrlWithNoAttribute()
245248
)->make(); // bypass the private constructor
246249
AspectMock::double(PageObjectHandler::class, ['getInstance' => $instance]);
247250

248-
// Call the method under test
249-
$actionObject->resolveReferences();
250-
251-
// Expect this warning to get generated
252-
TestLoggingUtil::getInstance()->validateMockLogStatement(
253-
"warning",
254-
"page url attribute not found and is required",
255-
['action' => $actionObject->getType(), 'url' => '{{PageObject}}', 'stepKey' => $actionObject->getStepKey()]
256-
);
257-
258-
// Verify
251+
// Expect
252+
$this->expectExceptionMessage('Can not resolve replacements: "{{PageObject}}"');
259253
$expected = [
260-
'url' => '{{PageObject}}'
254+
'url' => self::STUB_PAGE_URL_WITH_NO_ATTRIBUTE
261255
];
256+
257+
// When
258+
$actionObject->resolveReferences();
262259
$this->assertEquals($expected, $actionObject->getCustomActionAttributes());
263260
}
264261

src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ class ActionObject
7676
const ACTION_ATTRIBUTE_USERINPUT = 'userInput';
7777
const ACTION_TYPE_COMMENT = 'comment';
7878
const INVISIBLE_STEP_ACTIONS = ['retrieveEntityField', 'getSecret'];
79+
const REGEX_SINGLE_GROUP = '[\w]+';
80+
const REGEX_WITH_INDEX = '[\w]+\.[\w\[\]]+';
81+
const REGEX_WITH_PARAM = '[\w]+\.[\w]+\((?(?!}}).)+\)';
7982

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

417420
$replacement = $this->findAndReplaceReferences(PageObjectHandler::getInstance(), $url);
421+
422+
$missingReferences = $this->getMissingReferences($replacement);
423+
if (!empty($missingReferences)) {
424+
throw new TestReferenceException(
425+
sprintf('Can not resolve replacements: "%s"', implode('", "', $missingReferences))
426+
);
427+
}
428+
418429
if ($replacement) {
419430
$this->resolvedCustomAttributes[ActionObject::ACTION_ATTRIBUTE_URL] = $replacement;
420431
$allPages = PageObjectHandler::getInstance()->getAllObjects();
@@ -428,6 +439,27 @@ private function resolveUrlReference()
428439
}
429440
}
430441

442+
/**
443+
* Returns array of missing references
444+
*
445+
* @param string $replacement
446+
* @return array
447+
*/
448+
private function getMissingReferences($replacement): array
449+
{
450+
$matchPatterns = [
451+
self::REGEX_SINGLE_GROUP,
452+
self::REGEX_WITH_INDEX,
453+
self::REGEX_WITH_PARAM
454+
];
455+
456+
preg_match_all($this->getMustachePattern($matchPatterns), $replacement, $matches);
457+
458+
return array_filter($matches[1], function ($match) {
459+
return !empty($match) && false === strpos($match, '_ENV.');
460+
});
461+
}
462+
431463
/**
432464
* Look up the value for EntityDataObjectName.Key and set it as the corresponding attribute in the resolved custom
433465
* attributes.
@@ -521,10 +553,12 @@ private function stripAndReturnParameters($reference)
521553
*/
522554
private function findAndReplaceReferences($objectHandler, $inputString)
523555
{
524-
//look for parameter area, if so use different regex
525-
$regex = ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN;
556+
$matchPatterns = [
557+
self::REGEX_WITH_INDEX,
558+
self::REGEX_WITH_PARAM
559+
];
526560

527-
preg_match_all($regex, $inputString, $matches);
561+
preg_match_all($this->getMustachePattern($matchPatterns), $inputString, $matches);
528562

529563
$outputString = $inputString;
530564

@@ -722,7 +756,11 @@ private function resolveParameterization($isParameterized, $replacement, $match,
722756
*/
723757
private function matchParameterReferences($reference, $parameters)
724758
{
725-
preg_match_all('/{{[\w.]+}}/', $reference, $varMatches);
759+
$matchPatterns = [
760+
self::REGEX_SINGLE_GROUP
761+
];
762+
763+
preg_match_all($this->getMustachePattern($matchPatterns), $reference, $varMatches);
726764
$varMatches[0] = array_unique($varMatches[0]);
727765
$this->checkParameterCount($varMatches[0], $parameters, $reference);
728766

@@ -793,6 +831,17 @@ private function checkParameterCount($matches, $parameters, $reference)
793831
}
794832
}
795833

834+
/**
835+
* Returns Mustache regex pattern
836+
*
837+
* @param array|null $patterns
838+
* @return string
839+
*/
840+
private function getMustachePattern(array $patterns = []): string
841+
{
842+
return '/({{' .implode('}})|({{', $patterns).'}})/';
843+
}
844+
796845
/**
797846
* Returns array of deprecated usages in Action.
798847
*

0 commit comments

Comments
 (0)