From 07c014d221d0f1fe58efade48232057250a6cb7f Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Thu, 8 Apr 2021 12:25:54 -0500 Subject: [PATCH 01/29] MC-40601: Add support for data fixture classes --- .../Annotation/AbstractDataFixture.php | 97 ++++++-------- .../Fixture/DataFixtureDirectivesParser.php | 63 +++++++++ .../Fixture/DataFixtureInterface.php | 24 ++++ .../Fixture/DataFixturePathResolver.php | 81 ++++++++++++ .../Fixture/DataFixtureResultStorage.php | 70 ++++++++++ .../Fixture/Proxy/CallableDataFixture.php | 57 +++++++++ .../Fixture/Proxy/DataFixture.php | 69 ++++++++++ .../Fixture/Proxy/DataFixtureFactory.php | 73 +++++++++++ .../Fixture/Proxy/DataFixtureInterface.php | 17 +++ .../Fixture/Proxy/LegacyDataFixture.php | 78 +++++++++++ .../RevertibleDataFixtureInterface.php | 23 ++++ .../Override/Fixture/Applier/DataFixture.php | 56 +++++--- .../Workaround/Override/Fixture/Resolver.php | 92 ++----------- .../Test/Annotation/DataFixtureTest.php | 121 ++++++++---------- .../_files/sample_fixture_three.php | 8 ++ ....php => sample_fixture_three_rollback.php} | 2 +- .../Fixture/Applier/DataFixtureTest.php | 41 +++--- .../Override/Fixture/ResolverTest.php | 76 ----------- .../Annotation/DataFixtureTest.php | 114 +++++++++++++++++ .../TestFramework/DataFixtureTestStorage.php | 17 +++ .../Magento/TestFramework/Fixture/TestOne.php | 53 ++++++++ .../TestFramework/Fixture/TestThree.php | 41 ++++++ .../Magento/TestFramework/Fixture/TestTwo.php | 15 +++ 23 files changed, 969 insertions(+), 319 deletions(-) create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixturePathResolver.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureResultStorage.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/CallableDataFixture.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixture.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureFactory.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureInterface.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/LegacyDataFixture.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/_files/sample_fixture_three.php rename dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/_files/{sample_fixture_two_rollback.php => sample_fixture_three_rollback.php} (67%) create mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php create mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/DataFixtureTestStorage.php create mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestOne.php create mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php create mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestTwo.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 14799cd56e635..5dee419845a64 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -7,8 +7,13 @@ namespace Magento\TestFramework\Annotation; +use Magento\Framework\DataObject; +use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; +use Magento\TestFramework\Fixture\Proxy\DataFixtureFactory; +use Magento\TestFramework\Fixture\Proxy\DataFixtureInterface; +use Magento\TestFramework\Fixture\DataFixtureResultStorage; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; -use PHPUnit\Framework\Exception; use PHPUnit\Framework\TestCase; /** @@ -19,7 +24,7 @@ abstract class AbstractDataFixture /** * Fixtures that have been applied * - * @var array + * @var DataFixtureInterface[] */ protected $_appliedFixtures = []; @@ -46,7 +51,13 @@ protected function _getFixtures(TestCase $test, $scope = null) $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType($annotationKey); $annotations = $scope === null ? $this->getAnnotations($test) : $test->getAnnotations()[$scope]; - $existingFixtures = $annotations[$annotationKey] ?? []; + $existingFixtures = []; + $objectManager = Bootstrap::getObjectManager(); + $fixtureDirectivesParser = $objectManager->get(DataFixtureDirectivesParser::class); + foreach ($annotations[$annotationKey] ?? [] as $fixture) { + $existingFixtures[] = $fixtureDirectivesParser->parse($fixture); + } + /* Need to be applied even test does not have added fixtures because fixture can be added via config */ $this->fixtures[$annotationKey][$this->getTestKey($test)] = $resolver->applyDataFixtures( $test, @@ -71,35 +82,6 @@ protected function getAnnotations(TestCase $test): array return array_replace((array)$annotations['class'], (array)$annotations['method']); } - /** - * Execute single fixture script - * - * @param string|array $fixture - * @return void - * @throws \Exception - */ - protected function _applyOneFixture($fixture) - { - try { - if (is_callable($fixture)) { - call_user_func($fixture); - } else { - require $fixture; - } - } catch (\Exception $e) { - throw new Exception( - sprintf( - "Error in fixture: %s.\n %s\n %s", - json_encode($fixture), - $e->getMessage(), - $e->getTraceAsString() - ), - 500, - $e - ); - } - } - /** * Execute fixture scripts if any * @@ -109,17 +91,23 @@ protected function _applyOneFixture($fixture) */ protected function _applyFixtures(array $fixtures, TestCase $test) { - /** @var \Magento\TestFramework\Annotation\TestsIsolation $testsIsolation */ - $testsIsolation = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\TestFramework\Annotation\TestsIsolation::class - ); + $objectManager = Bootstrap::getObjectManager(); + /** @var TestsIsolation $testsIsolation */ + $testsIsolation = $objectManager->get(TestsIsolation::class); $dbIsolationState = $this->getDbIsolationState($test); $testsIsolation->createDbSnapshot($test, $dbIsolationState); - + $dataFixtureFactory = $objectManager->get(DataFixtureFactory::class); /* Execute fixture scripts */ - foreach ($fixtures as $oneFixture) { - $this->_applyOneFixture($oneFixture); - $this->_appliedFixtures[] = $oneFixture; + foreach ($fixtures as $key => $directives) { + if (is_callable([get_class($test), $directives['name']])) { + $directives['name'] = [get_class($test), $directives['name']]; + } + $fixture = $dataFixtureFactory->create($directives); + $data = $objectManager->create(DataObject::class, ['data' => $directives['data'] ?? []]); + $key = $directives['identifier'] ?? $key; + $result = $fixture->apply($data); + DataFixtureResultStorage::getInstance()->persist("$key", $result); + $this->_appliedFixtures[$key] = $fixture; } $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType(null); @@ -135,32 +123,19 @@ protected function _revertFixtures(?TestCase $test = null) { $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType($this->getAnnotation()); - $appliedFixtures = array_reverse($this->_appliedFixtures); - foreach ($appliedFixtures as $fixture) { - if (is_callable($fixture)) { - $fixture[1] .= 'Rollback'; - if (is_callable($fixture)) { - $this->_applyOneFixture($fixture); - } - } else { - $fileInfo = pathinfo($fixture); - $extension = ''; - if (isset($fileInfo['extension'])) { - $extension = '.' . $fileInfo['extension']; - } - $rollbackScript = $fileInfo['dirname'] . '/' . $fileInfo['filename'] . '_rollback' . $extension; - if (file_exists($rollbackScript)) { - $this->_applyOneFixture($rollbackScript); - } - } + $appliedFixtures = array_reverse($this->_appliedFixtures, true); + foreach ($appliedFixtures as $key => $fixture) { + $result = DataFixtureResultStorage::getInstance()->get("$key"); + $fixture->revert($result); } $this->_appliedFixtures = []; + DataFixtureResultStorage::getInstance()->flush(); $resolver->setCurrentFixtureType(null); if (null !== $test) { - /** @var \Magento\TestFramework\Annotation\TestsIsolation $testsIsolation */ - $testsIsolation = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\TestFramework\Annotation\TestsIsolation::class + /** @var TestsIsolation $testsIsolation */ + $testsIsolation = Bootstrap::getObjectManager()->get( + TestsIsolation::class ); $dbIsolationState = $this->getDbIsolationState($test); $testsIsolation->checkTestIsolation($test, $dbIsolationState); diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php new file mode 100644 index 0000000000000..74bcf84124faa --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php @@ -0,0 +1,63 @@ + $id, + 'name' => $name, + 'data' => $data, + ]; + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php new file mode 100644 index 0000000000000..4f030d85f52b8 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php @@ -0,0 +1,24 @@ +componentRegistrar = $componentRegistrar; + } + + /** + * Get the full path to the fixture + * + * @param string $fixture + * @return string + * @throws LocalizedException + */ + public function resolve(string $fixture): string + { + if ($this->isModuleAnnotation($fixture)) { + $filePath = $this->getModulePath($fixture); + } else { + $filePath = INTEGRATION_TESTS_DIR . '/testsuite/' . $fixture; + } + + return $filePath; + } + + /** + * Check if the fixture file is located in the module path + * + * @param string $fixture + * @return bool + */ + private function isModuleAnnotation(string $fixture): bool + { + return strpos($fixture, '::') !== false; + } + + /** + * Get the full path to the fixture in the module + * + * @param string $fixture + * @return string + * @throws LocalizedException + */ + private function getModulePath(string $fixture): string + { + [$moduleName, $fixtureFile] = explode('::', $fixture, 2); + + $modulePath = $this->componentRegistrar->getPath(ComponentRegistrar::MODULE, $moduleName); + + if ($modulePath === null) { + throw new LocalizedException(__('Can\'t find registered Module with name %1 .', $moduleName)); + } + + return $modulePath . '/' . ltrim($fixtureFile, '/'); + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureResultStorage.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureResultStorage.php new file mode 100644 index 0000000000000..31f46dc59de04 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureResultStorage.php @@ -0,0 +1,70 @@ +fixtures[$identifier] ?? null; + } + + /** + * Persist fixture result to the storage + * + * @param string $identifier + * @param DataObject|null $data + */ + public function persist(string $identifier, ?DataObject $data): void + { + $this->fixtures[$identifier] = $data; + } + + /** + * Flush the storage + */ + public function flush(): void + { + $this->fixtures = []; + } + + /** + * Get the unique instance of the storage + * + * @return DataFixtureResultStorage + */ + public static function getInstance(): DataFixtureResultStorage + { + if (self::$instance === null) { + self::$instance = new DataFixtureResultStorage(); + } + + return self::$instance; + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/CallableDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/CallableDataFixture.php new file mode 100644 index 0000000000000..5a2609d18cfcf --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/CallableDataFixture.php @@ -0,0 +1,57 @@ +callback = $callback; + } + + /** + * @inheritdoc + */ + public function apply(DataObject $data): ?DataObject + { + call_user_func($this->callback); + return null; + } + + /** + * @inheritdoc + */ + public function revert(?DataObject $data): void + { + $rollbackCallback = null; + if (is_array($this->callback)) { + $rollbackCallback = $this->callback; + $rollbackCallback[1] .= 'Rollback'; + } elseif (is_string($this->callback)) { + $rollbackCallback = $this->callback; + $rollbackCallback .= 'Rollback'; + } + if ($rollbackCallback && is_callable($rollbackCallback)) { + call_user_func($rollbackCallback); + } + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixture.php new file mode 100644 index 0000000000000..67f958159a9c8 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixture.php @@ -0,0 +1,69 @@ +objectManager = $objectManager; + $this->className = $className; + } + + /** + * @inheritdoc + */ + public function apply(DataObject $data): ?DataObject + { + return $this->getInstance()->apply($data); + } + + /** + * @inheritdoc + */ + public function revert(?DataObject $data): void + { + $fixture = $this->getInstance(); + if ($fixture instanceof RevertibleDataFixtureInterface) { + $fixture->revert($data); + } + } + + /** + * Get fixture class instance + * + * @return \Magento\TestFramework\Fixture\DataFixtureInterface + */ + private function getInstance(): \Magento\TestFramework\Fixture\DataFixtureInterface + { + return $this->objectManager->create($this->className); + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureFactory.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureFactory.php new file mode 100644 index 0000000000000..68ad446b080a2 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureFactory.php @@ -0,0 +1,73 @@ +objectManager = $objectManager; + $this->fixturePathResolver = $fixturePathResolver; + } + + /** + * Create new instance of data fixture + * + * @param array $directives + * @return DataFixtureInterface + */ + public function create(array $directives): DataFixtureInterface + { + if (is_callable($directives['name'])) { + $result = $this->objectManager->create( + CallableDataFixture::class, + [ + 'callback' => $directives['name'] + ] + ); + } elseif (class_exists($directives['name'])) { + $result = $this->objectManager->create( + DataFixture::class, + [ + 'className' => $directives['name'], + ] + ); + } else { + $result = $this->objectManager->create( + LegacyDataFixture::class, + [ + 'filePath' => $this->fixturePathResolver->resolve($directives['name']), + ] + ); + } + + return $result; + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureInterface.php new file mode 100644 index 0000000000000..a394aa381ecd0 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureInterface.php @@ -0,0 +1,17 @@ +filePath = $filePath; + } + + /** + * @inheritdoc + */ + public function apply(DataObject $data): ?DataObject + { + $this->execute($this->filePath); + return null; + } + + /** + * @inheritdoc + */ + public function revert(?DataObject $data): void + { + $fileInfo = pathinfo($this->filePath); + $extension = ''; + if (isset($fileInfo['extension'])) { + $extension = '.' . $fileInfo['extension']; + } + $rollbackScript = $fileInfo['dirname'] . DIRECTORY_SEPARATOR . $fileInfo['filename'] . '_rollback' . $extension; + if (file_exists($rollbackScript)) { + $this->execute($rollbackScript); + } + } + + /** + * Execute file + * + * @param string $filePath + */ + private function execute(string $filePath): void + { + try { + require $filePath; + } catch (\Exception $e) { + throw new Exception( + sprintf( + "Error in fixture: %s.\n %s\n %s", + $filePath, + $e->getMessage(), + $e->getTraceAsString() + ), + 500, + $e + ); + } + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php new file mode 100644 index 0000000000000..d208db26d7540 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php @@ -0,0 +1,23 @@ +replaceFixtures([$fixture], $replacedFixtures); + $fixture = $this->replaceFixtures([$this->getFixtureAsArray($fixture)], $replacedFixtures); - return is_array($fixture) ? reset($fixture) : $fixture; + return reset($fixture)['name']; } /** @@ -68,9 +68,11 @@ public function apply(array $fixtures): array */ private function replaceFixtures(array $fixtures, array $replacedFixtures): array { - foreach ($fixtures as $key => $fixture) { - if (!empty($replacedFixtures[$fixture])) { - $fixtures[$key] = $replacedFixtures[$fixture]; + if ($replacedFixtures) { + foreach ($fixtures as $key => $fixture) { + if (!empty($replacedFixtures[$fixture['name']])) { + $fixtures[$key] = $this->getFixtureAsArray($replacedFixtures[$fixture['name']]); + } } } @@ -86,9 +88,11 @@ private function replaceFixtures(array $fixtures, array $replacedFixtures): arra */ private function removeFixtures(array $fixtures, array $attributes): array { - $key = array_search($attributes['path'], $fixtures); - if ($key || $key === 0) { + try { + $key = $this->getFixturePosition($attributes['path'], $fixtures); unset($fixtures[$key]); + } catch (\Throwable $exception) { + //ignore exception } return $fixtures; @@ -106,22 +110,22 @@ private function sortFixtures(array $fixtures, array $attributes): array $beforeFixtures = []; $afterFixtures = []; if (!empty($attributes['before'])) { - $offset = $this->getFixturePosition($attributes['before'], $fixtures); - if ($attributes['before'] === '-' || $offset === 0) { - $beforeFixtures[] = $attributes['path']; + $offset = $attributes['before'] === '-' ? 0 : $this->getFixturePosition($attributes['before'], $fixtures); + if ($offset === 0) { + $beforeFixtures[] = $this->getFixtureAsArray($attributes['path']); } else { $fixtures = $this->insertFixture($fixtures, $attributes['path'], $offset); } } if (!empty($attributes['after'])) { if ($attributes['after'] === '-') { - $afterFixtures[] = $attributes['path']; + $afterFixtures[] = $this->getFixtureAsArray($attributes['path']); } else { $offset = $this->getFixturePosition($attributes['after'], $fixtures); $fixtures = $this->insertFixture($fixtures, $attributes['path'], $offset + 1); } } elseif (empty($attributes['before'])) { - $fixtures[] = $attributes['path']; + $fixtures[] = $this->getFixtureAsArray($attributes['path']); } return array_merge($beforeFixtures, $fixtures, $afterFixtures); @@ -137,13 +141,16 @@ private function sortFixtures(array $fixtures, array $attributes): array */ private function getFixturePosition(string $fixtureToFind, array $existingFixtures): int { - $offset = 0; - if ($fixtureToFind !== '-') { - $offset = array_search($fixtureToFind, $existingFixtures); - if ($offset === false) { - throw new LocalizedException(__('The fixture %1 does not exist in fixtures list', $fixtureToFind)); + $offset = false; + foreach ($existingFixtures as $key => $fixture) { + if ($fixture['name'] === $fixtureToFind) { + $offset = $key; + break; } } + if ($offset === false) { + throw new LocalizedException(__('The fixture %1 does not exist in fixtures list', $fixtureToFind)); + } return $offset; } @@ -160,8 +167,21 @@ private function insertFixture(array $fixtures, string $fixture, int $position): { return array_merge( array_slice($fixtures, 0, $position), - [$fixture], + [$this->getFixtureAsArray($fixture)], array_slice($fixtures, $position) ); } + + /** + * Creates an array with the supplied fixture name + * + * @param string $fixture + * @return string[] + */ + private function getFixtureAsArray(string $fixture): array + { + return [ + 'name' => $fixture + ]; + } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php index 33bf1011c5b7b..da4e04dd9f986 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php @@ -7,14 +7,15 @@ namespace Magento\TestFramework\Workaround\Override\Fixture; -use Magento\Framework\Component\ComponentRegistrar; -use Magento\Framework\Component\ComponentRegistrarInterface; +use Magento\Framework\DataObject; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Annotation\AdminConfigFixture; use Magento\TestFramework\Annotation\ConfigFixture; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Annotation\DataFixtureBeforeTransaction; +use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; +use Magento\TestFramework\Fixture\Proxy\DataFixtureFactory; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\ConfigInterface; use Magento\TestFramework\Workaround\Override\Fixture\Applier\AdminConfigFixture as AdminConfigFixtureApplier; @@ -49,6 +50,11 @@ class Resolver implements ResolverInterface /** @var string */ private $currentFixtureType = null; + /** + * @var DataFixtureFactory + */ + private $dataFixtureFactory; + /** * @param ConfigInterface $config */ @@ -56,6 +62,7 @@ public function __construct(ConfigInterface $config) { $this->config = $config; $this->objectManager = Bootstrap::getObjectManager(); + $this->dataFixtureFactory = $this->objectManager->create(DataFixtureFactory::class); } /** @@ -117,9 +124,8 @@ public function requireDataFixture(string $path): void } /** @var DataFixtureApplier $dataFixtureApplier */ $dataFixtureApplier = $this->getApplier($this->getCurrentTest(), $this->currentFixtureType); - $fixture = $this->processFixturePath($this->currentTest, $dataFixtureApplier->replace($path)); - - is_callable($fixture) ? call_user_func($fixture) : require $fixture; + $fixture = $this->dataFixtureFactory->create(['name' => $dataFixtureApplier->replace($path)]); + $fixture->apply($this->objectManager->create(DataObject::class)); } /** @@ -143,11 +149,7 @@ public function applyDataFixtures(TestCase $test, array $fixtures, string $fixtu $skipConfig = $this->config->getSkipConfiguration($test); if (!$skipConfig['skip']) { - $fixtures = $this->getApplier($test, $fixtureType)->apply($fixtures); - - foreach ($fixtures as $fixture) { - $result[] = $this->processFixturePath($test, $fixture); - } + $result = $this->getApplier($test, $fixtureType)->apply($fixtures); } return $result; @@ -179,16 +181,6 @@ protected function getApplierByFixtureType(string $fixtureType): ApplierInterfac return $applier; } - /** - * Get ComponentRegistrar object - * - * @return ComponentRegistrarInterface - */ - protected function getComponentRegistrar(): ComponentRegistrarInterface - { - return $this->objectManager->get(ComponentRegistrar::class); - } - /** * Get applier with prepared config by annotation type * @@ -214,64 +206,4 @@ private function getApplier(TestCase $test, string $fixtureType): ApplierInterfa return $applier; } - - /** - * Converts fixture path. - * - * @param TestCase $test - * @param string $fixture - * @return string|array - * @throws LocalizedException - */ - private function processFixturePath(TestCase $test, string $fixture) - { - if (strpos($fixture, '\\') !== false) { - // usage of a single directory separator symbol streamlines search across the source code - throw new LocalizedException(__('Directory separator "\\" is prohibited in fixture declaration.')); - } - - $fixtureMethod = [get_class($test), $fixture]; - if (is_callable($fixtureMethod)) { - $result = $fixtureMethod; - } elseif ($this->isModuleAnnotation($fixture)) { - $result = $this->getModulePath($fixture); - } else { - $result = INTEGRATION_TESTS_DIR . '/testsuite/' . $fixture; - } - - return $result; - } - - /** - * Check is the Annotation like Magento_InventoryApi::Test/_files/products.php - * - * @param string $fixture - * @return bool - */ - private function isModuleAnnotation(string $fixture): bool - { - return (strpos($fixture, '::') !== false); - } - - /** - * Resolve the fixture module annotation path. - * - * @param string $fixture - * @return string - * @throws LocalizedException - * @SuppressWarnings(PHPMD.StaticAccess) - */ - private function getModulePath(string $fixture): string - { - $componentRegistrar = $this->getComponentRegistrar(); - [$moduleName, $fixtureFile] = explode('::', $fixture, 2); - - $modulePath = $componentRegistrar->getPath(ComponentRegistrar::MODULE, $moduleName); - - if ($modulePath === null) { - throw new LocalizedException(__('Can\'t find registered Module with name %1 .', $moduleName)); - } - - return $modulePath . '/' . ltrim($fixtureFile, '/'); - } } diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php index 3abe6ea4e061d..81ba2d734a4bc 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php @@ -11,6 +11,8 @@ use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Event\Param\Transaction; +use Magento\TestFramework\Fixture\DataFixturePathResolver; +use Magento\TestFramework\Fixture\Proxy\DataFixtureFactory; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; use Magento\TestFramework\Annotation\TestsIsolation; @@ -45,11 +47,30 @@ protected function setUp(): void ->getMock(); /** @var ObjectManagerInterface|\PHPUnit\Framework\MockObject\MockObject $objectManager */ $objectManager = $this->getMockBuilder(ObjectManagerInterface::class) - ->setMethods(['get']) + ->setMethods(['get', 'create']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $objectManager->expects($this->atLeastOnce())->method('get')->with(TestsIsolation::class) - ->willReturn($this->testsIsolationMock); + + $fixturePathResolver = new DataFixturePathResolver(new ComponentRegistrar()); + $sharedInstances = [ + TestsIsolation::class => $this->testsIsolationMock, + //DataFixtureDirectivesParser::class => new DataFixtureDirectivesParser(), + DataFixtureFactory::class => new DataFixtureFactory($objectManager, $fixturePathResolver), + ]; + $objectManager->expects($this->atLeastOnce()) + ->method('get') + ->willReturnCallback( + function (string $type) use ($sharedInstances) { + return $sharedInstances[$type] ?? new $type(); + } + ); + $objectManager->expects($this->atLeastOnce()) + ->method('create') + ->willReturnCallback( + function (string $type, array $arguments = []) use ($sharedInstances) { + return new $type(...array_values($arguments)); + } + ); \Magento\TestFramework\Helper\Bootstrap::setObjectManager($objectManager); $directory = __DIR__; @@ -58,6 +79,16 @@ protected function setUp(): void } } + /** + * @inheritdoc + */ + protected function tearDown(): void + { + putenv('sample_fixture_one'); + putenv('sample_fixture_two'); + putenv('sample_fixture_three'); + } + /** * Dummy fixture * @@ -65,6 +96,7 @@ protected function setUp(): void */ public static function sampleFixtureOne(): void { + putenv('sample_fixture_one=1'); } /** @@ -74,6 +106,7 @@ public static function sampleFixtureOne(): void */ public static function sampleFixtureTwo(): void { + putenv('sample_fixture_two=2'); } /** @@ -83,6 +116,7 @@ public static function sampleFixtureTwo(): void */ public static function sampleFixtureTwoRollback(): void { + putenv('sample_fixture_two'); } /** @@ -104,7 +138,7 @@ public function testStartTestTransactionRequestClassAnnotation(): void /** * @magentoDataFixture sampleFixtureTwo - * @magentoDataFixture path/to/fixture/script.php + * @magentoDataFixture Magento/Test/Annotation/_files/sample_fixture_three.php * * @return void */ @@ -126,7 +160,7 @@ public function testStartTestTransactionRequestMethodAnnotation(): void /** * @magentoDbIsolation disabled * @magentoDataFixture sampleFixtureTwo - * @magentoDataFixture path/to/fixture/script.php + * @magentoDataFixture Magento/Test/Annotation/_files/sample_fixture_three.php * * @return void */ @@ -147,7 +181,7 @@ public function testDisabledDbIsolation(): void /** * @magentoDataFixture sampleFixtureTwo - * @magentoDataFixture path/to/fixture/script.php + * @magentoDataFixture Magento/Test/Annotation/_files/sample_fixture_three.php * * @return void */ @@ -172,32 +206,22 @@ public function testEndTestTransactionRequestMethodAnnotation(): void public function testStartTransactionClassAnnotation(): void { $this->createResolverMock(); - $this->object->expects($this->once()) - ->method('_applyOneFixture') - ->with([__CLASS__, 'sampleFixtureOne']); $this->object->startTransaction($this); + $this->assertEquals('1', getenv('sample_fixture_one')); } /** * @magentoDataFixture sampleFixtureTwo - * @magentoDataFixture path/to/fixture/script.php + * @magentoDataFixture Magento/Test/Annotation/_files/sample_fixture_three.php * * @return void */ public function testStartTransactionMethodAnnotation(): void { $this->createResolverMock(); - $this->object->expects($this->at(0)) - ->method('_applyOneFixture') - ->with([__CLASS__, 'sampleFixtureTwo']); - $this->object->expects( - $this->at(1) - )->method( - '_applyOneFixture' - )->with( - $this->stringEndsWith('path/to/fixture/script.php') - ); $this->object->startTransaction($this); + $this->assertEquals('2', getenv('sample_fixture_two')); + $this->assertEquals('3', getenv('sample_fixture_three')); } /** @@ -210,19 +234,15 @@ public function testRollbackTransactionRevertFixtureMethod(): void { $this->createResolverMock(); $this->object->startTransaction($this); - $this->object->expects( - $this->once() - )->method( - '_applyOneFixture' - )->with( - [__CLASS__, 'sampleFixtureTwoRollback'] - ); + $this->assertEquals('1', getenv('sample_fixture_one')); + $this->assertEquals('2', getenv('sample_fixture_two')); $this->object->rollbackTransaction(); + $this->assertEquals('1', getenv('sample_fixture_one')); + $this->assertFalse(getenv('sample_fixture_two')); } /** - * @magentoDataFixture path/to/fixture/script.php - * @magentoDataFixture Magento/Test/Annotation/_files/sample_fixture_two.php + * @magentoDataFixture Magento/Test/Annotation/_files/sample_fixture_three.php * * @return void */ @@ -230,18 +250,13 @@ public function testRollbackTransactionRevertFixtureFile(): void { $this->createResolverMock(); $this->object->startTransaction($this); - $this->object->expects( - $this->once() - )->method( - '_applyOneFixture' - )->with( - $this->stringEndsWith('sample_fixture_two_rollback.php') - ); + $this->assertEquals('3', getenv('sample_fixture_three')); $this->object->rollbackTransaction(); + $this->assertFalse(getenv('sample_fixture_three')); } /** - * @magentoDataFixture Foo_DataFixtureDummy::Test/Integration/foo.php + * @magentoDataFixture Foo_DataFixtureDummy::Annotation/_files/sample_fixture_three.php * * @return void * @SuppressWarnings(PHPMD.StaticAccess) @@ -251,12 +266,11 @@ public function testModuleDataFixture(): void ComponentRegistrar::register( ComponentRegistrar::MODULE, 'Foo_DataFixtureDummy', - __DIR__ + dirname(__DIR__) ); $this->createResolverMock(); - $this->object->expects($this->once())->method('_applyOneFixture') - ->with(__DIR__ . '/Test/Integration/foo.php'); $this->object->startTransaction($this); + $this->assertEquals('3', getenv('sample_fixture_three')); } /** @@ -269,36 +283,13 @@ private function createResolverMock(): void { $mock = $this->getMockBuilder(Resolver::class) ->disableOriginalConstructor() - ->setMethods(['applyDataFixtures', 'getComponentRegistrar']) + ->onlyMethods(['applyDataFixtures']) ->getMock(); - $mock->expects($this->any())->method('getComponentRegistrar') - ->willReturn(new ComponentRegistrar()); $reflection = new \ReflectionClass(Resolver::class); $reflectionProperty = $reflection->getProperty('instance'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue(Resolver::class, $mock); - $reflectionMethod = $reflection->getMethod('processFixturePath'); - $reflectionMethod->setAccessible(true); - $annotatedFixtures = $this->getFixturesAnnotations(); - $resolvedFixtures = []; - foreach ($annotatedFixtures as $fixture) { - $resolvedFixtures[] = $reflectionMethod->invoke($mock, $this, $fixture); - } $mock->method('applyDataFixtures') - ->willReturn($resolvedFixtures); - } - - /** - * Prepare mock method return value - * - * @return array - */ - private function getFixturesAnnotations(): array - { - $reflection = new \ReflectionClass(DataFixture::class); - $reflectionMethod = $reflection->getMethod('getAnnotations'); - $reflectionMethod->setAccessible(true); - - return $reflectionMethod->invoke($this->object, $this)['magentoDataFixture']; + ->willReturnArgument(1); } } diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/_files/sample_fixture_three.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/_files/sample_fixture_three.php new file mode 100644 index 0000000000000..d93bf932e3b5c --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/_files/sample_fixture_three.php @@ -0,0 +1,8 @@ + [ - 'existing_fixtures' => ['fixture'], + 'existing_fixtures' => [['name' => 'fixture']], 'config' => [ [ 'path' => 'added_fixture', @@ -90,10 +90,10 @@ public function fixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => ['added_fixture', 'fixture'], + 'expected_order' => [['name' => 'added_fixture'], ['name' => 'fixture']], ], 'sort_fixtures_after_all' => [ - 'existing_fixtures' => ['fixture'], + 'existing_fixtures' => [['name' => 'fixture']], 'config' => [ [ 'path' => 'added_fixture', @@ -103,10 +103,10 @@ public function fixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => ['fixture', 'added_fixture'], + 'expected_order' => [['name' => 'fixture'], ['name' => 'added_fixture']], ], 'sort_fixture_before_specific' => [ - 'existing_fixtures' => ['fixture1', 'fixture2'], + 'existing_fixtures' => [['name' => 'fixture1'], ['name' => 'fixture2']], 'config' => [ [ 'path' => 'added_fixture', @@ -116,10 +116,10 @@ public function fixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => ['fixture1', 'added_fixture', 'fixture2'], + 'expected_order' => [['name' => 'fixture1'], ['name' => 'added_fixture'], ['name' => 'fixture2']], ], 'sort_fixture_after_specific' => [ - 'existing_fixtures' => ['fixture1', 'fixture2', 'fixture3'], + 'existing_fixtures' => [['name' => 'fixture1'], ['name' => 'fixture2'], ['name' => 'fixture3']], 'config' => [ [ 'path' => 'added_fixture', @@ -129,7 +129,12 @@ public function fixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => ['fixture1', 'fixture2', 'added_fixture', 'fixture3'], + 'expected_order' => [ + ['name' => 'fixture1'], + ['name' => 'fixture2'], + ['name' => 'added_fixture'], + ['name' => 'fixture3'] + ], ], ]; } @@ -155,7 +160,7 @@ public function removeFixturesProvider(): array { return [ 'remove_fixture' => [ - 'existing_fixtures' => ['fixture', 'fixture2'], + 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -165,10 +170,10 @@ public function removeFixturesProvider(): array 'remove' => true, ] ], - 'expected_order' => ['fixture2'], + 'expected_order' => [['name' => 'fixture2']], ], 'remove_one_of_same_fixtures' => [ - 'existing_fixtures' => ['fixture', 'fixture', 'fixture2'], + 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture'], ['name' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -178,10 +183,10 @@ public function removeFixturesProvider(): array 'remove' => true, ] ], - 'expected_order' => ['fixture', 'fixture2'], + 'expected_order' => [['name' => 'fixture'], ['name' => 'fixture2']], ], 'remove_all_of_same_fixtures' => [ - 'existing_fixtures' => ['fixture', 'fixture', 'fixture2'], + 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture'], ['name' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -198,7 +203,7 @@ public function removeFixturesProvider(): array 'remove' => true, ] ], - 'expected_order' => ['fixture2'], + 'expected_order' => [['name' => 'fixture2']], ], ]; } @@ -224,7 +229,7 @@ public function replaceFixturesProvider(): array { return [ 'replace_one_fixture' => [ - 'existing_fixtures' => ['fixture', 'fixture2'], + 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -234,10 +239,10 @@ public function replaceFixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => ['new_fixture', 'fixture2'], + 'expected_order' => [['name' => 'new_fixture'], ['name' => 'fixture2']], ], 'replace_all_fixture' => [ - 'existing_fixtures' => ['fixture', 'fixture', 'fixture2'], + 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture'], ['name' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -247,7 +252,7 @@ public function replaceFixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => ['new_fixture', 'new_fixture', 'fixture2'], + 'expected_order' => [['name' => 'new_fixture'], ['name' => 'new_fixture'], ['name' => 'fixture2']], ], ]; } diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Override/Fixture/ResolverTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Override/Fixture/ResolverTest.php index 2531cc41f4abc..f6494d128c95f 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Override/Fixture/ResolverTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Override/Fixture/ResolverTest.php @@ -18,65 +18,6 @@ */ class ResolverTest extends TestCase { - /** - * Dummy fixture - * - * @return void - */ - public static function dummyFixture(): void - { - } - - /** - * @return void - */ - public function testProcessFixturePath(): void - { - if (!defined('INTEGRATION_TESTS_DIR')) { - define('INTEGRATION_TESTS_DIR', __DIR__); - } - $fixture = $this->processFixturePath('Some/Module/_files/some_fixture.php'); - $this->assertEquals( - INTEGRATION_TESTS_DIR . '/testsuite/' . 'Some/Module/_files/some_fixture.php', - $fixture - ); - } - - /** - * @return void - */ - public function testProcessFixturePathCallableFixture(): void - { - $fixture = $this->processFixturePath('dummyFixture'); - $this->assertTrue(is_array($fixture)); - $this->assertNotFalse(array_search('dummyFixture', $fixture)); - $this->assertNotFalse(array_search(get_class($this), $fixture)); - } - - /** - * @return void - */ - public function testProcessFixturePathNotRegisteredModule(): void - { - $this->expectException(LocalizedException::class); - $this->expectExceptionMessage('Can\'t find registered Module with name Some_Module .'); - $this->processFixturePath('Some_Module::some_fixture.php'); - } - - /** - * @return void - */ - public function testProcessFixturePathRegisteredModule(): void - { - ComponentRegistrar::register( - ComponentRegistrar::MODULE, - 'Some_Module', - __DIR__ - ); - $fixture = $this->processFixturePath('Some_Module::some_fixture.php'); - $this->assertStringEndsWith('some_fixture.php', $fixture); - } - /** * @return void */ @@ -103,23 +44,6 @@ public function testRequireDataFixture(): void $resolver->requireDataFixture('path/to/fixture.php'); } - /** - * Invoke resolver processFixturePath method - * - * @param string $annotation - * @return string|array - */ - private function processFixturePath(string $annotation) - { - $resolverMock = $this->createResolverMock(); - $resolverMock->method('getComponentRegistrar')->willReturn(new ComponentRegistrar()); - $reflection = new \ReflectionClass(Resolver::class); - $reflectionMethod = $reflection->getMethod('processFixturePath'); - $reflectionMethod->setAccessible(true); - - return $reflectionMethod->invoke($resolverMock, $this, $annotation); - } - /** * Create mock for resolver object * diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php b/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php new file mode 100644 index 0000000000000..7d73d6ba136f8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php @@ -0,0 +1,114 @@ +dataStorage = Bootstrap::getObjectManager()->get(DataFixtureTestStorage::class); + } + + /** + * @magentoDataFixture afterTestFixtureClass + * @magentoDataFixture Magento\TestFramework\Fixture\TestOne + * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo + */ + public function testFixtureClass(): void + { + $this->assertEquals( + [ + 'Magento\TestFramework\Fixture\TestOne' => true, + 'Magento\TestFramework\Fixture\TestTwo' => true + ], + $this->dataStorage->getData('fixtures') + ); + } + + /** + * @magentoDataFixture afterTestFixtureClass + * @magentoDataFixture Magento\TestFramework\Fixture\TestOne with:{"test1": "value1", "test11": "value11"} + * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo with:{"test2": "value2"} + * @magentoDataFixture Magento\TestFramework\Fixture\TestThree with:{"key": "test11", "value": "value12"} + */ + public function testFixtureClassWithParameters(): void + { + $this->assertEquals( + [ + 'Magento\TestFramework\Fixture\TestOne' => true, + 'Magento\TestFramework\Fixture\TestTwo' => true, + 'test1' => 'value1', + 'test11' => 'value12', + 'test2' => 'value2', + ], + $this->dataStorage->getData('fixtures') + ); + } + + /** + * @magentoDataFixture afterTestFixtureClass + * @magentoDataFixture Magento\TestFramework\Fixture\TestOne with:{"test1": "value1", "test11": "value11"} as:test1 + * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo with:{"test2": "value2"} as:test2 + * @magentoDataFixture Magento\TestFramework\Fixture\TestThree with:{"key": "test11", "value": "value12"} as:test3 + */ + public function testFixtureClassWithParametersAndAlias(): void + { + $this->assertEquals( + [ + 'Magento\TestFramework\Fixture\TestOne' => true, + 'test1' => 'value1', + 'test11' => 'value11', + ], + DataFixtureResultStorage::getInstance()->get('test1')->getData() + ); + $this->assertEquals( + [ + 'Magento\TestFramework\Fixture\TestTwo' => true, + 'test2' => 'value2', + ], + DataFixtureResultStorage::getInstance()->get('test2')->getData() + ); + $this->assertNull( + DataFixtureResultStorage::getInstance()->get('test3') + ); + $this->assertEquals( + [ + 'Magento\TestFramework\Fixture\TestOne' => true, + 'Magento\TestFramework\Fixture\TestTwo' => true, + 'test1' => 'value1', + 'test11' => 'value12', + 'test2' => 'value2', + ], + $this->dataStorage->getData('fixtures') + ); + } + + public static function afterTestFixtureClass(): void + { + self::assertEmpty(Bootstrap::getObjectManager()->get(DataFixtureTestStorage::class)->getData('fixtures')); + } + + public static function afterTestFixtureClassRollback(): void + { + self::assertEmpty(Bootstrap::getObjectManager()->get(DataFixtureTestStorage::class)->getData('fixtures')); + } +} diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/DataFixtureTestStorage.php b/dev/tests/integration/testsuite/Magento/TestFramework/DataFixtureTestStorage.php new file mode 100644 index 0000000000000..ec6c029d57f54 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/TestFramework/DataFixtureTestStorage.php @@ -0,0 +1,17 @@ +storage = $storage; + } + + /** + * @inheritdoc + */ + public function apply(DataObject $data): ?DataObject + { + $fixtures = $this->storage->getData('fixtures') ?? []; + $result = new DataObject(array_merge([get_class($this) => true], $data->getData())); + $this->storage->setData('fixtures', array_merge($fixtures, $result->getData())); + return $result; + } + + /** + * @inheritdoc + */ + public function revert(?DataObject $data): void + { + $fixtures = $this->storage->getData('fixtures') ?? []; + foreach (array_keys($data->getData()) as $key) { + unset($fixtures[$key]); + } + $this->storage->setData('fixtures', $fixtures); + } +} diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php new file mode 100644 index 0000000000000..168a812eb2bbe --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php @@ -0,0 +1,41 @@ +storage = $storage; + } + + /** + * @inheritdoc + */ + public function apply(DataObject $data): ?DataObject + { + $fixtures = $this->storage->getData('fixtures') ?? []; + $fixtures[$data->getData('key')] = $data->getData('value'); + $this->storage->setData('fixtures', $fixtures); + return null; + } +} diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestTwo.php b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestTwo.php new file mode 100644 index 0000000000000..575e2a0db97eb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestTwo.php @@ -0,0 +1,15 @@ + Date: Fri, 16 Apr 2021 16:01:23 -0500 Subject: [PATCH 02/29] MC-40601: Add support for data fixture classes - Replace DataObject with array in DataFixtureInterface and RevertibleDataFixtureInterface --- .../TestFramework/Annotation/AbstractDataFixture.php | 8 ++++---- .../TestFramework/Fixture/DataFixtureInterface.php | 8 +++----- .../Fixture/Proxy/CallableDataFixture.php | 6 ++---- .../TestFramework/Fixture/Proxy/DataFixture.php | 5 ++--- .../TestFramework/Fixture/Proxy/LegacyDataFixture.php | 5 ++--- .../Fixture/RevertibleDataFixtureInterface.php | 6 ++---- .../Workaround/Override/Fixture/Resolver.php | 2 +- .../Magento/TestFramework/Fixture/TestOne.php | 11 +++++------ .../Magento/TestFramework/Fixture/TestThree.php | 5 ++--- 9 files changed, 23 insertions(+), 33 deletions(-) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 5dee419845a64..74408999b2d41 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -103,10 +103,10 @@ protected function _applyFixtures(array $fixtures, TestCase $test) $directives['name'] = [get_class($test), $directives['name']]; } $fixture = $dataFixtureFactory->create($directives); - $data = $objectManager->create(DataObject::class, ['data' => $directives['data'] ?? []]); $key = $directives['identifier'] ?? $key; - $result = $fixture->apply($data); - DataFixtureResultStorage::getInstance()->persist("$key", $result); + $result = $fixture->apply($directives['data'] ?? []); + $resultObj = $result !== null ? $objectManager->create(DataObject::class, ['data' => $result]) : null; + DataFixtureResultStorage::getInstance()->persist("$key", $resultObj); $this->_appliedFixtures[$key] = $fixture; } $resolver = Resolver::getInstance(); @@ -126,7 +126,7 @@ protected function _revertFixtures(?TestCase $test = null) $appliedFixtures = array_reverse($this->_appliedFixtures, true); foreach ($appliedFixtures as $key => $fixture) { $result = DataFixtureResultStorage::getInstance()->get("$key"); - $fixture->revert($result); + $fixture->revert($result ? $result->getData() : []); } $this->_appliedFixtures = []; DataFixtureResultStorage::getInstance()->flush(); diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php index 4f030d85f52b8..ac0c2452179d6 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php @@ -7,8 +7,6 @@ namespace Magento\TestFramework\Fixture; -use Magento\Framework\DataObject; - /** * Interface for data fixtures */ @@ -17,8 +15,8 @@ interface DataFixtureInterface /** * Apply fixture data * - * @param DataObject $data - * @return DataObject + * @param array $data + * @return array|null */ - public function apply(DataObject $data): ?DataObject; + public function apply(array $data = []): ?array; } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/CallableDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/CallableDataFixture.php index 5a2609d18cfcf..7e967aba74cef 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/CallableDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/CallableDataFixture.php @@ -7,8 +7,6 @@ namespace Magento\TestFramework\Fixture\Proxy; -use Magento\Framework\DataObject; - /** * Callable data fixture type */ @@ -31,7 +29,7 @@ public function __construct( /** * @inheritdoc */ - public function apply(DataObject $data): ?DataObject + public function apply(array $data = []): ?array { call_user_func($this->callback); return null; @@ -40,7 +38,7 @@ public function apply(DataObject $data): ?DataObject /** * @inheritdoc */ - public function revert(?DataObject $data): void + public function revert(array $data = []): void { $rollbackCallback = null; if (is_array($this->callback)) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixture.php index 67f958159a9c8..0695c209c41bd 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixture.php @@ -7,7 +7,6 @@ namespace Magento\TestFramework\Fixture\Proxy; -use Magento\Framework\DataObject; use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; @@ -41,7 +40,7 @@ public function __construct( /** * @inheritdoc */ - public function apply(DataObject $data): ?DataObject + public function apply(array $data = []): ?array { return $this->getInstance()->apply($data); } @@ -49,7 +48,7 @@ public function apply(DataObject $data): ?DataObject /** * @inheritdoc */ - public function revert(?DataObject $data): void + public function revert(array $data = []): void { $fixture = $this->getInstance(); if ($fixture instanceof RevertibleDataFixtureInterface) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/LegacyDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/LegacyDataFixture.php index 4bdf78e7bc9d9..219d59cf55486 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/LegacyDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/LegacyDataFixture.php @@ -7,7 +7,6 @@ namespace Magento\TestFramework\Fixture\Proxy; -use Magento\Framework\DataObject; use PHPUnit\Framework\Exception; /** @@ -31,7 +30,7 @@ public function __construct(string $filePath) /** * @inheritdoc */ - public function apply(DataObject $data): ?DataObject + public function apply(array $data = []): ?array { $this->execute($this->filePath); return null; @@ -40,7 +39,7 @@ public function apply(DataObject $data): ?DataObject /** * @inheritdoc */ - public function revert(?DataObject $data): void + public function revert(array $data = []): void { $fileInfo = pathinfo($this->filePath); $extension = ''; diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php index d208db26d7540..e1a35a8bd9c87 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php @@ -7,8 +7,6 @@ namespace Magento\TestFramework\Fixture; -use Magento\Framework\DataObject; - /** * Interface for revertible data fixtures */ @@ -17,7 +15,7 @@ interface RevertibleDataFixtureInterface extends DataFixtureInterface /** * Revert fixture data * - * @param DataObject|null $data + * @param array $data */ - public function revert(?DataObject $data): void; + public function revert(array $data = []): void; } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php index da4e04dd9f986..4ef3f0ba3a7bb 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php @@ -125,7 +125,7 @@ public function requireDataFixture(string $path): void /** @var DataFixtureApplier $dataFixtureApplier */ $dataFixtureApplier = $this->getApplier($this->getCurrentTest(), $this->currentFixtureType); $fixture = $this->dataFixtureFactory->create(['name' => $dataFixtureApplier->replace($path)]); - $fixture->apply($this->objectManager->create(DataObject::class)); + $fixture->apply(); } /** diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestOne.php b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestOne.php index dc009a1a976e5..907c6dca1f567 100644 --- a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestOne.php +++ b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestOne.php @@ -7,7 +7,6 @@ namespace Magento\TestFramework\Fixture; -use Magento\Framework\DataObject; use Magento\TestFramework\DataFixtureTestStorage; /** @@ -31,21 +30,21 @@ public function __construct(DataFixtureTestStorage $storage) /** * @inheritdoc */ - public function apply(DataObject $data): ?DataObject + public function apply(array $data = []): ?array { $fixtures = $this->storage->getData('fixtures') ?? []; - $result = new DataObject(array_merge([get_class($this) => true], $data->getData())); - $this->storage->setData('fixtures', array_merge($fixtures, $result->getData())); + $result = array_merge([get_class($this) => true], $data); + $this->storage->setData('fixtures', array_merge($fixtures, $result)); return $result; } /** * @inheritdoc */ - public function revert(?DataObject $data): void + public function revert(array $data = []): void { $fixtures = $this->storage->getData('fixtures') ?? []; - foreach (array_keys($data->getData()) as $key) { + foreach (array_keys($data) as $key) { unset($fixtures[$key]); } $this->storage->setData('fixtures', $fixtures); diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php index 168a812eb2bbe..c83de390f3398 100644 --- a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php +++ b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php @@ -7,7 +7,6 @@ namespace Magento\TestFramework\Fixture; -use Magento\Framework\DataObject; use Magento\TestFramework\DataFixtureTestStorage; /** @@ -31,10 +30,10 @@ public function __construct(DataFixtureTestStorage $storage) /** * @inheritdoc */ - public function apply(DataObject $data): ?DataObject + public function apply(array $data = []): ?array { $fixtures = $this->storage->getData('fixtures') ?? []; - $fixtures[$data->getData('key')] = $data->getData('value'); + $fixtures[$data['key']] = $data['value']; $this->storage->setData('fixtures', $fixtures); return null; } From d00dda08868759daba66a8a807117820031779c7 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Wed, 21 Apr 2021 10:08:14 -0500 Subject: [PATCH 03/29] MC-40601: Add support for data fixture classes - Add product fixture --- .../Catalog/Fixture/CreateSimpleProduct.php | 104 ++++++++++++++++++ .../Model/ResourceModel/ProductTest.php | 6 +- 2 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php new file mode 100644 index 0000000000000..f0b0b994e1ce1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -0,0 +1,104 @@ + Type::TYPE_SIMPLE, + 'attribute_set_id' => 4, + 'name' => 'Simple Product', + 'sku' => 'simple', + 'price' => 10, + 'weight' => 1, + 'visibility' => Visibility::VISIBILITY_BOTH, + 'status' => Status::STATUS_ENABLED, + 'custom_attributes' => [ + [ + 'attribute_code' => 'tax_class_id', + 'value' => '2', + ] + ], + 'extension_attributes' => [ + 'website_ids' => [1], + 'stock_item' => [ + 'use_config_manage_stock' => true, + 'qty' => 100, + 'is_qty_decimal' => false, + 'is_in_stock' => true, + ] + ], + ]; + + /** + * @param ProductRepositoryInterface $productRepository + * @param ServiceInputProcessor $productHydrator + */ + public function __construct( + ProductRepositoryInterface $productRepository, + ServiceInputProcessor $productHydrator + ) { + $this->productRepository = $productRepository; + $this->productHydrator = $productHydrator; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?array + { + /** @var $product Product */ + $data = array_merge($this->defaultData, $data); + $product = $this->productHydrator->convertValue($data, ProductInterface::class); + $this->productRepository->save($product); + + return [ + 'product' => $product + ]; + } + + /** + * @inheritdoc + */ + public function revert(array $data = []): void + { + try { + /** @var $product Product */ + $product = $data['product']; + $this->productRepository->deleteById($product->getSku()); + } catch (NoSuchEntityException $e) { + //ignore + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index ab810aec2c835..f163149ec5ff1 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -6,10 +6,6 @@ namespace Magento\Catalog\Model\ResourceModel; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\ResourceModel\Product\Action; -use Magento\Eav\Api\Data\AttributeSetInterface; -use Magento\Eav\Model\AttributeSetRepository; -use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Eav\Model\GetAttributeSetByName; use Magento\TestFramework\Helper\Bootstrap; @@ -56,7 +52,7 @@ protected function setUp(): void /** * Checks a possibility to retrieve product raw attribute value. * - * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct */ public function testGetAttributeRawValue() { From 7d3eb7bb55baf302073f69b4d9756c3ffb1c7ad6 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Wed, 21 Apr 2021 14:29:24 -0500 Subject: [PATCH 04/29] MC-40601: Add support for data fixture classes - Add api data fixture --- .../Fixture/AbstractApiDataFixture.php | 76 ++++++++++++++ .../Fixture/ApiDataFixtureInterface.php | 55 +++++++++++ .../AddProductAttributeToAttributeSet.php | 55 +++++++++++ .../Fixture/CreateProductAttribute.php | 99 +++++++++++++++++++ .../Catalog/Fixture/CreateSimpleProduct.php | 79 +++++++-------- .../Model/ResourceModel/ProductTest.php | 50 ++++++---- 6 files changed, 351 insertions(+), 63 deletions(-) create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php new file mode 100644 index 0000000000000..95c6fe3ff678e --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php @@ -0,0 +1,76 @@ +objectManager = $objectManager; + $this->serviceInputProcessor = $serviceInputProcessor; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?array + { + $service = $this->getService(); + $serviceInstance = $this->objectManager->get($service[ApiDataFixtureInterface::SERVICE_CLASS]); + $params = $this->serviceInputProcessor->process( + $service[ApiDataFixtureInterface::SERVICE_CLASS], + $service[ApiDataFixtureInterface::SERVICE_METHOD], + $this->processServiceMethodParameters($data) + ); + $data = call_user_func_array([$serviceInstance, $service[ApiDataFixtureInterface::SERVICE_METHOD]], $params); + + return $this->processServiceResult($data); + } + + /** + * @inheritdoc + */ + public function revert(array $data = []): void + { + $service = $this->getRollbackService(); + $serviceInstance = $this->objectManager->get($service[ApiDataFixtureInterface::SERVICE_CLASS]); + $params = $this->serviceInputProcessor->process( + $service[ApiDataFixtureInterface::SERVICE_CLASS], + $service[ApiDataFixtureInterface::SERVICE_METHOD], + $this->processRollbackServiceMethodParameters($data) + ); + try { + call_user_func_array([$serviceInstance, $service[ApiDataFixtureInterface::SERVICE_METHOD]], $params); + } catch (NoSuchEntityException $exception) { + //ignore + } + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php new file mode 100644 index 0000000000000..3460397fa2bbe --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php @@ -0,0 +1,55 @@ +eavSetup = $eavSetup; + $this->eavConfig = $eavConfig; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?array + { + $attributeSetId = $data['attribute_set_id'] ?? $this->eavSetup->getAttributeSetId(Product::ENTITY, 'Default'); + $groupId = $data['group_id'] ?? $this->eavSetup->getDefaultAttributeGroupId(Product::ENTITY, $attributeSetId); + $attributeCode = $data['attribute_code'] ?? 'fixture_attribute'; + $this->eavSetup->addAttributeToGroup(Product::ENTITY, $attributeSetId, $groupId, $attributeCode); + $this->eavConfig->clear(); + + return []; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php new file mode 100644 index 0000000000000..7e87b68c7b9f1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php @@ -0,0 +1,99 @@ + false, + 'is_html_allowed_on_front' => true, + 'used_for_sort_by' => false, + 'is_filterable' => false, + 'is_filterable_in_search' => false, + 'is_used_in_grid' => true, + 'is_visible_in_grid' => true, + 'is_filterable_in_grid' => true, + 'position' => 0, + 'apply_to' => [], + 'is_searchable' => '0', + 'is_visible_in_advanced_search' => '0', + 'is_comparable' => '0', + 'is_used_for_promo_rules' => '0', + 'is_visible_on_front' => '0', + 'used_in_product_listing' => '0', + 'is_visible' => true, + 'scope' => 'store', + 'attribute_code' => 'fixture_attribute', + 'frontend_input' => 'text', + 'entity_type_id' => '4', + 'is_required' => false, + 'options' => [], + 'is_user_defined' => true, + 'default_frontend_label' => 'Fixture Attribute', + 'frontend_labels' => [], + 'backend_type' => 'varchar', + 'is_unique' => '0', + 'validation_rules' => [] + ]; + + /** + * @inheritdoc + */ + public function getService(): array + { + return [ + ApiDataFixtureInterface::SERVICE_CLASS => ProductAttributeRepositoryInterface::class, + ApiDataFixtureInterface::SERVICE_METHOD => 'save', + ]; + } + + /** + * @inheritdoc + */ + public function getRollbackService(): array + { + return [ + ApiDataFixtureInterface::SERVICE_CLASS => ProductAttributeRepositoryInterface::class, + ApiDataFixtureInterface::SERVICE_METHOD => 'deleteById', + ]; + } + + /** + * @inheritdoc + */ + public function processServiceMethodParameters(array $data): array + { + return [ + 'attribute' => array_merge(self::DEFAULT_DATA, $data) + ]; + } + + /** + * @inheritdoc + */ + public function processRollbackServiceMethodParameters(array $data): array + { + return [ + 'attributeCode' => $data['attribute']->getAttributeCode() + ]; + } + + /** + * @inheritdoc + */ + public function processServiceResult($data): array + { + return [ + 'attribute' => $data + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index f0b0b994e1ce1..38e4a464792c0 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -7,35 +7,19 @@ namespace Magento\Catalog\Fixture; -use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Catalog\Model\Product\Type; use Magento\Catalog\Model\Product\Visibility; -use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Webapi\ServiceInputProcessor; -use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; +use Magento\TestFramework\Fixture\AbstractApiDataFixture; +use Magento\TestFramework\Fixture\ApiDataFixtureInterface; /** * Create simple product fixture */ -class CreateSimpleProduct implements RevertibleDataFixtureInterface +class CreateSimpleProduct extends AbstractApiDataFixture { - /** - * @var ProductRepositoryInterface - */ - private $productRepository; - - /** - * @var ServiceInputProcessor - */ - private $productHydrator; - - /** - * @var array - */ - private $defaultData = [ + private const DEFAULT_DATA = [ 'type_id' => Type::TYPE_SIMPLE, 'attribute_set_id' => 4, 'name' => 'Simple Product', @@ -62,43 +46,54 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface ]; /** - * @param ProductRepositoryInterface $productRepository - * @param ServiceInputProcessor $productHydrator + * @inheritdoc */ - public function __construct( - ProductRepositoryInterface $productRepository, - ServiceInputProcessor $productHydrator - ) { - $this->productRepository = $productRepository; - $this->productHydrator = $productHydrator; + public function getService(): array + { + return [ + ApiDataFixtureInterface::SERVICE_CLASS => ProductRepositoryInterface::class, + ApiDataFixtureInterface::SERVICE_METHOD => 'save', + ]; } /** * @inheritdoc */ - public function apply(array $data = []): ?array + public function getRollbackService(): array { - /** @var $product Product */ - $data = array_merge($this->defaultData, $data); - $product = $this->productHydrator->convertValue($data, ProductInterface::class); - $this->productRepository->save($product); + return [ + ApiDataFixtureInterface::SERVICE_CLASS => ProductRepositoryInterface::class, + ApiDataFixtureInterface::SERVICE_METHOD => 'deleteById', + ]; + } + /** + * @inheritdoc + */ + public function processServiceMethodParameters(array $data): array + { + return [ + 'product' => array_merge_recursive(self::DEFAULT_DATA, $data) + ]; + } + + /** + * @inheritdoc + */ + public function processRollbackServiceMethodParameters(array $data): array + { return [ - 'product' => $product + 'sku' => $data['product']->getSku() ]; } /** * @inheritdoc */ - public function revert(array $data = []): void + public function processServiceResult($data): array { - try { - /** @var $product Product */ - $product = $data['product']; - $this->productRepository->deleteById($product->getSku()); - } catch (NoSuchEntityException $e) { - //ignore - } + return [ + 'product' => $data + ]; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index f163149ec5ff1..2f6bdd983b45f 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -66,7 +66,9 @@ public function testGetAttributeRawValue() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_store_scope_attribute.php + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -74,17 +76,19 @@ public function testGetAttributeRawValue() */ public function testGetAttributeRawValueGetDefault() { - $product = $this->productRepository->get('simple_with_store_scoped_custom_attribute', true, 0, true); - $product->setCustomAttribute('store_scoped_attribute_code', 'default_value'); + $product = $this->productRepository->get('simple', true, 0, true); + $product->setCustomAttribute('fixture_attribute', 'default_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'store_scoped_attribute_code', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); $this->assertEquals('default_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_store_scope_attribute.php + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -92,21 +96,23 @@ public function testGetAttributeRawValueGetDefault() */ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() { - $product = $this->productRepository->get('simple_with_store_scoped_custom_attribute', true, 0, true); - $product->setCustomAttribute('store_scoped_attribute_code', null); + $product = $this->productRepository->get('simple', true, 0, true); + $product->setCustomAttribute('fixture_attribute', null); $this->productRepository->save($product); - $product = $this->productRepository->get('simple_with_store_scoped_custom_attribute', true, 1, true); - $product->setCustomAttribute('store_scoped_attribute_code', 'store_value'); + $product = $this->productRepository->get('simple', true, 1, true); + $product->setCustomAttribute('fixture_attribute', 'store_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'store_scoped_attribute_code', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); $this->assertEquals('store_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_store_scope_attribute.php + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -114,21 +120,23 @@ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() */ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() { - $product = $this->productRepository->get('simple_with_store_scoped_custom_attribute', true, 0, true); - $product->setCustomAttribute('store_scoped_attribute_code', 'default_value'); + $product = $this->productRepository->get('simple', true, 0, true); + $product->setCustomAttribute('fixture_attribute', 'default_value'); $this->productRepository->save($product); - $product = $this->productRepository->get('simple_with_store_scoped_custom_attribute', true, 1, true); - $product->setCustomAttribute('store_scoped_attribute_code', 'store_value'); + $product = $this->productRepository->get('simple', true, 1, true); + $product->setCustomAttribute('fixture_attribute', 'store_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'store_scoped_attribute_code', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); $this->assertEquals('store_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_store_scope_attribute.php + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -137,17 +145,17 @@ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() */ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() { - $product = $this->productRepository->get('simple_with_store_scoped_custom_attribute', true, 0, true); - $product->setCustomAttribute('store_scoped_attribute_code', 'default_value'); + $product = $this->productRepository->get('simple', true, 0, true); + $product->setCustomAttribute('fixture_attribute', 'default_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'store_scoped_attribute_code', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); $this->assertEquals('default_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento/Catalog/_files/product_special_price.php + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"custom_attributes":[{"attribute_code":"special_price","value":5.99}]} * @magentoAppIsolation enabled * @magentoConfigFixture default_store catalog/price/scope 1 */ From 52251f091c059c75cf2083933a86665859c780a5 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Thu, 22 Apr 2021 13:26:29 -0500 Subject: [PATCH 05/29] MC-40601: Add support for data fixture classes - Refactor --- .../api-functional/framework/bootstrap.php | 3 + .../Annotation/AbstractDataFixture.php | 16 ++-- .../Fixture/AbstractApiDataFixture.php | 10 ++- .../Fixture/ApiDataFixtureInterface.php | 5 +- .../Fixture/DataFixtureDirectivesParser.php | 17 +++- ...sultStorage.php => DataFixtureStorage.php} | 23 +---- .../Fixture/DataFixtureStorageManager.php | 46 ++++++++++ .../Fixture/DataFixtureTypeInterface.php | 15 ++++ ....php => LegacyDataFixturePathResolver.php} | 2 +- .../Fixture/Proxy/DataFixtureInterface.php | 17 ---- .../{Proxy => Type}/CallableDataFixture.php | 6 +- .../Fixture/{Proxy => Type}/DataFixture.php | 5 +- .../Factory.php} | 24 ++---- .../{Proxy => Type}/LegacyDataFixture.php | 15 ++-- .../Workaround/Override/Fixture/Resolver.php | 6 +- dev/tests/integration/framework/bootstrap.php | 3 + .../Test/Annotation/DataFixtureTest.php | 8 +- .../AddProductAttributeToAttributeSet.php | 83 ++++++++++++++----- .../Fixture/CreateProductAttribute.php | 7 +- .../Catalog/Fixture/CreateSimpleProduct.php | 5 +- .../Annotation/DataFixtureTest.php | 8 +- 21 files changed, 211 insertions(+), 113 deletions(-) rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{DataFixtureResultStorage.php => DataFixtureStorage.php} (65%) create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorageManager.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureTypeInterface.php rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{DataFixturePathResolver.php => LegacyDataFixturePathResolver.php} (98%) delete mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/DataFixtureInterface.php rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{Proxy => Type}/CallableDataFixture.php (86%) rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{Proxy => Type}/DataFixture.php (89%) rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{Proxy/DataFixtureFactory.php => Type/Factory.php} (65%) rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{Proxy => Type}/LegacyDataFixture.php (75%) diff --git a/dev/tests/api-functional/framework/bootstrap.php b/dev/tests/api-functional/framework/bootstrap.php index d3a9a6add5776..6f196068fa2ab 100644 --- a/dev/tests/api-functional/framework/bootstrap.php +++ b/dev/tests/api-functional/framework/bootstrap.php @@ -101,6 +101,9 @@ Magento\TestFramework\Workaround\Override\Fixture\Resolver::setInstance( new \Magento\TestFramework\WebapiWorkaround\Override\Fixture\Resolver($overrideConfig) ); + Magento\TestFramework\Fixture\DataFixtureStorageManager::setStorage( + new Magento\TestFramework\Fixture\DataFixtureStorage() + ); \Magento\TestFramework\Workaround\Override\Config::setInstance($overrideConfig); unset($bootstrap, $application, $settings, $shell, $overrideConfig); } catch (\Exception $e) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 74408999b2d41..2e288621633b4 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -9,9 +9,9 @@ use Magento\Framework\DataObject; use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; -use Magento\TestFramework\Fixture\Proxy\DataFixtureFactory; -use Magento\TestFramework\Fixture\Proxy\DataFixtureInterface; -use Magento\TestFramework\Fixture\DataFixtureResultStorage; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; +use Magento\TestFramework\Fixture\Type\Factory; +use Magento\TestFramework\Fixture\DataFixtureTypeInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ abstract class AbstractDataFixture /** * Fixtures that have been applied * - * @var DataFixtureInterface[] + * @var DataFixtureTypeInterface[] */ protected $_appliedFixtures = []; @@ -96,7 +96,7 @@ protected function _applyFixtures(array $fixtures, TestCase $test) $testsIsolation = $objectManager->get(TestsIsolation::class); $dbIsolationState = $this->getDbIsolationState($test); $testsIsolation->createDbSnapshot($test, $dbIsolationState); - $dataFixtureFactory = $objectManager->get(DataFixtureFactory::class); + $dataFixtureFactory = $objectManager->get(Factory::class); /* Execute fixture scripts */ foreach ($fixtures as $key => $directives) { if (is_callable([get_class($test), $directives['name']])) { @@ -106,7 +106,7 @@ protected function _applyFixtures(array $fixtures, TestCase $test) $key = $directives['identifier'] ?? $key; $result = $fixture->apply($directives['data'] ?? []); $resultObj = $result !== null ? $objectManager->create(DataObject::class, ['data' => $result]) : null; - DataFixtureResultStorage::getInstance()->persist("$key", $resultObj); + DataFixtureStorageManager::getStorage()->persist("$key", $resultObj); $this->_appliedFixtures[$key] = $fixture; } $resolver = Resolver::getInstance(); @@ -125,11 +125,11 @@ protected function _revertFixtures(?TestCase $test = null) $resolver->setCurrentFixtureType($this->getAnnotation()); $appliedFixtures = array_reverse($this->_appliedFixtures, true); foreach ($appliedFixtures as $key => $fixture) { - $result = DataFixtureResultStorage::getInstance()->get("$key"); + $result = DataFixtureStorageManager::getStorage()->get("$key"); $fixture->revert($result ? $result->getData() : []); } $this->_appliedFixtures = []; - DataFixtureResultStorage::getInstance()->flush(); + DataFixtureStorageManager::getStorage()->flush(); $resolver->setCurrentFixtureType(null); if (null !== $test) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php index 95c6fe3ff678e..68b92f28570b3 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php @@ -43,16 +43,17 @@ public function __construct( */ public function apply(array $data = []): ?array { + $data = $this->processServiceMethodParameters($data); $service = $this->getService(); $serviceInstance = $this->objectManager->get($service[ApiDataFixtureInterface::SERVICE_CLASS]); $params = $this->serviceInputProcessor->process( $service[ApiDataFixtureInterface::SERVICE_CLASS], $service[ApiDataFixtureInterface::SERVICE_METHOD], - $this->processServiceMethodParameters($data) + $data ); - $data = call_user_func_array([$serviceInstance, $service[ApiDataFixtureInterface::SERVICE_METHOD]], $params); + $result = call_user_func_array([$serviceInstance, $service[ApiDataFixtureInterface::SERVICE_METHOD]], $params); - return $this->processServiceResult($data); + return $this->processServiceResult($data, $result); } /** @@ -60,12 +61,13 @@ public function apply(array $data = []): ?array */ public function revert(array $data = []): void { + $data = $this->processRollbackServiceMethodParameters($data); $service = $this->getRollbackService(); $serviceInstance = $this->objectManager->get($service[ApiDataFixtureInterface::SERVICE_CLASS]); $params = $this->serviceInputProcessor->process( $service[ApiDataFixtureInterface::SERVICE_CLASS], $service[ApiDataFixtureInterface::SERVICE_METHOD], - $this->processRollbackServiceMethodParameters($data) + $data ); try { call_user_func_array([$serviceInstance, $service[ApiDataFixtureInterface::SERVICE_METHOD]], $params); diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php index 3460397fa2bbe..eba872c587c49 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php @@ -48,8 +48,9 @@ public function processRollbackServiceMethodParameters(array $data): array; /** * Process service result * - * @param mixed $data + * @param array $data + * @param mixed $result * @return array */ - public function processServiceResult($data): array; + public function processServiceResult(array $data, $result): array; } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php index 74bcf84124faa..df176db9ac58b 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php @@ -8,12 +8,27 @@ namespace Magento\TestFramework\Fixture; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Serialize\Serializer\Json; /** * Data fixture directives parser service */ class DataFixtureDirectivesParser { + /** + * @var Json + */ + private $serializer; + + /** + * @param Json $serializer + */ + public function __construct( + Json $serializer + ) { + $this->serializer = $serializer; + } + /** * Parse data fixture directives * @@ -39,7 +54,7 @@ public function parse(string $fixture): array list($directive, $value) = explode(':', $pair, 2); switch ($directive) { case 'with': - $data = json_decode($json, true); + $data = $this->serializer->unserialize($json); break; case 'as': $id = $value; diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureResultStorage.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorage.php similarity index 65% rename from dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureResultStorage.php rename to dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorage.php index 31f46dc59de04..e4bbe026a659d 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureResultStorage.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorage.php @@ -10,15 +10,10 @@ use Magento\Framework\DataObject; /** - * Data fixture result storage service + * Data fixture storage model */ -class DataFixtureResultStorage +class DataFixtureStorage { - /** - * @var DataFixtureResultStorage - */ - private static $instance; - /** * @var array */ @@ -53,18 +48,4 @@ public function flush(): void { $this->fixtures = []; } - - /** - * Get the unique instance of the storage - * - * @return DataFixtureResultStorage - */ - public static function getInstance(): DataFixtureResultStorage - { - if (self::$instance === null) { - self::$instance = new DataFixtureResultStorage(); - } - - return self::$instance; - } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorageManager.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorageManager.php new file mode 100644 index 0000000000000..e4d5246474ebc --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorageManager.php @@ -0,0 +1,46 @@ +objectManager = $objectManager; - $this->fixturePathResolver = $fixturePathResolver; } /** * Create new instance of data fixture * * @param array $directives - * @return DataFixtureInterface + * @return DataFixtureTypeInterface */ - public function create(array $directives): DataFixtureInterface + public function create(array $directives): DataFixtureTypeInterface { if (is_callable($directives['name'])) { $result = $this->objectManager->create( @@ -63,7 +55,7 @@ public function create(array $directives): DataFixtureInterface $result = $this->objectManager->create( LegacyDataFixture::class, [ - 'filePath' => $this->fixturePathResolver->resolve($directives['name']), + 'filePath' => $directives['name'], ] ); } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/LegacyDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/LegacyDataFixture.php similarity index 75% rename from dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/LegacyDataFixture.php rename to dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/LegacyDataFixture.php index 219d59cf55486..7fbbb0cc00550 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Proxy/LegacyDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/LegacyDataFixture.php @@ -5,14 +5,16 @@ */ declare(strict_types=1); -namespace Magento\TestFramework\Fixture\Proxy; +namespace Magento\TestFramework\Fixture\Type; +use Magento\TestFramework\Fixture\DataFixtureTypeInterface; +use Magento\TestFramework\Fixture\LegacyDataFixturePathResolver; use PHPUnit\Framework\Exception; /** * File based data fixture */ -class LegacyDataFixture implements DataFixtureInterface +class LegacyDataFixture implements DataFixtureTypeInterface { /** * @var string @@ -20,11 +22,14 @@ class LegacyDataFixture implements DataFixtureInterface private $filePath; /** + * @param LegacyDataFixturePathResolver $fixturePathResolver * @param string $filePath */ - public function __construct(string $filePath) - { - $this->filePath = $filePath; + public function __construct( + LegacyDataFixturePathResolver $fixturePathResolver, + string $filePath + ) { + $this->filePath = $fixturePathResolver->resolve($filePath); } /** diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php index 4ef3f0ba3a7bb..2d36270c789a4 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php @@ -15,7 +15,7 @@ use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Annotation\DataFixtureBeforeTransaction; use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; -use Magento\TestFramework\Fixture\Proxy\DataFixtureFactory; +use Magento\TestFramework\Fixture\Type\Factory; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\ConfigInterface; use Magento\TestFramework\Workaround\Override\Fixture\Applier\AdminConfigFixture as AdminConfigFixtureApplier; @@ -51,7 +51,7 @@ class Resolver implements ResolverInterface private $currentFixtureType = null; /** - * @var DataFixtureFactory + * @var Factory */ private $dataFixtureFactory; @@ -62,7 +62,7 @@ public function __construct(ConfigInterface $config) { $this->config = $config; $this->objectManager = Bootstrap::getObjectManager(); - $this->dataFixtureFactory = $this->objectManager->create(DataFixtureFactory::class); + $this->dataFixtureFactory = $this->objectManager->create(Factory::class); } /** diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php index 114a6de74b5d7..5b95ae6588334 100644 --- a/dev/tests/integration/framework/bootstrap.php +++ b/dev/tests/integration/framework/bootstrap.php @@ -115,6 +115,9 @@ Magento\TestFramework\Workaround\Override\Fixture\Resolver::setInstance( new \Magento\TestFramework\Workaround\Override\Fixture\Resolver($overrideConfig) ); + Magento\TestFramework\Fixture\DataFixtureStorageManager::setStorage( + new Magento\TestFramework\Fixture\DataFixtureStorage() + ); /* Unset declared global variables to release the PHPUnit from maintaining their values between tests */ unset($testsBaseDir, $settings, $shell, $application, $bootstrap, $overrideConfig); } catch (\Exception $e) { diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php index 81ba2d734a4bc..85281a7823a8f 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php @@ -11,8 +11,8 @@ use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Event\Param\Transaction; -use Magento\TestFramework\Fixture\DataFixturePathResolver; -use Magento\TestFramework\Fixture\Proxy\DataFixtureFactory; +use Magento\TestFramework\Fixture\LegacyDataFixturePathResolver; +use Magento\TestFramework\Fixture\Type\Factory; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; use Magento\TestFramework\Annotation\TestsIsolation; @@ -51,11 +51,11 @@ protected function setUp(): void ->disableOriginalConstructor() ->getMockForAbstractClass(); - $fixturePathResolver = new DataFixturePathResolver(new ComponentRegistrar()); + $fixturePathResolver = new LegacyDataFixturePathResolver(new ComponentRegistrar()); $sharedInstances = [ TestsIsolation::class => $this->testsIsolationMock, //DataFixtureDirectivesParser::class => new DataFixtureDirectivesParser(), - DataFixtureFactory::class => new DataFixtureFactory($objectManager, $fixturePathResolver), + Factory::class => new Factory($objectManager, $fixturePathResolver), ]; $objectManager->expects($this->atLeastOnce()) ->method('get') diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php index be0c88cbf9c73..a09f921a192f3 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php @@ -8,14 +8,16 @@ namespace Magento\Catalog\Fixture; use Magento\Catalog\Model\Product; -use Magento\Eav\Model\Config; use Magento\Eav\Setup\EavSetup; -use Magento\TestFramework\Fixture\DataFixtureInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Webapi\ServiceInputProcessor; +use Magento\TestFramework\Fixture\AbstractApiDataFixture; +use Magento\TestFramework\Fixture\ApiDataFixtureInterface; /** * Add product attribute to attribute set fixture */ -class AddProductAttributeToAttributeSet implements DataFixtureInterface +class AddProductAttributeToAttributeSet extends AbstractApiDataFixture { /** * @var EavSetup @@ -23,33 +25,76 @@ class AddProductAttributeToAttributeSet implements DataFixtureInterface private $eavSetup; /** - * @var Config - */ - private $eavConfig; - - /** + * @param ObjectManagerInterface $objectManager + * @param ServiceInputProcessor $serviceInputProcessor * @param EavSetup $eavSetup - * @param Config $eavConfig */ public function __construct( - EavSetup $eavSetup, - Config $eavConfig + ObjectManagerInterface $objectManager, + ServiceInputProcessor $serviceInputProcessor, + EavSetup $eavSetup ) { + parent::__construct($objectManager, $serviceInputProcessor); $this->eavSetup = $eavSetup; - $this->eavConfig = $eavConfig; } /** * @inheritdoc */ - public function apply(array $data = []): ?array + public function getService(): array + { + return [ + ApiDataFixtureInterface::SERVICE_CLASS => \Magento\Catalog\Api\ProductAttributeManagementInterface::class, + ApiDataFixtureInterface::SERVICE_METHOD => 'assign', + ]; + } + + /** + * @inheritdoc + */ + public function getRollbackService(): array + { + return [ + ApiDataFixtureInterface::SERVICE_CLASS => \Magento\Catalog\Api\ProductAttributeManagementInterface::class, + ApiDataFixtureInterface::SERVICE_METHOD => 'unassign', + ]; + } + + /** + * @inheritdoc + */ + public function processServiceMethodParameters(array $data): array { - $attributeSetId = $data['attribute_set_id'] ?? $this->eavSetup->getAttributeSetId(Product::ENTITY, 'Default'); - $groupId = $data['group_id'] ?? $this->eavSetup->getDefaultAttributeGroupId(Product::ENTITY, $attributeSetId); - $attributeCode = $data['attribute_code'] ?? 'fixture_attribute'; - $this->eavSetup->addAttributeToGroup(Product::ENTITY, $attributeSetId, $groupId, $attributeCode); - $this->eavConfig->clear(); + $attributeSetId = $this->eavSetup->getAttributeSetId(Product::ENTITY, 'Default'); + $attributeGroupId = $this->eavSetup->getDefaultAttributeGroupId(Product::ENTITY, $attributeSetId); + $default = [ + 'attribute_set_id' => $attributeSetId, + 'attribute_group_id' => $attributeGroupId, + 'attribute_code' => 'fixture_attribute', + 'sort_order' => 0, + ]; + return array_merge( + $default, + $data + ); + } - return []; + /** + * @inheritdoc + */ + public function processRollbackServiceMethodParameters(array $data): array + { + return [ + 'attribute_set_id' => $data['attribute_set_id'], + 'attribute_code' => $data['attribute_code'], + ]; + } + + /** + * @inheritdoc + */ + public function processServiceResult(array $data, $result): array + { + return $data; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php index 7e87b68c7b9f1..3fcfa0dae262a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php @@ -11,6 +11,9 @@ use Magento\TestFramework\Fixture\AbstractApiDataFixture; use Magento\TestFramework\Fixture\ApiDataFixtureInterface; +/** + * Create product attribute fixture + */ class CreateProductAttribute extends AbstractApiDataFixture { private const DEFAULT_DATA = [ @@ -90,10 +93,10 @@ public function processRollbackServiceMethodParameters(array $data): array /** * @inheritdoc */ - public function processServiceResult($data): array + public function processServiceResult(array $data, $result): array { return [ - 'attribute' => $data + 'attribute' => $result ]; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 38e4a464792c0..50eb8ed04ccbf 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -88,12 +88,13 @@ public function processRollbackServiceMethodParameters(array $data): array } /** + * @param $result * @inheritdoc */ - public function processServiceResult($data): array + public function processServiceResult(array $data, $result): array { return [ - 'product' => $data + 'product' => $result ]; } } diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php b/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php index 7d73d6ba136f8..7599e72b88d04 100644 --- a/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php @@ -7,8 +7,8 @@ namespace Magento\TestFramework\Annotation; -use Magento\TestFramework\Fixture\DataFixtureResultStorage; use Magento\TestFramework\DataFixtureTestStorage; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Helper\Bootstrap; use PHPUnit\Framework\TestCase; @@ -78,17 +78,17 @@ public function testFixtureClassWithParametersAndAlias(): void 'test1' => 'value1', 'test11' => 'value11', ], - DataFixtureResultStorage::getInstance()->get('test1')->getData() + DataFixtureStorageManager::getStorage()->get('test1')->getData() ); $this->assertEquals( [ 'Magento\TestFramework\Fixture\TestTwo' => true, 'test2' => 'value2', ], - DataFixtureResultStorage::getInstance()->get('test2')->getData() + DataFixtureStorageManager::getStorage()->get('test2')->getData() ); $this->assertNull( - DataFixtureResultStorage::getInstance()->get('test3') + DataFixtureStorageManager::getStorage()->get('test3') ); $this->assertEquals( [ From 4991bdbf4b2dc6fc72adcd7e6bbe9567d9e4646d Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Thu, 22 Apr 2021 17:00:18 -0500 Subject: [PATCH 06/29] MC-40601: Add support for data fixture classes - Fix unit test --- .../Workaround/Override/Fixture/Resolver.php | 2 -- .../Test/Annotation/DataFixtureTest.php | 18 +++++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php index 2d36270c789a4..5f2e749f054de 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php @@ -7,14 +7,12 @@ namespace Magento\TestFramework\Workaround\Override\Fixture; -use Magento\Framework\DataObject; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Annotation\AdminConfigFixture; use Magento\TestFramework\Annotation\ConfigFixture; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Annotation\DataFixtureBeforeTransaction; -use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; use Magento\TestFramework\Fixture\Type\Factory; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\ConfigInterface; diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php index 85281a7823a8f..118468f9910b0 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php @@ -9,10 +9,16 @@ use Magento\Framework\Component\ComponentRegistrar; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Serialize\Serializer\Json; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Event\Param\Transaction; +use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; +use Magento\TestFramework\Fixture\DataFixtureStorage; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; +use Magento\TestFramework\Fixture\DataFixtureTypeInterface; use Magento\TestFramework\Fixture\LegacyDataFixturePathResolver; use Magento\TestFramework\Fixture\Type\Factory; +use Magento\TestFramework\Fixture\Type\LegacyDataFixture; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; use Magento\TestFramework\Annotation\TestsIsolation; @@ -21,6 +27,7 @@ * Test class for \Magento\TestFramework\Annotation\DataFixture. * * @magentoDataFixture sampleFixtureOne + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DataFixtureTest extends TestCase { @@ -51,11 +58,13 @@ protected function setUp(): void ->disableOriginalConstructor() ->getMockForAbstractClass(); - $fixturePathResolver = new LegacyDataFixturePathResolver(new ComponentRegistrar()); + DataFixtureStorageManager::setStorage(new DataFixtureStorage()); + $sharedInstances = [ TestsIsolation::class => $this->testsIsolationMock, - //DataFixtureDirectivesParser::class => new DataFixtureDirectivesParser(), - Factory::class => new Factory($objectManager, $fixturePathResolver), + DataFixtureDirectivesParser::class => new DataFixtureDirectivesParser(new Json()), + Factory::class => new Factory($objectManager), + LegacyDataFixture::class => $this->createMock(DataFixtureTypeInterface::class), ]; $objectManager->expects($this->atLeastOnce()) ->method('get') @@ -68,6 +77,9 @@ function (string $type) use ($sharedInstances) { ->method('create') ->willReturnCallback( function (string $type, array $arguments = []) use ($sharedInstances) { + if ($type === LegacyDataFixture::class) { + array_unshift($arguments, new LegacyDataFixturePathResolver(new ComponentRegistrar())); + } return new $type(...array_values($arguments)); } ); From 1f304cefca250b888e8043d9584752ab9bb29237 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Thu, 22 Apr 2021 18:26:13 -0500 Subject: [PATCH 07/29] MC-40601: Add support for data fixture classes - Remove AbstractApiDataFixture and create a service that encapsulates web-api service call --- .../Annotation/AbstractDataFixture.php | 7 +- .../Fixture/AbstractApiDataFixture.php | 78 ----------------- .../TestFramework/Fixture/Api/Service.php | 73 ++++++++++++++++ .../Fixture/Api/ServiceFactory.php | 48 +++++++++++ .../Fixture/ApiDataFixtureInterface.php | 56 ------------ .../AddProductAttributeToAttributeSet.php | 85 +++++++------------ .../Fixture/CreateProductAttribute.php | 58 ++++++------- .../Catalog/Fixture/CreateSimpleProduct.php | 59 ++++++------- 8 files changed, 209 insertions(+), 255 deletions(-) delete mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/Service.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/ServiceFactory.php delete mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 2e288621633b4..5032eef11cbb0 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -8,6 +8,7 @@ namespace Magento\TestFramework\Annotation; use Magento\Framework\DataObject; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Fixture\Type\Factory; @@ -126,7 +127,11 @@ protected function _revertFixtures(?TestCase $test = null) $appliedFixtures = array_reverse($this->_appliedFixtures, true); foreach ($appliedFixtures as $key => $fixture) { $result = DataFixtureStorageManager::getStorage()->get("$key"); - $fixture->revert($result ? $result->getData() : []); + try { + $fixture->revert($result ? $result->getData() : []); + } catch (NoSuchEntityException $exception) { + //ignore + } } $this->_appliedFixtures = []; DataFixtureStorageManager::getStorage()->flush(); diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php deleted file mode 100644 index 68b92f28570b3..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/AbstractApiDataFixture.php +++ /dev/null @@ -1,78 +0,0 @@ -objectManager = $objectManager; - $this->serviceInputProcessor = $serviceInputProcessor; - } - - /** - * @inheritdoc - */ - public function apply(array $data = []): ?array - { - $data = $this->processServiceMethodParameters($data); - $service = $this->getService(); - $serviceInstance = $this->objectManager->get($service[ApiDataFixtureInterface::SERVICE_CLASS]); - $params = $this->serviceInputProcessor->process( - $service[ApiDataFixtureInterface::SERVICE_CLASS], - $service[ApiDataFixtureInterface::SERVICE_METHOD], - $data - ); - $result = call_user_func_array([$serviceInstance, $service[ApiDataFixtureInterface::SERVICE_METHOD]], $params); - - return $this->processServiceResult($data, $result); - } - - /** - * @inheritdoc - */ - public function revert(array $data = []): void - { - $data = $this->processRollbackServiceMethodParameters($data); - $service = $this->getRollbackService(); - $serviceInstance = $this->objectManager->get($service[ApiDataFixtureInterface::SERVICE_CLASS]); - $params = $this->serviceInputProcessor->process( - $service[ApiDataFixtureInterface::SERVICE_CLASS], - $service[ApiDataFixtureInterface::SERVICE_METHOD], - $data - ); - try { - call_user_func_array([$serviceInstance, $service[ApiDataFixtureInterface::SERVICE_METHOD]], $params); - } catch (NoSuchEntityException $exception) { - //ignore - } - } -} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/Service.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/Service.php new file mode 100644 index 0000000000000..aa25237bdf594 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/Service.php @@ -0,0 +1,73 @@ +objectManager = $objectManager; + $this->serviceInputProcessor = $serviceInputProcessor; + $this->className = $className; + $this->methodName = $methodName; + } + + /** + * Execute the Api service with provided the data + * + * @param array $data + * @return mixed + */ + public function execute(array $data) + { + $params = $this->serviceInputProcessor->process( + $this->className, + $this->methodName, + $data + ); + $service = $this->objectManager->get($this->className); + + return call_user_func_array([$service, $this->methodName], $params); + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/ServiceFactory.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/ServiceFactory.php new file mode 100644 index 0000000000000..b118208f8a961 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/ServiceFactory.php @@ -0,0 +1,48 @@ +objectManager = $objectManager; + } + + /** + * Create Api service + * + * @param string $className + * @param string $methodName + * @return Service + */ + public function create(string $className, string $methodName): Service + { + return $this->objectManager->create( + Service::class, + [ + 'className' => $className, + 'methodName' => $methodName + ] + ); + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php deleted file mode 100644 index eba872c587c49..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/ApiDataFixtureInterface.php +++ /dev/null @@ -1,56 +0,0 @@ -serviceFactory = $serviceFactory; $this->eavSetup = $eavSetup; } /** * @inheritdoc */ - public function getService(): array - { - return [ - ApiDataFixtureInterface::SERVICE_CLASS => \Magento\Catalog\Api\ProductAttributeManagementInterface::class, - ApiDataFixtureInterface::SERVICE_METHOD => 'assign', - ]; - } - - /** - * @inheritdoc - */ - public function getRollbackService(): array - { - return [ - ApiDataFixtureInterface::SERVICE_CLASS => \Magento\Catalog\Api\ProductAttributeManagementInterface::class, - ApiDataFixtureInterface::SERVICE_METHOD => 'unassign', - ]; - } - - /** - * @inheritdoc - */ - public function processServiceMethodParameters(array $data): array + public function apply(array $data = []): ?array { $attributeSetId = $this->eavSetup->getAttributeSetId(Product::ENTITY, 'Default'); $attributeGroupId = $this->eavSetup->getDefaultAttributeGroupId(Product::ENTITY, $attributeSetId); - $default = [ - 'attribute_set_id' => $attributeSetId, - 'attribute_group_id' => $attributeGroupId, - 'attribute_code' => 'fixture_attribute', - 'sort_order' => 0, - ]; - return array_merge( - $default, + $data = array_merge( + [ + 'attribute_set_id' => $attributeSetId, + 'attribute_group_id' => $attributeGroupId, + 'attribute_code' => 'fixture_attribute', + 'sort_order' => 0, + ], $data ); - } - /** - * @inheritdoc - */ - public function processRollbackServiceMethodParameters(array $data): array - { - return [ - 'attribute_set_id' => $data['attribute_set_id'], - 'attribute_code' => $data['attribute_code'], - ]; + $service = $this->serviceFactory->create(ProductAttributeManagementInterface::class, 'assign'); + $service->execute($data); + + return $data; } /** * @inheritdoc */ - public function processServiceResult(array $data, $result): array + public function revert(array $data = []): void { - return $data; + $service = $this->serviceFactory->create(ProductAttributeManagementInterface::class, 'unassign'); + $service->execute( + [ + 'attribute_set_id' => $data['attribute_set_id'], + 'attribute_code' => $data['attribute_code'], + ] + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php index 3fcfa0dae262a..ccb44c2489976 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php @@ -8,13 +8,13 @@ namespace Magento\Catalog\Fixture; use Magento\Catalog\Api\ProductAttributeRepositoryInterface; -use Magento\TestFramework\Fixture\AbstractApiDataFixture; -use Magento\TestFramework\Fixture\ApiDataFixtureInterface; +use Magento\TestFramework\Fixture\Api\ServiceFactory; +use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; /** * Create product attribute fixture */ -class CreateProductAttribute extends AbstractApiDataFixture +class CreateProductAttribute implements RevertibleDataFixtureInterface { private const DEFAULT_DATA = [ 'is_wysiwyg_enabled' => false, @@ -49,54 +49,46 @@ class CreateProductAttribute extends AbstractApiDataFixture ]; /** - * @inheritdoc + * @var ServiceFactory */ - public function getService(): array - { - return [ - ApiDataFixtureInterface::SERVICE_CLASS => ProductAttributeRepositoryInterface::class, - ApiDataFixtureInterface::SERVICE_METHOD => 'save', - ]; - } + private $serviceFactory; /** - * @inheritdoc + * @param ServiceFactory $serviceFactory */ - public function getRollbackService(): array - { - return [ - ApiDataFixtureInterface::SERVICE_CLASS => ProductAttributeRepositoryInterface::class, - ApiDataFixtureInterface::SERVICE_METHOD => 'deleteById', - ]; + public function __construct( + ServiceFactory $serviceFactory + ) { + $this->serviceFactory = $serviceFactory; } /** * @inheritdoc */ - public function processServiceMethodParameters(array $data): array + public function apply(array $data = []): ?array { - return [ - 'attribute' => array_merge(self::DEFAULT_DATA, $data) - ]; - } + $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'save'); + $result = $service->execute( + [ + 'attribute' => array_merge(self::DEFAULT_DATA, $data) + ] + ); - /** - * @inheritdoc - */ - public function processRollbackServiceMethodParameters(array $data): array - { return [ - 'attributeCode' => $data['attribute']->getAttributeCode() + 'attribute' => $result ]; } /** * @inheritdoc */ - public function processServiceResult(array $data, $result): array + public function revert(array $data = []): void { - return [ - 'attribute' => $result - ]; + $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'deleteById'); + $service->execute( + [ + 'attributeCode' => $data['attribute']->getAttributeCode() + ] + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 50eb8ed04ccbf..5224dcb1e7732 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -11,13 +11,13 @@ use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Catalog\Model\Product\Type; use Magento\Catalog\Model\Product\Visibility; -use Magento\TestFramework\Fixture\AbstractApiDataFixture; -use Magento\TestFramework\Fixture\ApiDataFixtureInterface; +use Magento\TestFramework\Fixture\Api\ServiceFactory; +use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; /** * Create simple product fixture */ -class CreateSimpleProduct extends AbstractApiDataFixture +class CreateSimpleProduct implements RevertibleDataFixtureInterface { private const DEFAULT_DATA = [ 'type_id' => Type::TYPE_SIMPLE, @@ -46,55 +46,46 @@ class CreateSimpleProduct extends AbstractApiDataFixture ]; /** - * @inheritdoc + * @var ServiceFactory */ - public function getService(): array - { - return [ - ApiDataFixtureInterface::SERVICE_CLASS => ProductRepositoryInterface::class, - ApiDataFixtureInterface::SERVICE_METHOD => 'save', - ]; - } + private $serviceFactory; /** - * @inheritdoc + * @param ServiceFactory $serviceFactory */ - public function getRollbackService(): array - { - return [ - ApiDataFixtureInterface::SERVICE_CLASS => ProductRepositoryInterface::class, - ApiDataFixtureInterface::SERVICE_METHOD => 'deleteById', - ]; + public function __construct( + ServiceFactory $serviceFactory + ) { + $this->serviceFactory = $serviceFactory; } /** * @inheritdoc */ - public function processServiceMethodParameters(array $data): array + public function apply(array $data = []): ?array { - return [ - 'product' => array_merge_recursive(self::DEFAULT_DATA, $data) - ]; - } + $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'save'); + $result = $service->execute( + [ + 'product' => array_merge(self::DEFAULT_DATA, $data) + ] + ); - /** - * @inheritdoc - */ - public function processRollbackServiceMethodParameters(array $data): array - { return [ - 'sku' => $data['product']->getSku() + 'product' => $result ]; } /** - * @param $result * @inheritdoc */ - public function processServiceResult(array $data, $result): array + public function revert(array $data = []): void { - return [ - 'product' => $result - ]; + $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'deleteById'); + $service->execute( + [ + 'sku' => $data['product']->getSku() + ] + ); } } From 062dbf3dc27e6f56b9e5477f34094061850fea37 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Thu, 29 Apr 2021 13:02:47 -0500 Subject: [PATCH 08/29] MC-40601: Add support for data fixture classes - Add unit test --- .../Annotation/AbstractDataFixture.php | 6 +- .../Fixture/Type/DataFixture.php | 5 +- .../Magento/Test/Fixture/Api/ServiceTest.php | 73 ++++++++++++ .../Fixture/Type/CallableDataFixtureTest.php | 102 +++++++++++++++++ .../Test/Fixture/Type/DataFixtureTest.php | 108 ++++++++++++++++++ .../Magento/Test/Fixture/Type/FactoryTest.php | 82 +++++++++++++ .../Fixture/Type/LegacyDataFixtureTest.php | 77 +++++++++++++ 7 files changed, 449 insertions(+), 4 deletions(-) create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Api/ServiceTest.php create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/CallableDataFixtureTest.php create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/DataFixtureTest.php create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/FactoryTest.php create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/LegacyDataFixtureTest.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 5032eef11cbb0..f9861fe361822 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -106,8 +106,10 @@ protected function _applyFixtures(array $fixtures, TestCase $test) $fixture = $dataFixtureFactory->create($directives); $key = $directives['identifier'] ?? $key; $result = $fixture->apply($directives['data'] ?? []); - $resultObj = $result !== null ? $objectManager->create(DataObject::class, ['data' => $result]) : null; - DataFixtureStorageManager::getStorage()->persist("$key", $resultObj); + DataFixtureStorageManager::getStorage()->persist( + "$key", + $result !== null ? $objectManager->create(DataObject::class, ['data' => $result]) : null + ); $this->_appliedFixtures[$key] = $fixture; } $resolver = Resolver::getInstance(); diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/DataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/DataFixture.php index 23072fe716d6c..5ec7e85252047 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/DataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/DataFixture.php @@ -8,6 +8,7 @@ namespace Magento\TestFramework\Fixture\Type; use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Fixture\DataFixtureInterface; use Magento\TestFramework\Fixture\DataFixtureTypeInterface; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; @@ -60,9 +61,9 @@ public function revert(array $data = []): void /** * Get fixture class instance * - * @return \Magento\TestFramework\Fixture\DataFixtureInterface + * @return DataFixtureInterface */ - private function getInstance(): \Magento\TestFramework\Fixture\DataFixtureInterface + private function getInstance(): DataFixtureInterface { return $this->objectManager->create($this->className); } diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Api/ServiceTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Api/ServiceTest.php new file mode 100644 index 0000000000000..255a5fdab92e3 --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Api/ServiceTest.php @@ -0,0 +1,73 @@ +createMock(ObjectManagerInterface::class); + $serviceInputProcessor = $this->createMock(ServiceInputProcessor::class); + $serviceInputProcessor->expects($this->once()) + ->method('process') + ->willReturnArgument(2); + + $this->fakeClass = $this->getMockBuilder(stdClass::class) + ->addMethods(['fakeMethod']) + ->getMock(); + + $objectManager->expects($this->once()) + ->method('get') + ->willReturn($this->fakeClass); + + $this->model = new Service( + $objectManager, + $serviceInputProcessor, + get_class($this->fakeClass), + 'fakeMethod' + ); + } + + /** + * Test that the service method is executed with correct parameters + */ + public function testExecute(): void + { + $params = ['param1' => 'test1', 'param2' => 'test2']; + $this->fakeClass->expects($this->once()) + ->method('fakeMethod') + ->with('test1', 'test2'); + + $this->model->execute($params); + } +} diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/CallableDataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/CallableDataFixtureTest.php new file mode 100644 index 0000000000000..dfd3716446a3f --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/CallableDataFixtureTest.php @@ -0,0 +1,102 @@ +fakeClass = $this->getMockBuilder(stdClass::class) + ->addMethods(['fakeMethod', 'fakeMethodRollback']) + ->getMock(); + } + + /** + * @ingeritdoc + */ + protected function tearDown(): void + { + static::$testFlag = ''; + parent::tearDown(); + } + + /** + * Test apply with callable array + */ + public function testApplyCallableArray(): void + { + $model = new CallableDataFixture([$this->fakeClass, 'fakeMethod']); + $this->fakeClass->expects($this->once()) + ->method('fakeMethod'); + $model->apply(); + } + + /** + * Test revert with callable array + */ + public function testRevertCallableArray(): void + { + $model = new CallableDataFixture([$this->fakeClass, 'fakeMethod']); + $this->fakeClass->expects($this->once()) + ->method('fakeMethodRollback'); + $model->revert(); + } + + /** + * Test apply with callable string + */ + public function testApplyCallableString(): void + { + $model = new CallableDataFixture(get_class($this) . '::fixtureMethod'); + $model->apply(); + $this->assertEquals('applied', static::$testFlag); + } + + /** + * Test revert with callable string + */ + public function testRevertCallableString(): void + { + $model = new CallableDataFixture(get_class($this) . '::fixtureMethod'); + $model->revert(); + $this->assertEquals('reverted', static::$testFlag); + } + + public static function fixtureMethod(): void + { + static::$testFlag = 'applied'; + } + + public static function fixtureMethodRollback(): void + { + static::$testFlag = 'reverted'; + } +} diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/DataFixtureTest.php new file mode 100644 index 0000000000000..617b846a013af --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/DataFixtureTest.php @@ -0,0 +1,108 @@ +objectManager = $this->createMock(ObjectManagerInterface::class); + $this->testFixture = $this->getMockBuilder(DataFixtureInterface::class) + ->addMethods(['revert']) + ->getMockForAbstractClass(); + $this->testRevertibleFixture = $this->createMock(RevertibleDataFixtureInterface::class); + $this->objectManager->method('create') + ->willReturnMap( + [ + [get_class($this->testFixture), [], $this->testFixture], + [get_class($this->testRevertibleFixture), [], $this->testRevertibleFixture], + ] + ); + } + + /** + * Test apply with not revertible fixture + */ + public function testApplyNotRevertibleFixture(): void + { + $data = ['tesKey' => 'testVal']; + $model = new DataFixture($this->objectManager, get_class($this->testFixture)); + $this->testFixture->expects($this->once()) + ->method('apply') + ->with($data); + $model->apply($data); + } + + /** + * Test apply with revertible fixture + */ + public function testApplyRevertibleFixture(): void + { + $data = ['tesKey' => 'testVal']; + $model = new DataFixture($this->objectManager, get_class($this->testRevertibleFixture)); + $this->testRevertibleFixture->expects($this->once()) + ->method('apply') + ->with($data); + $model->apply($data); + } + + /** + * Test revert with not revertible fixture + */ + public function testRevertNotRevertibleFixture(): void + { + $data = ['tesKey' => 'testVal']; + $model = new DataFixture($this->objectManager, get_class($this->testFixture)); + $this->testFixture->expects($this->never()) + ->method('revert') + ->with($data); + $model->revert($data); + } + + /** + * Test revert with revertible fixture + */ + public function testRevertRevertibleFixture(): void + { + $data = ['tesKey' => 'testVal']; + $model = new DataFixture($this->objectManager, get_class($this->testRevertibleFixture)); + $this->testRevertibleFixture->expects($this->once()) + ->method('revert') + ->with($data); + $model->revert($data); + } +} diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/FactoryTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/FactoryTest.php new file mode 100644 index 0000000000000..d23b564af206f --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/FactoryTest.php @@ -0,0 +1,82 @@ +createMock(ObjectManagerInterface::class); + $objectManager->method('create') + ->willReturnCallback([$this, 'createFixture']); + $this->model = new Factory($objectManager); + } + + /** + * Test that callable data fixture is created + */ + public function testShouldCreateCallableDataFixture(): void + { + $fakeClass = $this->getMockBuilder(\stdClass::class) + ->addMethods(['fakeMethod']) + ->getMock(); + $directives = ['name' => [$fakeClass, 'fakeMethod']]; + $this->assertInstanceOf(CallableDataFixture::class, $this->model->create($directives)); + } + + /** + * Test that legacy data fixture is created + */ + public function testShouldCreateLegacyDataFixture(): void + { + $directives = ['name' => 'path/to/fixture.php']; + $this->assertInstanceOf(LegacyDataFixture::class, $this->model->create($directives)); + } + + /** + * Test that class based data fixture is created + */ + public function testShouldCreateDataFixture(): void + { + $fixtureClass = $this->createMock(DataFixtureInterface::class); + $directives = ['name' => get_class($fixtureClass)]; + $this->assertInstanceOf(DataFixture::class, $this->model->create($directives)); + } + + /** + * Create mock of provided class name + * + * @param string $className + * @return MockObject + */ + public function createFixture(string $className): MockObject + { + return $this->createMock($className); + } +} diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/LegacyDataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/LegacyDataFixtureTest.php new file mode 100644 index 0000000000000..2ae715834eb66 --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/LegacyDataFixtureTest.php @@ -0,0 +1,77 @@ +createMock(LegacyDataFixturePathResolver::class); + $fixturePath = 'Magento/Test/Annotation/_files/sample_fixture_three.php'; + $pathResolver->method('resolve') + ->willReturnCallback([$this, 'getFixtureAbsolutePath']); + $this->model = new LegacyDataFixture( + $pathResolver, + $fixturePath + ); + } + + /** + * @inheritdoc + */ + protected function tearDown(): void + { + putenv('sample_fixture_three'); + } + + /** + * Test that the fixture is executed + */ + public function testApply(): void + { + $this->model->apply(); + $this->assertEquals('3', getenv('sample_fixture_three')); + } + + /** + * Test that the rollback fixture is executed + */ + public function testRevert(): void + { + $this->model->apply(); + $this->model->revert(); + $this->assertEquals('', getenv('sample_fixture_three')); + } + + /** + * Get the absolute path of provided fixture + * + * @param string $path + * @return string + */ + public function getFixtureAbsolutePath(string $path): string + { + return dirname(__FILE__, 5) . DIRECTORY_SEPARATOR . $path; + } +} From a42afecf29532c721de7c1ddb77779474da968fa Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Thu, 29 Apr 2021 18:37:53 -0500 Subject: [PATCH 09/29] MC-40601: Add support for data fixture classes - Add unit test --- .../Fixture/DataFixtureDirectivesParser.php | 2 +- .../DataFixtureDirectivesParserTest.php | 105 ++++++++++++++++++ .../Test/Fixture/DataFixtureStorageTest.php | 32 ++++++ .../LegacyDataFixturePathResolverTest.php | 86 ++++++++++++++ 4 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureStorageTest.php create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixturePathResolverTest.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php index df176db9ac58b..19daf2b436fe1 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php @@ -64,7 +64,7 @@ public function parse(string $fixture): array } } } - if (strpos($name, '\\') !== false && !class_exists($name)) { + if (strpos($name, '\\') !== false && !class_exists($name) && !is_callable($name)) { // usage of a single directory separator symbol streamlines search across the source code throw new LocalizedException(__('Directory separator "\\" is prohibited in fixture declaration.')); } diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php new file mode 100644 index 0000000000000..73601cca41099 --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php @@ -0,0 +1,105 @@ +model = new DataFixtureDirectivesParser(new Json()); + } + + /** + * Test parse with different different format + * + * @param string $directive + * @dataProvider directivesDataProvider + */ + public function testParse(string $directive, array $expected): void + { + $this->assertEquals($expected, $this->model->parse($directive)); + } + + /** + * Test parse with invalid json + */ + public function testParseInvalidJson(): void + { + $this->expectExceptionMessage('Unable to unserialize value. Error: Syntax error'); + $this->model->parse('path/to/fixture.php as:test1 with:{"k1": "v1" "k2": ["v21", "v22"]}'); + } + + /** + * @return array + */ + public function directivesDataProvider(): array + { + return [ + [ + 'path/to/fixture.php as:test1 with:{"k1": "v1", "k2": ["v21", "v22"], "k3": {"k 31": "v 31"}}', + [ + 'identifier' => 'test1', + 'name' => 'path/to/fixture.php', + 'data' => [ + 'k1' => 'v1', + 'k2' => ['v21', 'v22'], + 'k3' => ['k 31' => 'v 31'], + ], + ] + ], + [ + 'path/to/fixture.php with:{"k1": "v1", "k2": ["v21", "v22"], "k3": {"k 31": "v 31"}} as:test1', + [ + 'identifier' => 'test1', + 'name' => 'path/to/fixture.php', + 'data' => [ + 'k1' => 'v1', + 'k2' => ['v21', 'v22'], + 'k3' => ['k 31' => 'v 31'], + ], + ] + ], + [ + 'path/to/fixture.php with:{"k1": "v1", "k2": ["v21", "v22"], "k3": {"k 31": "v 31"}}', + [ + 'identifier' => null, + 'name' => 'path/to/fixture.php', + 'data' => [ + 'k1' => 'v1', + 'k2' => ['v21', 'v22'], + 'k3' => ['k 31' => 'v 31'], + ], + ] + ], + [ + 'path/to/fixture.php as:test1', + [ + 'identifier' => 'test1', + 'name' => 'path/to/fixture.php', + 'data' => [], + ] + ], + ]; + } +} diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureStorageTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureStorageTest.php new file mode 100644 index 0000000000000..fc53d4827baec --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureStorageTest.php @@ -0,0 +1,32 @@ +persist('fixture1', $result); + $this->assertSame($result, $model->get('fixture1')); + $this->assertNull($model->get('fixture2')); + $model->flush(); + $this->assertNull($model->get('fixture1')); + } +} diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixturePathResolverTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixturePathResolverTest.php new file mode 100644 index 0000000000000..eab34c178b907 --- /dev/null +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixturePathResolverTest.php @@ -0,0 +1,86 @@ +model = new LegacyDataFixturePathResolver(new ComponentRegistrar()); + } + + /** + * Test that fixture full path is resolved correctly + * + * @param string $fixture + * @param string $path + * @dataProvider fixtureDataProvider + */ + public function testResolve(string $fixture, string $path): void + { + $path = str_replace('{{basePath}}', static::$basePath, $path); + $this->assertEquals($path, $this->model->resolve($fixture)); + } + + /** + * @return array + */ + public function fixtureDataProvider(): array + { + return [ + [ + 'Magento/Test/_files/fixture.php', + '{{basePath}}Magento/Test/_files/fixture.php' + ], + [ + 'Bar_DataFixtureTest::foo/bar/baz/fixture.php', + '{{basePath}}Bar/DataFixtureTest/foo/bar/baz/fixture.php' + ] + ]; + } +} From 49b3f6ddc091cebb7743a8582159da824d4b77ae Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Fri, 30 Apr 2021 10:21:14 -0500 Subject: [PATCH 10/29] MC-40601: Add support for data fixture classes - Fix issue with test using both DataFixtureBeforeTransaction and DataFixture --- .../Annotation/AbstractDataFixture.php | 27 ++++++++++++------- .../TestFramework/Bootstrap/DocBlock.php | 1 + .../Isolation/FlushDataFixtureStorage.php | 27 +++++++++++++++++++ 3 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Isolation/FlushDataFixtureStorage.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index f9861fe361822..12f9826a79c9a 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -34,6 +34,11 @@ abstract class AbstractDataFixture */ protected $fixtures = []; + /** + * @var array + */ + private $appliedFixturesResults = []; + /** * Retrieve fixtures from annotation * @@ -99,18 +104,20 @@ protected function _applyFixtures(array $fixtures, TestCase $test) $testsIsolation->createDbSnapshot($test, $dbIsolationState); $dataFixtureFactory = $objectManager->get(Factory::class); /* Execute fixture scripts */ - foreach ($fixtures as $key => $directives) { + foreach ($fixtures as $directives) { if (is_callable([get_class($test), $directives['name']])) { $directives['name'] = [get_class($test), $directives['name']]; } $fixture = $dataFixtureFactory->create($directives); - $key = $directives['identifier'] ?? $key; $result = $fixture->apply($directives['data'] ?? []); - DataFixtureStorageManager::getStorage()->persist( - "$key", - $result !== null ? $objectManager->create(DataObject::class, ['data' => $result]) : null - ); - $this->_appliedFixtures[$key] = $fixture; + if ($result !== null && isset($directives['identifier'])) { + DataFixtureStorageManager::getStorage()->persist( + $directives['identifier'], + $objectManager->create(DataObject::class, ['data' => $result]) + ); + } + $this->_appliedFixtures[] = $fixture; + $this->appliedFixturesResults[] = $result; } $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType(null); @@ -128,15 +135,15 @@ protected function _revertFixtures(?TestCase $test = null) $resolver->setCurrentFixtureType($this->getAnnotation()); $appliedFixtures = array_reverse($this->_appliedFixtures, true); foreach ($appliedFixtures as $key => $fixture) { - $result = DataFixtureStorageManager::getStorage()->get("$key"); + $result = $this->appliedFixturesResults[$key]; try { - $fixture->revert($result ? $result->getData() : []); + $fixture->revert($result ?? []); } catch (NoSuchEntityException $exception) { //ignore } } $this->_appliedFixtures = []; - DataFixtureStorageManager::getStorage()->flush(); + $this->appliedFixturesResults = []; $resolver->setCurrentFixtureType(null); if (null !== $test) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Bootstrap/DocBlock.php b/dev/tests/integration/framework/Magento/TestFramework/Bootstrap/DocBlock.php index e95b8821deebf..7b7770f44b6c3 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Bootstrap/DocBlock.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Bootstrap/DocBlock.php @@ -55,6 +55,7 @@ protected function _getSubscribers(Application $application) new \Magento\TestFramework\Workaround\Segfault(), new \Magento\TestFramework\Workaround\Cleanup\TestCaseProperties(), new \Magento\TestFramework\Workaround\Cleanup\StaticProperties(), + new \Magento\TestFramework\Isolation\FlushDataFixtureStorage(), new \Magento\TestFramework\Isolation\WorkingDirectory(), new \Magento\TestFramework\Isolation\DeploymentConfig(), new \Magento\TestFramework\Workaround\Override\Fixture\Resolver\TestSetter(), diff --git a/dev/tests/integration/framework/Magento/TestFramework/Isolation/FlushDataFixtureStorage.php b/dev/tests/integration/framework/Magento/TestFramework/Isolation/FlushDataFixtureStorage.php new file mode 100644 index 0000000000000..986e155b9de83 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Isolation/FlushDataFixtureStorage.php @@ -0,0 +1,27 @@ +flush(); + } +} From d02bac86e0f7bc4752236941bae6eaafbef11293 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Thu, 13 May 2021 18:19:33 -0500 Subject: [PATCH 11/29] MC-40601: Add support for data fixture classes - Implement code review suggestions --- .../Annotation/AbstractDataFixture.php | 85 ++++++++------ .../{Type => }/CallableDataFixture.php | 6 +- .../Factory.php => DataFixtureFactory.php} | 26 ++--- .../Fixture/DataFixtureTypeInterface.php | 15 --- .../Fixture/{Type => }/LegacyDataFixture.php | 6 +- .../Fixture/Type/DataFixture.php | 70 ------------ .../Workaround/Override/Fixture/Resolver.php | 6 +- .../Test/Annotation/DataFixtureTest.php | 10 +- .../{Type => }/CallableDataFixtureTest.php | 4 +- .../DataFixtureDirectivesParserTest.php | 2 +- .../Test/Fixture/{Type => }/FactoryTest.php | 33 +++--- .../{Type => }/LegacyDataFixtureTest.php | 6 +- .../Test/Fixture/Type/DataFixtureTest.php | 108 ------------------ 13 files changed, 94 insertions(+), 283 deletions(-) rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{Type => }/CallableDataFixture.php (86%) rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{Type/Factory.php => DataFixtureFactory.php} (58%) delete mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureTypeInterface.php rename dev/tests/integration/framework/Magento/TestFramework/Fixture/{Type => }/LegacyDataFixture.php (88%) delete mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/DataFixture.php rename dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/{Type => }/CallableDataFixtureTest.php (95%) rename dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/{Type => }/FactoryTest.php (61%) rename dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/{Type => }/LegacyDataFixtureTest.php (91%) delete mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/DataFixtureTest.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 12f9826a79c9a..5d96ca30b2816 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -11,8 +11,8 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; use Magento\TestFramework\Fixture\DataFixtureStorageManager; -use Magento\TestFramework\Fixture\Type\Factory; -use Magento\TestFramework\Fixture\DataFixtureTypeInterface; +use Magento\TestFramework\Fixture\DataFixtureFactory; +use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; @@ -25,7 +25,7 @@ abstract class AbstractDataFixture /** * Fixtures that have been applied * - * @var DataFixtureTypeInterface[] + * @var array */ protected $_appliedFixtures = []; @@ -34,11 +34,6 @@ abstract class AbstractDataFixture */ protected $fixtures = []; - /** - * @var array - */ - private $appliedFixturesResults = []; - /** * Retrieve fixtures from annotation * @@ -97,27 +92,17 @@ protected function getAnnotations(TestCase $test): array */ protected function _applyFixtures(array $fixtures, TestCase $test) { - $objectManager = Bootstrap::getObjectManager(); /** @var TestsIsolation $testsIsolation */ - $testsIsolation = $objectManager->get(TestsIsolation::class); + $testsIsolation = Bootstrap::getObjectManager()->get(TestsIsolation::class); $dbIsolationState = $this->getDbIsolationState($test); $testsIsolation->createDbSnapshot($test, $dbIsolationState); - $dataFixtureFactory = $objectManager->get(Factory::class); /* Execute fixture scripts */ - foreach ($fixtures as $directives) { - if (is_callable([get_class($test), $directives['name']])) { - $directives['name'] = [get_class($test), $directives['name']]; - } - $fixture = $dataFixtureFactory->create($directives); - $result = $fixture->apply($directives['data'] ?? []); - if ($result !== null && isset($directives['identifier'])) { - DataFixtureStorageManager::getStorage()->persist( - $directives['identifier'], - $objectManager->create(DataObject::class, ['data' => $result]) - ); + foreach ($fixtures as $fixture) { + if (is_callable([get_class($test), $fixture['name']])) { + $fixture['name'] = get_class($test) . '::' . $fixture['name']; } + $fixture['result'] = $this->applyDataFixture($fixture); $this->_appliedFixtures[] = $fixture; - $this->appliedFixturesResults[] = $result; } $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType(null); @@ -133,17 +118,11 @@ protected function _revertFixtures(?TestCase $test = null) { $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType($this->getAnnotation()); - $appliedFixtures = array_reverse($this->_appliedFixtures, true); - foreach ($appliedFixtures as $key => $fixture) { - $result = $this->appliedFixturesResults[$key]; - try { - $fixture->revert($result ?? []); - } catch (NoSuchEntityException $exception) { - //ignore - } + $appliedFixtures = array_reverse($this->_appliedFixtures); + foreach ($appliedFixtures as $fixture) { + $this->revertDataFixture($fixture); } $this->_appliedFixtures = []; - $this->appliedFixturesResults = []; $resolver->setCurrentFixtureType(null); if (null !== $test) { @@ -165,9 +144,7 @@ protected function _revertFixtures(?TestCase $test = null) protected function getDbIsolationState(TestCase $test) { $annotations = $this->getAnnotations($test); - return isset($annotations[DbIsolation::MAGENTO_DB_ISOLATION]) - ? $annotations[DbIsolation::MAGENTO_DB_ISOLATION] - : null; + return $annotations[DbIsolation::MAGENTO_DB_ISOLATION] ?? null; } /** @@ -187,4 +164,42 @@ private function getTestKey(TestCase $test): string * @return string */ abstract protected function getAnnotation(): string; + + /** + * Applies data fixture and returns the result. + * + * @param array $fixtureData + * @return array|null + */ + private function applyDataFixture(array $fixtureData): ?array + { + $dataFixtureFactory = Bootstrap::getObjectManager()->get(DataFixtureFactory::class); + $fixture = $dataFixtureFactory->create($fixtureData['name']); + $result = $fixture->apply($fixtureData['data'] ?? []); + if ($result !== null && isset($fixtureData['identifier'])) { + DataFixtureStorageManager::getStorage()->persist( + $fixtureData['identifier'], + Bootstrap::getObjectManager()->create(DataObject::class, ['data' => $result]) + ); + } + return $result; + } + + /** + * Revert data fixture. + * + * @param array $fixtureData + */ + private function revertDataFixture(array $fixtureData): void + { + $dataFixtureFactory = Bootstrap::getObjectManager()->get(DataFixtureFactory::class); + $fixture = $dataFixtureFactory->create($fixtureData['name']); + if ($fixture instanceof RevertibleDataFixtureInterface) { + try { + $fixture->revert($fixtureData['result'] ?? []); + } catch (NoSuchEntityException $exception) { + //ignore + } + } + } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/CallableDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php similarity index 86% rename from dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/CallableDataFixture.php rename to dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php index 04ded2099a677..822b7f1797847 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/CallableDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php @@ -5,14 +5,12 @@ */ declare(strict_types=1); -namespace Magento\TestFramework\Fixture\Type; - -use Magento\TestFramework\Fixture\DataFixtureTypeInterface; +namespace Magento\TestFramework\Fixture; /** * Callable data fixture type */ -class CallableDataFixture implements DataFixtureTypeInterface +class CallableDataFixture implements RevertibleDataFixtureInterface { /** * @var callable diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/Factory.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureFactory.php similarity index 58% rename from dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/Factory.php rename to dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureFactory.php index 504977858ff2e..0ca34305785f9 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Type/Factory.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureFactory.php @@ -5,15 +5,14 @@ */ declare(strict_types=1); -namespace Magento\TestFramework\Fixture\Type; +namespace Magento\TestFramework\Fixture; use Magento\Framework\ObjectManagerInterface; -use Magento\TestFramework\Fixture\DataFixtureTypeInterface; /** * Factory for data fixture type */ -class Factory +class DataFixtureFactory { /** * @var ObjectManagerInterface @@ -32,30 +31,25 @@ public function __construct( /** * Create new instance of data fixture * - * @param array $directives - * @return DataFixtureTypeInterface + * @param string $fixture + * @return DataFixtureInterface */ - public function create(array $directives): DataFixtureTypeInterface + public function create(string $fixture): DataFixtureInterface { - if (is_callable($directives['name'])) { + if (is_callable($fixture)) { $result = $this->objectManager->create( CallableDataFixture::class, [ - 'callback' => $directives['name'] - ] - ); - } elseif (class_exists($directives['name'])) { - $result = $this->objectManager->create( - DataFixture::class, - [ - 'className' => $directives['name'], + 'callback' => $fixture ] ); + } elseif (class_exists($fixture)) { + $result = $this->objectManager->create($fixture); } else { $result = $this->objectManager->create( LegacyDataFixture::class, [ - 'filePath' => $directives['name'], + 'filePath' => $fixture, ] ); } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureTypeInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureTypeInterface.php deleted file mode 100644 index c92d586f5c2b1..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureTypeInterface.php +++ /dev/null @@ -1,15 +0,0 @@ -objectManager = $objectManager; - $this->className = $className; - } - - /** - * @inheritdoc - */ - public function apply(array $data = []): ?array - { - return $this->getInstance()->apply($data); - } - - /** - * @inheritdoc - */ - public function revert(array $data = []): void - { - $fixture = $this->getInstance(); - if ($fixture instanceof RevertibleDataFixtureInterface) { - $fixture->revert($data); - } - } - - /** - * Get fixture class instance - * - * @return DataFixtureInterface - */ - private function getInstance(): DataFixtureInterface - { - return $this->objectManager->create($this->className); - } -} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php index 5f2e749f054de..46fba0dba7a7d 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php @@ -13,7 +13,7 @@ use Magento\TestFramework\Annotation\ConfigFixture; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Annotation\DataFixtureBeforeTransaction; -use Magento\TestFramework\Fixture\Type\Factory; +use Magento\TestFramework\Fixture\DataFixtureFactory; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\ConfigInterface; use Magento\TestFramework\Workaround\Override\Fixture\Applier\AdminConfigFixture as AdminConfigFixtureApplier; @@ -49,7 +49,7 @@ class Resolver implements ResolverInterface private $currentFixtureType = null; /** - * @var Factory + * @var DataFixtureFactory */ private $dataFixtureFactory; @@ -60,7 +60,7 @@ public function __construct(ConfigInterface $config) { $this->config = $config; $this->objectManager = Bootstrap::getObjectManager(); - $this->dataFixtureFactory = $this->objectManager->create(Factory::class); + $this->dataFixtureFactory = $this->objectManager->create(DataFixtureFactory::class); } /** diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php index 118468f9910b0..16d58401423c4 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php @@ -13,12 +13,12 @@ use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Event\Param\Transaction; use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; +use Magento\TestFramework\Fixture\DataFixtureInterface; use Magento\TestFramework\Fixture\DataFixtureStorage; use Magento\TestFramework\Fixture\DataFixtureStorageManager; -use Magento\TestFramework\Fixture\DataFixtureTypeInterface; use Magento\TestFramework\Fixture\LegacyDataFixturePathResolver; -use Magento\TestFramework\Fixture\Type\Factory; -use Magento\TestFramework\Fixture\Type\LegacyDataFixture; +use Magento\TestFramework\Fixture\DataFixtureFactory; +use Magento\TestFramework\Fixture\LegacyDataFixture; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; use Magento\TestFramework\Annotation\TestsIsolation; @@ -63,8 +63,8 @@ protected function setUp(): void $sharedInstances = [ TestsIsolation::class => $this->testsIsolationMock, DataFixtureDirectivesParser::class => new DataFixtureDirectivesParser(new Json()), - Factory::class => new Factory($objectManager), - LegacyDataFixture::class => $this->createMock(DataFixtureTypeInterface::class), + DataFixtureFactory::class => new DataFixtureFactory($objectManager), + LegacyDataFixture::class => $this->createMock(DataFixtureInterface::class), ]; $objectManager->expects($this->atLeastOnce()) ->method('get') diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/CallableDataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/CallableDataFixtureTest.php similarity index 95% rename from dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/CallableDataFixtureTest.php rename to dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/CallableDataFixtureTest.php index dfd3716446a3f..bc296cc95298b 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/CallableDataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/CallableDataFixtureTest.php @@ -5,9 +5,9 @@ */ declare(strict_types=1); -namespace Magento\Test\Fixture\Type; +namespace Magento\Test\Fixture; -use Magento\TestFramework\Fixture\Type\CallableDataFixture; +use Magento\TestFramework\Fixture\CallableDataFixture; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use stdClass; diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php index 73601cca41099..27298559a6394 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php @@ -31,7 +31,7 @@ protected function setUp(): void } /** - * Test parse with different different format + * Test parse with different format * * @param string $directive * @dataProvider directivesDataProvider diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/FactoryTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/FactoryTest.php similarity index 61% rename from dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/FactoryTest.php rename to dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/FactoryTest.php index d23b564af206f..87e8200636dff 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/FactoryTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/FactoryTest.php @@ -5,14 +5,14 @@ */ declare(strict_types=1); -namespace Magento\Test\Fixture\Type; +namespace Magento\Test\Fixture; use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Fixture\DataFixtureInterface; -use Magento\TestFramework\Fixture\Type\CallableDataFixture; -use Magento\TestFramework\Fixture\Type\DataFixture; -use Magento\TestFramework\Fixture\Type\Factory; -use Magento\TestFramework\Fixture\Type\LegacyDataFixture; +use Magento\TestFramework\Fixture\CallableDataFixture; +use Magento\TestFramework\Fixture\DataFixtureFactory; +use Magento\TestFramework\Fixture\LegacyDataFixture; +use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -22,7 +22,7 @@ class FactoryTest extends TestCase { /** - * @var Factory + * @var DataFixtureFactory */ private $model; @@ -35,7 +35,7 @@ protected function setUp(): void $objectManager = $this->createMock(ObjectManagerInterface::class); $objectManager->method('create') ->willReturnCallback([$this, 'createFixture']); - $this->model = new Factory($objectManager); + $this->model = new DataFixtureFactory($objectManager); } /** @@ -43,11 +43,10 @@ protected function setUp(): void */ public function testShouldCreateCallableDataFixture(): void { - $fakeClass = $this->getMockBuilder(\stdClass::class) - ->addMethods(['fakeMethod']) - ->getMock(); - $directives = ['name' => [$fakeClass, 'fakeMethod']]; - $this->assertInstanceOf(CallableDataFixture::class, $this->model->create($directives)); + $this->assertInstanceOf( + CallableDataFixture::class, + $this->model->create(get_class($this) . '::' . 'tearDownAfterClass') + ); } /** @@ -55,8 +54,7 @@ public function testShouldCreateCallableDataFixture(): void */ public function testShouldCreateLegacyDataFixture(): void { - $directives = ['name' => 'path/to/fixture.php']; - $this->assertInstanceOf(LegacyDataFixture::class, $this->model->create($directives)); + $this->assertInstanceOf(LegacyDataFixture::class, $this->model->create('path/to/fixture.php')); } /** @@ -64,9 +62,10 @@ public function testShouldCreateLegacyDataFixture(): void */ public function testShouldCreateDataFixture(): void { - $fixtureClass = $this->createMock(DataFixtureInterface::class); - $directives = ['name' => get_class($fixtureClass)]; - $this->assertInstanceOf(DataFixture::class, $this->model->create($directives)); + $this->assertInstanceOf( + RevertibleDataFixtureInterface::class, + $this->model->create(RevertibleDataFixtureInterface::class) + ); } /** diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/LegacyDataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixtureTest.php similarity index 91% rename from dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/LegacyDataFixtureTest.php rename to dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixtureTest.php index 2ae715834eb66..a6aaaaf20a36a 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/LegacyDataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixtureTest.php @@ -5,10 +5,10 @@ */ declare(strict_types=1); -namespace Magento\Test\Fixture\Type; +namespace Magento\Test\Fixture; use Magento\TestFramework\Fixture\LegacyDataFixturePathResolver; -use Magento\TestFramework\Fixture\Type\LegacyDataFixture; +use Magento\TestFramework\Fixture\LegacyDataFixture; use PHPUnit\Framework\TestCase; /** @@ -72,6 +72,6 @@ public function testRevert(): void */ public function getFixtureAbsolutePath(string $path): string { - return dirname(__FILE__, 5) . DIRECTORY_SEPARATOR . $path; + return dirname(__FILE__, 4) . DIRECTORY_SEPARATOR . $path; } } diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/DataFixtureTest.php deleted file mode 100644 index 617b846a013af..0000000000000 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Type/DataFixtureTest.php +++ /dev/null @@ -1,108 +0,0 @@ -objectManager = $this->createMock(ObjectManagerInterface::class); - $this->testFixture = $this->getMockBuilder(DataFixtureInterface::class) - ->addMethods(['revert']) - ->getMockForAbstractClass(); - $this->testRevertibleFixture = $this->createMock(RevertibleDataFixtureInterface::class); - $this->objectManager->method('create') - ->willReturnMap( - [ - [get_class($this->testFixture), [], $this->testFixture], - [get_class($this->testRevertibleFixture), [], $this->testRevertibleFixture], - ] - ); - } - - /** - * Test apply with not revertible fixture - */ - public function testApplyNotRevertibleFixture(): void - { - $data = ['tesKey' => 'testVal']; - $model = new DataFixture($this->objectManager, get_class($this->testFixture)); - $this->testFixture->expects($this->once()) - ->method('apply') - ->with($data); - $model->apply($data); - } - - /** - * Test apply with revertible fixture - */ - public function testApplyRevertibleFixture(): void - { - $data = ['tesKey' => 'testVal']; - $model = new DataFixture($this->objectManager, get_class($this->testRevertibleFixture)); - $this->testRevertibleFixture->expects($this->once()) - ->method('apply') - ->with($data); - $model->apply($data); - } - - /** - * Test revert with not revertible fixture - */ - public function testRevertNotRevertibleFixture(): void - { - $data = ['tesKey' => 'testVal']; - $model = new DataFixture($this->objectManager, get_class($this->testFixture)); - $this->testFixture->expects($this->never()) - ->method('revert') - ->with($data); - $model->revert($data); - } - - /** - * Test revert with revertible fixture - */ - public function testRevertRevertibleFixture(): void - { - $data = ['tesKey' => 'testVal']; - $model = new DataFixture($this->objectManager, get_class($this->testRevertibleFixture)); - $this->testRevertibleFixture->expects($this->once()) - ->method('revert') - ->with($data); - $model->revert($data); - } -} From 93bad3236a0ce3fc3bf48216c3ad1370470e25a6 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Thu, 13 May 2021 18:30:17 -0500 Subject: [PATCH 12/29] MC-40601: Add support for data fixture classes - Fix doc --- .../Magento/TestFramework/Fixture/CallableDataFixture.php | 2 +- .../Magento/TestFramework/Fixture/DataFixtureFactory.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php index 822b7f1797847..0202cbbd667c2 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php @@ -8,7 +8,7 @@ namespace Magento\TestFramework\Fixture; /** - * Callable data fixture type + * Callable data fixture */ class CallableDataFixture implements RevertibleDataFixtureInterface { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureFactory.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureFactory.php index 0ca34305785f9..425182448dba3 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureFactory.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureFactory.php @@ -10,7 +10,7 @@ use Magento\Framework\ObjectManagerInterface; /** - * Factory for data fixture type + * Factory for data fixture */ class DataFixtureFactory { From dcf856054f3b9a29f58226fda35f24856cadbb3e Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Fri, 14 May 2021 08:49:56 -0500 Subject: [PATCH 13/29] MC-40601: Add support for data fixture classes - Fix argument 1 passed to Magento\TestFramework\Fixture\DataFixtureFactory::create() must be of the type string, array given --- .../TestFramework/Workaround/Override/Fixture/Resolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php index 46fba0dba7a7d..8f626cda089cc 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php @@ -122,7 +122,7 @@ public function requireDataFixture(string $path): void } /** @var DataFixtureApplier $dataFixtureApplier */ $dataFixtureApplier = $this->getApplier($this->getCurrentTest(), $this->currentFixtureType); - $fixture = $this->dataFixtureFactory->create(['name' => $dataFixtureApplier->replace($path)]); + $fixture = $this->dataFixtureFactory->create($dataFixtureApplier->replace($path)); $fixture->apply(); } From 0775a7f8cd135bb89b812a22930b5863ff15585a Mon Sep 17 00:00:00 2001 From: Anna Bukatar Date: Mon, 14 Jun 2021 07:59:42 -0700 Subject: [PATCH 14/29] MC-42458: Add support for data fixture class and json string in data fixture annotation --- .../Annotation/FixtureDataResolver.php | 72 +++++++++++++++++++ .../Fixture/CreateProductAttribute.php | 22 +++++- .../Catalog/Fixture/CreateSimpleProduct.php | 21 +++++- .../Model/ResourceModel/ProductTest.php | 24 +++++++ 4 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Annotation/FixtureDataResolver.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/FixtureDataResolver.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/FixtureDataResolver.php new file mode 100644 index 0000000000000..26e647a04bdde --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/FixtureDataResolver.php @@ -0,0 +1,72 @@ +uniqueId[$reflection->getName()])) { + $this->uniqueId[$reflection->getName()] = self::INCREMENT; + return $data; + } + + $increment = ++$this->uniqueId[$reflection->getName()]; + + $uniqueFields = explode('@unique', $reflection->getDocComment()); + array_shift($uniqueFields); + array_walk($uniqueFields, function(&$val) { + $val= preg_replace('/[^a-z_]/i','',$val); + }); + $sequence = '_' . $increment; + + foreach ($data as $key => $value) { + if (in_array($key, $uniqueFields)) { + $data[$key] = $value . $sequence; + } + + } + + return $data; + } + + /** + * @param RevertibleDataFixture $class + * @throws \ReflectionException + */ + public function revert($class) + { + $reflection = (new \ReflectionClass($class)); + + if (!isset($this->uniqueId[$reflection->getName()])) { + return; + } + + $this->uniqueId[$reflection->getName()]--; + + if ($this->uniqueId[$reflection->getName()] <= 1) { + unset ($this->uniqueId[$reflection->getName()]); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php index ccb44c2489976..59844f5943d35 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php @@ -10,9 +10,13 @@ use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; +use Magento\TestFramework\Annotation\FixtureDataResolver; /** * Create product attribute fixture + * + * @unique attribute_code + * @unique default_frontend_label */ class CreateProductAttribute implements RevertibleDataFixtureInterface { @@ -53,13 +57,22 @@ class CreateProductAttribute implements RevertibleDataFixtureInterface */ private $serviceFactory; + + /** + * @var FixtureDataResolver + */ + private $fixtureDataResolver; + /** * @param ServiceFactory $serviceFactory + * @param FixtureDataResolver $fixtureDataResolver */ public function __construct( - ServiceFactory $serviceFactory + ServiceFactory $serviceFactory, + FixtureDataResolver $fixtureDataResolver ) { $this->serviceFactory = $serviceFactory; + $this->fixtureDataResolver = $fixtureDataResolver; } /** @@ -70,7 +83,10 @@ public function apply(array $data = []): ?array $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'save'); $result = $service->execute( [ - 'attribute' => array_merge(self::DEFAULT_DATA, $data) + 'attribute' => array_merge( + $this->fixtureDataResolver->resolveDataReferences(self::DEFAULT_DATA, $this), + $data + ) ] ); @@ -81,9 +97,11 @@ public function apply(array $data = []): ?array /** * @inheritdoc + * @throws \ReflectionException */ public function revert(array $data = []): void { + $this->fixtureDataResolver->revert($this); $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'deleteById'); $service->execute( [ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 5224dcb1e7732..a740918ec90ce 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -13,9 +13,14 @@ use Magento\Catalog\Model\Product\Visibility; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; +use Magento\TestFramework\Annotation\FixtureDataResolver; /** * Create simple product fixture + * + * @unique sku; + * @unique name; + * @unique url_key; */ class CreateSimpleProduct implements RevertibleDataFixtureInterface { @@ -50,13 +55,21 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface */ private $serviceFactory; + /** + * @var FixtureDataResolver + */ + private $fixtureDataResolver; + /** * @param ServiceFactory $serviceFactory + * @param FixtureDataResolver $fixtureDataResolver */ public function __construct( - ServiceFactory $serviceFactory + ServiceFactory $serviceFactory, + FixtureDataResolver $fixtureDataResolver ) { $this->serviceFactory = $serviceFactory; + $this->fixtureDataResolver = $fixtureDataResolver; } /** @@ -67,7 +80,10 @@ public function apply(array $data = []): ?array $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'save'); $result = $service->execute( [ - 'product' => array_merge(self::DEFAULT_DATA, $data) + 'product' => array_merge( + $this->fixtureDataResolver->resolveDataReferences(self::DEFAULT_DATA, $this), + $data + ) ] ); @@ -81,6 +97,7 @@ public function apply(array $data = []): ?array */ public function revert(array $data = []): void { + $this->fixtureDataResolver->revert($this); $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'deleteById'); $service->execute( [ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 2f6bdd983b45f..502ba06a7106c 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -202,4 +202,28 @@ public function testChangeAttributeSet() $attribute = $this->model->getAttributeRawValue($product->getId(), $attributeCode, 1); $this->assertEmpty($attribute); } + + /** + * @magentoAppArea adminhtml + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet with:{"attribute_code": "fixture_attribute_2"} + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @throws NoSuchEntityException + * @throws CouldNotSaveException + * @throws InputException + * @throws StateException + * @throws NoSuchEntityException + */ + public function testThirdProductCustomSecondAttribute(): void + { + $product = $this->productRepository->get('simple_3', true, 0, true); + $product->setCustomAttribute('fixture_attribute_2', 'default_value'); + $this->productRepository->save($product); + + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_2', 1); + $this->assertEquals('default_value', $actual); + } } From 671287a95799363f16465228c5c49daa724c7cf9 Mon Sep 17 00:00:00 2001 From: Anna Bukatar Date: Mon, 28 Jun 2021 07:28:49 -0700 Subject: [PATCH 15/29] MC-42458: Add support for unique suffix generation for data fixture unique fields - Fixed CR --- .../Annotation/FixtureDataResolver.php | 72 ------------------- .../Fixture/Data/CompositeProcessor.php | 72 +++++++++++++++++++ .../Fixture/Data/ProcessorInterface.php | 26 +++++++ .../Fixture/Data/UniqueIdProcessor.php | 57 +++++++++++++++ .../AddProductAttributeToAttributeSet.php | 2 +- .../Fixture/CreateProductAttribute.php | 28 ++++---- .../Catalog/Fixture/CreateSimpleProduct.php | 33 +++++---- .../Model/ResourceModel/ProductTest.php | 40 +++++------ 8 files changed, 204 insertions(+), 126 deletions(-) delete mode 100644 dev/tests/integration/framework/Magento/TestFramework/Annotation/FixtureDataResolver.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/FixtureDataResolver.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/FixtureDataResolver.php deleted file mode 100644 index 26e647a04bdde..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/FixtureDataResolver.php +++ /dev/null @@ -1,72 +0,0 @@ -uniqueId[$reflection->getName()])) { - $this->uniqueId[$reflection->getName()] = self::INCREMENT; - return $data; - } - - $increment = ++$this->uniqueId[$reflection->getName()]; - - $uniqueFields = explode('@unique', $reflection->getDocComment()); - array_shift($uniqueFields); - array_walk($uniqueFields, function(&$val) { - $val= preg_replace('/[^a-z_]/i','',$val); - }); - $sequence = '_' . $increment; - - foreach ($data as $key => $value) { - if (in_array($key, $uniqueFields)) { - $data[$key] = $value . $sequence; - } - - } - - return $data; - } - - /** - * @param RevertibleDataFixture $class - * @throws \ReflectionException - */ - public function revert($class) - { - $reflection = (new \ReflectionClass($class)); - - if (!isset($this->uniqueId[$reflection->getName()])) { - return; - } - - $this->uniqueId[$reflection->getName()]--; - - if ($this->uniqueId[$reflection->getName()] <= 1) { - unset ($this->uniqueId[$reflection->getName()]); - } - } -} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php new file mode 100644 index 0000000000000..cb40354adde40 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php @@ -0,0 +1,72 @@ +objectManager = $objectManager; + } + + /** + * @param array $data + * @param $fixture + * @return array + */ + public function process(array &$data, $fixture) + { + foreach ($this->getProcessors() as $processor) { + $this->objectManager->get($processor)->process($data, $fixture); + } + return $data; + } + + /** + * @param $fixture + */ + public function revert($fixture) + { + foreach ($this->getProcessors() as $processor) { + $this->objectManager->get($processor)->revert($fixture); + } + } + + /** + * Get registered processors + * + * @return array + */ + public function getProcessors(): array + { + return [ + UniqueIdProcessor::class + ]; + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php new file mode 100644 index 0000000000000..0efed232ae603 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php @@ -0,0 +1,26 @@ +uniqueId[$class])) { + $this->uniqueId[$class] = self::INCREMENT; + } + $increment = $this->uniqueId[$class]++; + array_walk_recursive($data, function (&$value) use ($increment) { + $value = str_replace(self::UNIQUE_ID_KEY, $increment, $value); + }); + return $data; + } + + /** + * @param RevertibleDataFixture $fixture + */ + public function revert($fixture) + { + $class = get_class($fixture); + + if (!isset($this->uniqueId[$class])) { + return; + } + + $this->uniqueId[$class]--; + + if ($this->uniqueId[$class] <= 1) { + unset ($this->uniqueId[$class]); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php index d9a7da6dc4ab0..ce7685d17fedd 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php @@ -51,7 +51,7 @@ public function apply(array $data = []): ?array [ 'attribute_set_id' => $attributeSetId, 'attribute_group_id' => $attributeGroupId, - 'attribute_code' => 'fixture_attribute', + 'attribute_code' => 'fixture_attribute_1', 'sort_order' => 0, ], $data diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php index 59844f5943d35..235f07b99d251 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php @@ -10,13 +10,11 @@ use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; -use Magento\TestFramework\Annotation\FixtureDataResolver; +use Magento\TestFramework\Fixture\Data\CompositeProcessor; +use Magento\TestFramework\Fixture\Data\UniqueIdProcessor; /** * Create product attribute fixture - * - * @unique attribute_code - * @unique default_frontend_label */ class CreateProductAttribute implements RevertibleDataFixtureInterface { @@ -39,13 +37,13 @@ class CreateProductAttribute implements RevertibleDataFixtureInterface 'used_in_product_listing' => '0', 'is_visible' => true, 'scope' => 'store', - 'attribute_code' => 'fixture_attribute', + 'attribute_code' => 'fixture_attribute_' . UniqueIdProcessor::UNIQUE_ID_KEY, 'frontend_input' => 'text', 'entity_type_id' => '4', 'is_required' => false, 'options' => [], 'is_user_defined' => true, - 'default_frontend_label' => 'Fixture Attribute', + 'default_frontend_label' => 'Fixture Attribute ' . UniqueIdProcessor::UNIQUE_ID_KEY, 'frontend_labels' => [], 'backend_type' => 'varchar', 'is_unique' => '0', @@ -59,20 +57,20 @@ class CreateProductAttribute implements RevertibleDataFixtureInterface /** - * @var FixtureDataResolver + * @var CompositeProcessor */ - private $fixtureDataResolver; + private $compositeProcessor; /** * @param ServiceFactory $serviceFactory - * @param FixtureDataResolver $fixtureDataResolver + * @param CompositeProcessor $compositeProcessor */ public function __construct( ServiceFactory $serviceFactory, - FixtureDataResolver $fixtureDataResolver + CompositeProcessor $compositeProcessor ) { $this->serviceFactory = $serviceFactory; - $this->fixtureDataResolver = $fixtureDataResolver; + $this->compositeProcessor = $compositeProcessor; } /** @@ -81,12 +79,10 @@ public function __construct( public function apply(array $data = []): ?array { $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'save'); + $fixtureData = array_merge(self::DEFAULT_DATA, $data); $result = $service->execute( [ - 'attribute' => array_merge( - $this->fixtureDataResolver->resolveDataReferences(self::DEFAULT_DATA, $this), - $data - ) + 'attribute' => $this->compositeProcessor->process($fixtureData, $this) ] ); @@ -101,7 +97,7 @@ public function apply(array $data = []): ?array */ public function revert(array $data = []): void { - $this->fixtureDataResolver->revert($this); + $this->compositeProcessor->revert($this); $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'deleteById'); $service->execute( [ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index a740918ec90ce..88603ae6a32d2 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -13,22 +13,19 @@ use Magento\Catalog\Model\Product\Visibility; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; -use Magento\TestFramework\Annotation\FixtureDataResolver; +use Magento\TestFramework\Fixture\Data\CompositeProcessor; +use Magento\TestFramework\Fixture\Data\UniqueIdProcessor; /** * Create simple product fixture - * - * @unique sku; - * @unique name; - * @unique url_key; */ class CreateSimpleProduct implements RevertibleDataFixtureInterface { private const DEFAULT_DATA = [ 'type_id' => Type::TYPE_SIMPLE, 'attribute_set_id' => 4, - 'name' => 'Simple Product', - 'sku' => 'simple', + 'name' => 'Simple Product ' . UniqueIdProcessor::UNIQUE_ID_KEY, + 'sku' => 'simple_' . UniqueIdProcessor::UNIQUE_ID_KEY, 'price' => 10, 'weight' => 1, 'visibility' => Visibility::VISIBILITY_BOTH, @@ -37,6 +34,10 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface [ 'attribute_code' => 'tax_class_id', 'value' => '2', + ], + [ + 'attribute_code' => 'url_key', + 'value' => 'simple_url_key_' . UniqueIdProcessor::UNIQUE_ID_KEY, ] ], 'extension_attributes' => [ @@ -56,20 +57,20 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface private $serviceFactory; /** - * @var FixtureDataResolver + * @var CompositeProcessor */ - private $fixtureDataResolver; + private $compositeProcessor; /** * @param ServiceFactory $serviceFactory - * @param FixtureDataResolver $fixtureDataResolver + * @param CompositeProcessor $compositeProcessor */ public function __construct( ServiceFactory $serviceFactory, - FixtureDataResolver $fixtureDataResolver + CompositeProcessor $compositeProcessor ) { $this->serviceFactory = $serviceFactory; - $this->fixtureDataResolver = $fixtureDataResolver; + $this->compositeProcessor = $compositeProcessor; } /** @@ -78,12 +79,10 @@ public function __construct( public function apply(array $data = []): ?array { $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'save'); + $fixtureData = array_merge(self::DEFAULT_DATA, $data); $result = $service->execute( [ - 'product' => array_merge( - $this->fixtureDataResolver->resolveDataReferences(self::DEFAULT_DATA, $this), - $data - ) + 'product' => $this->compositeProcessor->process($fixtureData, $this) ] ); @@ -97,7 +96,7 @@ public function apply(array $data = []): ?array */ public function revert(array $data = []): void { - $this->fixtureDataResolver->revert($this); + $this->compositeProcessor->revert($this); $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'deleteById'); $service->execute( [ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 502ba06a7106c..332a5838f3283 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -56,7 +56,7 @@ protected function setUp(): void */ public function testGetAttributeRawValue() { - $sku = 'simple'; + $sku = 'simple_1'; $attribute = 'name'; $product = $this->productRepository->get($sku); @@ -76,11 +76,11 @@ public function testGetAttributeRawValue() */ public function testGetAttributeRawValueGetDefault() { - $product = $this->productRepository->get('simple', true, 0, true); - $product->setCustomAttribute('fixture_attribute', 'default_value'); + $product = $this->productRepository->get('simple_1', true, 0, true); + $product->setCustomAttribute('fixture_attribute_1', 'default_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_1', 1); $this->assertEquals('default_value', $actual); } @@ -96,15 +96,15 @@ public function testGetAttributeRawValueGetDefault() */ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() { - $product = $this->productRepository->get('simple', true, 0, true); - $product->setCustomAttribute('fixture_attribute', null); + $product = $this->productRepository->get('simple_1', true, 0, true); + $product->setCustomAttribute('fixture_attribute_1', null); $this->productRepository->save($product); - $product = $this->productRepository->get('simple', true, 1, true); - $product->setCustomAttribute('fixture_attribute', 'store_value'); + $product = $this->productRepository->get('simple_1', true, 1, true); + $product->setCustomAttribute('fixture_attribute_1', 'store_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_1', 1); $this->assertEquals('store_value', $actual); } @@ -120,15 +120,15 @@ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() */ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() { - $product = $this->productRepository->get('simple', true, 0, true); - $product->setCustomAttribute('fixture_attribute', 'default_value'); + $product = $this->productRepository->get('simple_1', true, 0, true); + $product->setCustomAttribute('fixture_attribute_1', 'default_value'); $this->productRepository->save($product); - $product = $this->productRepository->get('simple', true, 1, true); - $product->setCustomAttribute('fixture_attribute', 'store_value'); + $product = $this->productRepository->get('simple_1', true, 1, true); + $product->setCustomAttribute('fixture_attribute_1', 'store_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_1', 1); $this->assertEquals('store_value', $actual); } @@ -145,11 +145,11 @@ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() */ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() { - $product = $this->productRepository->get('simple', true, 0, true); - $product->setCustomAttribute('fixture_attribute', 'default_value'); + $product = $this->productRepository->get('simple_1', true, 0, true); + $product->setCustomAttribute('fixture_attribute_1', 'default_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_1', 1); $this->assertEquals('default_value', $actual); } @@ -162,15 +162,15 @@ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() public function testUpdateStoreSpecificSpecialPrice() { /** @var \Magento\Catalog\Model\Product $product */ - $product = $this->productRepository->get('simple', true, 1); + $product = $this->productRepository->get('simple_1', true, 1); $this->assertEquals(5.99, $product->getSpecialPrice()); $product->setSpecialPrice(''); $this->model->save($product); - $product = $this->productRepository->get('simple', false, 1, true); + $product = $this->productRepository->get('simple_1', false, 1, true); $this->assertEmpty($product->getSpecialPrice()); - $product = $this->productRepository->get('simple', false, 0, true); + $product = $this->productRepository->get('simple_1', false, 0, true); $this->assertEquals(5.99, $product->getSpecialPrice()); } From 44332e020955a25a1505459ec19b059927f95209 Mon Sep 17 00:00:00 2001 From: Anna Bukatar Date: Fri, 3 Sep 2021 15:23:10 -0700 Subject: [PATCH 16/29] MC-42458: Add support for unique suffix generation for data fixture unique fields - Fixed CR --- .../Fixture/Data/CompositeProcessor.php | 14 +--- .../Fixture/Data/ProcessorInterface.php | 9 +-- .../Fixture/Data/UniqueIdProcessor.php | 43 ++++------- .../AddProductAttributeToAttributeSet.php | 2 +- .../Fixture/CreateProductAttribute.php | 7 +- .../Catalog/Fixture/CreateSimpleProduct.php | 17 ++--- .../Model/ResourceModel/ProductTest.php | 75 ++++++++++--------- 7 files changed, 69 insertions(+), 98 deletions(-) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php index cb40354adde40..33dbf7e8a3fc2 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php @@ -40,24 +40,14 @@ public function __construct( * @param $fixture * @return array */ - public function process(array &$data, $fixture) + public function process($fixture, array $data): array { foreach ($this->getProcessors() as $processor) { - $this->objectManager->get($processor)->process($data, $fixture); + $data = $this->objectManager->get($processor)->process($fixture, $data); } return $data; } - /** - * @param $fixture - */ - public function revert($fixture) - { - foreach ($this->getProcessors() as $processor) { - $this->objectManager->get($processor)->revert($fixture); - } - } - /** * Get registered processors * diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php index 0efed232ae603..3c398075b7274 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php @@ -13,14 +13,9 @@ interface ProcessorInterface { /** + * @param DataFixtureInterface $fixture * @param array $data - * @param $fixture * @return array */ - public function process(array &$data, $fixture); - - /** - * @param $fixture - */ - public function revert($fixture); + public function process(DataFixtureInterface $fixture, array $data): array; } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php index 79b79ef740884..8fa9be3d70184 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php @@ -6,12 +6,7 @@ class UniqueIdProcessor implements ProcessorInterface { - const UNIQUE_ID_KEY = '%uniqid%'; - /** - * Fixture's name storage - * @var array - */ - private $uniqueId = []; + private const PLACEHOLDER = '%uniqid%'; /** * Fixture starting increment number @@ -19,39 +14,27 @@ class UniqueIdProcessor implements ProcessorInterface */ private const INCREMENT = 1; + /** + * Fixture's name storage + * @var array + */ + static private array $storage = []; + /** * @param array $data * @param $fixture * @return array */ - public function process(array &$data, $fixture) + public function process($fixture, array $data): array { $class = get_class($fixture); - if (!isset($this->uniqueId[$class])) { - $this->uniqueId[$class] = self::INCREMENT; + if (!isset(self::$storage[$class])) { + self::$storage[$class] = ['prefix' => uniqid(), 'increment' => self::INCREMENT]; } - $increment = $this->uniqueId[$class]++; - array_walk_recursive($data, function (&$value) use ($increment) { - $value = str_replace(self::UNIQUE_ID_KEY, $increment, $value); + $hash = self::$storage[$class]['prefix'] . self::$storage[$class]['increment']++; + array_walk_recursive($data, function (&$value) use ($hash) { + $value = str_replace(self::PLACEHOLDER, $hash, $value); }); return $data; } - - /** - * @param RevertibleDataFixture $fixture - */ - public function revert($fixture) - { - $class = get_class($fixture); - - if (!isset($this->uniqueId[$class])) { - return; - } - - $this->uniqueId[$class]--; - - if ($this->uniqueId[$class] <= 1) { - unset ($this->uniqueId[$class]); - } - } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php index ce7685d17fedd..d9a7da6dc4ab0 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php @@ -51,7 +51,7 @@ public function apply(array $data = []): ?array [ 'attribute_set_id' => $attributeSetId, 'attribute_group_id' => $attributeGroupId, - 'attribute_code' => 'fixture_attribute_1', + 'attribute_code' => 'fixture_attribute', 'sort_order' => 0, ], $data diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php index 235f07b99d251..06523ffd7919c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php @@ -37,13 +37,13 @@ class CreateProductAttribute implements RevertibleDataFixtureInterface 'used_in_product_listing' => '0', 'is_visible' => true, 'scope' => 'store', - 'attribute_code' => 'fixture_attribute_' . UniqueIdProcessor::UNIQUE_ID_KEY, + 'attribute_code' => 'fixture_attribute_%uniqid%', 'frontend_input' => 'text', 'entity_type_id' => '4', 'is_required' => false, 'options' => [], 'is_user_defined' => true, - 'default_frontend_label' => 'Fixture Attribute ' . UniqueIdProcessor::UNIQUE_ID_KEY, + 'default_frontend_label' => 'Fixture Attribute %uniqid%', 'frontend_labels' => [], 'backend_type' => 'varchar', 'is_unique' => '0', @@ -82,7 +82,7 @@ public function apply(array $data = []): ?array $fixtureData = array_merge(self::DEFAULT_DATA, $data); $result = $service->execute( [ - 'attribute' => $this->compositeProcessor->process($fixtureData, $this) + 'attribute' => $this->compositeProcessor->process($this, $fixtureData) ] ); @@ -97,7 +97,6 @@ public function apply(array $data = []): ?array */ public function revert(array $data = []): void { - $this->compositeProcessor->revert($this); $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'deleteById'); $service->execute( [ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 88603ae6a32d2..3d23a06fd4f05 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -24,8 +24,8 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface private const DEFAULT_DATA = [ 'type_id' => Type::TYPE_SIMPLE, 'attribute_set_id' => 4, - 'name' => 'Simple Product ' . UniqueIdProcessor::UNIQUE_ID_KEY, - 'sku' => 'simple_' . UniqueIdProcessor::UNIQUE_ID_KEY, + 'name' => 'Simple Product %uniqid%', + 'sku' => 'simple_%uniqid%', 'price' => 10, 'weight' => 1, 'visibility' => Visibility::VISIBILITY_BOTH, @@ -37,7 +37,7 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface ], [ 'attribute_code' => 'url_key', - 'value' => 'simple_url_key_' . UniqueIdProcessor::UNIQUE_ID_KEY, + 'value' => 'simple_url_key_%uniqid%', ] ], 'extension_attributes' => [ @@ -59,18 +59,18 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface /** * @var CompositeProcessor */ - private $compositeProcessor; + private $dataProcessor; /** * @param ServiceFactory $serviceFactory - * @param CompositeProcessor $compositeProcessor + * @param CompositeProcessor $dataProcessor */ public function __construct( ServiceFactory $serviceFactory, - CompositeProcessor $compositeProcessor + CompositeProcessor $dataProcessor ) { $this->serviceFactory = $serviceFactory; - $this->compositeProcessor = $compositeProcessor; + $this->dataProcessor = $dataProcessor; } /** @@ -82,7 +82,7 @@ public function apply(array $data = []): ?array $fixtureData = array_merge(self::DEFAULT_DATA, $data); $result = $service->execute( [ - 'product' => $this->compositeProcessor->process($fixtureData, $this) + 'product' => $this->dataProcessor->process($this, $fixtureData) ] ); @@ -96,7 +96,6 @@ public function apply(array $data = []): ?array */ public function revert(array $data = []): void { - $this->compositeProcessor->revert($this); $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'deleteById'); $service->execute( [ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 332a5838f3283..74726520670ef 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -8,6 +8,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Eav\Model\GetAttributeSetByName; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Helper\Bootstrap; use PHPUnit\Framework\TestCase; use Magento\Framework\Exception\NoSuchEntityException; @@ -52,11 +53,11 @@ protected function setUp(): void /** * Checks a possibility to retrieve product raw attribute value. * - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} */ public function testGetAttributeRawValue() { - $sku = 'simple_1'; + $sku = 'simple'; $attribute = 'name'; $product = $this->productRepository->get($sku); @@ -66,9 +67,9 @@ public function testGetAttributeRawValue() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute"} * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -76,19 +77,19 @@ public function testGetAttributeRawValue() */ public function testGetAttributeRawValueGetDefault() { - $product = $this->productRepository->get('simple_1', true, 0, true); - $product->setCustomAttribute('fixture_attribute_1', 'default_value'); + $product = $this->productRepository->get('simple', true, 0, true); + $product->setCustomAttribute('fixture_attribute', 'default_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_1', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); $this->assertEquals('default_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute"} * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -96,23 +97,23 @@ public function testGetAttributeRawValueGetDefault() */ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() { - $product = $this->productRepository->get('simple_1', true, 0, true); - $product->setCustomAttribute('fixture_attribute_1', null); + $product = $this->productRepository->get('simple', true, 0, true); + $product->setCustomAttribute('fixture_attribute', null); $this->productRepository->save($product); - $product = $this->productRepository->get('simple_1', true, 1, true); - $product->setCustomAttribute('fixture_attribute_1', 'store_value'); + $product = $this->productRepository->get('simple', true, 1, true); + $product->setCustomAttribute('fixture_attribute', 'store_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_1', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); $this->assertEquals('store_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute"} * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -120,23 +121,23 @@ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() */ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() { - $product = $this->productRepository->get('simple_1', true, 0, true); - $product->setCustomAttribute('fixture_attribute_1', 'default_value'); + $product = $this->productRepository->get('simple', true, 0, true); + $product->setCustomAttribute('fixture_attribute', 'default_value'); $this->productRepository->save($product); - $product = $this->productRepository->get('simple_1', true, 1, true); - $product->setCustomAttribute('fixture_attribute_1', 'store_value'); + $product = $this->productRepository->get('simple', true, 1, true); + $product->setCustomAttribute('fixture_attribute', 'store_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_1', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); $this->assertEquals('store_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute"} * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -145,32 +146,32 @@ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() */ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() { - $product = $this->productRepository->get('simple_1', true, 0, true); - $product->setCustomAttribute('fixture_attribute_1', 'default_value'); + $product = $this->productRepository->get('simple', true, 0, true); + $product->setCustomAttribute('fixture_attribute', 'default_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_1', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); $this->assertEquals('default_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"custom_attributes":[{"attribute_code":"special_price","value":5.99}]} + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple", "custom_attributes":[{"attribute_code":"special_price","value":5.99}]} * @magentoAppIsolation enabled * @magentoConfigFixture default_store catalog/price/scope 1 */ public function testUpdateStoreSpecificSpecialPrice() { /** @var \Magento\Catalog\Model\Product $product */ - $product = $this->productRepository->get('simple_1', true, 1); + $product = $this->productRepository->get('simple', true, 1); $this->assertEquals(5.99, $product->getSpecialPrice()); $product->setSpecialPrice(''); $this->model->save($product); - $product = $this->productRepository->get('simple_1', false, 1, true); + $product = $this->productRepository->get('simple', false, 1, true); $this->assertEmpty($product->getSpecialPrice()); - $product = $this->productRepository->get('simple_1', false, 0, true); + $product = $this->productRepository->get('simple', false, 0, true); $this->assertEquals(5.99, $product->getSpecialPrice()); } @@ -206,11 +207,11 @@ public function testChangeAttributeSet() /** * @magentoAppArea adminhtml * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute + * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute_2"} * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet with:{"attribute_code": "fixture_attribute_2"} - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product1 + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product2 + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product3 * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -219,11 +220,15 @@ public function testChangeAttributeSet() */ public function testThirdProductCustomSecondAttribute(): void { - $product = $this->productRepository->get('simple_3', true, 0, true); + $product3 = DataFixtureStorageManager::getStorage()->get('product3')->getData('product'); + $product = $this->productRepository->get($product3->getSku(), true, 0, true); $product->setCustomAttribute('fixture_attribute_2', 'default_value'); $this->productRepository->save($product); $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_2', 1); $this->assertEquals('default_value', $actual); + + $product2 = DataFixtureStorageManager::getStorage()->get('product2')->getData('product'); + $this->assertNotEquals($product3->getSku(), $product2->getSku()); } } From ad692834376ac7b5fbbcb5f98dbc4d0f91a6d316 Mon Sep 17 00:00:00 2001 From: Anna Bukatar Date: Wed, 15 Sep 2021 12:59:03 -0700 Subject: [PATCH 17/29] MC-42458: Add support for unique suffix generation for data fixture unique fields - CR Fixes --- .../Annotation/AbstractDataFixture.php | 6 ++++ .../Magento/TestFramework/Application.php | 1 + .../Fixture/Data/CompositeProcessor.php | 9 +++--- .../Fixture/Data/ProcessorInterface.php | 2 ++ .../Fixture/Data/UniqueIdProcessor.php | 5 ++-- .../Magento/TestFramework/MultipleWishlist | 1 + .../Magento/TestFramework/ResourceConnections | 1 + .../Magento/TestFramework/SalesArchive | 1 + .../Fixture/CreateProductAttribute.php | 16 +++++----- .../Catalog/Fixture/CreateSimpleProduct.php | 9 +++--- .../Model/ResourceModel/ProductTest.php | 29 ------------------- .../Wishlist/Controller/Index/CartTest.php | 8 +++-- 12 files changed, 36 insertions(+), 52 deletions(-) create mode 120000 dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist create mode 120000 dev/tests/integration/framework/Magento/TestFramework/ResourceConnections create mode 120000 dev/tests/integration/framework/Magento/TestFramework/SalesArchive diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 5781ccf572b9f..7ba93962945ad 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -195,11 +195,17 @@ private function applyDataFixture(array $fixtureData): ?array */ private function revertDataFixture(array $fixtureData): void { + $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + $isSecureArea = $registry->registry('isSecureArea'); $dataFixtureFactory = Bootstrap::getObjectManager()->get(DataFixtureFactory::class); $fixture = $dataFixtureFactory->create($fixtureData['name']); if ($fixture instanceof RevertibleDataFixtureInterface) { try { + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', true); $fixture->revert($fixtureData['result'] ?? []); + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', $isSecureArea); } catch (NoSuchEntityException $exception) { //ignore } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php index 189f1bbb43c13..d170bd16c151c 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Application.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php @@ -416,6 +416,7 @@ public function initialize($overriddenParams = []) \Magento\Framework\App\State::class => TestFramework\App\State::class, Mail\TransportInterface::class => TestFramework\Mail\TransportInterfaceMock::class, Mail\Template\TransportBuilder::class => TestFramework\Mail\Template\TransportBuilderMock::class, + \Magento\TestFramework\Fixture\Data\ProcessorInterface::class => \Magento\TestFramework\Fixture\Data\CompositeProcessor::class, ] ]; if ($this->loadTestExtensionAttributes) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php index 33dbf7e8a3fc2..392be5d74a3a7 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php @@ -8,9 +8,10 @@ namespace Magento\TestFramework\Fixture\Data; use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Fixture\DataFixtureInterface; /** * Class CompositeProcessor - * @package Magento\TestFramework\Fixture\Data + * Invokes all registered processors for data fixture */ class CompositeProcessor implements ProcessorInterface { @@ -36,11 +37,11 @@ public function __construct( } /** + * @param DataFixtureInterface $fixture * @param array $data - * @param $fixture * @return array */ - public function process($fixture, array $data): array + public function process(DataFixtureInterface $fixture, array $data): array { foreach ($this->getProcessors() as $processor) { $data = $this->objectManager->get($processor)->process($fixture, $data); @@ -53,7 +54,7 @@ public function process($fixture, array $data): array * * @return array */ - public function getProcessors(): array + private function getProcessors(): array { return [ UniqueIdProcessor::class diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php index 3c398075b7274..9650076842878 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php @@ -7,6 +7,8 @@ namespace Magento\TestFramework\Fixture\Data; +use Magento\TestFramework\Fixture\DataFixtureInterface; + /** * Interface for data fixtures processors */ diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php index 8fa9be3d70184..eca3e558068e1 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php @@ -3,6 +3,7 @@ namespace Magento\TestFramework\Fixture\Data; +use Magento\TestFramework\Fixture\DataFixtureInterface; class UniqueIdProcessor implements ProcessorInterface { @@ -21,11 +22,11 @@ class UniqueIdProcessor implements ProcessorInterface static private array $storage = []; /** + * @param DataFixtureInterface $fixture * @param array $data - * @param $fixture * @return array */ - public function process($fixture, array $data): array + public function process(DataFixtureInterface $fixture, array $data): array { $class = get_class($fixture); if (!isset(self::$storage[$class])) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist b/dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist new file mode 120000 index 0000000000000..a32f630c73b1d --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist @@ -0,0 +1 @@ +/Users/abukatar/work/l3/magento2ee/dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist \ No newline at end of file diff --git a/dev/tests/integration/framework/Magento/TestFramework/ResourceConnections b/dev/tests/integration/framework/Magento/TestFramework/ResourceConnections new file mode 120000 index 0000000000000..1896b84a02017 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/ResourceConnections @@ -0,0 +1 @@ +/Users/abukatar/work/l3/magento2ee/dev/tests/integration/framework/Magento/TestFramework/ResourceConnections \ No newline at end of file diff --git a/dev/tests/integration/framework/Magento/TestFramework/SalesArchive b/dev/tests/integration/framework/Magento/TestFramework/SalesArchive new file mode 120000 index 0000000000000..f13b45e4c3f33 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/SalesArchive @@ -0,0 +1 @@ +/Users/abukatar/work/l3/magento2ee/dev/tests/integration/framework/Magento/TestFramework/SalesArchive \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php index 06523ffd7919c..d7864366a4405 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php @@ -10,8 +10,7 @@ use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; -use Magento\TestFramework\Fixture\Data\CompositeProcessor; -use Magento\TestFramework\Fixture\Data\UniqueIdProcessor; +use Magento\TestFramework\Fixture\Data\ProcessorInterface; /** * Create product attribute fixture @@ -57,20 +56,20 @@ class CreateProductAttribute implements RevertibleDataFixtureInterface /** - * @var CompositeProcessor + * @var ProcessorInterface */ - private $compositeProcessor; + private $dataProcessor; /** * @param ServiceFactory $serviceFactory - * @param CompositeProcessor $compositeProcessor + * @param ProcessorInterface $dataProcessor */ public function __construct( ServiceFactory $serviceFactory, - CompositeProcessor $compositeProcessor + ProcessorInterface $dataProcessor ) { $this->serviceFactory = $serviceFactory; - $this->compositeProcessor = $compositeProcessor; + $this->dataProcessor = $dataProcessor; } /** @@ -82,7 +81,7 @@ public function apply(array $data = []): ?array $fixtureData = array_merge(self::DEFAULT_DATA, $data); $result = $service->execute( [ - 'attribute' => $this->compositeProcessor->process($this, $fixtureData) + 'attribute' => $this->dataProcessor->process($this, $fixtureData) ] ); @@ -93,7 +92,6 @@ public function apply(array $data = []): ?array /** * @inheritdoc - * @throws \ReflectionException */ public function revert(array $data = []): void { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 3d23a06fd4f05..f9cec024c7bee 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -13,8 +13,7 @@ use Magento\Catalog\Model\Product\Visibility; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; -use Magento\TestFramework\Fixture\Data\CompositeProcessor; -use Magento\TestFramework\Fixture\Data\UniqueIdProcessor; +use Magento\TestFramework\Fixture\Data\ProcessorInterface; /** * Create simple product fixture @@ -57,17 +56,17 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface private $serviceFactory; /** - * @var CompositeProcessor + * @var ProcessorInterface */ private $dataProcessor; /** * @param ServiceFactory $serviceFactory - * @param CompositeProcessor $dataProcessor + * @param ProcessorInterface $dataProcessor */ public function __construct( ServiceFactory $serviceFactory, - CompositeProcessor $dataProcessor + ProcessorInterface $dataProcessor ) { $this->serviceFactory = $serviceFactory; $this->dataProcessor = $dataProcessor; diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 74726520670ef..f18a158c6225d 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -8,7 +8,6 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Eav\Model\GetAttributeSetByName; -use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Helper\Bootstrap; use PHPUnit\Framework\TestCase; use Magento\Framework\Exception\NoSuchEntityException; @@ -203,32 +202,4 @@ public function testChangeAttributeSet() $attribute = $this->model->getAttributeRawValue($product->getId(), $attributeCode, 1); $this->assertEmpty($attribute); } - - /** - * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute_2"} - * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet with:{"attribute_code": "fixture_attribute_2"} - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product1 - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product2 - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product3 - * @throws NoSuchEntityException - * @throws CouldNotSaveException - * @throws InputException - * @throws StateException - * @throws NoSuchEntityException - */ - public function testThirdProductCustomSecondAttribute(): void - { - $product3 = DataFixtureStorageManager::getStorage()->get('product3')->getData('product'); - $product = $this->productRepository->get($product3->getSku(), true, 0, true); - $product->setCustomAttribute('fixture_attribute_2', 'default_value'); - $this->productRepository->save($product); - - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute_2', 1); - $this->assertEquals('default_value', $actual); - - $product2 = DataFixtureStorageManager::getStorage()->get('product2')->getData('product'); - $this->assertNotEquals($product3->getSku(), $product2->getSku()); - } } diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php index 788dfb15894e0..77b6e5b800ab6 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php @@ -15,6 +15,7 @@ use Magento\Framework\Message\MessageInterface; use Magento\TestFramework\TestCase\AbstractController; use Magento\TestFramework\Wishlist\Model\GetWishlistByCustomerId; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; /** * Test for add product to cart from wish list. @@ -117,12 +118,13 @@ public function testAddNotExistingItemToCart(): void * * @return void * @magentoDataFixture Magento/Wishlist/_files/wishlist_with_simple_product.php - * @magentoDataFixture Magento/Catalog/_files/products.php + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product1 + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product2 */ public function testAddItemWithRelatedProducts(): void { - $firstProductId = $this->productRepository->get('simple')->getId(); - $secondProductID = $this->productRepository->get('custom-design-simple-product')->getId(); + $firstProductId = DataFixtureStorageManager::getStorage()->get('product1')->getProduct()->getId(); + $secondProductID = DataFixtureStorageManager::getStorage()->get('product2')->getProduct()->getId(); $relatedIds = $expectedAddedIds = [$firstProductId, $secondProductID]; $this->customerSession->setCustomerId(1); From e7a8a62f035fce781b227a0a4707680fb689896f Mon Sep 17 00:00:00 2001 From: Anna Bukatar Date: Fri, 17 Sep 2021 08:59:59 -0700 Subject: [PATCH 18/29] MC-42458: Add support for unique suffix generation for data fixture unique fields - remove EE module --- .../integration/framework/Magento/TestFramework/MultipleWishlist | 1 - .../framework/Magento/TestFramework/ResourceConnections | 1 - .../integration/framework/Magento/TestFramework/SalesArchive | 1 - 3 files changed, 3 deletions(-) delete mode 120000 dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist delete mode 120000 dev/tests/integration/framework/Magento/TestFramework/ResourceConnections delete mode 120000 dev/tests/integration/framework/Magento/TestFramework/SalesArchive diff --git a/dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist b/dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist deleted file mode 120000 index a32f630c73b1d..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist +++ /dev/null @@ -1 +0,0 @@ -/Users/abukatar/work/l3/magento2ee/dev/tests/integration/framework/Magento/TestFramework/MultipleWishlist \ No newline at end of file diff --git a/dev/tests/integration/framework/Magento/TestFramework/ResourceConnections b/dev/tests/integration/framework/Magento/TestFramework/ResourceConnections deleted file mode 120000 index 1896b84a02017..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/ResourceConnections +++ /dev/null @@ -1 +0,0 @@ -/Users/abukatar/work/l3/magento2ee/dev/tests/integration/framework/Magento/TestFramework/ResourceConnections \ No newline at end of file diff --git a/dev/tests/integration/framework/Magento/TestFramework/SalesArchive b/dev/tests/integration/framework/Magento/TestFramework/SalesArchive deleted file mode 120000 index f13b45e4c3f33..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/SalesArchive +++ /dev/null @@ -1 +0,0 @@ -/Users/abukatar/work/l3/magento2ee/dev/tests/integration/framework/Magento/TestFramework/SalesArchive \ No newline at end of file From 5404f2e550c9591e43a56047a8fc11f6b2d0876d Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Fri, 17 Sep 2021 14:55:50 -0500 Subject: [PATCH 19/29] =?UTF-8?q?MC-39920:=20Add=20support=20for=20paramet?= =?UTF-8?q?rized=20data=20fixtures=20in=20integration=20and=20API=20functi?= =?UTF-8?q?onal=20tests=E2=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix static tests - Fix unit tests --- .../Fixture/CallableDataFixture.php | 2 +- .../Test/Annotation/DataFixtureTest.php | 4 +- .../Catalog/Fixture/CreateSimpleProduct.php | 47 +++++++++++++++++-- .../Model/ResourceModel/ProductTest.php | 2 +- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php index 0202cbbd667c2..822b7f1797847 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php @@ -8,7 +8,7 @@ namespace Magento\TestFramework\Fixture; /** - * Callable data fixture + * Callable data fixture type */ class CallableDataFixture implements RevertibleDataFixtureInterface { diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php index 6521a3d9634c7..437e932ea0ca3 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php @@ -47,7 +47,7 @@ class DataFixtureTest extends TestCase protected function setUp(): void { $this->object = $this->getMockBuilder(DataFixture::class) - ->onlyMethods(['_applyOneFixture', 'getTestKey']) + ->onlyMethods(['getTestKey']) ->addMethods(['getComponentRegistrar']) ->getMock(); $this->testsIsolationMock = $this->getMockBuilder(TestsIsolation::class) @@ -77,7 +77,7 @@ function (string $type) use ($sharedInstances) { $objectManager->expects($this->atLeastOnce()) ->method('create') ->willReturnCallback( - function (string $type, array $arguments = []) use ($sharedInstances) { + function (string $type, array $arguments = []) { if ($type === LegacyDataFixture::class) { array_unshift($arguments, new LegacyDataFixturePathResolver(new ComponentRegistrar())); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 5224dcb1e7732..2ecf37b72a2be 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -29,10 +29,7 @@ class CreateSimpleProduct implements RevertibleDataFixtureInterface 'visibility' => Visibility::VISIBILITY_BOTH, 'status' => Status::STATUS_ENABLED, 'custom_attributes' => [ - [ - 'attribute_code' => 'tax_class_id', - 'value' => '2', - ] + 'tax_class_id' => '2' ], 'extension_attributes' => [ 'website_ids' => [1], @@ -67,7 +64,7 @@ public function apply(array $data = []): ?array $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'save'); $result = $service->execute( [ - 'product' => array_merge(self::DEFAULT_DATA, $data) + 'product' => $this->prepareData($data) ] ); @@ -88,4 +85,44 @@ public function revert(array $data = []): void ] ); } + + /** + * Prepare product data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $default = self::DEFAULT_DATA; + return $this->merge($default, $data); + } + + /** + * Recursively merge product data + * + * @param array ...$arrays + * @return array + */ + private function merge(array ...$arrays): array + { + $result = []; + while ($arrays) { + $array = array_shift($arrays); + // is array an associative array + if (array_values($array) !== $array) { + foreach ($array as $key => $value) { + if (is_array($value) && array_key_exists($key, $result) && is_array($result[$key])) { + $result[$key] = $this->merge($result[$key], $value); + } else { + $result[$key] = $value; + } + } + } else { + $result = $array; + } + } + + return $result; + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 2f6bdd983b45f..2d8dcd848d73d 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -155,7 +155,7 @@ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"custom_attributes":[{"attribute_code":"special_price","value":5.99}]} + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"custom_attributes":{"special_price":5.99}} * @magentoAppIsolation enabled * @magentoConfigFixture default_store catalog/price/scope 1 */ From 1b790f0101f2c7f72569a79bd33bb513707adb68 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Fri, 17 Sep 2021 16:20:46 -0500 Subject: [PATCH 20/29] =?UTF-8?q?MC-39920:=20Add=20support=20for=20paramet?= =?UTF-8?q?rized=20data=20fixtures=20in=20integration=20and=20API=20functi?= =?UTF-8?q?onal=20tests=E2=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix static tests --- .../testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 2ecf37b72a2be..39d888eff4c1f 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -101,7 +101,7 @@ private function prepareData(array $data): array /** * Recursively merge product data * - * @param array ...$arrays + * @param array $arrays * @return array */ private function merge(array ...$arrays): array @@ -114,7 +114,7 @@ private function merge(array ...$arrays): array foreach ($array as $key => $value) { if (is_array($value) && array_key_exists($key, $result) && is_array($result[$key])) { $result[$key] = $this->merge($result[$key], $value); - } else { + } else { $result[$key] = $value; } } From 2a0fe1f7d8747383dea0902414e8fe5e9b3a71dd Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Mon, 20 Sep 2021 11:18:28 -0500 Subject: [PATCH 21/29] MC-39920: Add support for parametrized data fixtures in integration and API functional tests - Fix integration test --- .../testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 39d888eff4c1f..d7aaf159ded9a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -118,7 +118,7 @@ private function merge(array ...$arrays): array $result[$key] = $value; } } - } else { + } elseif ($array) { $result = $array; } } From f5e9d325c67821e2129e313caebd60c6e7b8fd89 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Mon, 20 Sep 2021 16:23:16 -0500 Subject: [PATCH 22/29] MC-42458: Add support for unique suffix generation for data fixture unique fields - Fix static test --- .../Magento/Catalog/Model/ResourceModel/ProductTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index e4b26dc1f27c8..4dd524bb3a16f 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -155,7 +155,7 @@ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku":"simple","custom_attributes":{"special_price":5.99}} + * @magentoDataFixture Magento/Catalog/_files/product_special_price.php * @magentoAppIsolation enabled * @magentoConfigFixture default_store catalog/price/scope 1 */ From 27dc80c6dd29546e24a00e12a20be1e5026edc2c Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Mon, 20 Sep 2021 18:40:58 -0500 Subject: [PATCH 23/29] MC-42458: Add support for unique suffix generation for data fixture unique fields - Fix static test --- .../TestFramework/Annotation/AbstractDataFixture.php | 4 +++- .../framework/Magento/TestFramework/Application.php | 3 ++- .../TestFramework/Fixture/Data/CompositeProcessor.php | 6 ++---- .../TestFramework/Fixture/Data/ProcessorInterface.php | 2 ++ .../TestFramework/Fixture/Data/UniqueIdProcessor.php | 11 +++++++---- .../Catalog/Fixture/CreateProductAttribute.php | 1 - 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 7ba93962945ad..fc5bd7e67677e 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -20,6 +20,8 @@ /** * Class consist of dataFixtures base logic + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ abstract class AbstractDataFixture { @@ -195,7 +197,7 @@ private function applyDataFixture(array $fixtureData): ?array */ private function revertDataFixture(array $fixtureData): void { - $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + $registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); $isSecureArea = $registry->registry('isSecureArea'); $dataFixtureFactory = Bootstrap::getObjectManager()->get(DataFixtureFactory::class); $fixture = $dataFixtureFactory->create($fixtureData['name']); diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php index d170bd16c151c..20fe53e5ee74c 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Application.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php @@ -13,6 +13,7 @@ use Magento\Framework\Filesystem\Glob; use Magento\Framework\Mail; use Magento\TestFramework; +use Magento\TestFramework\Fixture\Data\ProcessorInterface; use Psr\Log\LoggerInterface; use DomainException; @@ -416,7 +417,7 @@ public function initialize($overriddenParams = []) \Magento\Framework\App\State::class => TestFramework\App\State::class, Mail\TransportInterface::class => TestFramework\Mail\TransportInterfaceMock::class, Mail\Template\TransportBuilder::class => TestFramework\Mail\Template\TransportBuilderMock::class, - \Magento\TestFramework\Fixture\Data\ProcessorInterface::class => \Magento\TestFramework\Fixture\Data\CompositeProcessor::class, + ProcessorInterface::class => \Magento\TestFramework\Fixture\Data\CompositeProcessor::class, ] ]; if ($this->loadTestExtensionAttributes) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php index 392be5d74a3a7..bc91f5cce5876 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/CompositeProcessor.php @@ -9,8 +9,8 @@ use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Fixture\DataFixtureInterface; + /** - * Class CompositeProcessor * Invokes all registered processors for data fixture */ class CompositeProcessor implements ProcessorInterface @@ -37,9 +37,7 @@ public function __construct( } /** - * @param DataFixtureInterface $fixture - * @param array $data - * @return array + * @inheritdoc */ public function process(DataFixtureInterface $fixture, array $data): array { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php index 9650076842878..6fab1a4822943 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/ProcessorInterface.php @@ -15,6 +15,8 @@ interface ProcessorInterface { /** + * Processes provided data + * * @param DataFixtureInterface $fixture * @param array $data * @return array diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php index eca3e558068e1..d6c697cf16f7d 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php @@ -5,26 +5,29 @@ use Magento\TestFramework\Fixture\DataFixtureInterface; +/** + * Replaces uniqid placeholder in the provided data with unique ID + */ class UniqueIdProcessor implements ProcessorInterface { private const PLACEHOLDER = '%uniqid%'; /** * Fixture starting increment number + * * @var int */ private const INCREMENT = 1; /** * Fixture's name storage + * * @var array */ - static private array $storage = []; + private static $storage = []; /** - * @param DataFixtureInterface $fixture - * @param array $data - * @return array + * @inheritdoc */ public function process(DataFixtureInterface $fixture, array $data): array { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php index d7864366a4405..81b78c70659d0 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php @@ -54,7 +54,6 @@ class CreateProductAttribute implements RevertibleDataFixtureInterface */ private $serviceFactory; - /** * @var ProcessorInterface */ From a7e867b7bffbd52975af1752a07e7c6456dea6b4 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Tue, 21 Sep 2021 09:27:54 -0500 Subject: [PATCH 24/29] MC-42458: Add support for unique suffix generation for data fixture unique fields - Fix static test --- .../TestFramework/Fixture/Data/UniqueIdProcessor.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php index d6c697cf16f7d..fdd44d640df9a 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php @@ -1,5 +1,9 @@ Date: Mon, 20 Sep 2021 09:58:47 -0500 Subject: [PATCH 25/29] MC-40747: Add support for fixture data provider --- .../Annotation/AbstractDataFixture.php | 103 +++++++++------ .../Annotation/DataFixtureDataProvider.php | 46 +++++++ .../Fixture/Data/UniqueIdProcessor.php | 8 +- .../Fixture/DataFixtureDirectivesParser.php | 10 +- .../Fixture/DataFixtureSetup.php | 55 ++++++++ .../Fixture/LegacyDataFixture.php | 15 +-- .../Override/Fixture/Applier/DataFixture.php | 12 +- .../Workaround/Override/Fixture/Resolver.php | 11 +- .../Test/Annotation/DataFixtureTest.php | 5 +- .../DataFixtureDirectivesParserTest.php | 16 +-- .../Fixture/Applier/DataFixtureTest.php | 54 ++++---- dev/tests/integration/phpunit.xml.dist | 3 + .../Catalog/Fixture/CreateCategory.php | 119 ++++++++++++++++++ .../Catalog/Fixture/CreateSimpleProduct.php | 2 +- .../Model/ResourceModel/ProductTest.php | 18 ++- .../Annotation/DataFixtureTest.php | 82 ++++++++++++ 16 files changed, 458 insertions(+), 101 deletions(-) create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDataProvider.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureSetup.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateCategory.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index fc5bd7e67677e..866bc3c65aafe 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -7,16 +7,17 @@ namespace Magento\TestFramework\Annotation; -use Magento\TestFramework\Annotation\TestCaseAnnotation; use Magento\Framework\DataObject; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; +use Magento\TestFramework\Fixture\DataFixtureSetup; use Magento\TestFramework\Fixture\DataFixtureStorageManager; -use Magento\TestFramework\Fixture\DataFixtureFactory; -use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Exception; +use Throwable; /** * Class consist of dataFixtures base logic @@ -26,8 +27,6 @@ abstract class AbstractDataFixture { /** - * Fixtures that have been applied - * * @var array */ protected $_appliedFixtures = []; @@ -59,8 +58,14 @@ protected function _getFixtures(TestCase $test, $scope = null) $existingFixtures = []; $objectManager = Bootstrap::getObjectManager(); $fixtureDirectivesParser = $objectManager->get(DataFixtureDirectivesParser::class); + $fixtureDataProviderAnnotation = $objectManager->get(DataFixtureDataProvider::class); + $fixtureDataProvider = $fixtureDataProviderAnnotation->getDataProvider($test); foreach ($annotations[$annotationKey] ?? [] as $fixture) { - $existingFixtures[] = $fixtureDirectivesParser->parse($fixture); + $metadata = $fixtureDirectivesParser->parse($fixture); + if ($metadata['name'] && empty($metadata['data']) && isset($fixtureDataProvider[$metadata['name']])) { + $metadata['data'] = $fixtureDataProvider[$metadata['name']]; + } + $existingFixtures[] = $metadata; } /* Need to be applied even test does not have added fixtures because fixture can be added via config */ @@ -97,14 +102,14 @@ protected function getAnnotations(TestCase $test): array */ protected function _applyFixtures(array $fixtures, TestCase $test) { - /** @var TestsIsolation $testsIsolation */ - $testsIsolation = Bootstrap::getObjectManager()->get(TestsIsolation::class); + $objectManager = Bootstrap::getObjectManager(); + $testsIsolation = $objectManager->get(TestsIsolation::class); $dbIsolationState = $this->getDbIsolationState($test); $testsIsolation->createDbSnapshot($test, $dbIsolationState); /* Execute fixture scripts */ foreach ($fixtures as $fixture) { - if (is_callable([get_class($test), $fixture['name']])) { - $fixture['name'] = get_class($test) . '::' . $fixture['name']; + if (is_callable([get_class($test), $fixture['factory']])) { + $fixture['factory'] = get_class($test) . '::' . $fixture['factory']; } $fixture['result'] = $this->applyDataFixture($fixture); $this->_appliedFixtures[] = $fixture; @@ -121,6 +126,7 @@ protected function _applyFixtures(array $fixtures, TestCase $test) */ protected function _revertFixtures(?TestCase $test = null) { + $objectManager = Bootstrap::getObjectManager(); $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType($this->getAnnotation()); $appliedFixtures = array_reverse($this->_appliedFixtures); @@ -132,9 +138,7 @@ protected function _revertFixtures(?TestCase $test = null) if (null !== $test) { /** @var TestsIsolation $testsIsolation */ - $testsIsolation = Bootstrap::getObjectManager()->get( - TestsIsolation::class - ); + $testsIsolation = $objectManager->get(TestsIsolation::class); $dbIsolationState = $this->getDbIsolationState($test); $testsIsolation->checkTestIsolation($test, $dbIsolationState); } @@ -173,44 +177,71 @@ abstract protected function getAnnotation(): string; /** * Applies data fixture and returns the result. * - * @param array $fixtureData + * @param array $fixture * @return array|null */ - private function applyDataFixture(array $fixtureData): ?array + private function applyDataFixture(array $fixture): ?array { - $dataFixtureFactory = Bootstrap::getObjectManager()->get(DataFixtureFactory::class); - $fixture = $dataFixtureFactory->create($fixtureData['name']); - $result = $fixture->apply($fixtureData['data'] ?? []); - if ($result !== null && isset($fixtureData['identifier'])) { + $objectManager = Bootstrap::getObjectManager(); + $dataFixtureSetup = $objectManager->get(DataFixtureSetup::class); + try { + $result = $dataFixtureSetup->apply($fixture['factory'], $fixture['data'] ?? []); + } catch (Throwable $exception) { + throw new Exception( + sprintf( + "Unable to apply fixture%s: %s.\n%s\n%s", + $fixture['name'] ? '"' . $fixture['name'] . '"' : '', + $fixture['factory'], + $exception->getMessage(), + $exception->getTraceAsString() + ), + 0, + $exception + ); + } + + if ($result !== null && !empty($fixture['name'])) { DataFixtureStorageManager::getStorage()->persist( - $fixtureData['identifier'], - Bootstrap::getObjectManager()->create(DataObject::class, ['data' => $result]) + $fixture['name'], + $objectManager->create(DataObject::class, ['data' => $result]) ); } + return $result; } /** * Revert data fixture. * - * @param array $fixtureData + * @param array $fixture */ - private function revertDataFixture(array $fixtureData): void + private function revertDataFixture(array $fixture): void { - $registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + $objectManager = Bootstrap::getObjectManager(); + $dataFixtureSetup = $objectManager->get(DataFixtureSetup::class); + $registry = $objectManager->get(Registry::class); $isSecureArea = $registry->registry('isSecureArea'); - $dataFixtureFactory = Bootstrap::getObjectManager()->get(DataFixtureFactory::class); - $fixture = $dataFixtureFactory->create($fixtureData['name']); - if ($fixture instanceof RevertibleDataFixtureInterface) { - try { - $registry->unregister('isSecureArea'); - $registry->register('isSecureArea', true); - $fixture->revert($fixtureData['result'] ?? []); - $registry->unregister('isSecureArea'); - $registry->register('isSecureArea', $isSecureArea); - } catch (NoSuchEntityException $exception) { - //ignore - } + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', true); + try { + $dataFixtureSetup->revert($fixture['factory'], $fixture['result'] ?? []); + } catch (NoSuchEntityException $exception) { + //ignore + } catch (Throwable $exception) { + throw new Exception( + sprintf( + "Unable to revert fixture%s: %s.\n%s\n%s", + $fixture['name'] ? '"' . $fixture['name'] . '"' : '', + $fixture['factory'], + $exception->getMessage(), + $exception->getTraceAsString() + ), + 0, + $exception + ); + } finally { + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', $isSecureArea); } } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDataProvider.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDataProvider.php new file mode 100644 index 0000000000000..38643ed13caa4 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDataProvider.php @@ -0,0 +1,46 @@ +getAnnotations($test); + $dataProvider = $annotations['method'][self::ANNOTATION] ?? $annotations['class'][self::ANNOTATION] ?? []; + $data = []; + if (isset($dataProvider[0])) { + if (is_callable([$test, $dataProvider[0]])) { + $data = call_user_func([$test, $dataProvider[0]]); + } elseif (is_callable($dataProvider[0])) { + $data = call_user_func($dataProvider[0]); + } else { + throw new Exception('Fixture dataprovider must be a callable'); + } + } + + return $data; + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php index fdd44d640df9a..242fc35cd8405 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Data/UniqueIdProcessor.php @@ -17,15 +17,11 @@ class UniqueIdProcessor implements ProcessorInterface private const PLACEHOLDER = '%uniqid%'; /** - * Fixture starting increment number - * * @var int */ private const INCREMENT = 1; /** - * Fixture's name storage - * * @var array */ private static $storage = []; @@ -41,7 +37,9 @@ public function process(DataFixtureInterface $fixture, array $data): array } $hash = self::$storage[$class]['prefix'] . self::$storage[$class]['increment']++; array_walk_recursive($data, function (&$value) use ($hash) { - $value = str_replace(self::PLACEHOLDER, $hash, $value); + if (is_string($value)) { + $value = str_replace(self::PLACEHOLDER, $hash, $value); + } }); return $data; } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php index 19daf2b436fe1..405833d6b20af 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php @@ -38,8 +38,8 @@ public function __construct( */ public function parse(string $fixture): array { - list($name, $directives) = array_pad(array_values(array_filter(explode(' ', $fixture, 2))), 2, ''); - $id = null; + list($factory, $directives) = array_pad(array_values(array_filter(explode(' ', $fixture, 2))), 2, ''); + $name = null; $data = []; if ($directives) { $json = '{}'; @@ -57,21 +57,21 @@ public function parse(string $fixture): array $data = $this->serializer->unserialize($json); break; case 'as': - $id = $value; + $name = $value; break; default: throw new \InvalidArgumentException("Unknown data fixture directive '$directive'"); } } } - if (strpos($name, '\\') !== false && !class_exists($name) && !is_callable($name)) { + if (strpos($factory, '\\') !== false && !class_exists($factory) && !is_callable($factory)) { // usage of a single directory separator symbol streamlines search across the source code throw new LocalizedException(__('Directory separator "\\" is prohibited in fixture declaration.')); } return [ - 'identifier' => $id, 'name' => $name, + 'factory' => $factory, 'data' => $data, ]; } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureSetup.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureSetup.php new file mode 100644 index 0000000000000..b80f7f06bf606 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureSetup.php @@ -0,0 +1,55 @@ +dataFixtureFactory = $dataFixtureFactory; + } + + /** + * Applies data fixture and returns the result + * + * @param string $factory + * @param array $data + * @return array|null + */ + public function apply(string $factory, array $data = []): ?array + { + $fixture = $this->dataFixtureFactory->create($factory); + return $fixture->apply($data); + } + + /** + * Revert data fixture + * + * @param string $factory + * @param array $data + */ + public function revert(string $factory, array $data): void + { + $fixture = $this->dataFixtureFactory->create($factory); + if ($fixture instanceof RevertibleDataFixtureInterface) { + $fixture->revert($data); + } + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php index 251804c324d5a..7b91974bb64d0 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php @@ -7,8 +7,6 @@ namespace Magento\TestFramework\Fixture; -use PHPUnit\Framework\Exception; - /** * File based data fixture */ @@ -64,15 +62,10 @@ private function execute(string $filePath): void { try { require $filePath; - } catch (\Exception $e) { - throw new Exception( - sprintf( - "Error in fixture: %s.\n %s\n %s", - $filePath, - $e->getMessage(), - $e->getTraceAsString() - ), - 500, + } catch (\Throwable $e) { + throw new \Exception( + 'Error in fixture: ' . $filePath, + 0, $e ); } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Applier/DataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Applier/DataFixture.php index 4793f72e76f29..9528282c288b2 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Applier/DataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Applier/DataFixture.php @@ -32,7 +32,7 @@ public function replace(string $fixture): string } $fixture = $this->replaceFixtures([$this->getFixtureAsArray($fixture)], $replacedFixtures); - return reset($fixture)['name']; + return reset($fixture)['factory']; } /** @@ -70,8 +70,8 @@ private function replaceFixtures(array $fixtures, array $replacedFixtures): arra { if ($replacedFixtures) { foreach ($fixtures as $key => $fixture) { - if (!empty($replacedFixtures[$fixture['name']])) { - $fixtures[$key] = $this->getFixtureAsArray($replacedFixtures[$fixture['name']]); + if (!empty($replacedFixtures[$fixture['factory']])) { + $fixtures[$key] = $this->getFixtureAsArray($replacedFixtures[$fixture['factory']]); } } } @@ -143,7 +143,7 @@ private function getFixturePosition(string $fixtureToFind, array $existingFixtur { $offset = false; foreach ($existingFixtures as $key => $fixture) { - if ($fixture['name'] === $fixtureToFind) { + if ($fixture['factory'] === $fixtureToFind) { $offset = $key; break; } @@ -173,7 +173,7 @@ private function insertFixture(array $fixtures, string $fixture, int $position): } /** - * Creates an array with the supplied fixture name + * Creates an array with the supplied fixture factory * * @param string $fixture * @return string[] @@ -181,7 +181,7 @@ private function insertFixture(array $fixtures, string $fixture, int $position): private function getFixtureAsArray(string $fixture): array { return [ - 'name' => $fixture + 'factory' => $fixture ]; } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php index 8f626cda089cc..4edc485c55b53 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php @@ -13,7 +13,7 @@ use Magento\TestFramework\Annotation\ConfigFixture; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Annotation\DataFixtureBeforeTransaction; -use Magento\TestFramework\Fixture\DataFixtureFactory; +use Magento\TestFramework\Fixture\DataFixtureSetup; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\ConfigInterface; use Magento\TestFramework\Workaround\Override\Fixture\Applier\AdminConfigFixture as AdminConfigFixtureApplier; @@ -49,9 +49,9 @@ class Resolver implements ResolverInterface private $currentFixtureType = null; /** - * @var DataFixtureFactory + * @var DataFixtureSetup */ - private $dataFixtureFactory; + private $dataFixtureSetup; /** * @param ConfigInterface $config @@ -60,7 +60,7 @@ public function __construct(ConfigInterface $config) { $this->config = $config; $this->objectManager = Bootstrap::getObjectManager(); - $this->dataFixtureFactory = $this->objectManager->create(DataFixtureFactory::class); + $this->dataFixtureSetup = $this->objectManager->create(DataFixtureSetup::class); } /** @@ -122,8 +122,7 @@ public function requireDataFixture(string $path): void } /** @var DataFixtureApplier $dataFixtureApplier */ $dataFixtureApplier = $this->getApplier($this->getCurrentTest(), $this->currentFixtureType); - $fixture = $this->dataFixtureFactory->create($dataFixtureApplier->replace($path)); - $fixture->apply(); + $this->dataFixtureSetup->apply($dataFixtureApplier->replace($path)); } /** diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php index 437e932ea0ca3..97bdf1b8e7e67 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php @@ -14,6 +14,7 @@ use Magento\TestFramework\Event\Param\Transaction; use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; use Magento\TestFramework\Fixture\DataFixtureInterface; +use Magento\TestFramework\Fixture\DataFixtureSetup; use Magento\TestFramework\Fixture\DataFixtureStorage; use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Fixture\LegacyDataFixturePathResolver; @@ -60,12 +61,14 @@ protected function setUp(): void ->getMockForAbstractClass(); DataFixtureStorageManager::setStorage(new DataFixtureStorage()); + $dataFixtureFactory = new DataFixtureFactory($objectManager); $sharedInstances = [ TestsIsolation::class => $this->testsIsolationMock, DataFixtureDirectivesParser::class => new DataFixtureDirectivesParser(new Json()), - DataFixtureFactory::class => new DataFixtureFactory($objectManager), + DataFixtureFactory::class => $dataFixtureFactory, LegacyDataFixture::class => $this->createMock(DataFixtureInterface::class), + DataFixtureSetup::class => new DataFixtureSetup($dataFixtureFactory), ]; $objectManager->expects($this->atLeastOnce()) ->method('get') diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php index 27298559a6394..c7e3a3ec5e9e9 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php @@ -59,8 +59,8 @@ public function directivesDataProvider(): array [ 'path/to/fixture.php as:test1 with:{"k1": "v1", "k2": ["v21", "v22"], "k3": {"k 31": "v 31"}}', [ - 'identifier' => 'test1', - 'name' => 'path/to/fixture.php', + 'name' => 'test1', + 'factory' => 'path/to/fixture.php', 'data' => [ 'k1' => 'v1', 'k2' => ['v21', 'v22'], @@ -71,8 +71,8 @@ public function directivesDataProvider(): array [ 'path/to/fixture.php with:{"k1": "v1", "k2": ["v21", "v22"], "k3": {"k 31": "v 31"}} as:test1', [ - 'identifier' => 'test1', - 'name' => 'path/to/fixture.php', + 'name' => 'test1', + 'factory' => 'path/to/fixture.php', 'data' => [ 'k1' => 'v1', 'k2' => ['v21', 'v22'], @@ -83,8 +83,8 @@ public function directivesDataProvider(): array [ 'path/to/fixture.php with:{"k1": "v1", "k2": ["v21", "v22"], "k3": {"k 31": "v 31"}}', [ - 'identifier' => null, - 'name' => 'path/to/fixture.php', + 'name' => null, + 'factory' => 'path/to/fixture.php', 'data' => [ 'k1' => 'v1', 'k2' => ['v21', 'v22'], @@ -95,8 +95,8 @@ public function directivesDataProvider(): array [ 'path/to/fixture.php as:test1', [ - 'identifier' => 'test1', - 'name' => 'path/to/fixture.php', + 'name' => 'test1', + 'factory' => 'path/to/fixture.php', 'data' => [], ] ], diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Override/Fixture/Applier/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Override/Fixture/Applier/DataFixtureTest.php index ffd9ebb732de4..5c301cafa4914 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Override/Fixture/Applier/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Override/Fixture/Applier/DataFixtureTest.php @@ -80,7 +80,7 @@ public function fixturesProvider(): array { return [ 'sort_fixtures_before_all' => [ - 'existing_fixtures' => [['name' => 'fixture']], + 'existing_fixtures' => [['factory' => 'fixture']], 'config' => [ [ 'path' => 'added_fixture', @@ -90,10 +90,10 @@ public function fixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => [['name' => 'added_fixture'], ['name' => 'fixture']], + 'expected_order' => [['factory' => 'added_fixture'], ['factory' => 'fixture']], ], 'sort_fixtures_after_all' => [ - 'existing_fixtures' => [['name' => 'fixture']], + 'existing_fixtures' => [['factory' => 'fixture']], 'config' => [ [ 'path' => 'added_fixture', @@ -103,10 +103,10 @@ public function fixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => [['name' => 'fixture'], ['name' => 'added_fixture']], + 'expected_order' => [['factory' => 'fixture'], ['factory' => 'added_fixture']], ], 'sort_fixture_before_specific' => [ - 'existing_fixtures' => [['name' => 'fixture1'], ['name' => 'fixture2']], + 'existing_fixtures' => [['factory' => 'fixture1'], ['factory' => 'fixture2']], 'config' => [ [ 'path' => 'added_fixture', @@ -116,10 +116,18 @@ public function fixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => [['name' => 'fixture1'], ['name' => 'added_fixture'], ['name' => 'fixture2']], + 'expected_order' => [ + ['factory' => 'fixture1'], + ['factory' => 'added_fixture'], + ['factory' => 'fixture2'] + ], ], 'sort_fixture_after_specific' => [ - 'existing_fixtures' => [['name' => 'fixture1'], ['name' => 'fixture2'], ['name' => 'fixture3']], + 'existing_fixtures' => [ + ['factory' => 'fixture1'], + ['factory' => 'fixture2'], + ['factory' => 'fixture3'] + ], 'config' => [ [ 'path' => 'added_fixture', @@ -130,10 +138,10 @@ public function fixturesProvider(): array ] ], 'expected_order' => [ - ['name' => 'fixture1'], - ['name' => 'fixture2'], - ['name' => 'added_fixture'], - ['name' => 'fixture3'] + ['factory' => 'fixture1'], + ['factory' => 'fixture2'], + ['factory' => 'added_fixture'], + ['factory' => 'fixture3'] ], ], ]; @@ -160,7 +168,7 @@ public function removeFixturesProvider(): array { return [ 'remove_fixture' => [ - 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture2']], + 'existing_fixtures' => [['factory' => 'fixture'], ['factory' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -170,10 +178,10 @@ public function removeFixturesProvider(): array 'remove' => true, ] ], - 'expected_order' => [['name' => 'fixture2']], + 'expected_order' => [['factory' => 'fixture2']], ], 'remove_one_of_same_fixtures' => [ - 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture'], ['name' => 'fixture2']], + 'existing_fixtures' => [['factory' => 'fixture'], ['factory' => 'fixture'], ['factory' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -183,10 +191,10 @@ public function removeFixturesProvider(): array 'remove' => true, ] ], - 'expected_order' => [['name' => 'fixture'], ['name' => 'fixture2']], + 'expected_order' => [['factory' => 'fixture'], ['factory' => 'fixture2']], ], 'remove_all_of_same_fixtures' => [ - 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture'], ['name' => 'fixture2']], + 'existing_fixtures' => [['factory' => 'fixture'], ['factory' => 'fixture'], ['factory' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -203,7 +211,7 @@ public function removeFixturesProvider(): array 'remove' => true, ] ], - 'expected_order' => [['name' => 'fixture2']], + 'expected_order' => [['factory' => 'fixture2']], ], ]; } @@ -229,7 +237,7 @@ public function replaceFixturesProvider(): array { return [ 'replace_one_fixture' => [ - 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture2']], + 'existing_fixtures' => [['factory' => 'fixture'], ['factory' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -239,10 +247,10 @@ public function replaceFixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => [['name' => 'new_fixture'], ['name' => 'fixture2']], + 'expected_order' => [['factory' => 'new_fixture'], ['factory' => 'fixture2']], ], 'replace_all_fixture' => [ - 'existing_fixtures' => [['name' => 'fixture'], ['name' => 'fixture'], ['name' => 'fixture2']], + 'existing_fixtures' => [['factory' => 'fixture'], ['factory' => 'fixture'], ['factory' => 'fixture2']], 'config' => [ [ 'path' => 'fixture', @@ -252,7 +260,11 @@ public function replaceFixturesProvider(): array 'remove' => false, ] ], - 'expected_order' => [['name' => 'new_fixture'], ['name' => 'new_fixture'], ['name' => 'fixture2']], + 'expected_order' => [ + ['factory' => 'new_fixture'], + ['factory' => 'new_fixture'], + ['factory' => 'fixture2'] + ], ], ]; } diff --git a/dev/tests/integration/phpunit.xml.dist b/dev/tests/integration/phpunit.xml.dist index 0197ecd88c735..75d78d58c7a48 100644 --- a/dev/tests/integration/phpunit.xml.dist +++ b/dev/tests/integration/phpunit.xml.dist @@ -131,6 +131,9 @@ magentoIndexerDimensionMode + + magentoDataFixtureDataProvider + diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateCategory.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateCategory.php new file mode 100644 index 0000000000000..7a0d0ace261b0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateCategory.php @@ -0,0 +1,119 @@ + 'Category%uniqid%', + 'parent_id' => self::DEFAULT_PARENT_ID, + 'is_active' => true, + 'position' => 1, + 'available_sort_by' => ['position', 'name'], + 'default_sort_by' => 'name' + ]; + + /** + * @var CategoryFactory + */ + private $categoryFactory; + + /** + * @var CategoryResource + */ + private $categoryResource; + + /** + * @var ProcessorInterface + */ + private $dataProcessor; + + /** + * @param CategoryFactory $categoryFactory + * @param CategoryResource $categoryResource + * @param ProcessorInterface $dataProcessor + */ + public function __construct( + CategoryFactory $categoryFactory, + CategoryResource $categoryResource, + ProcessorInterface $dataProcessor + ) { + $this->categoryFactory = $categoryFactory; + $this->categoryResource = $categoryResource; + $this->dataProcessor = $dataProcessor; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?array + { + $data = $this->prepareData($data); + /** @var \Magento\Catalog\Model\Category $category */ + $category = $this->categoryFactory->create(); + $category->isObjectNew(true); + $category->setData($data); + if (isset($data['id'])) { + $category->setId($data['id']); + } + $this->categoryResource->save($category); + + return [ + 'category' => $category + ]; + } + + /** + * Prepare category data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = $this->dataProcessor->process($this, array_merge(self::DEFAULT_DATA, $data)); + if (!isset($data['path'])) { + $data['path'] = self::DEFAULT_PARENT_PATH; + if ((int) $data['parent_id'] !== self::DEFAULT_PARENT_ID) { + /** @var \Magento\Catalog\Model\Category $parentCategory */ + $parentCategory = $this->categoryFactory->create(); + $this->categoryResource->load($parentCategory, $data['parent_id']); + $data['path'] = $parentCategory->getPath(); + } + if (isset($data['id'])) { + $data['path'] .= '/' . $data['id']; + } + } + return $data; + } + + /** + * @inheritdoc + */ + public function revert(array $data = []): void + { + /** @var \Magento\Catalog\Model\Category $category */ + $category = $this->categoryFactory->create(); + $this->categoryResource->load($category, $data['category']->getId()); + if ($category->getId()) { + $this->categoryResource->delete($category); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php index 765cac6435b44..f96694762747b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php @@ -127,7 +127,7 @@ private function merge(array ...$arrays): array $result[$key] = $value; } } - } elseif ($array) { + } elseif (array_values($result) === $result) { $result = $array; } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 4dd524bb3a16f..292ea9e4db994 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -155,9 +155,10 @@ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento/Catalog/_files/product_special_price.php + * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product * @magentoAppIsolation enabled * @magentoConfigFixture default_store catalog/price/scope 1 + * @magentoDataFixtureDataProvider productFixtureDataProvider */ public function testUpdateStoreSpecificSpecialPrice() { @@ -174,6 +175,21 @@ public function testUpdateStoreSpecificSpecialPrice() $this->assertEquals(5.99, $product->getSpecialPrice()); } + /** + * @return array + */ + public function productFixtureDataProvider(): array + { + return [ + 'product' => [ + 'sku' => 'simple', + 'custom_attributes' => [ + 'special_price' => 5.99 + ], + ] + ]; + } + /** * Checks that product has no attribute values for attributes not assigned to the product's attribute set. * diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php b/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php index 7599e72b88d04..1b88615756095 100644 --- a/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php @@ -14,6 +14,7 @@ /** * @magentoDbIsolation disabled + * @magentoDataFixtureDataProvider classFixtureDataProvider */ class DataFixtureTest extends TestCase { @@ -102,6 +103,87 @@ public function testFixtureClassWithParametersAndAlias(): void ); } + /** + * @magentoDataFixture afterTestFixtureClass + * @magentoDataFixture Magento\TestFramework\Fixture\TestOne as:test1 + * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo as:test2 + * @magentoDataFixture Magento\TestFramework\Fixture\TestThree as:test3 + * @magentoDataFixtureDataProvider methodFixtureDataProvider + */ + public function testMethodFixtureDataProvider(): void + { + $this->assertEquals( + [ + 'Magento\TestFramework\Fixture\TestOne' => true, + 'Magento\TestFramework\Fixture\TestTwo' => true, + 'test01' => 'value03', + 'test11' => 'value11', + 'test02' => 'value02', + ], + $this->dataStorage->getData('fixtures') + ); + } + + /** + * @return array + */ + public function methodFixtureDataProvider(): array + { + return [ + 'test1' => [ + 'test01' => 'value01', + 'test11' => 'value11', + ], + 'test2' => [ + 'test02' => 'value02', + ], + 'test3' => [ + 'key' => 'test01', + 'value' => 'value03', + ], + ]; + } + + /** + * @magentoDataFixture afterTestFixtureClass + * @magentoDataFixture Magento\TestFramework\Fixture\TestOne as:test1 + * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo as:test2 + * @magentoDataFixture Magento\TestFramework\Fixture\TestThree as:test3 + */ + public function testClassFixtureDataProvider(): void + { + $this->assertEquals( + [ + 'Magento\TestFramework\Fixture\TestOne' => true, + 'Magento\TestFramework\Fixture\TestTwo' => true, + 'test01' => 'class-value03', + 'test11' => 'class-value11', + 'test02' => 'class-value02', + ], + $this->dataStorage->getData('fixtures') + ); + } + + /** + * @return array + */ + public function classFixtureDataProvider(): array + { + return [ + 'test1' => [ + 'test01' => 'class-value01', + 'test11' => 'class-value11', + ], + 'test2' => [ + 'test02' => 'class-value02', + ], + 'test3' => [ + 'key' => 'test01', + 'value' => 'class-value03', + ], + ]; + } + public static function afterTestFixtureClass(): void { self::assertEmpty(Bootstrap::getObjectManager()->get(DataFixtureTestStorage::class)->getData('fixtures')); From de15fd26bb552f3e9e2247bdae98f3628ce11451 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Mon, 20 Sep 2021 09:58:47 -0500 Subject: [PATCH 26/29] MC-43250: Add support for data fixture class and fixture data provider in API functional tests --- .../Fixture/AddAttributeToAttributeSet.php | 22 +++------------ .../Catalog/Test/Fixture/Attribute.php | 6 ++-- .../Magento/Catalog/Test/Fixture/Category.php | 6 ++-- .../Magento/Catalog/Test/Fixture/Product.php | 6 ++-- .../api-functional/phpunit_graphql.xml.dist | 3 ++ .../api-functional/phpunit_rest.xml.dist | 3 ++ .../api-functional/phpunit_soap.xml.dist | 3 ++ .../Catalog/Api/CategoryRepositoryTest.php | 21 ++++++++++---- .../Magento/GraphQl/Catalog/CategoryTest.php | 4 +-- .../Magento/Test/Fixture/Api/ServiceTest.php | 8 +++++- .../Model/ResourceModel/ProductTest.php | 28 +++++++++---------- .../Wishlist/Controller/Index/CartTest.php | 4 +-- 12 files changed, 63 insertions(+), 51 deletions(-) rename dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php => app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php (70%) rename dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php => app/code/Magento/Catalog/Test/Fixture/Attribute.php (95%) rename dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateCategory.php => app/code/Magento/Catalog/Test/Fixture/Category.php (96%) rename dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php => app/code/Magento/Catalog/Test/Fixture/Product.php (96%) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php b/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php similarity index 70% rename from dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php rename to app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php index d9a7da6dc4ab0..262808df43645 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/AddProductAttributeToAttributeSet.php +++ b/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php @@ -5,18 +5,18 @@ */ declare(strict_types=1); -namespace Magento\Catalog\Fixture; +namespace Magento\Catalog\Test\Fixture; use Magento\Catalog\Api\ProductAttributeManagementInterface; use Magento\Catalog\Model\Product; use Magento\Eav\Setup\EavSetup; use Magento\TestFramework\Fixture\Api\ServiceFactory; -use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; +use Magento\TestFramework\Fixture\DataFixtureInterface; /** - * Add product attribute to attribute set fixture + * Add product attribute to attribute set */ -class AddProductAttributeToAttributeSet implements RevertibleDataFixtureInterface +class AddAttributeToAttributeSet implements DataFixtureInterface { /** * @var ServiceFactory @@ -62,18 +62,4 @@ public function apply(array $data = []): ?array return $data; } - - /** - * @inheritdoc - */ - public function revert(array $data = []): void - { - $service = $this->serviceFactory->create(ProductAttributeManagementInterface::class, 'unassign'); - $service->execute( - [ - 'attribute_set_id' => $data['attribute_set_id'], - 'attribute_code' => $data['attribute_code'], - ] - ); - } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php b/app/code/Magento/Catalog/Test/Fixture/Attribute.php similarity index 95% rename from dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php rename to app/code/Magento/Catalog/Test/Fixture/Attribute.php index 81b78c70659d0..11df1b913e67e 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateProductAttribute.php +++ b/app/code/Magento/Catalog/Test/Fixture/Attribute.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\Catalog\Fixture; +namespace Magento\Catalog\Test\Fixture; use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\TestFramework\Fixture\Api\ServiceFactory; @@ -13,9 +13,9 @@ use Magento\TestFramework\Fixture\Data\ProcessorInterface; /** - * Create product attribute fixture + * Creates product attribute fixture */ -class CreateProductAttribute implements RevertibleDataFixtureInterface +class Attribute implements RevertibleDataFixtureInterface { private const DEFAULT_DATA = [ 'is_wysiwyg_enabled' => false, diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateCategory.php b/app/code/Magento/Catalog/Test/Fixture/Category.php similarity index 96% rename from dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateCategory.php rename to app/code/Magento/Catalog/Test/Fixture/Category.php index 7a0d0ace261b0..fd858b4a4e8a4 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateCategory.php +++ b/app/code/Magento/Catalog/Test/Fixture/Category.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\Catalog\Fixture; +namespace Magento\Catalog\Test\Fixture; use Magento\Catalog\Model\CategoryFactory; use Magento\Catalog\Model\ResourceModel\Category as CategoryResource; @@ -13,9 +13,9 @@ use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; /** - * Create categpry fixture + * Creates category fixture */ -class CreateCategory implements RevertibleDataFixtureInterface +class Category implements RevertibleDataFixtureInterface { private const DEFAULT_PARENT_ID = 2; diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php b/app/code/Magento/Catalog/Test/Fixture/Product.php similarity index 96% rename from dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php rename to app/code/Magento/Catalog/Test/Fixture/Product.php index f96694762747b..31cb385eb6752 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Fixture/CreateSimpleProduct.php +++ b/app/code/Magento/Catalog/Test/Fixture/Product.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\Catalog\Fixture; +namespace Magento\Catalog\Test\Fixture; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product\Attribute\Source\Status; @@ -16,9 +16,9 @@ use Magento\TestFramework\Fixture\Data\ProcessorInterface; /** - * Create simple product fixture + * Creates simple product fixture */ -class CreateSimpleProduct implements RevertibleDataFixtureInterface +class Product implements RevertibleDataFixtureInterface { private const DEFAULT_DATA = [ 'type_id' => Type::TYPE_SIMPLE, diff --git a/dev/tests/api-functional/phpunit_graphql.xml.dist b/dev/tests/api-functional/phpunit_graphql.xml.dist index fc49642eaa721..650d6f33cfef6 100644 --- a/dev/tests/api-functional/phpunit_graphql.xml.dist +++ b/dev/tests/api-functional/phpunit_graphql.xml.dist @@ -110,6 +110,9 @@ Override + + magentoDataFixtureDataProvider + diff --git a/dev/tests/api-functional/phpunit_rest.xml.dist b/dev/tests/api-functional/phpunit_rest.xml.dist index f12905369245b..691320476029e 100644 --- a/dev/tests/api-functional/phpunit_rest.xml.dist +++ b/dev/tests/api-functional/phpunit_rest.xml.dist @@ -116,6 +116,9 @@ Override + + magentoDataFixtureDataProvider + diff --git a/dev/tests/api-functional/phpunit_soap.xml.dist b/dev/tests/api-functional/phpunit_soap.xml.dist index 6897807a3e052..590f861ee0f49 100644 --- a/dev/tests/api-functional/phpunit_soap.xml.dist +++ b/dev/tests/api-functional/phpunit_soap.xml.dist @@ -115,6 +115,9 @@ Override + + magentoDataFixtureDataProvider + diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php index 2e8eedf96b0f8..9c46054d7a76f 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php @@ -17,6 +17,8 @@ use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; use Magento\Integration\Api\AdminTokenServiceInterface; use Magento\Store\Model\Store; +use Magento\TestFramework\Fixture\DataFixtureStorage; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; use Magento\UrlRewrite\Model\Storage\DbStorage; @@ -32,6 +34,9 @@ class CategoryRepositoryTest extends WebapiAbstract const RESOURCE_PATH = '/V1/categories'; const SERVICE_NAME = 'catalogCategoryRepositoryV1'; + /** + * @var int + */ private $modelId = 333; /** @@ -54,6 +59,11 @@ class CategoryRepositoryTest extends WebapiAbstract */ private $createdCategories; + /** + * @var DataFixtureStorage + */ + private $fixtures; + /** * @inheritDoc */ @@ -64,6 +74,7 @@ protected function setUp(): void $this->roleFactory = Bootstrap::getObjectManager()->get(RoleFactory::class); $this->rulesFactory = Bootstrap::getObjectManager()->get(RulesFactory::class); $this->adminTokens = Bootstrap::getObjectManager()->get(AdminTokenServiceInterface::class); + $this->fixtures = Bootstrap::getObjectManager()->get(DataFixtureStorageManager::class)->getStorage(); } /** @@ -230,7 +241,7 @@ private function buildExceptionMessage(int $categoryId): string } /** - * @magentoApiDataFixture Magento/Catalog/_files/category.php + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":333} */ public function testUpdate() { @@ -257,11 +268,11 @@ public function testUpdate() } /** - * @magentoApiDataFixture Magento/Catalog/_files/category.php + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category as:category */ public function testUpdateWithDefaultSortByAttribute() { - $categoryId = 333; + $categoryId = $this->fixtures->get('category')->getCategory()->getId(); $categoryData = [ 'name' => 'Update Category Test With default_sort_by Attribute', 'is_active' => true, @@ -285,7 +296,7 @@ public function testUpdateWithDefaultSortByAttribute() } /** - * @magentoApiDataFixture Magento/Catalog/_files/category.php + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":333} */ public function testUpdateUrlKey() { @@ -590,7 +601,7 @@ public function testSaveDesign(): void /** * Check if repository does not override default values for attributes out of request * - * @magentoApiDataFixture Magento/Catalog/_files/category.php + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":333} */ public function testUpdateScopeAttribute() { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index d080f87d6a148..7bba82049e58e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -275,7 +275,7 @@ public function testCategoriesTreeWithDisabledCategory() } /** - * @magentoApiDataFixture Magento/Catalog/_files/categories.php + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":13,"name":"Category 1.2"} */ public function testGetCategoryById() { @@ -294,7 +294,7 @@ public function testGetCategoryById() } /** - * @magentoApiDataFixture Magento/Catalog/_files/categories.php + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":8,"is_active":false} */ public function testGetDisabledCategory() { diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Api/ServiceTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Api/ServiceTest.php index 255a5fdab92e3..b6df04721103f 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Api/ServiceTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/Api/ServiceTest.php @@ -16,6 +16,8 @@ /** * Test fixture api service + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ class ServiceTest extends TestCase { @@ -40,7 +42,11 @@ protected function setUp(): void $serviceInputProcessor = $this->createMock(ServiceInputProcessor::class); $serviceInputProcessor->expects($this->once()) ->method('process') - ->willReturnArgument(2); + ->willReturnCallback( + function (string $serviceClassName, string $serviceMethodName, array $params) { + return array_values($params); + } + ); $this->fakeClass = $this->getMockBuilder(stdClass::class) ->addMethods(['fakeMethod']) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 292ea9e4db994..b9a7c005749f1 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -52,7 +52,7 @@ protected function setUp(): void /** * Checks a possibility to retrieve product raw attribute value. * - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} */ public function testGetAttributeRawValue() { @@ -66,9 +66,9 @@ public function testGetAttributeRawValue() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute"} - * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "fixture_attribute"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -86,9 +86,9 @@ public function testGetAttributeRawValueGetDefault() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute"} - * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "fixture_attribute"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -110,9 +110,9 @@ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute"} - * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "fixture_attribute"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -134,9 +134,9 @@ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateProductAttribute with:{"attribute_code": "fixture_attribute"} - * @magentoDataFixture Magento\Catalog\Fixture\AddProductAttributeToAttributeSet - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct with:{"sku": "simple"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "fixture_attribute"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException * @throws InputException @@ -155,7 +155,7 @@ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product as:product * @magentoAppIsolation enabled * @magentoConfigFixture default_store catalog/price/scope 1 * @magentoDataFixtureDataProvider productFixtureDataProvider diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php index 77b6e5b800ab6..4ec4438f7a049 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php @@ -118,8 +118,8 @@ public function testAddNotExistingItemToCart(): void * * @return void * @magentoDataFixture Magento/Wishlist/_files/wishlist_with_simple_product.php - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product1 - * @magentoDataFixture Magento\Catalog\Fixture\CreateSimpleProduct as:product2 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product as:product1 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product as:product2 */ public function testAddItemWithRelatedProducts(): void { From 1a3e06d756e79f26de850a1efdd64feb36251ef6 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Mon, 20 Sep 2021 09:58:47 -0500 Subject: [PATCH 27/29] MC-40746: Add support for variables in fixture parameters --- .../Fixture/AddAttributeToAttributeSet.php | 8 +- .../Catalog/Test/Fixture/Attribute.php | 33 +- .../Magento/Catalog/Test/Fixture/Category.php | 115 +++--- .../Magento/Catalog/Test/Fixture/Product.php | 74 ++-- .../Quote/Test/Fixture/AddProductToCart.php | 50 +++ .../Magento/Quote/Test/Fixture/GuestCart.php | 91 +++++ .../Quote/Test/Fixture/SetBillingAddress.php | 59 +++ .../Quote/Test/Fixture/SetShippingAddress.php | 56 +++ app/code/Magento/Store/Test/Fixture/Group.php | 101 +++++ app/code/Magento/Store/Test/Fixture/Store.php | 114 ++++++ .../Magento/Store/Test/Fixture/Website.php | 104 +++++ .../Catalog/Api/CategoryRepositoryTest.php | 16 +- .../Magento/GraphQl/Catalog/CategoryTest.php | 17 +- .../GraphQl/Quote/Guest/CartTotalsTest.php | 29 +- .../Annotation/AbstractDataFixture.php | 85 +--- .../Annotation/DataFixtureDataProvider.php | 46 ++- .../DataFixtureDirectivesParser.php | 2 +- .../Annotation/DataFixtureSetup.php | 147 +++++++ .../TestFramework/Fixture/Api/DataMerger.php | 129 ++++++ .../Fixture/CallableDataFixture.php | 6 +- .../Fixture/DataFixtureInterface.php | 6 +- .../Fixture/DataFixtureSetup.php | 55 --- .../Fixture/DataFixtureStorage.php | 12 +- .../Fixture/LegacyDataFixture.php | 6 +- .../RevertibleDataFixtureInterface.php | 6 +- .../Workaround/Override/Fixture/Resolver.php | 4 +- .../framework/tests/unit/phpunit.xml.dist | 5 +- .../DataFixtureDirectivesParserTest.php | 4 +- .../Test/Annotation/DataFixtureTest.php | 370 ++++++++++++++++-- .../Test/Fixture/CallableDataFixtureTest.php | 5 +- .../Test/Fixture/LegacyDataFixtureTest.php | 3 +- .../Product/Attribute/Backend/PriceTest.php | 48 ++- .../ResourceModel/Product/CollectionTest.php | 21 +- .../Model/ResourceModel/ProductTest.php | 4 +- .../Annotation/DataFixtureTest.php | 196 ---------- .../TestFramework/DataFixtureTestStorage.php | 17 - .../Magento/TestFramework/Fixture/TestOne.php | 52 --- .../TestFramework/Fixture/TestThree.php | 40 -- .../Magento/TestFramework/Fixture/TestTwo.php | 15 - .../Wishlist/Controller/Index/CartTest.php | 4 +- 40 files changed, 1476 insertions(+), 679 deletions(-) create mode 100644 app/code/Magento/Quote/Test/Fixture/AddProductToCart.php create mode 100644 app/code/Magento/Quote/Test/Fixture/GuestCart.php create mode 100644 app/code/Magento/Quote/Test/Fixture/SetBillingAddress.php create mode 100644 app/code/Magento/Quote/Test/Fixture/SetShippingAddress.php create mode 100644 app/code/Magento/Store/Test/Fixture/Group.php create mode 100644 app/code/Magento/Store/Test/Fixture/Store.php create mode 100644 app/code/Magento/Store/Test/Fixture/Website.php rename dev/tests/integration/framework/Magento/TestFramework/{Fixture => Annotation}/DataFixtureDirectivesParser.php (98%) create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureSetup.php create mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/DataMerger.php delete mode 100644 dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureSetup.php rename dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/{Fixture => Annotation}/DataFixtureDirectivesParserTest.php (96%) delete mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php delete mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/DataFixtureTestStorage.php delete mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestOne.php delete mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php delete mode 100644 dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestTwo.php diff --git a/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php b/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php index 262808df43645..53c60cca5af3a 100644 --- a/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php +++ b/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php @@ -10,12 +10,10 @@ use Magento\Catalog\Api\ProductAttributeManagementInterface; use Magento\Catalog\Model\Product; use Magento\Eav\Setup\EavSetup; +use Magento\Framework\DataObject; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\DataFixtureInterface; -/** - * Add product attribute to attribute set - */ class AddAttributeToAttributeSet implements DataFixtureInterface { /** @@ -43,7 +41,7 @@ public function __construct( /** * @inheritdoc */ - public function apply(array $data = []): ?array + public function apply(array $data = []): ?DataObject { $attributeSetId = $this->eavSetup->getAttributeSetId(Product::ENTITY, 'Default'); $attributeGroupId = $this->eavSetup->getDefaultAttributeGroupId(Product::ENTITY, $attributeSetId); @@ -60,6 +58,6 @@ public function apply(array $data = []): ?array $service = $this->serviceFactory->create(ProductAttributeManagementInterface::class, 'assign'); $service->execute($data); - return $data; + return null; } } diff --git a/app/code/Magento/Catalog/Test/Fixture/Attribute.php b/app/code/Magento/Catalog/Test/Fixture/Attribute.php index 11df1b913e67e..fedaa86e83517 100644 --- a/app/code/Magento/Catalog/Test/Fixture/Attribute.php +++ b/app/code/Magento/Catalog/Test/Fixture/Attribute.php @@ -8,13 +8,11 @@ namespace Magento\Catalog\Test\Fixture; use Magento\Catalog\Api\ProductAttributeRepositoryInterface; +use Magento\Framework\DataObject; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; use Magento\TestFramework\Fixture\Data\ProcessorInterface; -/** - * Creates product attribute fixture - */ class Attribute implements RevertibleDataFixtureInterface { private const DEFAULT_DATA = [ @@ -74,31 +72,40 @@ public function __construct( /** * @inheritdoc */ - public function apply(array $data = []): ?array + public function apply(array $data = []): ?DataObject { $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'save'); - $fixtureData = array_merge(self::DEFAULT_DATA, $data); - $result = $service->execute( + + return $service->execute( [ - 'attribute' => $this->dataProcessor->process($this, $fixtureData) + 'attribute' => $this->prepareData($data) ] ); - - return [ - 'attribute' => $result - ]; } /** * @inheritdoc */ - public function revert(array $data = []): void + public function revert(DataObject $data): void { $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'deleteById'); $service->execute( [ - 'attributeCode' => $data['attribute']->getAttributeCode() + 'attributeCode' => $data->getAttributeCode() ] ); } + + /** + * Prepare attribute data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + + return $this->dataProcessor->process($this, $data); + } } diff --git a/app/code/Magento/Catalog/Test/Fixture/Category.php b/app/code/Magento/Catalog/Test/Fixture/Category.php index fd858b4a4e8a4..bec0d3ea06abc 100644 --- a/app/code/Magento/Catalog/Test/Fixture/Category.php +++ b/app/code/Magento/Catalog/Test/Fixture/Category.php @@ -7,77 +7,86 @@ namespace Magento\Catalog\Test\Fixture; -use Magento\Catalog\Model\CategoryFactory; -use Magento\Catalog\Model\ResourceModel\Category as CategoryResource; +use Magento\Catalog\Api\CategoryRepositoryInterface; +use Magento\Framework\DataObject; +use Magento\TestFramework\Fixture\Api\DataMerger; +use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\Data\ProcessorInterface; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; -/** - * Creates category fixture - */ class Category implements RevertibleDataFixtureInterface { - private const DEFAULT_PARENT_ID = 2; - - private const DEFAULT_PARENT_PATH = '1/2'; - private const DEFAULT_DATA = [ + 'id' => null, 'name' => 'Category%uniqid%', - 'parent_id' => self::DEFAULT_PARENT_ID, + 'parent_id' => 2, 'is_active' => true, 'position' => 1, - 'available_sort_by' => ['position', 'name'], - 'default_sort_by' => 'name' + 'level' => 1, + 'path' => null, + 'include_in_menu' => true, + 'available_sort_by' => [], + 'custom_attributes' => [ + 'default_sort_by' => ['name'] + ], + 'extension_attributes' => [], + 'created_at' => null, + 'updated_at' => null, ]; /** - * @var CategoryFactory - */ - private $categoryFactory; - - /** - * @var CategoryResource + * @var ServiceFactory */ - private $categoryResource; + private $serviceFactory; /** * @var ProcessorInterface */ private $dataProcessor; + /** + * @var DataMerger + */ + private $dataMerger; /** - * @param CategoryFactory $categoryFactory - * @param CategoryResource $categoryResource + * @param ServiceFactory $serviceFactory * @param ProcessorInterface $dataProcessor */ public function __construct( - CategoryFactory $categoryFactory, - CategoryResource $categoryResource, - ProcessorInterface $dataProcessor + ServiceFactory $serviceFactory, + ProcessorInterface $dataProcessor, + DataMerger $dataMerger ) { - $this->categoryFactory = $categoryFactory; - $this->categoryResource = $categoryResource; + $this->serviceFactory = $serviceFactory; $this->dataProcessor = $dataProcessor; + $this->dataMerger = $dataMerger; } /** * @inheritdoc */ - public function apply(array $data = []): ?array + public function apply(array $data = []): ?DataObject { - $data = $this->prepareData($data); - /** @var \Magento\Catalog\Model\Category $category */ - $category = $this->categoryFactory->create(); - $category->isObjectNew(true); - $category->setData($data); - if (isset($data['id'])) { - $category->setId($data['id']); - } - $this->categoryResource->save($category); + $service = $this->serviceFactory->create(CategoryRepositoryInterface::class, 'save'); + + return $service->execute( + [ + 'category' => $this->prepareData($data) + ] + ); + } - return [ - 'category' => $category - ]; + /** + * @inheritdoc + */ + public function revert(DataObject $data): void + { + $service = $this->serviceFactory->create(CategoryRepositoryInterface::class, 'deleteByIdentifier'); + $service->execute( + [ + 'categoryId' => $data->getId() + ] + ); } /** @@ -88,32 +97,8 @@ public function apply(array $data = []): ?array */ private function prepareData(array $data): array { - $data = $this->dataProcessor->process($this, array_merge(self::DEFAULT_DATA, $data)); - if (!isset($data['path'])) { - $data['path'] = self::DEFAULT_PARENT_PATH; - if ((int) $data['parent_id'] !== self::DEFAULT_PARENT_ID) { - /** @var \Magento\Catalog\Model\Category $parentCategory */ - $parentCategory = $this->categoryFactory->create(); - $this->categoryResource->load($parentCategory, $data['parent_id']); - $data['path'] = $parentCategory->getPath(); - } - if (isset($data['id'])) { - $data['path'] .= '/' . $data['id']; - } - } - return $data; - } + $data = $this->dataMerger->merge(self::DEFAULT_DATA, $data); - /** - * @inheritdoc - */ - public function revert(array $data = []): void - { - /** @var \Magento\Catalog\Model\Category $category */ - $category = $this->categoryFactory->create(); - $this->categoryResource->load($category, $data['category']->getId()); - if ($category->getId()) { - $this->categoryResource->delete($category); - } + return $this->dataProcessor->process($this, $data); } } diff --git a/app/code/Magento/Catalog/Test/Fixture/Product.php b/app/code/Magento/Catalog/Test/Fixture/Product.php index 31cb385eb6752..cd3ad0fafef5e 100644 --- a/app/code/Magento/Catalog/Test/Fixture/Product.php +++ b/app/code/Magento/Catalog/Test/Fixture/Product.php @@ -11,20 +11,20 @@ use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Catalog\Model\Product\Type; use Magento\Catalog\Model\Product\Visibility; +use Magento\Framework\DataObject; +use Magento\TestFramework\Fixture\Api\DataMerger; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; use Magento\TestFramework\Fixture\Data\ProcessorInterface; -/** - * Creates simple product fixture - */ class Product implements RevertibleDataFixtureInterface { private const DEFAULT_DATA = [ + 'id' => null, 'type_id' => Type::TYPE_SIMPLE, 'attribute_set_id' => 4, - 'name' => 'Simple Product %uniqid%', - 'sku' => 'simple_%uniqid%', + 'name' => 'Simple Product%uniqid%', + 'sku' => 'simple%uniqid%', 'price' => 10, 'weight' => 1, 'visibility' => Visibility::VISIBILITY_BOTH, @@ -34,6 +34,7 @@ class Product implements RevertibleDataFixtureInterface ], 'extension_attributes' => [ 'website_ids' => [1], + 'category_links' => [], 'stock_item' => [ 'use_config_manage_stock' => true, 'qty' => 100, @@ -41,6 +42,12 @@ class Product implements RevertibleDataFixtureInterface 'is_in_stock' => true, ] ], + 'product_links' => [], + 'options' => [], + 'media_gallery_entries' => [], + 'tier_prices' => [], + 'created_at' => null, + 'updated_at' => null, ]; /** @@ -53,44 +60,48 @@ class Product implements RevertibleDataFixtureInterface */ private $dataProcessor; + /** + * @var DataMerger + */ + private $dataMerger; + /** * @param ServiceFactory $serviceFactory * @param ProcessorInterface $dataProcessor */ public function __construct( ServiceFactory $serviceFactory, - ProcessorInterface $dataProcessor + ProcessorInterface $dataProcessor, + DataMerger $dataMerger ) { $this->serviceFactory = $serviceFactory; $this->dataProcessor = $dataProcessor; + $this->dataMerger = $dataMerger; } /** * @inheritdoc */ - public function apply(array $data = []): ?array + public function apply(array $data = []): ?DataObject { $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'save'); - $result = $service->execute( + + return $service->execute( [ - 'product' => $this->dataProcessor->process($this, $this->prepareData($data)) + 'product' => $this->prepareData($data) ] ); - - return [ - 'product' => $result - ]; } /** * @inheritdoc */ - public function revert(array $data = []): void + public function revert(DataObject $data): void { $service = $this->serviceFactory->create(ProductRepositoryInterface::class, 'deleteById'); $service->execute( [ - 'sku' => $data['product']->getSku() + 'sku' => $data->getSku() ] ); } @@ -103,35 +114,12 @@ public function revert(array $data = []): void */ private function prepareData(array $data): array { - $default = self::DEFAULT_DATA; - return $this->merge($default, $data); - } - - /** - * Recursively merge product data - * - * @param array $arrays - * @return array - */ - private function merge(array ...$arrays): array - { - $result = []; - while ($arrays) { - $array = array_shift($arrays); - // is array an associative array - if (array_values($array) !== $array) { - foreach ($array as $key => $value) { - if (is_array($value) && array_key_exists($key, $result) && is_array($result[$key])) { - $result[$key] = $this->merge($result[$key], $value); - } else { - $result[$key] = $value; - } - } - } elseif (array_values($result) === $result) { - $result = $array; - } + $data = $this->dataMerger->merge(self::DEFAULT_DATA, $data); + // remove category_links if empty in order for category_ids to processed if exists + if (empty($data['extension_attributes']['category_links'])) { + unset($data['extension_attributes']['category_links']); } - return $result; + return $this->dataProcessor->process($this, $data); } } diff --git a/app/code/Magento/Quote/Test/Fixture/AddProductToCart.php b/app/code/Magento/Quote/Test/Fixture/AddProductToCart.php new file mode 100644 index 0000000000000..059a372f92f6b --- /dev/null +++ b/app/code/Magento/Quote/Test/Fixture/AddProductToCart.php @@ -0,0 +1,50 @@ +cartRepository = $cartRepository; + $this->productRepository = $productRepository; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + $cart = $this->cartRepository->get($data['cart_id']); + $product = $this->productRepository->getById($data['product_id']); + $catItem = $cart->addProduct($product, $data['qty'] ?? 1); + $this->cartRepository->save($cart); + return $catItem; + } +} diff --git a/app/code/Magento/Quote/Test/Fixture/GuestCart.php b/app/code/Magento/Quote/Test/Fixture/GuestCart.php new file mode 100644 index 0000000000000..ae724f36f50e3 --- /dev/null +++ b/app/code/Magento/Quote/Test/Fixture/GuestCart.php @@ -0,0 +1,91 @@ +cartRepository = $cartRepository; + $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->guestCartManagement = $guestCartManagement; + $this->quoteResource = $quoteResource; + $this->quoteFactory = $quoteFactory; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + $maskId = $this->guestCartManagement->createEmptyCart(); + $cartId = $this->maskedQuoteIdToQuoteId->execute($maskId); + + return $this->cartRepository->get($cartId); + } + + /** + * @inheritdoc + */ + public function revert(DataObject $data): void + { + /** @var Quote $cart */ + $cart = $data; + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, $cart->getId()); + if ($quote->getId()) { + $this->cartRepository->delete($cart); + } + } +} diff --git a/app/code/Magento/Quote/Test/Fixture/SetBillingAddress.php b/app/code/Magento/Quote/Test/Fixture/SetBillingAddress.php new file mode 100644 index 0000000000000..5b86b8190ad1e --- /dev/null +++ b/app/code/Magento/Quote/Test/Fixture/SetBillingAddress.php @@ -0,0 +1,59 @@ + 3468676, + AddressInterface::KEY_POSTCODE => 75477, + AddressInterface::KEY_COUNTRY_ID => 'US', + AddressInterface::KEY_CITY => 'CityM', + AddressInterface::KEY_COMPANY => 'CompanyName', + AddressInterface::KEY_STREET => ['Green str, 67'], + AddressInterface::KEY_LASTNAME => 'Smith', + AddressInterface::KEY_FIRSTNAME => 'John', + AddressInterface::KEY_REGION_ID => 1, + ]; + + /** + * @var ServiceFactory + */ + private $serviceFactory; + + /** + * @param ServiceFactory $serviceFactory + */ + public function __construct( + ServiceFactory $serviceFactory + ) { + $this->serviceFactory = $serviceFactory; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + $service = $this->serviceFactory->create(BillingAddressManagementInterface::class, 'assign'); + + $service->execute( + [ + 'cartId' => $data['cart_id'], + 'address' => array_merge(self::DEFAULT_DATA, $data['address'] ?? []) + ] + ); + return null; + } +} diff --git a/app/code/Magento/Quote/Test/Fixture/SetShippingAddress.php b/app/code/Magento/Quote/Test/Fixture/SetShippingAddress.php new file mode 100644 index 0000000000000..e817e4578defe --- /dev/null +++ b/app/code/Magento/Quote/Test/Fixture/SetShippingAddress.php @@ -0,0 +1,56 @@ + 3468676, + AddressInterface::KEY_POSTCODE => '75477', + AddressInterface::KEY_COUNTRY_ID => 'US', + AddressInterface::KEY_CITY => 'CityM', + AddressInterface::KEY_COMPANY => 'CompanyName', + AddressInterface::KEY_STREET => ['Green str, 67'], + AddressInterface::KEY_LASTNAME => 'Smith', + AddressInterface::KEY_FIRSTNAME => 'John', + AddressInterface::KEY_REGION_ID => 1, + ]; + + /** + * @var ServiceFactory + */ + private $serviceFactory; + + public function __construct( + ServiceFactory $serviceFactory + ) { + $this->serviceFactory = $serviceFactory; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + $service = $this->serviceFactory->create(ShippingAddressManagementInterface::class, 'assign'); + + $service->execute( + [ + 'cartId' => $data['cart_id'], + 'address' => array_merge(self::DEFAULT_DATA, $data['address'] ?? []) + ] + ); + return null; + } +} diff --git a/app/code/Magento/Store/Test/Fixture/Group.php b/app/code/Magento/Store/Test/Fixture/Group.php new file mode 100644 index 0000000000000..950e457e1d0f8 --- /dev/null +++ b/app/code/Magento/Store/Test/Fixture/Group.php @@ -0,0 +1,101 @@ + 'test_store_group%uniqid%', + 'name' => 'Test Store Group%uniqid%', + ]; + + /** + * @var GroupInterfaceFactory + */ + private $groupFactory; + + /** + * @var GroupResource + */ + private $groupResource; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var DefaultCategory + */ + private $defaultCategory; + + /** + * @var ProcessorInterface + */ + private $dataProcessor; + + /** + * @param GroupInterfaceFactory $groupFactory + * @param GroupResource $groupResource + * @param StoreManagerInterface $storeManager + * @param DefaultCategory $defaultCategory + * @param ProcessorInterface $dataProcessor + */ + public function __construct( + GroupInterfaceFactory $groupFactory, + GroupResource $groupResource, + StoreManagerInterface $storeManager, + DefaultCategory $defaultCategory, + ProcessorInterface $dataProcessor + ) { + $this->groupFactory = $groupFactory; + $this->groupResource = $groupResource; + $this->storeManager = $storeManager; + $this->defaultCategory = $defaultCategory; + $this->dataProcessor = $dataProcessor; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + /** @var GroupInterface $group */ + $group = $this->groupFactory->create(); + $group->setData($this->prepareData($data)); + $this->groupResource->save($group); + $this->storeManager->reinitStores(); + + return $group; + } + + /** + * Prepare store group data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $defaultData = self::DEFAULT_DATA; + $defaultData['root_category_id'] = $this->defaultCategory->getId(); + $defaultData['website_id'] = $this->storeManager->getDefaultStoreView()->getWebsiteId(); + $data = array_merge($defaultData, $data); + + return $this->dataProcessor->process($this, $data); + } +} diff --git a/app/code/Magento/Store/Test/Fixture/Store.php b/app/code/Magento/Store/Test/Fixture/Store.php new file mode 100644 index 0000000000000..0fdf835b83cc9 --- /dev/null +++ b/app/code/Magento/Store/Test/Fixture/Store.php @@ -0,0 +1,114 @@ + 'test_store_view%uniqid%', + 'name' => 'Test Store View%uniqid%', + 'sort_order' => '1' + ]; + + /** + * @var StoreInterfaceFactory + */ + private $storeFactory; + + /** + * @var StoreResource + */ + private $storeResource; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var ProcessorInterface + */ + private $dataProcessor; + + /** + * @param StoreInterfaceFactory $storeFactory + * @param StoreResource $storeResource + * @param StoreManagerInterface $storeManager + * @param ProcessorInterface $dataProcessor + */ + public function __construct( + StoreInterfaceFactory $storeFactory, + StoreResource $storeResource, + StoreManagerInterface $storeManager, + ProcessorInterface $dataProcessor + ) { + $this->storeFactory = $storeFactory; + $this->storeResource = $storeResource; + $this->storeManager = $storeManager; + $this->dataProcessor = $dataProcessor; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + /** @var StoreInterface $store */ + $store = $this->storeFactory->create(); + $store->setData($this->prepareData($data)); + $this->storeResource->save($store); + $this->storeManager->reinitStores(); + + return $store; + } + + /** + * @inheritdoc + */ + public function revert(DataObject $data): void + { + /** @var StoreInterface $store */ + $store = $this->storeFactory->create(); + $this->storeResource->load($store, $data->getCode(), 'code'); + if ($store->getId()) { + $this->storeResource->delete($store); + } + $this->storeManager->reinitStores(); + } + + /** + * Prepare store data + * + * @param array $data + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + + if (!isset($data['store_group_id']) && !isset($data['website_id'])) { + $data['store_group_id'] = $this->storeManager->getDefaultStoreView()->getStoreGroupId(); + } + if (isset($data['store_group_id']) && !isset($data['website_id'])) { + $data['website_id'] = $this->storeManager->getGroup($data['store_group_id'])->getWebsiteId(); + } elseif (!isset($data['store_group_id']) && isset($data['website_id'])) { + $data['store_group_id'] = $this->storeManager->getWebsite($data['website_id'])->getDefaultGroupId(); + } + + return $this->dataProcessor->process($this, $data); + } +} diff --git a/app/code/Magento/Store/Test/Fixture/Website.php b/app/code/Magento/Store/Test/Fixture/Website.php new file mode 100644 index 0000000000000..cad3b765ad97a --- /dev/null +++ b/app/code/Magento/Store/Test/Fixture/Website.php @@ -0,0 +1,104 @@ + 'test_website%uniqid%', + 'name' => 'Test Website%uniqid%', + 'is_default' => '0' + ]; + + /** + * @var WebsiteInterfaceFactory + */ + private $websiteFactory; + + /** + * @var WebsiteResource + */ + private $websiteResource; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var ProcessorInterface + */ + private $dataProcessor; + + /** + * @param WebsiteInterfaceFactory $websiteFactory + * @param WebsiteResource $websiteResource + * @param StoreManagerInterface $storeManager + * @param ProcessorInterface $dataProcessor + */ + public function __construct( + WebsiteInterfaceFactory $websiteFactory, + WebsiteResource $websiteResource, + StoreManagerInterface $storeManager, + ProcessorInterface $dataProcessor + ) { + $this->websiteFactory = $websiteFactory; + $this->websiteResource = $websiteResource; + $this->storeManager = $storeManager; + $this->dataProcessor = $dataProcessor; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + /** @var WebsiteInterface $website */ + $website = $this->websiteFactory->create(); + $website->setData($this->prepareData($data)); + $this->websiteResource->save($website); + $this->storeManager->reinitStores(); + + return $website; + } + + /** + * @inheritdoc + */ + public function revert(DataObject $data): void + { + /** @var WebsiteInterface $website */ + $website = $this->websiteFactory->create(); + $this->websiteResource->load($website, $data->getCode(), 'code'); + if ($website->getId()) { + $this->websiteResource->delete($website); + } + $this->storeManager->reinitStores(); + } + + /** + * Prepare website data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + + return $this->dataProcessor->process($this, $data); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php index 9c46054d7a76f..9e61a87caf6c3 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php @@ -241,11 +241,11 @@ private function buildExceptionMessage(int $categoryId): string } /** - * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":333} + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category as:category */ public function testUpdate() { - $categoryId = 333; + $categoryId = $this->fixtures->get('category')->getId(); $categoryData = [ 'name' => 'Update Category Test', 'is_active' => false, @@ -268,11 +268,11 @@ public function testUpdate() } /** - * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category as:category + * @magentoApiDataFixture Magento/Catalog/_files/category.php */ public function testUpdateWithDefaultSortByAttribute() { - $categoryId = $this->fixtures->get('category')->getCategory()->getId(); + $categoryId = 333; $categoryData = [ 'name' => 'Update Category Test With default_sort_by Attribute', 'is_active' => true, @@ -296,13 +296,13 @@ public function testUpdateWithDefaultSortByAttribute() } /** - * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":333} + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category as:category */ public function testUpdateUrlKey() { $this->_markTestAsRestOnly('Functionality available in REST mode only.'); - $categoryId = 333; + $categoryId = $this->fixtures->get('category')->getId(); $categoryData = [ 'name' => 'Update Category Test Old Name', 'custom_attributes' => [ @@ -601,11 +601,11 @@ public function testSaveDesign(): void /** * Check if repository does not override default values for attributes out of request * - * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":333} + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category as:category */ public function testUpdateScopeAttribute() { - $categoryId = 333; + $categoryId = $this->fixtures->get('category')->getId(); $categoryData = [ 'name' => 'Scope Specific Value', ]; diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index 7bba82049e58e..81f27dfafd332 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -17,6 +17,7 @@ use Magento\Framework\EntityManager\MetadataPool; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException; @@ -49,12 +50,18 @@ class CategoryTest extends GraphQlAbstract */ private $metadataPool; + /** + * @var \Magento\TestFramework\Fixture\DataFixtureStorage + */ + private $fixtures; + protected function setUp(): void { $this->objectManager = Bootstrap::getObjectManager(); $this->categoryRepository = $this->objectManager->get(CategoryRepository::class); $this->store = $this->objectManager->get(Store::class); $this->metadataPool = $this->objectManager->get(MetadataPool::class); + $this->fixtures = Bootstrap::getObjectManager()->get(DataFixtureStorageManager::class)->getStorage(); } /** @@ -275,11 +282,11 @@ public function testCategoriesTreeWithDisabledCategory() } /** - * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":13,"name":"Category 1.2"} + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"name":"Category 1.2"} as:category */ public function testGetCategoryById() { - $categoryId = 13; + $categoryId = $this->fixtures->get('category')->getId(); $query = <<graphQlQuery($query); self::assertEquals('Category 1.2', $response['category']['name']); - self::assertEquals(13, $response['category']['id']); + self::assertEquals($categoryId, $response['category']['id']); } /** - * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"id":8,"is_active":false} + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Category with:{"is_active":false} as:category */ public function testGetDisabledCategory() { $this->expectException(\Exception::class); $this->expectExceptionMessage('Category doesn\'t exist'); - $categoryId = 8; + $categoryId = $this->fixtures->get('category')->getId(); $query = <<getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); + $this->quoteIdToMaskedQuoteIdInterface = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class); + $this->fixtures = $objectManager->get(DataFixtureStorageManager::class)->getStorage(); } /** @@ -179,15 +194,17 @@ public function testGetCartTotalsWithEmptyCart() } /** - * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php + * @magentoApiDataFixture Magento\Catalog\Test\Fixture\Product as:product + * @magentoApiDataFixture Magento\Quote\Test\Fixture\GuestCart as:cart + * @magentoApiDataFixture Magento\Quote\Test\Fixture\AddProductToCart as:item1 + * @magentoApiDataFixture Magento\Quote\Test\Fixture\SetBillingAddress with:{"cart_id":"$cart.id$"} + * @magentoApiDataFixture Magento\Quote\Test\Fixture\SetShippingAddress with:{"cart_id":"$cart.id$"} + * @magentoDataFixtureDataProvider {"item1":{"cart_id":"$cart.id$","product_id":"$product.id$","qty":2}} */ public function testGetTotalsWithNoTaxApplied() { - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $cart = $this->fixtures->get('cart'); + $maskedQuoteId = $this->quoteIdToMaskedQuoteIdInterface->execute((int) $cart->getId()); $query = $this->getQuery($maskedQuoteId); $response = $this->graphQlQuery($query); diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php index 866bc3c65aafe..fec8760fa8449 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/AbstractDataFixture.php @@ -7,17 +7,9 @@ namespace Magento\TestFramework\Annotation; -use Magento\Framework\DataObject; -use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Registry; -use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; -use Magento\TestFramework\Fixture\DataFixtureSetup; -use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; use PHPUnit\Framework\TestCase; -use PHPUnit\Framework\Exception; -use Throwable; /** * Class consist of dataFixtures base logic @@ -106,12 +98,13 @@ protected function _applyFixtures(array $fixtures, TestCase $test) $testsIsolation = $objectManager->get(TestsIsolation::class); $dbIsolationState = $this->getDbIsolationState($test); $testsIsolation->createDbSnapshot($test, $dbIsolationState); + $dataFixtureSetup = $objectManager->get(DataFixtureSetup::class); /* Execute fixture scripts */ foreach ($fixtures as $fixture) { if (is_callable([get_class($test), $fixture['factory']])) { $fixture['factory'] = get_class($test) . '::' . $fixture['factory']; } - $fixture['result'] = $this->applyDataFixture($fixture); + $fixture['result'] = $dataFixtureSetup->apply($fixture); $this->_appliedFixtures[] = $fixture; } $resolver = Resolver::getInstance(); @@ -127,11 +120,12 @@ protected function _applyFixtures(array $fixtures, TestCase $test) protected function _revertFixtures(?TestCase $test = null) { $objectManager = Bootstrap::getObjectManager(); + $dataFixtureSetup = $objectManager->get(DataFixtureSetup::class); $resolver = Resolver::getInstance(); $resolver->setCurrentFixtureType($this->getAnnotation()); $appliedFixtures = array_reverse($this->_appliedFixtures); foreach ($appliedFixtures as $fixture) { - $this->revertDataFixture($fixture); + $dataFixtureSetup->revert($fixture); } $this->_appliedFixtures = []; $resolver->setCurrentFixtureType(null); @@ -173,75 +167,4 @@ private function getTestKey(TestCase $test): string * @return string */ abstract protected function getAnnotation(): string; - - /** - * Applies data fixture and returns the result. - * - * @param array $fixture - * @return array|null - */ - private function applyDataFixture(array $fixture): ?array - { - $objectManager = Bootstrap::getObjectManager(); - $dataFixtureSetup = $objectManager->get(DataFixtureSetup::class); - try { - $result = $dataFixtureSetup->apply($fixture['factory'], $fixture['data'] ?? []); - } catch (Throwable $exception) { - throw new Exception( - sprintf( - "Unable to apply fixture%s: %s.\n%s\n%s", - $fixture['name'] ? '"' . $fixture['name'] . '"' : '', - $fixture['factory'], - $exception->getMessage(), - $exception->getTraceAsString() - ), - 0, - $exception - ); - } - - if ($result !== null && !empty($fixture['name'])) { - DataFixtureStorageManager::getStorage()->persist( - $fixture['name'], - $objectManager->create(DataObject::class, ['data' => $result]) - ); - } - - return $result; - } - - /** - * Revert data fixture. - * - * @param array $fixture - */ - private function revertDataFixture(array $fixture): void - { - $objectManager = Bootstrap::getObjectManager(); - $dataFixtureSetup = $objectManager->get(DataFixtureSetup::class); - $registry = $objectManager->get(Registry::class); - $isSecureArea = $registry->registry('isSecureArea'); - $registry->unregister('isSecureArea'); - $registry->register('isSecureArea', true); - try { - $dataFixtureSetup->revert($fixture['factory'], $fixture['result'] ?? []); - } catch (NoSuchEntityException $exception) { - //ignore - } catch (Throwable $exception) { - throw new Exception( - sprintf( - "Unable to revert fixture%s: %s.\n%s\n%s", - $fixture['name'] ? '"' . $fixture['name'] . '"' : '', - $fixture['factory'], - $exception->getMessage(), - $exception->getTraceAsString() - ), - 0, - $exception - ); - } finally { - $registry->unregister('isSecureArea'); - $registry->register('isSecureArea', $isSecureArea); - } - } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDataProvider.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDataProvider.php index 38643ed13caa4..28f89afb599ad 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDataProvider.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDataProvider.php @@ -7,6 +7,7 @@ namespace Magento\TestFramework\Annotation; +use Magento\Framework\Serialize\Serializer\Json; use PHPUnit\Framework\Exception; use PHPUnit\Framework\TestCase; @@ -20,6 +21,20 @@ class DataFixtureDataProvider */ public const ANNOTATION = 'magentoDataFixtureDataProvider'; + /** + * @var Json + */ + private $serializer; + + /** + * @param Json $serializer + */ + public function __construct( + Json $serializer + ) { + $this->serializer = $serializer; + } + /** * Return data from fixture data provider * @@ -29,18 +44,29 @@ class DataFixtureDataProvider public function getDataProvider(TestCase $test): array { $annotations = TestCaseAnnotation::getInstance()->getAnnotations($test); - $dataProvider = $annotations['method'][self::ANNOTATION] ?? $annotations['class'][self::ANNOTATION] ?? []; - $data = []; - if (isset($dataProvider[0])) { - if (is_callable([$test, $dataProvider[0]])) { - $data = call_user_func([$test, $dataProvider[0]]); - } elseif (is_callable($dataProvider[0])) { - $data = call_user_func($dataProvider[0]); - } else { - throw new Exception('Fixture dataprovider must be a callable'); + $dataProviders = array_merge( + $annotations['class'][self::ANNOTATION] ?? [], + $annotations['method'][self::ANNOTATION] ?? [] + ); + $result = []; + foreach (array_reverse($dataProviders) as $dataProvider) { + if (isset($dataProvider)) { + if (is_callable([$test, $dataProvider])) { + $data = $test->$dataProvider(); + } elseif (is_callable($dataProvider)) { + $data = $dataProvider(); + } else { + try { + $data = $this->serializer->unserialize($dataProvider); + } catch (\InvalidArgumentException $exception) { + throw new Exception('Fixture data provider must be a callable or valid JSON'); + } + } + $result += $data; } + } - return $data; + return $result; } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDirectivesParser.php similarity index 98% rename from dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php rename to dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDirectivesParser.php index 405833d6b20af..6932d80ce2540 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureDirectivesParser.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureDirectivesParser.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\TestFramework\Fixture; +namespace Magento\TestFramework\Annotation; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Serialize\Serializer\Json; diff --git a/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureSetup.php b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureSetup.php new file mode 100644 index 0000000000000..1edb1b058091d --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Annotation/DataFixtureSetup.php @@ -0,0 +1,147 @@ +registry = $registry; + $this->dataFixtureFactory = $dataFixtureFactory; + } + + /** + * Applies data fixture and returns the result. + * + * @param array $fixture + * @return DataObject|null + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function apply(array $fixture): ?DataObject + { + $data = $this->resolveVariables($fixture['data'] ?? []); + try { + $factory = $this->dataFixtureFactory->create($fixture['factory']); + $result = $factory->apply($data); + } catch (\Throwable $exception) { + throw new Exception( + sprintf( + "Unable to apply fixture%s: %s.\n%s\n%s", + $fixture['name'] ? ' "' . $fixture['name'] . '"' : '', + $fixture['factory'], + $exception->getMessage(), + $exception->getTraceAsString() + ), + 0, + $exception + ); + } + + if ($result !== null && !empty($fixture['name'])) { + DataFixtureStorageManager::getStorage()->persist( + $fixture['name'], + $result + ); + } + + return $result; + } + + /** + * Revert data fixture. + * + * @param array $fixture + */ + public function revert(array $fixture): void + { + $isSecureArea = $this->registry->registry('isSecureArea'); + $this->registry->unregister('isSecureArea'); + $this->registry->register('isSecureArea', true); + try { + $factory = $this->dataFixtureFactory->create($fixture['factory']); + if ($factory instanceof RevertibleDataFixtureInterface) { + $factory->revert($fixture['result'] ?? new DataObject()); + } + } catch (NoSuchEntityException $exception) { + //ignore + } catch (\Throwable $exception) { + throw new Exception( + sprintf( + "Unable to revert fixture%s: %s.\n%s\n%s", + $fixture['name'] ? '"' . $fixture['name'] . '"' : '', + $fixture['factory'], + $exception->getMessage(), + $exception->getTraceAsString() + ), + 0, + $exception + ); + } finally { + $this->registry->unregister('isSecureArea'); + $this->registry->register('isSecureArea', $isSecureArea); + } + } + + /** + * Replace fixtures references in the data by their value + * + * Supported formats: + * - $fixture$ + * - $fixture.attribute$ + * + * @param array $data + * @return array + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function resolveVariables(array $data): array + { + foreach ($data as $key => $value) { + if (is_array($value)) { + $data[$key] = $this->resolveVariables($value); + } else { + if (is_string($value) && preg_match('/^\$\w+(\.\w+)?\$$/', $value)) { + list($fixtureName, $attribute) = array_pad(explode('.', trim($value, '$')), 2, null); + $fixtureData = DataFixtureStorageManager::getStorage()->get($fixtureName); + if (!$fixtureData) { + throw new \InvalidArgumentException("Unable to resolve fixture reference '$value'"); + } + $data[$key] = $attribute ? $fixtureData->getDataUsingMethod($attribute) : $fixtureData; + } + } + } + + return $data; + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/DataMerger.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/DataMerger.php new file mode 100644 index 0000000000000..e06dc3b5bbd44 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/Api/DataMerger.php @@ -0,0 +1,129 @@ +convertCustomAttributesToMap( + $data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES] + ); + foreach ($data as $key => $value) { + if (!array_key_exists($key, $defaultData)) { + if (array_key_exists($key, $defaultData[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY])) { + $data[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY][$key] = $value; + } else { + $data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES][$key] = $value; + } + unset($data[$key]); + } + } + } + + $result = $this->mergeRecursive($defaultData, $data); + + if ($isExtensible) { + $result[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES] = $this->convertCustomAttributesToCollection( + $result[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES] + ); + } + + return $result; + } + + /** + * Recursively merge entity data + * + * @param array $arrays + * @return array + */ + public function mergeRecursive(array ...$arrays): array + { + $result = []; + while ($arrays) { + $array = array_shift($arrays); + // is array an associative array + if (array_values($array) !== $array) { + foreach ($array as $key => $value) { + if (is_array($value) && array_key_exists($key, $result) && is_array($result[$key])) { + $result[$key] = $this->mergeRecursive($result[$key], $value); + } else { + $result[$key] = $value; + } + } + } elseif (array_values($result) === $result) { + $result = $array; + } + } + + return $result; + } + + /** + * Return an associative array with attribute codes as key + * + * @param array $data + * @return mixed + */ + private function convertCustomAttributesToMap(array $data): array + { + $result = []; + // check if data is not an associative array + if (array_values($data) === $data) { + foreach ($data as $item) { + $result[$item[AttributeInterface::ATTRIBUTE_CODE]] = $item[AttributeInterface::VALUE]; + } + } else { + $result = $data; + } + + return $result; + } + + /** + * Return a multi-dimension array with attribute codes and values + * + * @param array $data + * @return mixed + */ + private function convertCustomAttributesToCollection(array $data): array + { + $result = []; + foreach ($data as $key => $value) { + $result[] = [ + AttributeInterface::ATTRIBUTE_CODE => $key, + AttributeInterface::VALUE => $value, + ]; + } + + return $result; + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php index 822b7f1797847..007c17475f124 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/CallableDataFixture.php @@ -7,6 +7,8 @@ namespace Magento\TestFramework\Fixture; +use Magento\Framework\DataObject; + /** * Callable data fixture type */ @@ -29,7 +31,7 @@ public function __construct( /** * @inheritdoc */ - public function apply(array $data = []): ?array + public function apply(array $data = []): ?DataObject { call_user_func($this->callback); return null; @@ -38,7 +40,7 @@ public function apply(array $data = []): ?array /** * @inheritdoc */ - public function revert(array $data = []): void + public function revert(DataObject $data): void { $rollbackCallback = null; if (is_array($this->callback)) { diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php index ac0c2452179d6..539e72e5b4a17 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureInterface.php @@ -7,6 +7,8 @@ namespace Magento\TestFramework\Fixture; +use Magento\Framework\DataObject; + /** * Interface for data fixtures */ @@ -16,7 +18,7 @@ interface DataFixtureInterface * Apply fixture data * * @param array $data - * @return array|null + * @return DataObject|null */ - public function apply(array $data = []): ?array; + public function apply(array $data = []): ?DataObject; } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureSetup.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureSetup.php deleted file mode 100644 index b80f7f06bf606..0000000000000 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureSetup.php +++ /dev/null @@ -1,55 +0,0 @@ -dataFixtureFactory = $dataFixtureFactory; - } - - /** - * Applies data fixture and returns the result - * - * @param string $factory - * @param array $data - * @return array|null - */ - public function apply(string $factory, array $data = []): ?array - { - $fixture = $this->dataFixtureFactory->create($factory); - return $fixture->apply($data); - } - - /** - * Revert data fixture - * - * @param string $factory - * @param array $data - */ - public function revert(string $factory, array $data): void - { - $fixture = $this->dataFixtureFactory->create($factory); - if ($fixture instanceof RevertibleDataFixtureInterface) { - $fixture->revert($data); - } - } -} diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorage.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorage.php index e4bbe026a659d..bba120ba7da56 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorage.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/DataFixtureStorage.php @@ -22,23 +22,23 @@ class DataFixtureStorage /** * Get fixture result by its identifier * - * @param string $identifier + * @param string $name * @return DataObject|null */ - public function get(string $identifier): ?DataObject + public function get(string $name): ?DataObject { - return $this->fixtures[$identifier] ?? null; + return $this->fixtures[$name] ?? null; } /** * Persist fixture result to the storage * - * @param string $identifier + * @param string $name * @param DataObject|null $data */ - public function persist(string $identifier, ?DataObject $data): void + public function persist(string $name, ?DataObject $data): void { - $this->fixtures[$identifier] = $data; + $this->fixtures[$name] = $data; } /** diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php index 7b91974bb64d0..dc1c066e4ea3d 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php @@ -7,6 +7,8 @@ namespace Magento\TestFramework\Fixture; +use Magento\Framework\DataObject; + /** * File based data fixture */ @@ -31,7 +33,7 @@ public function __construct( /** * @inheritdoc */ - public function apply(array $data = []): ?array + public function apply(array $data = []): ?DataObject { $this->execute($this->filePath); return null; @@ -40,7 +42,7 @@ public function apply(array $data = []): ?array /** * @inheritdoc */ - public function revert(array $data = []): void + public function revert(DataObject $data): void { $fileInfo = pathinfo($this->filePath); $extension = ''; diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php index e1a35a8bd9c87..1902002ca5d96 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/RevertibleDataFixtureInterface.php @@ -7,6 +7,8 @@ namespace Magento\TestFramework\Fixture; +use Magento\Framework\DataObject; + /** * Interface for revertible data fixtures */ @@ -15,7 +17,7 @@ interface RevertibleDataFixtureInterface extends DataFixtureInterface /** * Revert fixture data * - * @param array $data + * @param DataObject $data */ - public function revert(array $data = []): void; + public function revert(DataObject $data): void; } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php index 4edc485c55b53..f7bbfbf326cae 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Override/Fixture/Resolver.php @@ -13,7 +13,7 @@ use Magento\TestFramework\Annotation\ConfigFixture; use Magento\TestFramework\Annotation\DataFixture; use Magento\TestFramework\Annotation\DataFixtureBeforeTransaction; -use Magento\TestFramework\Fixture\DataFixtureSetup; +use Magento\TestFramework\Annotation\DataFixtureSetup; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\ConfigInterface; use Magento\TestFramework\Workaround\Override\Fixture\Applier\AdminConfigFixture as AdminConfigFixtureApplier; @@ -122,7 +122,7 @@ public function requireDataFixture(string $path): void } /** @var DataFixtureApplier $dataFixtureApplier */ $dataFixtureApplier = $this->getApplier($this->getCurrentTest(), $this->currentFixtureType); - $this->dataFixtureSetup->apply($dataFixtureApplier->replace($path)); + $this->dataFixtureSetup->apply(['factory' => $dataFixtureApplier->replace($path)]); } /** diff --git a/dev/tests/integration/framework/tests/unit/phpunit.xml.dist b/dev/tests/integration/framework/tests/unit/phpunit.xml.dist index b9d3b513bcfb0..f411244be86f9 100644 --- a/dev/tests/integration/framework/tests/unit/phpunit.xml.dist +++ b/dev/tests/integration/framework/tests/unit/phpunit.xml.dist @@ -38,12 +38,15 @@ magentoConfigFixture - + magentoDataFixture magentoDbIsolation + + magentoDataFixtureDataProvider + diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureDirectivesParserTest.php similarity index 96% rename from dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php rename to dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureDirectivesParserTest.php index c7e3a3ec5e9e9..a2b213aed7db9 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/DataFixtureDirectivesParserTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureDirectivesParserTest.php @@ -5,10 +5,10 @@ */ declare(strict_types=1); -namespace Magento\Test\Fixture; +namespace Magento\Test\Annotation; use Magento\Framework\Serialize\Serializer\Json; -use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; +use Magento\TestFramework\Annotation\DataFixtureDirectivesParser; use PHPUnit\Framework\TestCase; /** diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php index 97bdf1b8e7e67..61b39b04520d6 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Annotation/DataFixtureTest.php @@ -8,67 +8,107 @@ namespace Magento\Test\Annotation; use Magento\Framework\Component\ComponentRegistrar; +use Magento\Framework\DataObject; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Registry; use Magento\Framework\Serialize\Serializer\Json; use Magento\TestFramework\Annotation\DataFixture; +use Magento\TestFramework\Annotation\DataFixtureDataProvider; +use Magento\TestFramework\Annotation\DataFixtureSetup; use Magento\TestFramework\Event\Param\Transaction; -use Magento\TestFramework\Fixture\DataFixtureDirectivesParser; +use Magento\TestFramework\Annotation\DataFixtureDirectivesParser; use Magento\TestFramework\Fixture\DataFixtureInterface; -use Magento\TestFramework\Fixture\DataFixtureSetup; use Magento\TestFramework\Fixture\DataFixtureStorage; use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Fixture\LegacyDataFixturePathResolver; use Magento\TestFramework\Fixture\DataFixtureFactory; use Magento\TestFramework\Fixture\LegacyDataFixture; +use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Workaround\Override\Fixture\Resolver; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Magento\TestFramework\Annotation\TestsIsolation; +use ReflectionException; /** * Test class for \Magento\TestFramework\Annotation\DataFixture. * * @magentoDataFixture sampleFixtureOne + * @magentoDataFixtureDataProvider classFixtureDataProvider * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DataFixtureTest extends TestCase { /** - * @var DataFixture|\PHPUnit\Framework\MockObject\MockObject + * @var DataFixture|MockObject */ protected $object; /** - * @var TestsIsolation|\PHPUnit\Framework\MockObject\MockObject + * @var TestsIsolation|MockObject */ protected $testsIsolationMock; + /** + * @var RevertibleDataFixtureInterface|MockObject + */ + private $fixture1; + + /** + * @var RevertibleDataFixtureInterface|MockObject + */ + private $fixture2; + + /** + * @var DataFixtureInterface|MockObject + */ + private $fixture3; + + /** + * @var DataObject + */ + private $fixtureStorage; + /** * @inheritdoc */ protected function setUp(): void { - $this->object = $this->getMockBuilder(DataFixture::class) - ->onlyMethods(['getTestKey']) - ->addMethods(['getComponentRegistrar']) - ->getMock(); + $this->object = new DataFixture(); $this->testsIsolationMock = $this->getMockBuilder(TestsIsolation::class) ->onlyMethods(['createDbSnapshot', 'checkTestIsolation']) ->getMock(); - /** @var ObjectManagerInterface|\PHPUnit\Framework\MockObject\MockObject $objectManager */ + /** @var ObjectManagerInterface|MockObject $objectManager */ $objectManager = $this->getMockBuilder(ObjectManagerInterface::class) ->onlyMethods(['get', 'create']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - DataFixtureStorageManager::setStorage(new DataFixtureStorage()); + $this->fixture1 = $this->getMockBuilder(RevertibleDataFixtureInterface::class) + ->setMockClassName('MockFixture1') + ->getMockForAbstractClass(); + $this->fixture2 = $this->getMockBuilder(RevertibleDataFixtureInterface::class) + ->setMockClassName('MockFixture2') + ->getMockForAbstractClass(); + $this->fixture3 = $this->getMockBuilder(DataFixtureInterface::class) + ->setMockClassName('MockFixture3') + ->getMockForAbstractClass(); + + $this->fixtureStorage = new DataFixtureStorage(); + DataFixtureStorageManager::setStorage($this->fixtureStorage); + $dataFixtureFactory = new DataFixtureFactory($objectManager); $sharedInstances = [ TestsIsolation::class => $this->testsIsolationMock, DataFixtureDirectivesParser::class => new DataFixtureDirectivesParser(new Json()), DataFixtureFactory::class => $dataFixtureFactory, - LegacyDataFixture::class => $this->createMock(DataFixtureInterface::class), - DataFixtureSetup::class => new DataFixtureSetup($dataFixtureFactory), + DataFixtureSetup::class => new DataFixtureSetup(new Registry(), $dataFixtureFactory), + DataFixtureDataProvider::class => new DataFixtureDataProvider(new Json()), + 'MockFixture1' => $this->fixture1, + 'MockFixture2' => $this->fixture2, + 'MockFixture3' => $this->fixture3, ]; $objectManager->expects($this->atLeastOnce()) ->method('get') @@ -80,19 +120,21 @@ function (string $type) use ($sharedInstances) { $objectManager->expects($this->atLeastOnce()) ->method('create') ->willReturnCallback( - function (string $type, array $arguments = []) { + function (string $type, array $arguments = []) use ($sharedInstances) { if ($type === LegacyDataFixture::class) { array_unshift($arguments, new LegacyDataFixturePathResolver(new ComponentRegistrar())); } - return new $type(...array_values($arguments)); + return $sharedInstances[$type] ?? new $type(...array_values($arguments)); } ); - \Magento\TestFramework\Helper\Bootstrap::setObjectManager($objectManager); + Bootstrap::setObjectManager($objectManager); $directory = __DIR__; if (!defined('INTEGRATION_TESTS_DIR')) { define('INTEGRATION_TESTS_DIR', dirname($directory, 4)); } + + $this->createResolverMock(); } /** @@ -140,7 +182,6 @@ public static function sampleFixtureTwoRollback(): void */ public function testStartTestTransactionRequestClassAnnotation(): void { - $this->createResolverMock(); $eventParam = new Transaction(); $this->object->startTestTransactionRequest($this, $eventParam); $this->assertTrue($eventParam->isTransactionStartRequested()); @@ -160,7 +201,6 @@ public function testStartTestTransactionRequestClassAnnotation(): void */ public function testStartTestTransactionRequestMethodAnnotation(): void { - $this->createResolverMock(); $eventParam = new Transaction(); $this->object->startTestTransactionRequest($this, $eventParam); $this->assertTrue($eventParam->isTransactionStartRequested()); @@ -182,7 +222,6 @@ public function testStartTestTransactionRequestMethodAnnotation(): void */ public function testDisabledDbIsolation(): void { - $this->createResolverMock(); $eventParam = new Transaction(); $this->object->startTestTransactionRequest($this, $eventParam); $this->assertFalse($eventParam->isTransactionStartRequested()); @@ -203,7 +242,6 @@ public function testDisabledDbIsolation(): void */ public function testEndTestTransactionRequestMethodAnnotation(): void { - $this->createResolverMock(); $eventParam = new Transaction(); $this->object->endTestTransactionRequest($this, $eventParam); $this->assertFalse($eventParam->isTransactionStartRequested()); @@ -221,7 +259,6 @@ public function testEndTestTransactionRequestMethodAnnotation(): void */ public function testStartTransactionClassAnnotation(): void { - $this->createResolverMock(); $this->object->startTransaction($this); $this->assertEquals('1', getenv('sample_fixture_one')); } @@ -234,7 +271,6 @@ public function testStartTransactionClassAnnotation(): void */ public function testStartTransactionMethodAnnotation(): void { - $this->createResolverMock(); $this->object->startTransaction($this); $this->assertEquals('2', getenv('sample_fixture_two')); $this->assertEquals('3', getenv('sample_fixture_three')); @@ -248,7 +284,6 @@ public function testStartTransactionMethodAnnotation(): void */ public function testRollbackTransactionRevertFixtureMethod(): void { - $this->createResolverMock(); $this->object->startTransaction($this); $this->assertEquals('1', getenv('sample_fixture_one')); $this->assertEquals('2', getenv('sample_fixture_two')); @@ -264,7 +299,6 @@ public function testRollbackTransactionRevertFixtureMethod(): void */ public function testRollbackTransactionRevertFixtureFile(): void { - $this->createResolverMock(); $this->object->startTransaction($this); $this->assertEquals('3', getenv('sample_fixture_three')); $this->object->rollbackTransaction(); @@ -284,11 +318,299 @@ public function testModuleDataFixture(): void 'Foo_DataFixtureDummy', dirname(__DIR__) ); - $this->createResolverMock(); $this->object->startTransaction($this); $this->assertEquals('3', getenv('sample_fixture_three')); } + /** + * @magentoDataFixture MockFixture1 + * @magentoDataFixture MockFixture2 + * @magentoDataFixture MockFixture3 + * @magentoDbIsolation disabled + */ + public function testFixtureClass(): void + { + $fixture1 = new DataObject(); + $fixture2 = new DataObject(); + $this->fixture1->expects($this->once()) + ->method('apply') + ->with([]) + ->willReturn($fixture1); + $this->fixture2->expects($this->once()) + ->method('apply') + ->with([]) + ->willReturn($fixture2); + $this->fixture3->expects($this->once()) + ->method('apply') + ->with([]); + $this->applyFixtures(); + $this->fixture1->expects($this->once()) + ->method('revert') + ->with($fixture1); + $this->fixture2->expects($this->once()) + ->method('revert') + ->with($fixture2); + $this->revertFixtures(); + } + + /** + * @magentoDataFixture MockFixture1 with:{"key1": "value1"} + * @magentoDataFixture MockFixture2 with:{"key2": "value2"} + * @magentoDataFixture MockFixture3 with:{"key3": "value3"} + * @magentoDbIsolation disabled + */ + public function testFixtureClassWithParameters(): void + { + $fixture1 = new DataObject(); + $fixture2 = new DataObject(); + $this->fixture1->expects($this->once()) + ->method('apply') + ->with(['key1' => 'value1']) + ->willReturn($fixture1); + $this->fixture2->expects($this->once()) + ->method('apply') + ->with(['key2' => 'value2']) + ->willReturn($fixture2); + $this->fixture3->expects($this->once()) + ->method('apply') + ->with(['key3' => 'value3']); + $this->applyFixtures(); + $this->fixture1->expects($this->once()) + ->method('revert') + ->with($fixture1); + $this->fixture2->expects($this->once()) + ->method('revert') + ->with($fixture2); + $this->revertFixtures(); + } + + /** + * @magentoDataFixture MockFixture1 with:{"alias-key1": "alias-value1"} as:fixture1 + * @magentoDataFixture MockFixture2 with:{"alias-key2": "alias-value2"} as:fixture2 + * @magentoDataFixture MockFixture3 with:{"alias-key3": "alias-value3"} as:fixture3 + * @magentoDbIsolation disabled + */ + public function testFixtureClassWithParametersAndAlias(): void + { + $fixture1 = new DataObject(); + $fixture2 = new DataObject(); + $this->fixture1->expects($this->once()) + ->method('apply') + ->with(['alias-key1' => 'alias-value1']) + ->willReturn($fixture1); + $this->fixture2->expects($this->once()) + ->method('apply') + ->with(['alias-key2' => 'alias-value2']) + ->willReturn($fixture2); + $this->fixture3->expects($this->once()) + ->method('apply') + ->with(['alias-key3' => 'alias-value3']); + $this->applyFixtures(); + $this->assertSame($fixture1, $this->fixtureStorage->get('fixture1')); + $this->assertSame($fixture2, $this->fixtureStorage->get('fixture2')); + $this->assertNull($this->fixtureStorage->get('fixture3')); + $this->fixture1->expects($this->once()) + ->method('revert') + ->with($fixture1); + $this->fixture2->expects($this->once()) + ->method('revert') + ->with($fixture2); + $this->revertFixtures(); + } + + /** + * @magentoDataFixture MockFixture1 as:fixture1 + * @magentoDataFixture MockFixture2 as:fixture2 + * @magentoDataFixture MockFixture3 as:fixture3 + * @magentoDataFixtureDataProvider methodFixtureDataProvider + * @magentoDbIsolation disabled + */ + public function testMethodFixtureDataProvider(): void + { + $fixture1 = new DataObject(); + $fixture2 = new DataObject(); + $this->fixture1->expects($this->once()) + ->method('apply') + ->with(['method-key1' => 'method-value1']) + ->willReturn($fixture1); + $this->fixture2->expects($this->once()) + ->method('apply') + ->with(['method-key2' => 'method-value2']) + ->willReturn($fixture2); + $this->fixture3->expects($this->once()) + ->method('apply') + ->with(['method-key3' => 'method-value3']); + $this->applyFixtures(); + $this->assertSame($fixture1, $this->fixtureStorage->get('fixture1')); + $this->assertSame($fixture2, $this->fixtureStorage->get('fixture2')); + $this->assertNull($this->fixtureStorage->get('fixture3')); + $this->fixture1->expects($this->once()) + ->method('revert') + ->with($fixture1); + $this->fixture2->expects($this->once()) + ->method('revert') + ->with($fixture2); + $this->revertFixtures(); + } + + /** + * @return array + */ + public function methodFixtureDataProvider(): array + { + return [ + 'fixture1' => [ + 'method-key1' => 'method-value1', + ], + 'fixture2' => [ + 'method-key2' => 'method-value2', + ], + 'fixture3' => [ + 'method-key3' => 'method-value3', + ], + ]; + } + + /** + * @magentoDataFixture MockFixture1 as:fixture1 + * @magentoDataFixture MockFixture2 as:fixture2 + * @magentoDataFixture MockFixture3 as:fixture3 + * @magentoDbIsolation disabled + */ + public function testClassFixtureDataProvider(): void + { + $fixture1 = new DataObject(); + $fixture2 = new DataObject(); + $this->fixture1->expects($this->once()) + ->method('apply') + ->with(['class-key1' => 'class-value1']) + ->willReturn($fixture1); + $this->fixture2->expects($this->once()) + ->method('apply') + ->with(['class-key2' => 'class-value2']) + ->willReturn($fixture2); + $this->fixture3->expects($this->once()) + ->method('apply') + ->with(['class-key3' => 'class-value3']); + $this->applyFixtures(); + $this->assertSame($fixture1, $this->fixtureStorage->get('fixture1')); + $this->assertSame($fixture2, $this->fixtureStorage->get('fixture2')); + $this->assertNull($this->fixtureStorage->get('fixture3')); + $this->fixture1->expects($this->once()) + ->method('revert') + ->with($fixture1); + $this->fixture2->expects($this->once()) + ->method('revert') + ->with($fixture2); + $this->revertFixtures(); + } + + /** + * @return array + */ + public function classFixtureDataProvider(): array + { + return [ + 'fixture1' => [ + 'class-key1' => 'class-value1', + ], + 'fixture2' => [ + 'class-key2' => 'class-value2', + ], + 'fixture3' => [ + 'class-key3' => 'class-value3', + ], + ]; + } + + /** + * @magentoDataFixture MockFixture1 as:fixture1 + * @magentoDataFixture MockFixture2 as:fixture2 + * @magentoDataFixture MockFixture3 as:fixture3 + * @magentoDbIsolation disabled + * @magentoDataFixtureDataProvider {"fixture1":{"inline-key1":"inline-value1"}} + * @magentoDataFixtureDataProvider {"fixture2":{"inline-key2":"inline-value2"}} + * @magentoDataFixtureDataProvider {"fixture3":{"inline-key3":"inline-value3"}} + */ + public function testInlineFixtureDataProvider(): void + { + $fixture1 = new DataObject(); + $fixture2 = new DataObject(); + $this->fixture1->expects($this->once()) + ->method('apply') + ->with(['inline-key1' => 'inline-value1']) + ->willReturn($fixture1); + $this->fixture2->expects($this->once()) + ->method('apply') + ->with(['inline-key2' => 'inline-value2']) + ->willReturn($fixture2); + $this->fixture3->expects($this->once()) + ->method('apply') + ->with(['inline-key3' => 'inline-value3']); + $this->applyFixtures(); + $this->assertSame($fixture1, $this->fixtureStorage->get('fixture1')); + $this->assertSame($fixture2, $this->fixtureStorage->get('fixture2')); + $this->assertNull($this->fixtureStorage->get('fixture3')); + $this->fixture1->expects($this->once()) + ->method('revert') + ->with($fixture1); + $this->fixture2->expects($this->once()) + ->method('revert') + ->with($fixture2); + $this->revertFixtures(); + } + + /** + * @magentoDataFixture MockFixture1 with:{"p1": "param-value1"} as:fixture1 + * @magentoDataFixture MockFixture2 with:{"p2": "$fixture1.attr_1$"} as:fixture2 + * @magentoDataFixture MockFixture3 with:{"p3": "$fixture2.attr_3$", "p4": {"p5": "$fixture1$" }} as:fixture3 + * @magentoDbIsolation disabled + */ + public function testVariables(): void + { + $fixture1 = new DataObject(['attr_1' => 'attr-value1', 'attr_2' => 'attr-value2']); + $fixture2 = new DataObject(['attr_3' => 1]); + $this->fixture1->expects($this->once()) + ->method('apply') + ->with(['p1' => 'param-value1']) + ->willReturn($fixture1); + $this->fixture2->expects($this->once()) + ->method('apply') + ->with(['p2' => 'attr-value1']) + ->willReturn($fixture2); + $this->fixture3->expects($this->once()) + ->method('apply') + ->with(['p3' => 1, 'p4' => ['p5' => $fixture1]]); + $this->applyFixtures(); + $this->assertSame($fixture1, $this->fixtureStorage->get('fixture1')); + $this->assertSame($fixture2, $this->fixtureStorage->get('fixture2')); + $this->assertNull($this->fixtureStorage->get('fixture3')); + $this->fixture1->expects($this->once()) + ->method('revert') + ->with($fixture1); + $this->fixture2->expects($this->once()) + ->method('revert') + ->with($fixture2); + $this->revertFixtures(); + } + + /** + * @throws ReflectionException + */ + private function applyFixtures(): void + { + $this->object->startTransaction($this); + } + + /** + * @return void + */ + private function revertFixtures(): void + { + $eventParam = new Transaction(); + $this->object->endTestTransactionRequest($this, $eventParam); + } + /** * Create mock for Resolver object * diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/CallableDataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/CallableDataFixtureTest.php index bc296cc95298b..66f15db66697f 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/CallableDataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/CallableDataFixtureTest.php @@ -7,6 +7,7 @@ namespace Magento\Test\Fixture; +use Magento\Framework\DataObject; use Magento\TestFramework\Fixture\CallableDataFixture; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -67,7 +68,7 @@ public function testRevertCallableArray(): void $model = new CallableDataFixture([$this->fakeClass, 'fakeMethod']); $this->fakeClass->expects($this->once()) ->method('fakeMethodRollback'); - $model->revert(); + $model->revert(new DataObject()); } /** @@ -86,7 +87,7 @@ public function testApplyCallableString(): void public function testRevertCallableString(): void { $model = new CallableDataFixture(get_class($this) . '::fixtureMethod'); - $model->revert(); + $model->revert(new DataObject()); $this->assertEquals('reverted', static::$testFlag); } diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixtureTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixtureTest.php index a6aaaaf20a36a..b02fc6aa13101 100644 --- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixtureTest.php +++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Fixture/LegacyDataFixtureTest.php @@ -7,6 +7,7 @@ namespace Magento\Test\Fixture; +use Magento\Framework\DataObject; use Magento\TestFramework\Fixture\LegacyDataFixturePathResolver; use Magento\TestFramework\Fixture\LegacyDataFixture; use PHPUnit\Framework\TestCase; @@ -60,7 +61,7 @@ public function testApply(): void public function testRevert(): void { $this->model->apply(); - $this->model->revert(); + $this->model->revert(new DataObject()); $this->assertEquals('', getenv('sample_fixture_three')); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/PriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/PriceTest.php index 19a23d8543870..f814d60c48179 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/PriceTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/PriceTest.php @@ -6,8 +6,10 @@ namespace Magento\Catalog\Model\Product\Attribute\Backend; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\ResourceModel\Product; use Magento\Catalog\Observer\SwitchPriceAttributeScopeOnConfigChange; use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; /** * Test class for \Magento\Catalog\Model\Product\Attribute\Backend\Price. @@ -30,6 +32,16 @@ class PriceTest extends \PHPUnit\Framework\TestCase /** @var ProductRepositoryInterface */ private $productRepository; + /** + * @var Product + */ + private $productResource; + + /** + * @var \Magento\TestFramework\Fixture\DataFixtureStorage + */ + private $fixtures; + protected function setUp(): void { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -49,6 +61,10 @@ protected function setUp(): void $this->productRepository = $this->objectManager->create( ProductRepositoryInterface::class ); + $this->productResource = $this->objectManager->create( + Product::class + ); + $this->fixtures = $this->objectManager->get(DataFixtureStorageManager::class)->getStorage(); $this->model->setAttribute( $this->objectManager->get( \Magento\Eav\Model\Config::class @@ -103,14 +119,17 @@ public function testAfterSave() $product = $this->productRepository->get('simple'); $product->setPrice('9.99'); $product->setStoreId($globalStoreId); - $product->getResource()->save($product); + $this->productResource->save($product); $product = $this->productRepository->get('simple', false, $globalStoreId, true); $this->assertEquals('9.990000', $product->getPrice()); } /** - * @magentoDataFixture Magento/Catalog/_files/product_simple.php - * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php + * @magentoDataFixture Magento\Store\Test\Fixture\Website as:website2 + * @magentoDataFixture Magento\Store\Test\Fixture\Group with:{"website_id":"$website2.id$"} as:store_group2 + * @magentoDataFixture Magento\Store\Test\Fixture\Store with:{"store_group_id":"$store_group2.id$"} as:store2 + * @magentoDataFixture Magento\Store\Test\Fixture\Store with:{"store_group_id":"$store_group2.id$"} as:store3 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product as:product * @magentoConfigFixture current_store catalog/price/scope 1 * @magentoDbIsolation disabled * @magentoAppArea adminhtml @@ -122,27 +141,28 @@ public function testAfterSaveWithDifferentStores() \Magento\Store\Model\Store::class ); $globalStoreId = $store->load('admin')->getId(); - $secondStoreId = $store->load('fixture_second_store')->getId(); - $thirdStoreId = $store->load('fixture_third_store')->getId(); + $secondStoreId = $this->fixtures->get('store2')->getId(); + $thirdStoreId = $this->fixtures->get('store3')->getId(); + $productSku = $this->fixtures->get('product')->getSku(); /** @var \Magento\Catalog\Model\Product\Action $productAction */ $productAction = $this->objectManager->create( \Magento\Catalog\Model\Product\Action::class ); - $product = $this->productRepository->get('simple'); + $product = $this->productRepository->get($productSku); $productId = $product->getId(); $productAction->updateWebsites([$productId], [$store->load('fixture_second_store')->getWebsiteId()], 'add'); $product->setStoreId($secondStoreId); $product->setPrice('9.99'); - $product->getResource()->save($product); + $this->productResource->save($product); - $product = $this->productRepository->get('simple', false, $globalStoreId, true); + $product = $this->productRepository->get($productSku, false, $globalStoreId, true); $this->assertEquals(10, $product->getPrice()); - $product = $this->productRepository->get('simple', false, $secondStoreId, true); + $product = $this->productRepository->get($productSku, false, $secondStoreId, true); $this->assertEquals('9.990000', $product->getPrice()); - $product = $this->productRepository->get('simple', false, $thirdStoreId, true); + $product = $this->productRepository->get($productSku, false, $thirdStoreId, true); $this->assertEquals('9.990000', $product->getPrice()); } @@ -173,7 +193,7 @@ public function testAfterSaveWithSameCurrency() $product->setOrigData(); $product->setStoreId($secondStoreId); $product->setPrice('9.99'); - $product->getResource()->save($product); + $this->productResource->save($product); $product = $this->productRepository->get('simple', false, $globalStoreId, true); $this->assertEquals(10, $product->getPrice()); @@ -212,7 +232,7 @@ public function testAfterSaveWithUseDefault() $product->setOrigData(); $product->setStoreId($secondStoreId); $product->setPrice('9.99'); - $product->getResource()->save($product); + $this->productResource->save($product); $product = $this->productRepository->get('simple', false, $globalStoreId, true); $this->assertEquals(10, $product->getPrice()); @@ -225,7 +245,7 @@ public function testAfterSaveWithUseDefault() $product->setStoreId($thirdStoreId); $product->setPrice(null); - $product->getResource()->save($product); + $this->productResource->save($product); $product = $this->productRepository->get('simple', false, $globalStoreId, true); $this->assertEquals(10, $product->getPrice()); @@ -281,7 +301,7 @@ public function testAfterSaveForWebsitesWithDifferentCurrencies() $product->setOrigData(); $product->setStoreId($globalStoreId); $product->setPrice(100); - $product->getResource()->save($product); + $this->productResource->save($product); $product = $this->productRepository->get('simple', false, $globalStoreId, true); $this->assertEquals(100, $product->getPrice()); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php index 885a7dff06633..9f73d09776318 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php @@ -11,6 +11,7 @@ use Magento\Framework\App\Area; use Magento\Framework\App\State; use Magento\Store\Model\Store; +use Magento\TestFramework\Fixture\DataFixtureStorageManager; use Magento\TestFramework\Helper\Bootstrap; /** @@ -35,6 +36,11 @@ class CollectionTest extends \PHPUnit\Framework\TestCase */ private $productRepository; + /** + * @var \Magento\TestFramework\Fixture\DataFixtureStorage + */ + private $fixtures; + /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. @@ -52,6 +58,7 @@ protected function setUp(): void $this->productRepository = Bootstrap::getObjectManager()->create( \Magento\Catalog\Api\ProductRepositoryInterface::class ); + $this->fixtures = Bootstrap::getObjectManager()->get(DataFixtureStorageManager::class)->getStorage(); } /** @@ -144,19 +151,29 @@ public function testSetCategoryWithStoreFilter() } /** - * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDataFixture Magento\Catalog\Test\Fixture\Category as:c1 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"parent_id":"$c1.id$","is_anchor":0} as:c11 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"parent_id":"$c1.id$","is_anchor":0} as:c12 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Category with:{"parent_id":"$c11.id$"} as:c111 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Category as:c2 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"category_ids":["$c1.id$"]} as:p1 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"category_ids":["$c111.id$"]} as:p2 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"category_ids":["$c12.id$"]} as:p3 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"category_ids":["$c2.id$"]} as:p4 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"category_ids":["$c2.id$"]} as:p5 * @magentoAppIsolation enabled * @magentoDbIsolation disabled */ public function testSetCategoryFilter() { + $categoryId = $this->fixtures->get('c1')->getId(); $appState = Bootstrap::getObjectManager() ->create(State::class); $appState->setAreaCode(Area::AREA_CRONTAB); $category = \Magento\Framework\App\ObjectManager::getInstance()->get( \Magento\Catalog\Model\Category::class - )->load(3); + )->load($categoryId); $this->collection->addCategoryFilter($category); $this->collection->load(); $this->assertEquals($this->collection->getSize(), 3); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index b9a7c005749f1..592752406f62c 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -183,9 +183,7 @@ public function productFixtureDataProvider(): array return [ 'product' => [ 'sku' => 'simple', - 'custom_attributes' => [ - 'special_price' => 5.99 - ], + 'special_price' => 5.99, ] ]; } diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php b/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php deleted file mode 100644 index 1b88615756095..0000000000000 --- a/dev/tests/integration/testsuite/Magento/TestFramework/Annotation/DataFixtureTest.php +++ /dev/null @@ -1,196 +0,0 @@ -dataStorage = Bootstrap::getObjectManager()->get(DataFixtureTestStorage::class); - } - - /** - * @magentoDataFixture afterTestFixtureClass - * @magentoDataFixture Magento\TestFramework\Fixture\TestOne - * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo - */ - public function testFixtureClass(): void - { - $this->assertEquals( - [ - 'Magento\TestFramework\Fixture\TestOne' => true, - 'Magento\TestFramework\Fixture\TestTwo' => true - ], - $this->dataStorage->getData('fixtures') - ); - } - - /** - * @magentoDataFixture afterTestFixtureClass - * @magentoDataFixture Magento\TestFramework\Fixture\TestOne with:{"test1": "value1", "test11": "value11"} - * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo with:{"test2": "value2"} - * @magentoDataFixture Magento\TestFramework\Fixture\TestThree with:{"key": "test11", "value": "value12"} - */ - public function testFixtureClassWithParameters(): void - { - $this->assertEquals( - [ - 'Magento\TestFramework\Fixture\TestOne' => true, - 'Magento\TestFramework\Fixture\TestTwo' => true, - 'test1' => 'value1', - 'test11' => 'value12', - 'test2' => 'value2', - ], - $this->dataStorage->getData('fixtures') - ); - } - - /** - * @magentoDataFixture afterTestFixtureClass - * @magentoDataFixture Magento\TestFramework\Fixture\TestOne with:{"test1": "value1", "test11": "value11"} as:test1 - * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo with:{"test2": "value2"} as:test2 - * @magentoDataFixture Magento\TestFramework\Fixture\TestThree with:{"key": "test11", "value": "value12"} as:test3 - */ - public function testFixtureClassWithParametersAndAlias(): void - { - $this->assertEquals( - [ - 'Magento\TestFramework\Fixture\TestOne' => true, - 'test1' => 'value1', - 'test11' => 'value11', - ], - DataFixtureStorageManager::getStorage()->get('test1')->getData() - ); - $this->assertEquals( - [ - 'Magento\TestFramework\Fixture\TestTwo' => true, - 'test2' => 'value2', - ], - DataFixtureStorageManager::getStorage()->get('test2')->getData() - ); - $this->assertNull( - DataFixtureStorageManager::getStorage()->get('test3') - ); - $this->assertEquals( - [ - 'Magento\TestFramework\Fixture\TestOne' => true, - 'Magento\TestFramework\Fixture\TestTwo' => true, - 'test1' => 'value1', - 'test11' => 'value12', - 'test2' => 'value2', - ], - $this->dataStorage->getData('fixtures') - ); - } - - /** - * @magentoDataFixture afterTestFixtureClass - * @magentoDataFixture Magento\TestFramework\Fixture\TestOne as:test1 - * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo as:test2 - * @magentoDataFixture Magento\TestFramework\Fixture\TestThree as:test3 - * @magentoDataFixtureDataProvider methodFixtureDataProvider - */ - public function testMethodFixtureDataProvider(): void - { - $this->assertEquals( - [ - 'Magento\TestFramework\Fixture\TestOne' => true, - 'Magento\TestFramework\Fixture\TestTwo' => true, - 'test01' => 'value03', - 'test11' => 'value11', - 'test02' => 'value02', - ], - $this->dataStorage->getData('fixtures') - ); - } - - /** - * @return array - */ - public function methodFixtureDataProvider(): array - { - return [ - 'test1' => [ - 'test01' => 'value01', - 'test11' => 'value11', - ], - 'test2' => [ - 'test02' => 'value02', - ], - 'test3' => [ - 'key' => 'test01', - 'value' => 'value03', - ], - ]; - } - - /** - * @magentoDataFixture afterTestFixtureClass - * @magentoDataFixture Magento\TestFramework\Fixture\TestOne as:test1 - * @magentoDataFixture Magento\TestFramework\Fixture\TestTwo as:test2 - * @magentoDataFixture Magento\TestFramework\Fixture\TestThree as:test3 - */ - public function testClassFixtureDataProvider(): void - { - $this->assertEquals( - [ - 'Magento\TestFramework\Fixture\TestOne' => true, - 'Magento\TestFramework\Fixture\TestTwo' => true, - 'test01' => 'class-value03', - 'test11' => 'class-value11', - 'test02' => 'class-value02', - ], - $this->dataStorage->getData('fixtures') - ); - } - - /** - * @return array - */ - public function classFixtureDataProvider(): array - { - return [ - 'test1' => [ - 'test01' => 'class-value01', - 'test11' => 'class-value11', - ], - 'test2' => [ - 'test02' => 'class-value02', - ], - 'test3' => [ - 'key' => 'test01', - 'value' => 'class-value03', - ], - ]; - } - - public static function afterTestFixtureClass(): void - { - self::assertEmpty(Bootstrap::getObjectManager()->get(DataFixtureTestStorage::class)->getData('fixtures')); - } - - public static function afterTestFixtureClassRollback(): void - { - self::assertEmpty(Bootstrap::getObjectManager()->get(DataFixtureTestStorage::class)->getData('fixtures')); - } -} diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/DataFixtureTestStorage.php b/dev/tests/integration/testsuite/Magento/TestFramework/DataFixtureTestStorage.php deleted file mode 100644 index ec6c029d57f54..0000000000000 --- a/dev/tests/integration/testsuite/Magento/TestFramework/DataFixtureTestStorage.php +++ /dev/null @@ -1,17 +0,0 @@ -storage = $storage; - } - - /** - * @inheritdoc - */ - public function apply(array $data = []): ?array - { - $fixtures = $this->storage->getData('fixtures') ?? []; - $result = array_merge([get_class($this) => true], $data); - $this->storage->setData('fixtures', array_merge($fixtures, $result)); - return $result; - } - - /** - * @inheritdoc - */ - public function revert(array $data = []): void - { - $fixtures = $this->storage->getData('fixtures') ?? []; - foreach (array_keys($data) as $key) { - unset($fixtures[$key]); - } - $this->storage->setData('fixtures', $fixtures); - } -} diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php deleted file mode 100644 index c83de390f3398..0000000000000 --- a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestThree.php +++ /dev/null @@ -1,40 +0,0 @@ -storage = $storage; - } - - /** - * @inheritdoc - */ - public function apply(array $data = []): ?array - { - $fixtures = $this->storage->getData('fixtures') ?? []; - $fixtures[$data['key']] = $data['value']; - $this->storage->setData('fixtures', $fixtures); - return null; - } -} diff --git a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestTwo.php b/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestTwo.php deleted file mode 100644 index 575e2a0db97eb..0000000000000 --- a/dev/tests/integration/testsuite/Magento/TestFramework/Fixture/TestTwo.php +++ /dev/null @@ -1,15 +0,0 @@ -get('product1')->getProduct()->getId(); - $secondProductID = DataFixtureStorageManager::getStorage()->get('product2')->getProduct()->getId(); + $firstProductId = DataFixtureStorageManager::getStorage()->get('product1')->getId(); + $secondProductID = DataFixtureStorageManager::getStorage()->get('product2')->getId(); $relatedIds = $expectedAddedIds = [$firstProductId, $secondProductID]; $this->customerSession->setCustomerId(1); From feea6f69c426bb7833faa6f4bef3c82d2ad5d13a Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Mon, 29 Nov 2021 15:37:31 -0600 Subject: [PATCH 28/29] MC-40793: Update "Data fixture annotation" documentation - Add documentation for new fixture classes --- .../Fixture/AddAttributeToAttributeSet.php | 12 +++++-- .../Catalog/Test/Fixture/Attribute.php | 7 ++-- .../Magento/Catalog/Test/Fixture/Category.php | 5 ++- .../Magento/Catalog/Test/Fixture/Product.php | 6 ++-- .../Quote/Test/Fixture/AddProductToCart.php | 10 +++++- .../Quote/Test/Fixture/SetBillingAddress.php | 19 ++++++---- .../Quote/Test/Fixture/SetShippingAddress.php | 19 ++++++---- app/code/Magento/Store/Test/Fixture/Group.php | 13 ++++++- app/code/Magento/Store/Test/Fixture/Store.php | 18 ++++++++-- .../Magento/Store/Test/Fixture/Website.php | 13 ++++++- .../Model/ResourceModel/ProductTest.php | 36 +++++++++---------- 11 files changed, 115 insertions(+), 43 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php b/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php index 53c60cca5af3a..6aacb366c0681 100644 --- a/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php +++ b/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php @@ -39,7 +39,16 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters + *
+     *    $data = [
+     *      'attribute_code'     => (string) Attribute Code. Required.
+     *      'attribute_set_id'   => (int) Attribute Set ID. Optional. Default: default attribute set.
+     *      'attribute_group_id' => (int) Attribute Group ID. Optional. Default: default attribute group.
+     *      'sort_order'         => (int) Sort Order. Optional. Default: 0.
+     *    ]
+     * 
*/ public function apply(array $data = []): ?DataObject { @@ -49,7 +58,6 @@ public function apply(array $data = []): ?DataObject [ 'attribute_set_id' => $attributeSetId, 'attribute_group_id' => $attributeGroupId, - 'attribute_code' => 'fixture_attribute', 'sort_order' => 0, ], $data diff --git a/app/code/Magento/Catalog/Test/Fixture/Attribute.php b/app/code/Magento/Catalog/Test/Fixture/Attribute.php index fedaa86e83517..c98db8401efd0 100644 --- a/app/code/Magento/Catalog/Test/Fixture/Attribute.php +++ b/app/code/Magento/Catalog/Test/Fixture/Attribute.php @@ -34,13 +34,13 @@ class Attribute implements RevertibleDataFixtureInterface 'used_in_product_listing' => '0', 'is_visible' => true, 'scope' => 'store', - 'attribute_code' => 'fixture_attribute_%uniqid%', + 'attribute_code' => 'product_attribute%uniqid%', 'frontend_input' => 'text', 'entity_type_id' => '4', 'is_required' => false, 'options' => [], 'is_user_defined' => true, - 'default_frontend_label' => 'Fixture Attribute %uniqid%', + 'default_frontend_label' => 'Product Attribute%uniqid%', 'frontend_labels' => [], 'backend_type' => 'varchar', 'is_unique' => '0', @@ -70,7 +70,8 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters. Same format as Attribute::DEFAULT_DATA. */ public function apply(array $data = []): ?DataObject { diff --git a/app/code/Magento/Catalog/Test/Fixture/Category.php b/app/code/Magento/Catalog/Test/Fixture/Category.php index bec0d3ea06abc..4e3a2d67c3aea 100644 --- a/app/code/Magento/Catalog/Test/Fixture/Category.php +++ b/app/code/Magento/Catalog/Test/Fixture/Category.php @@ -43,6 +43,7 @@ class Category implements RevertibleDataFixtureInterface * @var ProcessorInterface */ private $dataProcessor; + /** * @var DataMerger */ @@ -63,7 +64,9 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters. Same format as Category::DEFAULT_DATA. Custom attributes and extension attributes + * can be passed directly in the outer array instead of custom_attributes or extension_attributes. */ public function apply(array $data = []): ?DataObject { diff --git a/app/code/Magento/Catalog/Test/Fixture/Product.php b/app/code/Magento/Catalog/Test/Fixture/Product.php index cd3ad0fafef5e..157e3f7b0c2c9 100644 --- a/app/code/Magento/Catalog/Test/Fixture/Product.php +++ b/app/code/Magento/Catalog/Test/Fixture/Product.php @@ -80,7 +80,9 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters. Same format as Product::DEFAULT_DATA. Custom attributes and extension attributes + * can be passed directly in the outer array instead of custom_attributes or extension_attributes. */ public function apply(array $data = []): ?DataObject { @@ -115,7 +117,7 @@ public function revert(DataObject $data): void private function prepareData(array $data): array { $data = $this->dataMerger->merge(self::DEFAULT_DATA, $data); - // remove category_links if empty in order for category_ids to processed if exists + // remove category_links if empty in order for category_ids to be processed if exists if (empty($data['extension_attributes']['category_links'])) { unset($data['extension_attributes']['category_links']); } diff --git a/app/code/Magento/Quote/Test/Fixture/AddProductToCart.php b/app/code/Magento/Quote/Test/Fixture/AddProductToCart.php index 059a372f92f6b..27d764a224a6a 100644 --- a/app/code/Magento/Quote/Test/Fixture/AddProductToCart.php +++ b/app/code/Magento/Quote/Test/Fixture/AddProductToCart.php @@ -37,7 +37,15 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters + *
+     *    $data = [
+     *      'cart_id'    => (int) Cart ID. Required.
+     *      'product_id' => (int) Product ID. Required.
+     *      'qty'        => (int) Quantity. Optional. Default: 1.
+     *    ]
+     * 
*/ public function apply(array $data = []): ?DataObject { diff --git a/app/code/Magento/Quote/Test/Fixture/SetBillingAddress.php b/app/code/Magento/Quote/Test/Fixture/SetBillingAddress.php index 5b86b8190ad1e..5ad4aaef9e66e 100644 --- a/app/code/Magento/Quote/Test/Fixture/SetBillingAddress.php +++ b/app/code/Magento/Quote/Test/Fixture/SetBillingAddress.php @@ -16,14 +16,14 @@ class SetBillingAddress implements DataFixtureInterface { private const DEFAULT_DATA = [ - AddressInterface::KEY_TELEPHONE => 3468676, - AddressInterface::KEY_POSTCODE => 75477, + AddressInterface::KEY_TELEPHONE => 3340000000, + AddressInterface::KEY_POSTCODE => 36104, AddressInterface::KEY_COUNTRY_ID => 'US', - AddressInterface::KEY_CITY => 'CityM', - AddressInterface::KEY_COMPANY => 'CompanyName', + AddressInterface::KEY_CITY => 'Montgomery', + AddressInterface::KEY_COMPANY => 'Magento', AddressInterface::KEY_STREET => ['Green str, 67'], - AddressInterface::KEY_LASTNAME => 'Smith', AddressInterface::KEY_FIRSTNAME => 'John', + AddressInterface::KEY_LASTNAME => 'Doe', AddressInterface::KEY_REGION_ID => 1, ]; @@ -42,7 +42,14 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters + *
+     *    $data = [
+     *      'cart_id' => (int) Cart ID. Required.
+     *      'address' => (array) Address Data. Optional. Default: SetBillingAddress::DEFAULT_DATA
+     *    ]
+     * 
*/ public function apply(array $data = []): ?DataObject { diff --git a/app/code/Magento/Quote/Test/Fixture/SetShippingAddress.php b/app/code/Magento/Quote/Test/Fixture/SetShippingAddress.php index e817e4578defe..e12b813d99b71 100644 --- a/app/code/Magento/Quote/Test/Fixture/SetShippingAddress.php +++ b/app/code/Magento/Quote/Test/Fixture/SetShippingAddress.php @@ -16,13 +16,13 @@ class SetShippingAddress implements DataFixtureInterface { private const DEFAULT_DATA = [ - AddressInterface::KEY_TELEPHONE => 3468676, - AddressInterface::KEY_POSTCODE => '75477', + AddressInterface::KEY_TELEPHONE => 3340000000, + AddressInterface::KEY_POSTCODE => 36104, AddressInterface::KEY_COUNTRY_ID => 'US', - AddressInterface::KEY_CITY => 'CityM', - AddressInterface::KEY_COMPANY => 'CompanyName', + AddressInterface::KEY_CITY => 'Montgomery', + AddressInterface::KEY_COMPANY => 'Magento', AddressInterface::KEY_STREET => ['Green str, 67'], - AddressInterface::KEY_LASTNAME => 'Smith', + AddressInterface::KEY_LASTNAME => 'Doe', AddressInterface::KEY_FIRSTNAME => 'John', AddressInterface::KEY_REGION_ID => 1, ]; @@ -39,7 +39,14 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters + *
+     *    $data = [
+     *      'cart_id' => (int) Cart ID. Required.
+     *      'address' => (array) Address Data. Optional. Default: SetShippingAddress::DEFAULT_DATA
+     *    ]
+     * 
*/ public function apply(array $data = []): ?DataObject { diff --git a/app/code/Magento/Store/Test/Fixture/Group.php b/app/code/Magento/Store/Test/Fixture/Group.php index 950e457e1d0f8..da768b72bb62e 100644 --- a/app/code/Magento/Store/Test/Fixture/Group.php +++ b/app/code/Magento/Store/Test/Fixture/Group.php @@ -70,7 +70,18 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters + *
+     *    $data = [
+     *      'id'               => (int) ID. Optional.
+     *      'code'             => (string) Code. Optional.
+     *      'name'             => (string) Name. Optional.
+     *      'website_id'       => (int) Website ID. Optional. Default: default website.
+     *      'root_category_id' => (int) Root Category ID. Optional. Default: default root category.
+     *      'default_store_id' => (int) Default Store ID. Optional.
+     *    ]
+     * 
*/ public function apply(array $data = []): ?DataObject { diff --git a/app/code/Magento/Store/Test/Fixture/Store.php b/app/code/Magento/Store/Test/Fixture/Store.php index 0fdf835b83cc9..744f079c37f7a 100644 --- a/app/code/Magento/Store/Test/Fixture/Store.php +++ b/app/code/Magento/Store/Test/Fixture/Store.php @@ -20,7 +20,8 @@ class Store implements RevertibleDataFixtureInterface private const DEFAULT_DATA = [ 'code' => 'test_store_view%uniqid%', 'name' => 'Test Store View%uniqid%', - 'sort_order' => '1' + 'sort_order' => '0', + 'is_active' => '1' ]; /** @@ -62,7 +63,19 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters + *
+     *    $data = [
+     *      'id'             => (int) ID. Optional.
+     *      'code'           => (string) Code. Optional.
+     *      'name'           => (string) Name. Optional.
+     *      'website_id'     => (int) Website ID. Optional. Default: default website.
+     *      'store_group_id' => (int) Store Group ID. Optional. Default: default store group.
+     *      'is_active'      => (int) Is Active. Optional. Default: 1
+     *      'sort_order'     => (int) Sort Order. Optional. Default: 0
+     *    ]
+     * 
*/ public function apply(array $data = []): ?DataObject { @@ -108,6 +121,7 @@ private function prepareData(array $data): array } elseif (!isset($data['store_group_id']) && isset($data['website_id'])) { $data['store_group_id'] = $this->storeManager->getWebsite($data['website_id'])->getDefaultGroupId(); } + $data['group_id'] = $data['store_group_id']; return $this->dataProcessor->process($this, $data); } diff --git a/app/code/Magento/Store/Test/Fixture/Website.php b/app/code/Magento/Store/Test/Fixture/Website.php index cad3b765ad97a..b491f0e593b41 100644 --- a/app/code/Magento/Store/Test/Fixture/Website.php +++ b/app/code/Magento/Store/Test/Fixture/Website.php @@ -62,7 +62,18 @@ public function __construct( } /** - * @inheritdoc + * {@inheritdoc} + * @param array $data Parameters + *
+     *    $data = [
+     *      'id'               => (int) ID. Optional.
+     *      'code'             => (string) Code. Optional.
+     *      'name'             => (string) Name. Optional.
+     *      'default_group_id' => (int) Default Group ID. Optional.
+     *      'is_default'       => (int) Is Default. Optional. Default: 0.
+     *      'sort_order'       => (int) Sort Order. Optional. Default: 0.
+     *    ]
+     * 
*/ public function apply(array $data = []): ?DataObject { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 592752406f62c..5d92ee51a0fac 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -66,8 +66,8 @@ public function testGetAttributeRawValue() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "fixture_attribute"} - * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "prod_attr"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet with:{"attribute_code": "prod_attr"} * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException @@ -77,17 +77,17 @@ public function testGetAttributeRawValue() public function testGetAttributeRawValueGetDefault() { $product = $this->productRepository->get('simple', true, 0, true); - $product->setCustomAttribute('fixture_attribute', 'default_value'); + $product->setCustomAttribute('prod_attr', 'default_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'prod_attr', 1); $this->assertEquals('default_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "fixture_attribute"} - * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "prod_attr"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet with:{"attribute_code": "prod_attr"} * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException @@ -97,21 +97,21 @@ public function testGetAttributeRawValueGetDefault() public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() { $product = $this->productRepository->get('simple', true, 0, true); - $product->setCustomAttribute('fixture_attribute', null); + $product->setCustomAttribute('prod_attr', null); $this->productRepository->save($product); $product = $this->productRepository->get('simple', true, 1, true); - $product->setCustomAttribute('fixture_attribute', 'store_value'); + $product->setCustomAttribute('prod_attr', 'store_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'prod_attr', 1); $this->assertEquals('store_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "fixture_attribute"} - * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "prod_attr"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet with:{"attribute_code": "prod_attr"} * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException @@ -121,21 +121,21 @@ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() { $product = $this->productRepository->get('simple', true, 0, true); - $product->setCustomAttribute('fixture_attribute', 'default_value'); + $product->setCustomAttribute('prod_attr', 'default_value'); $this->productRepository->save($product); $product = $this->productRepository->get('simple', true, 1, true); - $product->setCustomAttribute('fixture_attribute', 'store_value'); + $product->setCustomAttribute('prod_attr', 'store_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'prod_attr', 1); $this->assertEquals('store_value', $actual); } /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "fixture_attribute"} - * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet + * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "prod_attr"} + * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet with:{"attribute_code": "prod_attr"} * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException @@ -146,10 +146,10 @@ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() public function testGetAttributeRawValueGetStoreValueFallbackToDefault() { $product = $this->productRepository->get('simple', true, 0, true); - $product->setCustomAttribute('fixture_attribute', 'default_value'); + $product->setCustomAttribute('prod_attr', 'default_value'); $this->productRepository->save($product); - $actual = $this->model->getAttributeRawValue($product->getId(), 'fixture_attribute', 1); + $actual = $this->model->getAttributeRawValue($product->getId(), 'prod_attr', 1); $this->assertEquals('default_value', $actual); } From 3c71d4bad0f4947919e610652b87e903b39e2e28 Mon Sep 17 00:00:00 2001 From: Buba Suma Date: Fri, 10 Dec 2021 11:51:21 -0600 Subject: [PATCH 29/29] MC-42476: Refactor the most used legacy data fixtures to parametrized data fixtures --- app/code/Magento/Bundle/Test/Fixture/Link.php | 72 ++++++ .../Magento/Bundle/Test/Fixture/Option.php | 113 ++++++++++ .../Magento/Bundle/Test/Fixture/Product.php | 70 ++++++ .../Fixture/AddAttributeToAttributeSet.php | 71 ------ .../Catalog/Test/Fixture/Attribute.php | 67 +++++- .../Magento/Catalog/Test/Fixture/Product.php | 2 +- .../Magento/Catalog/Test/Fixture/Virtual.php | 42 ++++ .../Test/Fixture/Attribute.php | 50 +++++ .../Test/Fixture/Product.php | 211 ++++++++++++++++++ .../GroupedProduct/Test/Fixture/Product.php | 122 ++++++++++ .../Catalog/Api/CategoryRepositoryTest.php | 4 +- .../Magento/TestFramework/Application.php | 2 +- .../Fixture/LegacyDataFixture.php | 2 +- .../Bundle/Model/Product/PriceTest.php | 22 +- .../Model/ResourceModel/ProductTest.php | 20 +- .../ResourceModel/Product/RelationTest.php | 20 +- .../Model/Product/Type/GroupedTest.php | 15 +- .../Wishlist/Controller/Index/CartTest.php | 10 +- 18 files changed, 800 insertions(+), 115 deletions(-) create mode 100644 app/code/Magento/Bundle/Test/Fixture/Link.php create mode 100644 app/code/Magento/Bundle/Test/Fixture/Option.php create mode 100644 app/code/Magento/Bundle/Test/Fixture/Product.php delete mode 100644 app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php create mode 100644 app/code/Magento/Catalog/Test/Fixture/Virtual.php create mode 100644 app/code/Magento/ConfigurableProduct/Test/Fixture/Attribute.php create mode 100644 app/code/Magento/ConfigurableProduct/Test/Fixture/Product.php create mode 100644 app/code/Magento/GroupedProduct/Test/Fixture/Product.php diff --git a/app/code/Magento/Bundle/Test/Fixture/Link.php b/app/code/Magento/Bundle/Test/Fixture/Link.php new file mode 100644 index 0000000000000..eae4a81034753 --- /dev/null +++ b/app/code/Magento/Bundle/Test/Fixture/Link.php @@ -0,0 +1,72 @@ + null, + 'sku' => null, + 'option_id' => null, + 'qty' => 1, + 'position' => 1, + 'is_default' => false, + 'price' => null, + 'price_type' => null, + 'can_change_quantity' => 0 + ]; + + /** + * @var ProcessorInterface + */ + private $dataProcessor; + + /** + * @var DataObjectFactory + */ + private $dataObjectFactory; + + /** + * @param ProcessorInterface $dataProcessor + * @param DataObjectFactory $dataObjectFactory + */ + public function __construct( + ProcessorInterface $dataProcessor, + DataObjectFactory $dataObjectFactory + ) { + $this->dataProcessor = $dataProcessor; + $this->dataObjectFactory = $dataObjectFactory; + } + + /** + * {@inheritdoc} + * @param array $data Parameters. Same format as Link::DEFAULT_DATA. + */ + public function apply(array $data = []): ?DataObject + { + return $this->dataObjectFactory->create(['data' => $this->prepareData($data)]); + } + + /** + * Prepare link data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + + return $this->dataProcessor->process($this, $data); + } +} diff --git a/app/code/Magento/Bundle/Test/Fixture/Option.php b/app/code/Magento/Bundle/Test/Fixture/Option.php new file mode 100644 index 0000000000000..8575db1ebe18d --- /dev/null +++ b/app/code/Magento/Bundle/Test/Fixture/Option.php @@ -0,0 +1,113 @@ + null, + 'title' => 'option%uniqid%', + 'required' => true, + 'type' => 'select', + 'position' => 1, + 'sku' => null, + 'product_links' => [] + ]; + + /** + * @var ProcessorInterface + */ + private $dataProcessor; + + /** + * @var DataObjectFactory + */ + private $dataObjectFactory; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @param ProcessorInterface $dataProcessor + * @param DataObjectFactory $dataObjectFactory + */ + public function __construct( + ProcessorInterface $dataProcessor, + DataObjectFactory $dataObjectFactory, + ProductRepositoryInterface $productRepository + ) { + $this->dataProcessor = $dataProcessor; + $this->dataObjectFactory = $dataObjectFactory; + $this->productRepository = $productRepository; + } + + /** + * {@inheritdoc} + * @param array $data Parameters. Same format as Option::DEFAULT_DATA. + * - $data['product_links']: An array of product IDs, SKUs or instances. For advanced configuration use an array + * like Link::DEFAULT_DATA. + */ + public function apply(array $data = []): ?DataObject + { + return $this->dataObjectFactory->create(['data' => $this->prepareData($data)]); + } + + /** + * Prepare option data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + $data['product_links'] = $this->prepareLinksData($data); + + return $this->dataProcessor->process($this, $data); + } + + /** + * Prepare links data + * + * @param array $data + * @return array + */ + private function prepareLinksData(array $data): array + { + $links = []; + + foreach ($data['product_links'] as $link) { + $linkData = []; + if (is_numeric($link)) { + $product = $this->productRepository->getById($link); + $linkData['sku'] = $product->getSku(); + } elseif (is_string($link)) { + $linkData['sku'] = $link; + } elseif ($link instanceof ProductInterface) { + $product = $this->productRepository->get($link->getSku()); + $linkData['sku'] = $product->getSku(); + } else { + $linkData = $link instanceof DataObject ? $link->toArray() : $link; + } + + $linkData += Link::DEFAULT_DATA; + $links[] = $linkData; + } + + return $links; + } +} diff --git a/app/code/Magento/Bundle/Test/Fixture/Product.php b/app/code/Magento/Bundle/Test/Fixture/Product.php new file mode 100644 index 0000000000000..dd88f263c536c --- /dev/null +++ b/app/code/Magento/Bundle/Test/Fixture/Product.php @@ -0,0 +1,70 @@ + null, + 'type_id' => Type::TYPE_BUNDLE, + 'attribute_set_id' => 4, + 'name' => 'Bundle Product%uniqid%', + 'sku' => 'bundle-product%uniqid%', + 'price' => null, + 'weight' => null, + 'custom_attributes' => [ + 'price_view' => '0', + 'sku_type' => '0', + 'price_type' => '0', + 'weight_type' => '0', + 'shipment_type' => '0', + ], + 'extension_attributes' => [ + 'bundle_product_options' => [], + ] + ]; + + /** + * {@inheritdoc} + * @param array $data Parameters. Same format as \Magento\Catalog\Test\Fixture\Product::DEFAULT_DATA. + * Custom attributes and extension attributes can be passed directly in the outer array instead of custom_attributes + * or extension_attributes. + * Additional fields: + * - $data['_options']: An array of options. See Magento\Bundle\Test\Fixture\Option + */ + public function apply(array $data = []): ?DataObject + { + return parent::apply($this->prepareData($data)); + } + + /** + * Prepare product data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + + if (isset($data['_options'])) { + $data['extension_attributes']['bundle_product_options'] = array_map( + static function ($option) { + return $option instanceof DataObject ? $option->toArray() : $option; + }, + $data['_options'] + ); + unset($data['_options']); + } + + return $data; + } +} diff --git a/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php b/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php deleted file mode 100644 index 6aacb366c0681..0000000000000 --- a/app/code/Magento/Catalog/Test/Fixture/AddAttributeToAttributeSet.php +++ /dev/null @@ -1,71 +0,0 @@ -serviceFactory = $serviceFactory; - $this->eavSetup = $eavSetup; - } - - /** - * {@inheritdoc} - * @param array $data Parameters - *
-     *    $data = [
-     *      'attribute_code'     => (string) Attribute Code. Required.
-     *      'attribute_set_id'   => (int) Attribute Set ID. Optional. Default: default attribute set.
-     *      'attribute_group_id' => (int) Attribute Group ID. Optional. Default: default attribute group.
-     *      'sort_order'         => (int) Sort Order. Optional. Default: 0.
-     *    ]
-     * 
- */ - public function apply(array $data = []): ?DataObject - { - $attributeSetId = $this->eavSetup->getAttributeSetId(Product::ENTITY, 'Default'); - $attributeGroupId = $this->eavSetup->getDefaultAttributeGroupId(Product::ENTITY, $attributeSetId); - $data = array_merge( - [ - 'attribute_set_id' => $attributeSetId, - 'attribute_group_id' => $attributeGroupId, - 'sort_order' => 0, - ], - $data - ); - - $service = $this->serviceFactory->create(ProductAttributeManagementInterface::class, 'assign'); - $service->execute($data); - - return null; - } -} diff --git a/app/code/Magento/Catalog/Test/Fixture/Attribute.php b/app/code/Magento/Catalog/Test/Fixture/Attribute.php index c98db8401efd0..1f68eb2b832d3 100644 --- a/app/code/Magento/Catalog/Test/Fixture/Attribute.php +++ b/app/code/Magento/Catalog/Test/Fixture/Attribute.php @@ -7,7 +7,11 @@ namespace Magento\Catalog\Test\Fixture; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Api\ProductAttributeManagementInterface; use Magento\Catalog\Api\ProductAttributeRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Eav\Setup\EavSetup; use Magento\Framework\DataObject; use Magento\TestFramework\Fixture\Api\ServiceFactory; use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface; @@ -45,6 +49,13 @@ class Attribute implements RevertibleDataFixtureInterface 'backend_type' => 'varchar', 'is_unique' => '0', 'validation_rules' => [] + + ]; + + private const DEFAULT_ATTRIBUTE_SET_DATA = [ + '_set_id' => null, + '_group_id' => null, + '_sort_order' => 0, ]; /** @@ -57,16 +68,31 @@ class Attribute implements RevertibleDataFixtureInterface */ private $dataProcessor; + /** + * @var EavSetup + */ + private $eavSetup; + + /** + * @var ProductAttributeManagementInterface + */ + private $productAttributeManagement; + /** * @param ServiceFactory $serviceFactory * @param ProcessorInterface $dataProcessor + * @param EavSetup $eavSetup */ public function __construct( ServiceFactory $serviceFactory, - ProcessorInterface $dataProcessor + ProcessorInterface $dataProcessor, + EavSetup $eavSetup, + ProductAttributeManagementInterface $productAttributeManagement ) { $this->serviceFactory = $serviceFactory; $this->dataProcessor = $dataProcessor; + $this->eavSetup = $eavSetup; + $this->productAttributeManagement = $productAttributeManagement; } /** @@ -77,11 +103,27 @@ public function apply(array $data = []): ?DataObject { $service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'save'); - return $service->execute( + /** + * @var ProductAttributeInterface $attribute + */ + $attribute = $service->execute( [ - 'attribute' => $this->prepareData($data) + 'attribute' => $this->prepareData(array_diff_key($data, self::DEFAULT_ATTRIBUTE_SET_DATA)) ] ); + + $attributeSetData = $this->prepareAttributeSetData( + array_intersect_key($data, self::DEFAULT_ATTRIBUTE_SET_DATA) + ); + + $this->productAttributeManagement->assign( + $attributeSetData['_set_id'], + $attributeSetData['_group_id'], + $attribute->getAttributeCode(), + $attributeSetData['_sort_order'] + ); + + return $attribute; } /** @@ -109,4 +151,23 @@ private function prepareData(array $data): array return $this->dataProcessor->process($this, $data); } + + /** + * Prepare attribute set data + * + * @param array $data + * @return array + */ + private function prepareAttributeSetData(array $data): array + { + $attributeSetId = $this->eavSetup->getAttributeSetId(Product::ENTITY, 'Default'); + $attributeGroupId = $this->eavSetup->getDefaultAttributeGroupId(Product::ENTITY, $attributeSetId); + $attributeSetData = [ + '_set_id' => $attributeSetId, + '_group_id' => $attributeGroupId, + ]; + $data = array_merge(self::DEFAULT_ATTRIBUTE_SET_DATA, $attributeSetData, $data); + + return array_intersect_key($data, self::DEFAULT_ATTRIBUTE_SET_DATA); + } } diff --git a/app/code/Magento/Catalog/Test/Fixture/Product.php b/app/code/Magento/Catalog/Test/Fixture/Product.php index 157e3f7b0c2c9..3528afaf63423 100644 --- a/app/code/Magento/Catalog/Test/Fixture/Product.php +++ b/app/code/Magento/Catalog/Test/Fixture/Product.php @@ -24,7 +24,7 @@ class Product implements RevertibleDataFixtureInterface 'type_id' => Type::TYPE_SIMPLE, 'attribute_set_id' => 4, 'name' => 'Simple Product%uniqid%', - 'sku' => 'simple%uniqid%', + 'sku' => 'simple-product%uniqid%', 'price' => 10, 'weight' => 1, 'visibility' => Visibility::VISIBILITY_BOTH, diff --git a/app/code/Magento/Catalog/Test/Fixture/Virtual.php b/app/code/Magento/Catalog/Test/Fixture/Virtual.php new file mode 100644 index 0000000000000..35bf4de065d18 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Fixture/Virtual.php @@ -0,0 +1,42 @@ + Type::TYPE_VIRTUAL, + 'name' => 'Virtual Product%uniqid%', + 'sku' => 'virtual-product%uniqid%', + 'weight' => null, + ]; + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + return parent::apply($this->prepareData($data)); + } + + /** + * Prepare product data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + + return $data; + } +} diff --git a/app/code/Magento/ConfigurableProduct/Test/Fixture/Attribute.php b/app/code/Magento/ConfigurableProduct/Test/Fixture/Attribute.php new file mode 100644 index 0000000000000..94766e0affd92 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Fixture/Attribute.php @@ -0,0 +1,50 @@ + 'select', + 'options' => [ + [ + 'label' => 'option1%uniqid%', + 'sort_order' => 0, + ], + [ + 'label' => 'option2%uniqid%', + 'sort_order' => 1, + ] + ], + ]; + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + $data = $this->prepareData($data); + + return parent::apply($data); + } + + /** + * Prepare attribute data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + + return $data; + } +} diff --git a/app/code/Magento/ConfigurableProduct/Test/Fixture/Product.php b/app/code/Magento/ConfigurableProduct/Test/Fixture/Product.php new file mode 100644 index 0000000000000..67e2d9c217fce --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Fixture/Product.php @@ -0,0 +1,211 @@ + null, + 'type_id' => Configurable::TYPE_CODE, + 'attribute_set_id' => 4, + 'name' => 'Configurable Product%uniqid%', + 'sku' => 'configurable-product%uniqid%', + 'price' => null, + 'weight' => null, + 'extension_attributes' => [ + 'configurable_product_options' => [], + 'configurable_product_links' => [], + ] + ]; + + /** + * @var Config + */ + private $eavConfig; + + /** + * @var VariationMatrix + */ + private $variationMatrix; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @param ServiceFactory $serviceFactory + * @param ProcessorInterface $dataProcessor + * @param DataMerger $dataMerger + * @param Config $eavConfig + * @param ProductRepositoryInterface $productRepository + * @param VariationMatrix $variationMatrix + */ + public function __construct( + ServiceFactory $serviceFactory, + ProcessorInterface $dataProcessor, + DataMerger $dataMerger, + Config $eavConfig, + ProductRepositoryInterface $productRepository, + VariationMatrix $variationMatrix + ) { + parent::__construct($serviceFactory, $dataProcessor, $dataMerger); + $this->eavConfig = $eavConfig; + $this->variationMatrix = $variationMatrix; + $this->productRepository = $productRepository; + } + + /** + * {@inheritdoc} + * @param array $data Parameters. Same format as \Magento\Catalog\Test\Fixture\Product::DEFAULT_DATA. + * Custom attributes and extension attributes can be passed directly in the outer array instead of custom_attributes + * or extension_attributes. + * Additional fields: + * - $data['_options']: An array of attribute IDs, codes, or instances to use as configurable product options. + * - $data['_links']: An array of product IDs, SKUs or instances to associate to the configurable options. + * Products will be assigned to the variation in the same order as they are listed. Use 0 to skip a variation. + */ + public function apply(array $data = []): ?DataObject + { + return parent::apply($this->prepareData($data)); + } + + /** + * Prepare product data + * + * @param array $data + * @return array + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + + if (isset($data['_options'])) { + $productIds = []; + $options = $this->prepareOptions($data); + if (isset($data['_links'])) { + $links = $this->prepareLinks($data); + $this->associateProducts($links, $options); + // remove holes + $productIds = array_values(array_filter($links)); + } + unset($data['_options'], $data['_links']); + $data['extension_attributes']['configurable_product_options'] = $options; + $data['extension_attributes']['configurable_product_links'] = $productIds; + } + + return $data; + } + + /** + * Generate configurable options + * + * @param array $data + * @return array + */ + private function prepareOptions(array $data): array + { + $options = []; + foreach ($data['_options'] as $index => $attribute) { + $attributeId = $attribute instanceof AttributeInterface ? $attribute->getAttributeId() : $attribute; + $attributeObject = $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeId); + $values = []; + foreach ($attributeObject->getOptions() as $option) { + if ($option->getValue()) { + $values[] = [ + 'value_index' => $option->getValue(), + ]; + } + } + $options[] = [ + 'attribute_id' => $attributeObject->getId(), + 'label' => $attributeObject->getStoreLabel(), + 'position' => $index, + 'values' => $values, + ]; + } + return $options; + } + + /** + * Prepare configurable associated products + * + * @param array $data + * @return array + */ + private function prepareLinks(array $data): array + { + $links = []; + foreach ($data['_links'] as $link) { + if (!is_numeric($link)) { + $sku = $link instanceof ProductInterface + ? $link->getSku() + : $link; + $product = $this->productRepository->get($sku); + $productId = $product->getId(); + } else { + $productId = $link; + } + $links[] = (int) $productId; + } + + return $links; + } + + /** + * Associate provided products list to configurable options + * + * @param array $links List of product IDs to associate to each variation in order. + * 0 in the list means no product will be associated to the corresponding variation. + * @param array $options + * @return void + */ + private function associateProducts(array $links, array $options): void + { + $variations = $this->variationMatrix->getVariations( + array_map( + static function (array $option) { + return [ + 'attribute_id' => $option['attribute_id'], + 'values' => $option['values'], + 'options' => array_map( + static function (array $value) { + return ['value' => $value['value_index']]; + }, + $option['values'] + ) + ]; + }, + $options + ) + ); + $variationIndex = 0; + foreach ($variations as $variation) { + foreach ($variation as $attributeId => $valueInfo) { + if (isset($links[$variationIndex]) && $links[$variationIndex] !== 0) { + $attribute = $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeId); + $product = $this->productRepository->getById($links[$variationIndex]); + $product->setCustomAttribute($attribute->getAttributeCode(), $valueInfo['value']); + $this->productRepository->save($product); + } + $variationIndex++; + } + } + } +} diff --git a/app/code/Magento/GroupedProduct/Test/Fixture/Product.php b/app/code/Magento/GroupedProduct/Test/Fixture/Product.php new file mode 100644 index 0000000000000..dc6640dbb7f79 --- /dev/null +++ b/app/code/Magento/GroupedProduct/Test/Fixture/Product.php @@ -0,0 +1,122 @@ + Grouped::TYPE_CODE, + 'name' => 'Grouped Product%uniqid%', + 'sku' => 'grouped-product%uniqid%', + 'price' => null, + 'weight' => null, + 'product_links' => [], + ]; + + private const DEFAULT_PRODUCT_LINK_DATA = [ + 'sku' => null, + 'position' => 1, + 'qty' => 1, + ]; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @param ServiceFactory $serviceFactory + * @param ProcessorInterface $dataProcessor + * @param DataMerger $dataMerger + * @param ProductRepositoryInterface $productRepository + */ + public function __construct( + ServiceFactory $serviceFactory, + ProcessorInterface $dataProcessor, + DataMerger $dataMerger, + ProductRepositoryInterface $productRepository + ) { + parent::__construct($serviceFactory, $dataProcessor, $dataMerger); + $this->productRepository = $productRepository; + } + + /** + * @inheritdoc + */ + public function apply(array $data = []): ?DataObject + { + return parent::apply($this->prepareData($data)); + } + + /** + * {@inheritdoc} + * @param array $data Parameters. Same format as \Magento\Catalog\Test\Fixture\Product::DEFAULT_DATA. + * Custom attributes and extension attributes can be passed directly in the outer array instead of custom_attributes + * or extension_attributes. + * - $data['product_links']: An array of product IDs, SKUs or instances to associate to the grouped product. For + * advanced configuration, use an array{sku: string, position: int, qty: int} + */ + private function prepareData(array $data): array + { + $data = array_merge(self::DEFAULT_DATA, $data); + $data['product_links'] = $this->prepareLinksData($data); + + return $data; + } + + /** + * Prepare links data + * + * @param array $data + * @return array + */ + private function prepareLinksData(array $data): array + { + $links = []; + + $position = 1; + foreach ($data['product_links'] as $link) { + $linkData = []; + $defaultLinkData = self::DEFAULT_PRODUCT_LINK_DATA; + $defaultLinkData['position'] = $position; + if (is_numeric($link)) { + $product = $this->productRepository->getById($link); + } elseif (is_string($link)) { + $product = $this->productRepository->get($link); + } elseif ($link instanceof ProductInterface) { + $product = $this->productRepository->get($link->getSku()); + } else { + $linkData = $link instanceof DataObject ? $link->toArray() : $link; + $product = $this->productRepository->get($linkData['sku']); + } + + $linkData += $defaultLinkData; + $links[] = [ + 'sku' => $data['sku'], + 'link_type' => 'associated', + 'linked_product_sku' => $product->getSku(), + 'linked_product_type' => $product->getTypeId(), + 'position' => $linkData['position'], + 'extension_attributes' => [ + 'qty' => $linkData['qty'] + ], + ]; + $position++; + } + + return $links; + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php index 9e61a87caf6c3..7dedeb3f9bc96 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php @@ -31,8 +31,8 @@ */ class CategoryRepositoryTest extends WebapiAbstract { - const RESOURCE_PATH = '/V1/categories'; - const SERVICE_NAME = 'catalogCategoryRepositoryV1'; + private const RESOURCE_PATH = '/V1/categories'; + private const SERVICE_NAME = 'catalogCategoryRepositoryV1'; /** * @var int diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php index 20fe53e5ee74c..57c46d197c62f 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Application.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php @@ -28,7 +28,7 @@ class Application /** * Default application area. */ - const DEFAULT_APP_AREA = 'global'; + public const DEFAULT_APP_AREA = 'global'; /** * DB vendor adapter instance. diff --git a/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php b/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php index dc1c066e4ea3d..4cb672b296364 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Fixture/LegacyDataFixture.php @@ -66,7 +66,7 @@ private function execute(string $filePath): void require $filePath; } catch (\Throwable $e) { throw new \Exception( - 'Error in fixture: ' . $filePath, + 'Error in fixture ' . $filePath . PHP_EOL . $e->getTraceAsString(), 0, $e ); diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/PriceTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/PriceTest.php index fb1afc5040c03..02c41c305d5f5 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/PriceTest.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/PriceTest.php @@ -143,14 +143,23 @@ public function testFixedBundleProductPriceWithCatalogRule(): void /** * Fixed Bundle Product without discounts - * @magentoDataFixture Magento/Bundle/_files/fixed_bundle_product_without_discounts.php + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple1","price":10} as:p1 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple2","price":20} as:p2 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple3","price":30} as:p3 + * @magentoDataFixture Magento\Bundle\Test\Fixture\Link with:{"sku":"$p1.sku$","price":10,"price_type":0} as:link1 + * @magentoDataFixture Magento\Bundle\Test\Fixture\Link with:{"sku":"$p2.sku$","price":25,"price_type":1} as:link2 + * @magentoDataFixture Magento\Bundle\Test\Fixture\Link with:{"sku":"$p3.sku$","price":25,"price_type":0} as:link3 + * @magentoDataFixture Magento\Bundle\Test\Fixture\Option as:opt1 + * @magentoDataFixture Magento\Bundle\Test\Fixture\Product as:bundle1 + * @magentoDataFixtureDataProvider {"opt1":{"product_links":["$link1$","$link2$","$link3$"]}} + * @magentoDataFixtureDataProvider {"bundle1":{"sku":"bundle1","price":50,"price_type":1,"_options":["$opt1$"]}} * * @return void */ public function testFixedBundleProductPriceWithoutDiscounts(): void { $this->checkBundlePrices( - 'fixed_bundle_product_without_discounts', + 'bundle1', ['price' => 50, 'final_price' => 50, 'min_price' => 60, 'max_price' => 75, 'tier_price' => null], ['simple1' => 60, 'simple2' => 62.5, 'simple3' => 75] ); @@ -188,14 +197,19 @@ public function testFixedBundleProductPriceWithTierPrice(): void /** * Dynamic Bundle Product without discount + options without discounts - * @magentoDataFixture Magento/Bundle/_files/dynamic_bundle_product_without_discounts.php + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple1000","price":10} as:p1 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple1001","price":20} as:p2 + * @magentoDataFixture Magento\Bundle\Test\Fixture\Option as:opt1 + * @magentoDataFixture Magento\Bundle\Test\Fixture\Product as:bundle1 + * @magentoDataFixtureDataProvider {"opt1":{"product_links":["$p1$","$p2$"]}} + * @magentoDataFixtureDataProvider {"bundle1":{"sku":"bundle1","_options":["$opt1$"]}} * * @return void */ public function testDynamicBundleProductWithoutDiscountAndOptionsWithoutDiscounts(): void { $this->checkBundlePrices( - 'dynamic_bundle_product_without_discounts', + 'bundle1', ['price' => 0, 'final_price' => 0, 'min_price' => 10, 'max_price' => 20, 'tier_price' => null], ['simple1000' => 10, 'simple1001' => 20] ); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 5d92ee51a0fac..85c350166c65f 100755 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -67,7 +67,6 @@ public function testGetAttributeRawValue() /** * @magentoAppArea adminhtml * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "prod_attr"} - * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet with:{"attribute_code": "prod_attr"} * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException @@ -87,7 +86,6 @@ public function testGetAttributeRawValueGetDefault() /** * @magentoAppArea adminhtml * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "prod_attr"} - * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet with:{"attribute_code": "prod_attr"} * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException @@ -111,7 +109,6 @@ public function testGetAttributeRawValueGetStoreSpecificValueNoDefault() /** * @magentoAppArea adminhtml * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "prod_attr"} - * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet with:{"attribute_code": "prod_attr"} * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException @@ -135,7 +132,6 @@ public function testGetAttributeRawValueGetStoreSpecificValueWithDefault() /** * @magentoAppArea adminhtml * @magentoDataFixture Magento\Catalog\Test\Fixture\Attribute with:{"attribute_code": "prod_attr"} - * @magentoDataFixture Magento\Catalog\Test\Fixture\AddAttributeToAttributeSet with:{"attribute_code": "prod_attr"} * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku": "simple"} * @throws NoSuchEntityException * @throws CouldNotSaveException @@ -155,10 +151,9 @@ public function testGetAttributeRawValueGetStoreValueFallbackToDefault() /** * @magentoAppArea adminhtml - * @magentoDataFixture Magento\Catalog\Test\Fixture\Product as:product + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple","special_price":"5.99"} * @magentoAppIsolation enabled * @magentoConfigFixture default_store catalog/price/scope 1 - * @magentoDataFixtureDataProvider productFixtureDataProvider */ public function testUpdateStoreSpecificSpecialPrice() { @@ -175,19 +170,6 @@ public function testUpdateStoreSpecificSpecialPrice() $this->assertEquals(5.99, $product->getSpecialPrice()); } - /** - * @return array - */ - public function productFixtureDataProvider(): array - { - return [ - 'product' => [ - 'sku' => 'simple', - 'special_price' => 5.99, - ] - ]; - } - /** * Checks that product has no attribute values for attributes not assigned to the product's attribute set. * diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/RelationTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/RelationTest.php index 20d366d05ac4a..be0631a181272 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/RelationTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/RelationTest.php @@ -53,17 +53,25 @@ protected function setUp(): void /** * Tests that getRelationsByChildren will return parent products entity ids of child products entity ids. * - * @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_products.php + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple_10"} as:p1 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple_20"} as:p2 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple_30"} as:p3 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product with:{"sku":"simple_40"} as:p4 + * @magentoDataFixture Magento\ConfigurableProduct\Test\Fixture\Attribute as:attr + * @magentoDataFixture Magento\ConfigurableProduct\Test\Fixture\Product as:conf1 + * @magentoDataFixture Magento\ConfigurableProduct\Test\Fixture\Product as:conf2 + * @magentoDataFixtureDataProvider {"conf1":{"sku":"conf1","_options":["$attr$"],"_links":["$p1$","$p2$"]}} + * @magentoDataFixtureDataProvider {"conf2":{"sku":"conf2","_options":["$attr$"],"_links":["$p3$","$p4$"]}} */ public function testGetRelationsByChildren(): void { $childSkusOfParentSkus = [ - 'configurable' => ['simple_10', 'simple_20'], - 'configurable_12345' => ['simple_30', 'simple_40'], + 'conf1' => ['simple_10', 'simple_20'], + 'conf2' => ['simple_30', 'simple_40'], ]; $configurableSkus = [ - 'configurable', - 'configurable_12345', + 'conf1', + 'conf2', 'simple_10', 'simple_20', 'simple_30', @@ -114,7 +122,7 @@ public function testGetRelationsByChildren(): void */ private function sortParentIdsOfChildIds(array $array): array { - foreach ($array as $childId => &$parentIds) { + foreach ($array as &$parentIds) { sort($parentIds, SORT_NUMERIC); } diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php index 25ddef8d7590d..6f4d58b8a5620 100644 --- a/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php @@ -49,7 +49,12 @@ public function testFactory() } /** - * @magentoDataFixture Magento/GroupedProduct/_files/product_grouped.php + * @magentoDataFixture Magento\Catalog\Test\Fixture\Product as:p1 + * @magentoDataFixture Magento\Catalog\Test\Fixture\Virtual as:p2 + * @magentoDataFixture Magento\GroupedProduct\Test\Fixture\Product as:gr1 + * @magentoDataFixtureDataProvider {"p1":{"sku":"simple","name":"Simple Product","price":10}} + * @magentoDataFixtureDataProvider {"p2":{"sku":"virtual-product","name":"Virtual Product","price":10}} + * @magentoDataFixtureDataProvider {"gr1":{"sku":"gr1","product_links":["$p1$",{"sku":"$p2.sku$","qty":2}]}} * @magentoAppArea frontend */ public function testGetAssociatedProducts() @@ -57,7 +62,7 @@ public function testGetAssociatedProducts() $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); /** @var Product $product */ - $product = $productRepository->get('grouped-product'); + $product = $productRepository->get('gr1'); $type = $product->getTypeInstance(); $this->assertInstanceOf(Grouped::class, $type); @@ -74,14 +79,14 @@ public function testGetAssociatedProducts() private function assertProductInfo($product) { $data = [ - 1 => [ + 'simple' => [ 'sku' => 'simple', 'name' => 'Simple Product', 'price' => '10.000000', 'qty' => '1', 'position' => '1' ], - 21 => [ + 'virtual-product' => [ 'sku' => 'virtual-product', 'name' => 'Virtual Product', 'price' => '10.000000', @@ -89,7 +94,7 @@ private function assertProductInfo($product) 'position' => '2' ] ]; - $productId = $product->getId(); + $productId = $product->getSku(); $this->assertEquals($data[$productId]['sku'], $product->getSku()); $this->assertEquals($data[$productId]['name'], $product->getName()); $this->assertEquals($data[$productId]['price'], $product->getPrice()); diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php index b2672b9093660..3bf4f459b63fc 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/CartTest.php @@ -40,6 +40,11 @@ class CartTest extends AbstractController /** @var ProductRepositoryInterface */ private $productRepository; + /** + * @var \Magento\TestFramework\Fixture\DataFixtureStorage + */ + private $fixtures; + /** * @inheritdoc */ @@ -52,6 +57,7 @@ protected function setUp(): void $this->cartFactory = $this->_objectManager->get(CartFactory::class); $this->escaper = $this->_objectManager->get(Escaper::class); $this->productRepository = $this->_objectManager->get(ProductRepositoryInterface::class); + $this->fixtures = $this->_objectManager->get(DataFixtureStorageManager::class)->getStorage(); } /** @@ -123,8 +129,8 @@ public function testAddNotExistingItemToCart(): void */ public function testAddItemWithRelatedProducts(): void { - $firstProductId = DataFixtureStorageManager::getStorage()->get('product1')->getId(); - $secondProductID = DataFixtureStorageManager::getStorage()->get('product2')->getId(); + $firstProductId = $this->fixtures->get('product1')->getId(); + $secondProductID = $this->fixtures->get('product2')->getId(); $relatedIds = $expectedAddedIds = [$firstProductId, $secondProductID]; $this->customerSession->setCustomerId(1);