Skip to content

Commit ab81af6

Browse files
committed
MQE-790: Error for duplicate step keys in a single action group definition
- add new ExceptionCollector to throw all exceptions following stepKey validation
1 parent a3bb056 commit ab81af6

File tree

5 files changed

+102
-21
lines changed

5 files changed

+102
-21
lines changed

dev/tests/unit/Magento/FunctionalTestFramework/Test/Config/ActionGroupDomTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
namespace Tests\unit\Magento\FunctionalTestFramework\Test\Config;
77

8-
use Magento\FunctionalTestingFramework\Exceptions\XmlException;
8+
use Magento\FunctionalTestingFramework\Exceptions\Collector\ExceptionCollector;
99
use Magento\FunctionalTestingFramework\Test\Config\ActionGroupDom;
1010
use PHPUnit\Framework\TestCase;
1111

@@ -23,10 +23,10 @@ public function testActionGroupDomStepKeyValidation()
2323
</actionGroup>
2424
</actionGroups>";
2525

26-
$actionDom = new ActionGroupDom($sampleXml, 'test.xml');
27-
$this->expectException(XmlException::class);
26+
$exceptionCollector = new ExceptionCollector();
27+
$actionDom = new ActionGroupDom($sampleXml, 'dupeStepKeyActionGroup.xml', $exceptionCollector);
2828

29-
// an exception is only thrown for Action Group files.
30-
$actionDom->initDom($sampleXml, 'dupeStepKeyActionGroup.xml');
29+
$this->expectException(\Exception::class);
30+
$exceptionCollector->throwException();
3131
}
3232
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\FunctionalTestingFramework\Exceptions\Collector;
7+
8+
class ExceptionCollector
9+
{
10+
/**
11+
* Private array containing all errors to be thrown as part of the exception.
12+
*
13+
* @var array
14+
*/
15+
private $errors = [];
16+
17+
/**
18+
* Function to add a filename and message for the filename
19+
*
20+
* @param string $filename
21+
* @param string $message
22+
* @return void
23+
*/
24+
public function addError($filename, $message)
25+
{
26+
$error[$filename] = $message;
27+
$this->errors = array_merge_recursive($this->errors, $error);
28+
}
29+
30+
/**
31+
* Function which throws an exception when there are errors present.
32+
*
33+
* @return void
34+
* @throws \Exception
35+
*/
36+
public function throwException()
37+
{
38+
if (empty($this->errors)) {
39+
return;
40+
}
41+
42+
$errorMsg = implode("\n\n", $this->formatErrors($this->errors));
43+
throw new \Exception("\n" . $errorMsg);
44+
}
45+
46+
/**
47+
* If there are multiple exceptions for a single file, the function flattens the array so they can be printed
48+
* as separate messages.
49+
*
50+
* @param array $errors
51+
* @return array
52+
*/
53+
private function formatErrors($errors)
54+
{
55+
$flattenedErrors = [];
56+
foreach ($errors as $key => $errorMsg) {
57+
if (is_array($errorMsg)) {
58+
$flattenedErrors = array_merge($flattenedErrors, $this->formatErrors($errorMsg));
59+
continue;
60+
}
61+
62+
$flattenedErrors[] = $errorMsg;
63+
}
64+
65+
return $flattenedErrors;
66+
}
67+
}

src/Magento/FunctionalTestingFramework/Test/Config/ActionGroupDom.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\FunctionalTestingFramework\Test\Config;
77

