Skip to content

Commit 744244d

Browse files
authored
Merge pull request #159 from magento-gl/MQE-1677
MQE-1677 : Static check for created data outside action group
2 parents 4d600ed + ff2e0f2 commit 744244d

File tree

2 files changed

+196
-1
lines changed

2 files changed

+196
-1
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\FunctionalTestingFramework\StaticCheck;
8+
9+
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
10+
use InvalidArgumentException;
11+
use Exception;
12+
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
13+
use Magento\FunctionalTestingFramework\Exceptions\XmlException;
14+
use Magento\FunctionalTestingFramework\Page\Objects\SectionObject;
15+
use Magento\FunctionalTestingFramework\Test\Objects\ActionObject;
16+
use Magento\FunctionalTestingFramework\Page\Objects\ElementObject;
17+
use Magento\FunctionalTestingFramework\Test\Objects\ActionGroupObject;
18+
use Magento\FunctionalTestingFramework\Page\Objects\PageObject;
19+
use Magento\FunctionalTestingFramework\Test\Objects\TestObject;
20+
use Symfony\Component\Console\Input\InputInterface;
21+
use Symfony\Component\Finder\Finder;
22+
use Magento\FunctionalTestingFramework\Util\Script\ScriptUtil;
23+
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\OperationDefinitionObjectHandler;
24+
use Magento\FunctionalTestingFramework\DataGenerator\Objects\OperationDefinitionObject;
25+
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler;
26+
use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject;
27+
use Symfony\Component\Finder\SplFileInfo;
28+
use DOMNodeList;
29+
use DOMElement;
30+
31+
/**
32+
* Class CreatedDataFromOutsideActionGroupCheck
33+
* @package Magento\FunctionalTestingFramework\StaticCheck
34+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
35+
*/
36+
class CreatedDataFromOutsideActionGroupCheck implements StaticCheckInterface
37+
{
38+
const ACTIONGROUP_REGEX_PATTERN = '/\$(\$)*([\w.]+)(\$)*\$/';
39+
const ERROR_LOG_FILENAME = 'create-data-from-outside-action-group';
40+
const ERROR_MESSAGE = 'Created Data From Outside Action Group';
41+
42+
/**
43+
* Array containing all errors found after running the execute() function
44+
*
45+
* @var array
46+
*/
47+
private $errors = [];
48+
49+
/**
50+
* String representing the output summary found after running the execute() function
51+
*
52+
* @var string
53+
*/
54+
private $output;
55+
56+
/**
57+
* ScriptUtil instance
58+
*
59+
* @var ScriptUtil
60+
*/
61+
private $scriptUtil;
62+
63+
/**
64+
* Checks test dependencies, determined by references in tests versus the dependencies listed in the Magento module
65+
*
66+
* @param InputInterface $input
67+
* @return void
68+
* @throws Exception
69+
*/
70+
public function execute(InputInterface $input)
71+
{
72+
$this->scriptUtil = new ScriptUtil();
73+
$this->loadAllXmlFiles($input);
74+
$this->errors = [];
75+
$this->errors += $this->findReferenceErrorsInActionFiles($this->actionGroupXmlFile);
76+
// hold on to the output and print any errors to a file
77+
$this->output = $this->scriptUtil->printErrorsToFile(
78+
$this->errors,
79+
StaticChecksList::getErrorFilesPath() . DIRECTORY_SEPARATOR . self::ERROR_LOG_FILENAME . '.txt',
80+
self::ERROR_MESSAGE
81+
);
82+
}
83+
84+
/**
85+
* Return array containing all errors found after running the execute() function
86+
*
87+
* @return array
88+
*/
89+
public function getErrors()
90+
{
91+
return $this->errors;
92+
}
93+
94+
/**
95+
* Return string of a short human readable result of the check. For example: "No Dependency errors found."
96+
*
97+
* @return string
98+
*/
99+
public function getOutput()
100+
{
101+
return $this->output;
102+
}
103+
104+
/**
105+
* Read all XML files for scanning
106+
*
107+
* @param InputInterface $input
108+
* @return void
109+
* @throws Exception
110+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
111+
*/
112+
private function loadAllXmlFiles($input)
113+
{
114+
$modulePaths = [];
115+
$path = $input->getOption('path');
116+
if ($path) {
117+
if (!realpath($path)) {
118+
throw new InvalidArgumentException('Invalid --path option: ' . $path);
119+
}
120+
MftfApplicationConfig::create(
121+
true,
122+
MftfApplicationConfig::UNIT_TEST_PHASE,
123+
false,
124+
MftfApplicationConfig::LEVEL_DEFAULT,
125+
true
126+
);
127+
$modulePaths[] = realpath($path);
128+
} else {
129+
$modulePaths = $this->scriptUtil->getAllModulePaths();
130+
}
131+
132+
// These files can contain references to other entities
133+
$this->actionGroupXmlFile = $this->scriptUtil->getModuleXmlFilesByScope($modulePaths, 'ActionGroup');
134+
135+
if (empty($this->actionGroupXmlFile)) {
136+
if ($path) {
137+
throw new InvalidArgumentException(
138+
'Invalid --path option: '
139+
. $path
140+
. PHP_EOL
141+
. 'Please make sure --path points to a valid MFTF Test Module.'
142+
);
143+
} elseif (empty($this->rootSuiteXmlFiles)) {
144+
throw new TestFrameworkException('No xml file to scan.');
145+
}
146+
}
147+
}
148+
149+
/**
150+
* Find reference errors in set of action files
151+
*
152+
* @param Finder $files
153+
* @return array
154+
* @throws XmlException
155+
*/
156+
private function findReferenceErrorsInActionFiles($files)
157+
{
158+
$testErrors = [];
159+
/** @var SplFileInfo $filePath */
160+
foreach ($files as $filePath) {
161+
$contents = file_get_contents($filePath);
162+
preg_match_all(self::ACTIONGROUP_REGEX_PATTERN, $contents, $actionGroupReferences);
163+
if (count($actionGroupReferences) > 0) {
164+
$testErrors = array_merge($testErrors, $this->setErrorOutput($actionGroupReferences, $filePath));
165+
}
166+
}
167+
168+
return $testErrors;
169+
}
170+
171+
/**
172+
* Build and return error output for violating references
173+
*
174+
* @param array $actionGroupReferences
175+
* @param SplFileInfo $path
176+
* @return mixed
177+
*/
178+
private function setErrorOutput($actionGroupReferences, $path)
179+
{
180+
$testErrors = [];
181+
$errorOutput = "";
182+
$filePath = StaticChecksList::getFilePath($path->getRealPath());
183+
184+
foreach ($actionGroupReferences as $key => $actionGroupReferencesData) {
185+
foreach ($actionGroupReferencesData as $actionGroupReferencesDataResult) {
186+
$errorOutput .= "\nFile \"{$filePath}\" contains: ". "\n\t
187+
{$actionGroupReferencesDataResult} in {$filePath}";
188+
$testErrors[$filePath][] = $errorOutput;
189+
}
190+
}
191+
return $testErrors;
192+
}
193+
}

