Skip to content

Commit a1afd8f

Browse files
committed
Merge remote-tracking branch 'origin/2.3-develop' into MC-18945-PR
2 parents ebb3f2d + 8f911bb commit a1afd8f

File tree

8 files changed

+162
-42
lines changed

8 files changed

+162
-42
lines changed

app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductGridActionGroup.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,5 +400,6 @@
400400
<click selector="{{AdminProductGridSection.bulkActionOption('Delete')}}" stepKey="clickDeleteAction"/>
401401
<waitForElementVisible selector="{{AdminProductGridConfirmActionSection.ok}}" stepKey="waitForModalPopUp"/>
402402
<click selector="{{AdminProductGridConfirmActionSection.ok}}" stepKey="confirmProductDelete"/>
403+
<waitForPageLoad stepKey="waitForGridLoad"/>
403404
</actionGroup>
404405
</actionGroups>

app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
<deleteData createDataKey="createSimpleCategory1" stepKey="deleteSimpleCategory1"/>
117117
<deleteData createDataKey="createSimpleProduct1" stepKey="deleteSimpleProduct1"/>
118118
<deleteData createDataKey="createSimpleProduct2" stepKey="deleteSimpleProduct2"/>
119+
<deleteData createDataKey="createConfigChildProduct" stepKey="deleteConfigChildProduct"/>
119120
<deleteData createDataKey="createConfigProduct1" stepKey="deleteConfigProduct1"/>
120121
<deleteData createDataKey="createVirtualProduct1" stepKey="deleteVirtualProduct1"/>
121122
<deleteData createDataKey="createBundleProduct1" stepKey="deleteBundleProduct1"/>

app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php

Lines changed: 111 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@
77

88
namespace Magento\Developer\Console\Command;
99

10-
use Magento\Developer\Model\Di\Information;
10+
use Magento\Framework\App\ObjectManager;
1111
use Magento\Framework\Component\ComponentRegistrar;
1212
use Magento\Framework\Console\Cli;
13+
use Magento\Framework\Exception\FileSystemException;
14+
use Magento\Framework\Filesystem\DirectoryList;
15+
use Magento\Framework\Filesystem\Directory\ReadFactory;
16+
use Magento\Framework\Filesystem\Directory\WriteFactory;
1317
use Symfony\Component\Console\Command\Command;
14-
use Symfony\Component\Console\Exception\InvalidArgumentException;
18+
use Symfony\Component\Console\Input\InputArgument;
1519
use Symfony\Component\Console\Input\InputInterface;
1620
use Symfony\Component\Console\Input\InputOption;
1721
use Symfony\Component\Console\Output\OutputInterface;
18-
use Symfony\Component\Console\Input\InputArgument;
19-
use Symfony\Component\Console\Helper\Table;
2022

2123
/**
2224
* Allows to generate setup patches
@@ -37,20 +39,45 @@ class GeneratePatchCommand extends Command
3739
*/
3840
private $componentRegistrar;
3941