8+
use Magento\FunctionalTestingFramework\Exceptions\Collector\ExceptionCollector;
9+
810
class ActionGroupDom extends Dom
911
{
1012
const ACTION_GROUP_FILE_NAME_ENDING = "ActionGroup.xml";
@@ -15,9 +17,10 @@ class ActionGroupDom extends Dom
1517
*
1618
* @param string $xml
1719
* @param string|null $filename
20+
* @param ExceptionCollector $exceptionCollector
1821
* @return \DOMDocument
1922
*/
20-
public function initDom($xml, $filename = null)
23+
public function initDom($xml, $filename = null, $exceptionCollector = null)
2124
{
2225
$dom = parent::initDom($xml);
2326

@@ -26,7 +29,7 @@ public function initDom($xml, $filename = null)
2629
foreach ($actionGroupNodes as $actionGroupNode) {
2730
/** @var \DOMElement $actionGroupNode */
2831
$actionGroupNode->setAttribute(self::TEST_META_FILENAME_ATTRIBUTE, $filename);
29-
$this->validateDomStepKeys($actionGroupNode, $filename, 'Action Group');
32+
$this->validateDomStepKeys($actionGroupNode, $filename, 'Action Group', $exceptionCollector);
3033
}
3134
}
3235

src/Magento/FunctionalTestingFramework/Test/Config/Dom.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\FunctionalTestingFramework\Test\Config;
88

9+
use Magento\FunctionalTestingFramework\Exceptions\Collector\ExceptionCollector;
910
use Magento\FunctionalTestingFramework\Exceptions\XmlException;
1011
use Magento\FunctionalTestingFramework\Config\Dom\NodeMergingConfig;
1112
use Magento\FunctionalTestingFramework\Config\Dom\NodePathMatcher;
@@ -21,6 +22,7 @@ class Dom extends \Magento\FunctionalTestingFramework\Config\Dom
2122
* TestDom constructor.
2223
* @param string $xml
2324
* @param string $filename
25+
* @param ExceptionCollector $exceptionCollector
2426
* @param array $idAttributes
2527
* @param string $typeAttributeName
2628
* @param string $schemaFile
@@ -29,6 +31,7 @@ class Dom extends \Magento\FunctionalTestingFramework\Config\Dom
2931
public function __construct(
3032
$xml,
3133
$filename,
34+
$exceptionCollector,
3235
array $idAttributes = [],
3336
$typeAttributeName = null,
3437
$schemaFile = null,
@@ -38,7 +41,7 @@ public function __construct(
3841
$this->nodeMergingConfig = new NodeMergingConfig(new NodePathMatcher(), $idAttributes);
3942
$this->typeAttributeName = $typeAttributeName;
4043
$this->errorFormat = $errorFormat;
41-
$this->dom = $this->initDom($xml, $filename);
44+
$this->dom = $this->initDom($xml, $filename, $exceptionCollector);
4245
$this->rootNamespace = $this->dom->lookupNamespaceUri($this->dom->namespaceURI);
4346
}
4447

@@ -47,9 +50,10 @@ public function __construct(
4750
*
4851
* @param string $xml
4952
* @param string|null $filename
53+
* @param ExceptionCollector $exceptionCollector
5054
* @return \DOMDocument
5155
*/
52-
public function initDom($xml, $filename = null)
56+
public function initDom($xml, $filename = null, $exceptionCollector = null)
5357
{
5458
$dom = parent::initDom($xml);
5559

@@ -58,7 +62,7 @@ public function initDom($xml, $filename = null)
5862
foreach ($testNodes as $testNode) {
5963
/** @var \DOMElement $testNode */
6064
$testNode->setAttribute(self::TEST_META_FILENAME_ATTRIBUTE, $filename);
61-
$this->validateDomStepKeys($testNode, $filename, 'Test');
65+
$this->validateDomStepKeys($testNode, $filename, 'Test', $exceptionCollector);
6266
}
6367
}
6468

@@ -70,11 +74,12 @@ public function initDom($xml, $filename = null)
7074
*
7175
* @param string $xml
7276
* @param string|null $filename
77+
* @param ExceptionCollector $exceptionCollector
7378
* @return void
7479
*/
75-
public function merge($xml, $filename = null)
80+
public function merge($xml, $filename = null, $exceptionCollector = null)
7681
{
77-
$dom = $this->initDom($xml, $filename);
82+
$dom = $this->initDom($xml, $filename, $exceptionCollector);
7883
$this->mergeNode($dom->documentElement, '');
7984
}
8085

@@ -84,10 +89,11 @@ public function merge($xml, $filename = null)
8489
* @param \DOMElement $testNode
8590
* @param string $filename
8691
* @param string $type
92+
* @param ExceptionCollector $exceptionCollector
8793
* @return void
8894
* @throws XmlException
8995
*/
90-
protected function validateDomStepKeys($testNode, $filename, $type)
96+
protected function validateDomStepKeys($testNode, $filename, $type, $exceptionCollector)
9197
{
9298
$childNodes = $testNode->childNodes;
9399

@@ -100,7 +106,7 @@ protected function validateDomStepKeys($testNode, $filename, $type)
100106
}
101107

102108
if (in_array($currentNode->nodeName, self::TEST_HOOK_NAMES)) {
103-
$this->validateDomStepKeys($currentNode, $filename, $type);
109+
$this->validateDomStepKeys($currentNode, $filename, $type, $exceptionCollector);
104110
}
105111

106112
if ($currentNode->hasAttribute('stepKey')) {
@@ -117,9 +123,8 @@ protected function validateDomStepKeys($testNode, $filename, $type)
117123
$stepKeyError .= "\tstepKey: {$duplicateValue} is used more than once.\n";
118124
}
119125

120-
throw new XmlException(
121-
"{$type}s cannot use stepKey more than once!\t\n{$stepKeyError}\tin file: {$filename}"
122-
);
126+
$errorMsg = "{$type}s cannot use stepKey more than once.\t\n{$stepKeyError}\tin file: {$filename}";
127+
$exceptionCollector->addError($filename, $errorMsg);
123128
}
124129
}
125130
}