src/Magento/FunctionalTestingFramework/StaticCheck/StaticChecksList.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class StaticChecksList implements StaticCheckListInterface
1818
{
1919
const DEPRECATED_ENTITY_USAGE_CHECK_NAME = 'deprecatedEntityUsage';
2020
const PAUSE_ACTION_USAGE_CHECK_NAME = 'pauseActionUsage';
21+
const CREATED_DATA_FROM_OUTSIDE_ACTIONGROUP = 'createdDataFromOutsideActionGroup';
2122
const STATIC_RESULTS = 'tests' . DIRECTORY_SEPARATOR .'_output' . DIRECTORY_SEPARATOR . 'static-results';
2223

2324
/**
@@ -47,7 +48,8 @@ public function __construct(array $checks = [])
4748
'actionGroupArguments' => new ActionGroupArgumentsCheck(),
4849
self::DEPRECATED_ENTITY_USAGE_CHECK_NAME => new DeprecatedEntityUsageCheck(),
4950
'annotations' => new AnnotationsCheck(),
50-
self::PAUSE_ACTION_USAGE_CHECK_NAME => new PauseActionUsageCheck()
51+
self::PAUSE_ACTION_USAGE_CHECK_NAME => new PauseActionUsageCheck(),
52+
self::CREATED_DATA_FROM_OUTSIDE_ACTIONGROUP => new CreatedDataFromOutsideActionGroupCheck()
5153
] + $checks;
5254

5355
// Static checks error files directory

0 commit comments

Comments
 (0)