Skip to content

Commit 6288937

Browse files
committed
MC-40833: Create automated test for: "Checking product images after Add/Update import failure"
1 parent 10a7065 commit 6288937

File tree

3 files changed

+240
-0
lines changed

3 files changed

+240
-0
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogImportExport\Model\Import;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\Product;
12+
use Magento\CatalogImportExport\Model\Import\ProductImport;
13+
use Magento\Framework\App\Filesystem\DirectoryList;
14+
use Magento\Framework\File\Csv;
15+
use Magento\Framework\Filesystem;
16+
use Magento\Framework\Filesystem\Directory\Write;
17+
use Magento\Framework\MessageQueue\MessageEncoder;
18+
use Magento\Framework\ObjectManagerInterface;
19+
use Magento\ImportExport\Model\Export\Consumer;
20+
use Magento\ImportExport\Model\Import as ImportModel;
21+
use Magento\ImportExport\Model\Import\Source\Csv as CsvSource;
22+
use Magento\ImportExport\Model\Import\Source\CsvFactory;
23+
use Magento\MysqlMq\Model\Driver\Queue;
24+
use Magento\TestFramework\Helper\Bootstrap;
25+
use PHPUnit\Framework\TestCase;
26+
27+
/**
28+
* Checks that import with not exist images will fail
29+
*
30+
* @see \Magento\CatalogImportExport\Model\Import\Product
31+
*
32+
* @magentoAppArea adminhtml
33+
*/
34+
class ImportWithNotExistImagesTest extends TestCase
35+
{
36+
/** @var ObjectManagerInterface */
37+
private $objectManager;
38+
39+
/** @var MessageEncoder */
40+
private $messageEncoder;
41+
42+
/** @var Consumer */
43+
private $consumer;
44+
45+
/** @var Queue */
46+
private $queue;
47+
48+
/** @var Csv */
49+
private $csvReader;
50+
51+
/** @var Write */
52+
private $directory;
53+
54+
/** @var string */
55+
private $filePath;
56+
57+
/** @var ProductImport */
58+
private $import;
59+
60+
/** @var CsvFactory */
61+
private $csvFactory;
62+
63+
/** @var Filesystem */
64+
private $fileSystem;
65+
66+
/** @var ProductRepositoryInterface */
67+
private $productRepository;
68+
69+
/**
70+
* @inheritdoc
71+
*/
72+
protected function setUp(): void
73+
{
74+
parent::setUp();
75+
76+
$this->objectManager = Bootstrap::getObjectManager();
77+
$this->queue = $this->objectManager->create(Queue::class, ['queueName' => 'export']);
78+
$this->messageEncoder = $this->objectManager->get(MessageEncoder::class);
79+
$this->consumer = $this->objectManager->get(Consumer::class);
80+
$this->directory = $this->objectManager->get(Filesystem::class)->getDirectoryWrite(DirectoryList::VAR_DIR);
81+
$this->csvReader = $this->objectManager->get(Csv::class);
82+
$this->import = $this->objectManager->get(ProductFactory::class)->create();
83+
$this->csvFactory = $this->objectManager->get(CsvFactory::class);
84+
$this->fileSystem = $this->objectManager->get(Filesystem::class);
85+
$this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
86+
}
87+
88+
/**
89+
* @inheritdoc
90+
*/
91+
protected function tearDown(): void
92+
{
93+
if ($this->filePath && $this->directory->isExist($this->filePath)) {
94+
$this->directory->delete($this->filePath);
95+
}
96+
97+
parent::tearDown();
98+
}
99+
100+
/**
101+
* @magentoDataFixture Magento/CatalogImportExport/_files/export_queue_product_with_images.php
102+
*
103+
* @return void
104+
*/
105+
public function testImportFailure(): void
106+
{
107+
$this->exportProducts();
108+
$this->assertTrue($this->directory->isExist($this->filePath));
109+
$csv = $this->csvReader->getData($this->directory->getAbsolutePath($this->filePath));
110+
$this->assertCount(2, $csv);
111+
$this->updateExportFile();
112+
$this->import->setParameters([
113+
'entity' => Product::ENTITY,
114+
'behavior' => ImportModel::BEHAVIOR_ADD_UPDATE,
115+
]);
116+
$this->assertImportErrors();
117+
$this->assertProductNoHaveChanges();
118+
}
119+
120+
/**
121+
* Export products from queue to csv file
122+
*
123+
* @return void
124+
*/
125+
private function exportProducts(): void
126+
{
127+
$envelope = $this->queue->dequeue();
128+
$decodedMessage = $this->messageEncoder->decode('import_export.export', $envelope->getBody());
129+
$this->consumer->process($decodedMessage);
130+
$this->filePath = 'export/' . $decodedMessage->getFileName();
131+
}
132+
133+
/**
134+
* Change image names in an export file
135+
*
136+
* @return void
137+
*/
138+
private function updateExportFile(): void
139+
{
140+
$absolutePath = $this->directory->getAbsolutePath($this->filePath);
141+
$csv = $this->csvReader->getData($absolutePath);
142+
foreach ($csv[1] as $key => $data) {
143+
if ($data === '/m/a/magento_image.jpg') {
144+
$csv[1][$key] = '/m/a/invalid_image.jpg';
145+
}
146+
}
147+
148+
$this->csvReader->appendData($absolutePath, $csv);
149+
}
150+
151+
/**
152+
* Get export csv file
153+
*
154+
* @param string $file
155+
* @return CsvSource
156+
*/
157+
private function prepareFile(string $file): CsvSource
158+
{
159+
return $this->csvFactory->create([
160+
'file' => $file,
161+
'directory' => $this->fileSystem->getDirectoryWrite(DirectoryList::VAR_DIR),
162+
]);
163+
}
164+
165+
/**
166+
* Assert import errors
167+
*
168+
* @return void
169+
*/
170+
private function assertImportErrors(): void
171+
{
172+
$errors = $this->import->setSource($this->prepareFile($this->filePath))->validateData();
173+
$this->assertEmpty($errors->getAllErrors());
174+
$this->import->importData();
175+
$this->assertEquals(1, $errors->getErrorsCount());
176+
$error = $errors->getAllErrors()[0];
177+
$this->assertEquals('mediaUrlNotAvailable', $error->getErrorCode());
178+
$errorMsg = (string)__('Imported resource (image) could not be downloaded ' .
179+
'from external resource due to timeout or access permissions');
180+
$this->assertEquals($errorMsg, $error->getErrorMessage());
181+
}
182+
183+
/**
184+
* Assert product images were not changed after import
185+
*
186+
* @return void
187+
*/
188+
private function assertProductNoHaveChanges(): void
189+
{
190+
$product = $this->productRepository->get('simple');
191+
$this->assertEquals('/m/a/magento_image.jpg', $product->getImage());
192+
$this->assertEquals('/m/a/magento_image.jpg', $product->getSmallImage());
193+
$this->assertEquals('/m/a/magento_image.jpg', $product->getThumbnail());
194+
}
195+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\Catalog\Api\Data\ProductAttributeInterface;
9+
use Magento\Catalog\Api\Data\ProductInterface;
10+
use Magento\Framework\MessageQueue\PublisherInterface;
11+
use Magento\ImportExport\Model\Export\Entity\ExportInfoFactory;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
14+
15+
Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_with_image.php');
16+
17+
$objectManager = Bootstrap::getObjectManager();
18+
/** @var ExportInfoFactory $exportInfoFactory */
19+
$exportInfoFactory = $objectManager->get(ExportInfoFactory::class);
20+
/** @var PublisherInterface $messagePublisher */
21+
$messagePublisher = $objectManager->get(PublisherInterface::class);
22+
$dataObject = $exportInfoFactory->create(
23+
'csv',
24+
ProductAttributeInterface::ENTITY_TYPE_CODE,
25+
[ProductInterface::SKU => 'simple'],
26+
[]
27+
);
28+
$messagePublisher->publish('import_export.export', $dataObject);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
use Magento\TestFramework\MysqlMq\DeleteTopicRelatedMessages;
9+
use Magento\TestFramework\Helper\Bootstrap;
10+
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
11+
12+
$objectManager = Bootstrap::getObjectManager();
13+
/** @var DeleteTopicRelatedMessages $deleteTopicRelatedMessages */
14+
$deleteTopicRelatedMessages = $objectManager->get(DeleteTopicRelatedMessages::class);
15+
$deleteTopicRelatedMessages->execute('import_export.export');
16+
17+
Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_with_image_rollback.php');

0 commit comments

Comments
 (0)