src/Magento/FunctionalTestingFramework/Test/Config/Reader/Filesystem.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\FunctionalTestingFramework\Test\Config\Reader;
88

9+
use Magento\FunctionalTestingFramework\Exceptions\Collector\ExceptionCollector;
910
use Magento\FunctionalTestingFramework\Util\Iterator\File;
1011

1112
class Filesystem extends \Magento\FunctionalTestingFramework\Config\Reader\Filesystem
@@ -19,6 +20,8 @@ class Filesystem extends \Magento\FunctionalTestingFramework\Config\Reader\Files
1920
*/
2021
public function readFiles($fileList)
2122
{
23+
$exceptionCollector = new ExceptionCollector();
24+
$errors = [];
2225
/** @var \Magento\FunctionalTestingFramework\Test\Config\Dom $configMerger */
2326
$configMerger = null;
2427
foreach ($fileList as $key => $content) {
@@ -27,17 +30,18 @@ public function readFiles($fileList)
2730
$configMerger = $this->createConfigMerger(
2831
$this->domDocumentClass,
2932
$content,
30-
$fileList->getFilename()
33+
$fileList->getFilename(),
34+
$exceptionCollector
3135
);
3236
} else {
33-
$configMerger->merge($content, $fileList->getFilename());
37+
$configMerger->merge($content, $fileList->getFilename(), $exceptionCollector);
3438
}
3539
} catch (\Magento\FunctionalTestingFramework\Config\Dom\ValidationException $e) {
3640
throw new \Exception("Invalid XML in file " . $key . ":\n" . $e->getMessage());
3741
}
3842
}
43+
$exceptionCollector->throwException();
3944
if ($this->validationState->isValidationRequired()) {
40-
$errors = [];
4145
if ($configMerger && !$configMerger->validate($this->schemaFile, $errors)) {
4246
$message = "Invalid Document \n";
4347
throw new \Exception($message . implode("\n", $errors));
@@ -57,14 +61,16 @@ public function readFiles($fileList)
5761
* @param string $mergerClass
5862
* @param string $initialContents
5963
* @param string $filename
64+
* @param ExceptionCollector $exceptionCollector
6065
* @return \Magento\FunctionalTestingFramework\Config\Dom
6166
* @throws \UnexpectedValueException
6267
*/
63-
protected function createConfigMerger($mergerClass, $initialContents, $filename = null)
68+
protected function createConfigMerger($mergerClass, $initialContents, $filename = null, $exceptionCollector = null)
6469
{
6570
$result = new $mergerClass(
6671
$initialContents,
6772
$filename,
73+
$exceptionCollector,
6874
$this->idAttributes,
6975
null,
7076
$this->perFileSchema

0 commit comments

Comments
 (0)