42+
/**
43+
* @var DirectoryList
44+
*/
45+
private $directoryList;
46+
47+
/**
48+
* @var ReadFactory
49+
*/
50+
private $readFactory;
51+
52+
/**
53+
* @var WriteFactory
54+
*/
55+
private $writeFactory;
56+
4057
/**
4158
* GeneratePatchCommand constructor.
59+
*
4260
* @param ComponentRegistrar $componentRegistrar
61+
* @param DirectoryList|null $directoryList
62+
* @param ReadFactory|null $readFactory
63+
* @param WriteFactory|null $writeFactory
4364
*/
44-
public function __construct(ComponentRegistrar $componentRegistrar)
45-
{
65+
public function __construct(
66+
ComponentRegistrar $componentRegistrar,
67+
DirectoryList $directoryList = null,
68+
ReadFactory $readFactory = null,
69+
WriteFactory $writeFactory = null
70+
) {
4671
$this->componentRegistrar = $componentRegistrar;
72+
$this->directoryList = $directoryList ?: ObjectManager::getInstance()->get(DirectoryList::class);
73+
$this->readFactory = $readFactory ?: ObjectManager::getInstance()->get(ReadFactory::class);
74+
$this->writeFactory = $writeFactory ?: ObjectManager::getInstance()->get(WriteFactory::class);
75+
4776
parent::__construct();
4877
}
4978

5079
/**
51-
* @inheritdoc
52-
*
53-
* @throws InvalidArgumentException
80+
* Configures the current command.
5481
*/
5582
protected function configure()
5683
{
@@ -89,24 +116,21 @@ protected function configure()
89116
}
90117

91118
/**
92-
* Patch template
119+
* Execute command
93120
*
94-
* @return string
95-
*/
96-
private function getPatchTemplate(): string
97-
{
98-
// phpcs:ignore Magento2.Functions.DiscouragedFunction
99-
return file_get_contents(__DIR__ . '/patch_template.php.dist');
100-
}
101-
102-
/**
103-
* @inheritdoc
104-
* @throws \InvalidArgumentException
121+
* @param InputInterface $input
122+
* @param OutputInterface $output
123+
* @return int
124+
* @throws FileSystemException
105125
*/
106126
protected function execute(InputInterface $input, OutputInterface $output): int
107127
{
108128
$moduleName = $input->getArgument(self::MODULE_NAME);
109129
$patchName = $input->getArgument(self::INPUT_KEY_PATCH_NAME);
130+
$includeRevertMethod = false;
131+
if ($input->getOption(self::INPUT_KEY_IS_REVERTABLE)) {
132+
$includeRevertMethod = true;
133+
}
110134
$type = $input->getOption(self::INPUT_KEY_PATCH_TYPE);
111135
$modulePath = $this->componentRegistrar->getPath(ComponentRegistrar::MODULE, $moduleName);
112136
$preparedModuleName = str_replace('_', '\\', $moduleName);
@@ -115,18 +139,75 @@ protected function execute(InputInterface $input, OutputInterface $output): int
115139
$patchTemplateData = $this->getPatchTemplate();
116140
$patchTemplateData = str_replace('%moduleName%', $preparedModuleName, $patchTemplateData);
117141
$patchTemplateData = str_replace('%patchType%', $preparedType, $patchTemplateData);
118-
$patchTemplateData = str_replace('%patchInterface%', $patchInterface, $patchTemplateData);
119142
$patchTemplateData = str_replace('%class%', $patchName, $patchTemplateData);
120-
$patchDir = $patchToFile = $modulePath . '/Setup/Patch/' . $preparedType;
121143

122-
// phpcs:ignore Magento2.Functions.DiscouragedFunction
123-
if (!is_dir($patchDir)) {
124-
// phpcs:ignore Magento2.Functions.DiscouragedFunction
125-
mkdir($patchDir, 0777, true);
144+
$tplUseSchemaPatchInt = '%SchemaPatchInterface%';
145+
$tplUseDataPatchInt = '%useDataPatchInterface%';
146+
$valUseSchemaPatchInt = 'use Magento\Framework\Setup\Patch\SchemaPatchInterface;' . "\n";
147+
$valUseDataPatchInt = 'use Magento\Framework\Setup\Patch\DataPatchInterface;' . "\n";
148+
if ($type === 'schema') {
149+
$patchTemplateData = str_replace($tplUseSchemaPatchInt, $valUseSchemaPatchInt, $patchTemplateData);
150+
$patchTemplateData = str_replace($tplUseDataPatchInt, '', $patchTemplateData);
151+
} else {
152+
$patchTemplateData = str_replace($tplUseDataPatchInt, $valUseDataPatchInt, $patchTemplateData);
153+
$patchTemplateData = str_replace($tplUseSchemaPatchInt, '', $patchTemplateData);
126154
}
127-
$patchToFile = $patchDir . '/' . $patchName . '.php';
128-
// phpcs:ignore Magento2.Functions.DiscouragedFunction
129-
file_put_contents($patchToFile, $patchTemplateData);
155+
156+
$tplUsePatchRevertInt = '%usePatchRevertableInterface%';
157+
$tplImplementsInt = '%implementsInterfaces%';
158+
$tplRevertFunction = '%revertFunction%';
159+
$valUsePatchRevertInt = 'use Magento\Framework\Setup\Patch\PatchRevertableInterface;' . "\n";
160+
161+
if ($includeRevertMethod) {
162+
$valImplementsInt = <<<BOF
163+
164+
$patchInterface,
165+
PatchRevertableInterface
166+
BOF;
167+
$patchTemplateData = str_replace($tplUsePatchRevertInt, $valUsePatchRevertInt, $patchTemplateData);
168+
$patchTemplateData = str_replace(' ' . $tplImplementsInt, $valImplementsInt, $patchTemplateData);
169+
$patchTemplateData = str_replace($tplRevertFunction, $this->getRevertMethodTemplate(), $patchTemplateData);
170+
} else {
171+
$patchTemplateData = str_replace($tplUsePatchRevertInt, '', $patchTemplateData);
172+
$patchTemplateData = str_replace($tplImplementsInt, $patchInterface, $patchTemplateData);
173+
$patchTemplateData = str_replace($tplRevertFunction, '', $patchTemplateData);
174+
}
175+
176+
$patchDir = $modulePath . '/Setup/Patch/' . $preparedType;
177+
$patchFile = $patchName . '.php';
178+
179+
$fileWriter = $this->writeFactory->create($patchDir);
180+
$fileWriter->writeFile($patchFile, $patchTemplateData);
181+
182+
$outputPatchFile = str_replace($this->directoryList->getRoot() . '/', '', $patchDir . '/' . $patchFile);
183+
$output->writeln(__('Patch %1 has been successfully generated.', $outputPatchFile));
184+
130185
return Cli::RETURN_SUCCESS;
131186
}
187+
188+
/**
189+
* Returns patch template
190+
*
191+
* @return string
192+
* @throws FileSystemException
193+
*/
194+
private function getPatchTemplate(): string
195+
{
196+
$read = $this->readFactory->create(__DIR__ . '/');
197+
$content = $read->readFile('patch_template.php.dist');
198+
return $content;
199+
}
200+
201+
/**
202+
* Returns template of revert() function
203+
*
204+
* @return string
205+
* @throws FileSystemException
206+
*/
207+
private function getRevertMethodTemplate(): string
208+
{
209+
$read = $this->readFactory->create(__DIR__ . '/');
210+
$content = $read->readFile('template_revert_function.php.dist');
211+
return $content;
212+
}
132213
}

app/code/Magento/Developer/Console/Command/patch_template.php.dist

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,12 @@
66

77
namespace %moduleName%\Setup\Patch\%patchType%;
88

9-
use Magento\Framework\Setup\Patch\DataPatchInterface;
10-
use Magento\Framework\Setup\Patch\SchemaPatchInterface;
11-
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
129
use Magento\Framework\Setup\ModuleDataSetupInterface;
13-
10+
%useDataPatchInterface%%usePatchRevertableInterface%%SchemaPatchInterface%
1411
/**
1512
* Patch is mechanism, that allows to do atomic upgrade data changes
1613
*/
17-
class %class% implements
18-
%patchInterface%
14+
class %class% implements %implementsInterfaces%
1915
{
2016
/**
2117
* @var ModuleDataSetupInterface $moduleDataSetup
@@ -38,7 +34,7 @@ class %class% implements
3834
public function apply()
3935
{
4036
}
41-
37+
%revertFunction%
4238
/**
4339
* {@inheritdoc}
4440
*/
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
/**
3+
* @inheritdoc
4+
*/
5+
public function revert()
6+
{
7+
}

app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
2323
</before>
2424
<after>
25+
<actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteProduct">
26+
<argument name="product" value="DownloadableProduct"/>
27+
</actionGroup>
2528
<amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/>
2629
</after>
2730

app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminDataGridPaginationActionGroup.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
<click selector="{{AdminDataGridPaginationSection.perPageDropdown}}" stepKey="clickPerPageDropdown"/>
2020
<click selector="{{AdminDataGridPaginationSection.perPageOption(perPage)}}" stepKey="selectCustomPerPage"/>
21-
<waitForLoadingMaskToDisappear stepKey="waitForGridLoad"/>
21+
<waitForPageLoad stepKey="waitForGridLoad"/>
2222
</actionGroup>
2323

2424
<actionGroup name="adminDataGridSelectCustomPerPage">

dev/tests/integration/framework/Magento/TestFramework/Workaround/Cleanup/StaticProperties.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@
99
*/
1010
namespace Magento\TestFramework\Workaround\Cleanup;
1111

12+
use Magento\Framework\App\CacheInterface;
1213
use Magento\Framework\App\Utility\Files;
1314
use Magento\Framework\Component\ComponentRegistrar;
15+
use Magento\Framework\Serialize\SerializerInterface;
16+
use Magento\TestFramework\Helper\Bootstrap;
1417

18+
/**
19+
* Resets static properties of classes before each test run
20+
*/
1521
class StaticProperties
1622
{
1723
/**
@@ -42,6 +48,8 @@ class StaticProperties
4248
\Magento\Framework\Phrase::class,
4349
];
4450

51+
private const CACHE_NAME = 'integration_test_static_properties';
52+
4553
/**
4654
* Constructor
4755
*/
@@ -67,6 +75,7 @@ public function __construct()
6775
*
6876
* @param \ReflectionClass $reflectionClass
6977
* @return bool
78+
* phpcs:disable Magento2.Functions.StaticFunction
7079
*/
7180
protected static function _isClassCleanable(\ReflectionClass $reflectionClass)
7281
{
@@ -88,6 +97,7 @@ protected static function _isClassCleanable(\ReflectionClass $reflectionClass)
8897
*
8998
* @param string $classFile
9099
* @return bool
100+
* phpcs:disable Magento2.Functions.StaticFunction
91101
*/
92102
protected static function _isClassInCleanableFolders($classFile)
93103
{
@@ -112,8 +122,11 @@ protected static function _isClassInCleanableFolders($classFile)
112122
protected static $classes = [];
113123

114124
/**
125+
* Create a reflection class from the provided class
126+
*
115127
* @param string $class
116128
* @return \ReflectionClass
129+
* phpcs:disable Magento2.Functions.StaticFunction
117130
*/
118131
private static function getReflectionClass($class)
119132
{
@@ -125,7 +138,9 @@ private static function getReflectionClass($class)
125138

126139
/**
127140
* Restore static variables (after running controller test case)
141+
*
128142
* @TODO: refactor all code where objects are stored to static variables to use object manager instead
143+
* phpcs:ignore Magento2.Functions.StaticFunction
129144
*/
130145
public static function restoreStaticVariables()
131146
{
@@ -142,12 +157,27 @@ public static function restoreStaticVariables()
142157
/**
143158
* Backup static variables
144159
*
160+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
161+
* phpcs:disable Magento2.Functions.StaticFunction
145162
*/
146163
public static function backupStaticVariables()
147164
{
148165
if (count(self::$backupStaticVariables) > 0) {
149166
return;
150167
}
168+
169+
$objectManager = Bootstrap::getInstance()->getObjectManager();
170+
$cache = $objectManager->get(CacheInterface::class);
171+
$serializer = $objectManager->get(SerializerInterface::class);
172+
$cachedProperties = $cache->load(self::CACHE_NAME);
173+
174+
if ($cachedProperties) {
175+
self::$backupStaticVariables = $serializer->unserialize($cachedProperties);
176+
return;
177+
}
178+
179+
unset($cachedProperties, $objectManager);
180+
151181
$classFiles = array_filter(
152182
Files::init()->getPhpFiles(
153183
Files::INCLUDE_APP_CODE
@@ -156,12 +186,14 @@ public static function backupStaticVariables()
156186
),
157187
function ($classFile) {
158188
return StaticProperties::_isClassInCleanableFolders($classFile)
189+
// phpcs:ignore Magento2.Functions.DiscouragedFunction
159190
&& strpos(file_get_contents($classFile), ' static ') > 0;
160191
}
161192
);
162193
$namespacePattern = '/namespace [a-zA-Z0-9\\\\]+;/';
163194
$classPattern = '/\nclass [a-zA-Z0-9_]+/';
164195
foreach ($classFiles as $classFile) {
196+
// phpcs:ignore Magento2.Functions.DiscouragedFunction
165197
$code = file_get_contents($classFile);
166198
preg_match($namespacePattern, $code, $namespace);
167199
preg_match($classPattern, $code, $class);
@@ -187,17 +219,16 @@ function ($classFile) {
187219
}
188220
}
189221
}
222+
223+
$cache->save($serializer->serialize(self::$backupStaticVariables), self::CACHE_NAME);
190224
}
191225

192226
/**
193227
* Handler for 'startTestSuite' event
194-
*
195228
*/
196229
public function startTestSuite()
197230
{
198-
if (empty(self::$backupStaticVariables)) {
199-
self::backupStaticVariables();
200-
}
231+
self::backupStaticVariables();
201232
}
202233

203234
/**

0 commit comments

Comments
 (0)