From bc7db1dc306206430d84aa55f9efa12d72c420ef Mon Sep 17 00:00:00 2001 From: "vadim.malesh" Date: Tue, 10 Mar 2020 10:29:37 +0200 Subject: [PATCH 1/4] 26749: Product flat table - Incorrect data --- .../Model/Indexer/Product/Flat/Action/Row.php | 81 ++++++++++++++----- .../Indexer/Product/Flat/Action/RowTest.php | 63 +++++++++++++-- 2 files changed, 117 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php index 64a7c4be4e03c..ef45a38def024 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php @@ -6,16 +6,28 @@ namespace Magento\Catalog\Model\Indexer\Product\Flat\Action; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Helper\Product\Flat\Indexer as FlatIndexer; +use Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction; use Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder; use Magento\Catalog\Model\Indexer\Product\Flat\TableBuilder; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\Product\Type; +use Magento\Catalog\Model\ResourceModel\Product\Website\Link; +use Magento\Eav\Model\Entity\Attribute; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\Exception\LocalizedException; +use Magento\Store\Model\ResourceModel\Store\Collection; +use Magento\Store\Model\ResourceModel\Store\CollectionFactory; +use Magento\Store\Model\StoreManagerInterface; /** * Class Row reindex action. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Row extends \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction +class Row extends AbstractAction { /** * @var Indexer @@ -33,25 +45,41 @@ class Row extends \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction private $metadataPool; /** - * @param \Magento\Framework\App\ResourceConnection $resource - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Catalog\Helper\Product\Flat\Indexer $productHelper - * @param \Magento\Catalog\Model\Product\Type $productType + * @var Link + */ + private $productWebsiteLink; + + /** + * @var CollectionFactory + */ + private $storeCollectionFactory; + + /** + * @param ResourceConnection $resource + * @param StoreManagerInterface $storeManager + * @param FlatIndexer $productHelper + * @param Type $productType * @param TableBuilder $tableBuilder * @param FlatTableBuilder $flatTableBuilder * @param Indexer $flatItemWriter * @param Eraser $flatItemEraser + * @param Link $productWebsiteLink + * @param CollectionFactory $storeCollectionFactory * @param MetadataPool|null $metadataPool + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( - \Magento\Framework\App\ResourceConnection $resource, - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Catalog\Helper\Product\Flat\Indexer $productHelper, - \Magento\Catalog\Model\Product\Type $productType, + ResourceConnection $resource, + StoreManagerInterface $storeManager, + FlatIndexer $productHelper, + Type $productType, TableBuilder $tableBuilder, FlatTableBuilder $flatTableBuilder, Indexer $flatItemWriter, Eraser $flatItemEraser, + Link $productWebsiteLink, + CollectionFactory $storeCollectionFactory, MetadataPool $metadataPool = null ) { parent::__construct( @@ -64,36 +92,35 @@ public function __construct( ); $this->flatItemWriter = $flatItemWriter; $this->flatItemEraser = $flatItemEraser; - $this->metadataPool = $metadataPool ?: - \Magento\Framework\App\ObjectManager::getInstance()->get(MetadataPool::class); + $this->productWebsiteLink = $productWebsiteLink; + $this->storeCollectionFactory = $storeCollectionFactory; + $this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class); } /** * Execute row reindex action * * @param int|null $id - * @return \Magento\Catalog\Model\Indexer\Product\Flat\Action\Row - * @throws \Magento\Framework\Exception\LocalizedException + * @return Row + * @throws LocalizedException */ public function execute($id = null) { - if (!isset($id) || empty($id)) { - throw new \Magento\Framework\Exception\LocalizedException( - __('We can\'t rebuild the index for an undefined product.') - ); + if (!isset($id) || $id === null) { + throw new LocalizedException(__('We can\'t rebuild the index for an undefined product.')); } $ids = [$id]; $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + $productWebsites = $this->productWebsiteLink->getWebsiteIdsByProductId($id); - $stores = $this->_storeManager->getStores(); - foreach ($stores as $store) { + foreach ($this->getStoresByWebsiteIds($productWebsites) as $store) { $tableExists = $this->_isFlatTableExists($store->getId()); if ($tableExists) { $this->flatItemEraser->removeDeletedProducts($ids, $store->getId()); $this->flatItemEraser->removeDisabledProducts($ids, $store->getId()); } - /* @var $status \Magento\Eav\Model\Entity\Attribute */ + /* @var $status Attribute */ $status = $this->_productIndexerHelper->getAttribute(ProductInterface::STATUS); $statusTable = $status->getBackend()->getTable(); $catalogProductEntityTable = $this->_productIndexerHelper->getTable('catalog_product_entity'); @@ -111,7 +138,7 @@ public function execute($id = null) $result = $this->_connection->query($select); $status = $result->fetchColumn(0); - if ($status == \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) { + if ((int) $status === Status::STATUS_ENABLED) { if (!$tableExists) { $this->_flatTableBuilder->build( $store->getId(), @@ -129,4 +156,16 @@ public function execute($id = null) return $this; } + + /** + * Stores collection by website id's + * + * @param array $websiteIds + * @return Collection + */ + private function getStoresByWebsiteIds(array $websiteIds): Collection + { + return $this->storeCollectionFactory->create() + ->addWebsiteFilter($websiteIds); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RowTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RowTest.php index a32b476fe75ff..7fb82be2a710f 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RowTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/RowTest.php @@ -7,15 +7,22 @@ namespace Magento\Catalog\Model\Indexer\Product\Flat\Action; -use Magento\TestFramework\Indexer\TestCase as IndexerTestCase; -use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\Indexer\Product\Flat\Processor; use Magento\Catalog\Block\Product\ListProduct; -use Magento\Catalog\Api\CategoryRepositoryInterface; +use Magento\Catalog\Model\Indexer\Product\Flat\Processor; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Catalog\Helper\Product\Flat\Indexer as FlatIndexerHelper; +use Magento\TestFramework\Indexer\TestCase as IndexerTestCase; /** - * Class RowTest + * Test for \Magento\Catalog\Model\Indexer\Product\Flat\Action\Row. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class RowTest extends IndexerTestCase { @@ -25,7 +32,7 @@ class RowTest extends IndexerTestCase private $processor; /** - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ private $objectManager; @@ -39,6 +46,16 @@ class RowTest extends IndexerTestCase */ private $categoryRepository; + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var FlatIndexerHelper + */ + private $flatIndexerHelper; + /** * @inheritdoc */ @@ -48,6 +65,8 @@ protected function setUp(): void $this->processor = $this->objectManager->get(Processor::class); $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); $this->categoryRepository = $this->objectManager->get(CategoryRepositoryInterface::class); + $this->storeManager = $this->objectManager->get(StoreManagerInterface::class); + $this->flatIndexerHelper = $this->objectManager->get(FlatIndexerHelper::class); } /** @@ -114,4 +133,36 @@ public function testProductUpdate(): void } } } + + /** + * Assign product to one website + * + * @magentoDbIsolation disabled + * @magentoAppArea frontend + * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1 + * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php + * @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat.php + * + * @return void + */ + public function testProductToWebsiteAssign(): void + { + $secondWebsite = $this->storeManager->getWebsite('test'); + $secondStoreId = current($secondWebsite->getStoreIds()); + + $product = $this->productRepository->get('simple-1'); + $this->productRepository->save($product->setWebsiteIds([$secondWebsite->getId()])); + + $secondFlatTable = $this->flatIndexerHelper->getFlatTableName($secondStoreId); + + $resource = $this->objectManager->get(ResourceConnection::class); + /** @var AdapterInterface $connection */ + $connection = $resource->getConnection(); + + $skus = $connection->fetchCol($connection->select()->from($secondFlatTable, ['sku'])); + + $this->assertCount(1, $skus); + $this->assertEquals(current($skus), 'simple-1'); + } } From cc7eeba60e11b18e5a7e0ca8f2b664ad1582758c Mon Sep 17 00:00:00 2001 From: "vadim.malesh" Date: Tue, 10 Mar 2020 11:01:53 +0200 Subject: [PATCH 2/4] Backward compatible changes --- .../Model/Indexer/Product/Flat/Action/Row.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php index ef45a38def024..c05dbc60783fc 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php @@ -63,9 +63,9 @@ class Row extends AbstractAction * @param FlatTableBuilder $flatTableBuilder * @param Indexer $flatItemWriter * @param Eraser $flatItemEraser - * @param Link $productWebsiteLink - * @param CollectionFactory $storeCollectionFactory * @param MetadataPool|null $metadataPool + * @param Link|null $productWebsiteLink + * @param CollectionFactory|null $storeCollectionFactory * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -78,9 +78,9 @@ public function __construct( FlatTableBuilder $flatTableBuilder, Indexer $flatItemWriter, Eraser $flatItemEraser, - Link $productWebsiteLink, - CollectionFactory $storeCollectionFactory, - MetadataPool $metadataPool = null + MetadataPool $metadataPool = null, + Link $productWebsiteLink = null, + CollectionFactory $storeCollectionFactory = null ) { parent::__construct( $resource, @@ -92,9 +92,10 @@ public function __construct( ); $this->flatItemWriter = $flatItemWriter; $this->flatItemEraser = $flatItemEraser; - $this->productWebsiteLink = $productWebsiteLink; - $this->storeCollectionFactory = $storeCollectionFactory; $this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class); + $this->productWebsiteLink = $productWebsiteLink ?: ObjectManager::getInstance()->get(Link::class); + $this->storeCollectionFactory = $storeCollectionFactory ?: + ObjectManager::getInstance()->get(CollectionFactory::class); } /** From 5d604683f07e51e740953cc170c48451a3e7970b Mon Sep 17 00:00:00 2001 From: "vadim.malesh" Date: Wed, 11 Mar 2020 12:12:10 +0200 Subject: [PATCH 3/4] fixed unit test --- .../Indexer/Product/Flat/Action/RowTest.php | 233 ++++++++++++------ 1 file changed, 158 insertions(+), 75 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php index 11d07872fef91..ec22ac241cae6 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Action/RowTest.php @@ -4,61 +4,89 @@ * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Test\Unit\Model\Indexer\Product\Flat\Action; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Helper\Product\Flat\Indexer as FlatIndexerHelper; +use Magento\Catalog\Model\Indexer\Product\Flat\Action\Eraser; +use Magento\Catalog\Model\Indexer\Product\Flat\Action\Indexer; +use Magento\Catalog\Model\Indexer\Product\Flat\Action\Row; +use Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder; +use Magento\Catalog\Model\ResourceModel\Product\Website\Link; +use Magento\Eav\Model\Entity\Attribute; +use Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Select; +use Magento\Framework\EntityManager\EntityMetadataInterface; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Magento\Store\Model\ResourceModel\Store\Collection; +use Magento\Store\Model\ResourceModel\Store\CollectionFactory; +use Magento\Store\Model\Store; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class RowTest extends \PHPUnit\Framework\TestCase +class RowTest extends TestCase { + private const STUB_ATTRIBUTE_TABLE = 'catalog_product_entity_int'; + private const STUB_STATUS_ID = 22; + + /** + * @var Row + */ + private $model; + /** - * @var \Magento\Catalog\Model\Indexer\Product\Flat\Action\Row + * @var Store|MockObject */ - protected $model; + private $storeMock; /** - * @var MockObject + * @var FlatIndexerHelper|MockObject */ - protected $storeManager; + private $productIndexerHelperMock; /** - * @var MockObject + * @var ResourceConnection|MockObject */ - protected $store; + private $resourceMock; /** - * @var MockObject + * @var AdapterInterface|MockObject */ - protected $productIndexerHelper; + private $connectionMock; /** - * @var MockObject + * @var Indexer|MockObject */ - protected $resource; + private $flatItemWriterMock; /** - * @var MockObject + * @var Eraser|MockObject */ - protected $connection; + private $flatItemEraserMock; /** - * @var MockObject + * @var FlatTableBuilder|MockObject */ - protected $flatItemWriter; + private $flatTableBuilderMock; /** - * @var MockObject + * @var Collection|MockObject */ - protected $flatItemEraser; + private $storeCollectionMock; /** - * @var MockObject + * @var Link|MockObject */ - protected $flatTableBuilder; + private $productWebsiteLinkMock; /** * @inheritdoc @@ -67,66 +95,80 @@ protected function setUp() { $objectManager = new ObjectManager($this); - $attributeTable = 'catalog_product_entity_int'; - $statusId = 22; - $this->connection = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class); - $this->resource = $this->createMock(\Magento\Framework\App\ResourceConnection::class); - $this->resource->expects($this->any())->method('getConnection') + $this->connectionMock = $this->createMock(AdapterInterface::class); + $this->resourceMock = $this->createMock(ResourceConnection::class); + $this->resourceMock->method('getConnection') ->with('default') - ->willReturn($this->connection); - $this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class); - $this->store = $this->createMock(\Magento\Store\Model\Store::class); - $this->store->expects($this->any())->method('getId')->willReturn('store_id_1'); - $this->storeManager->expects($this->any())->method('getStores')->willReturn([$this->store]); - $this->flatItemEraser = $this->createMock(\Magento\Catalog\Model\Indexer\Product\Flat\Action\Eraser::class); - $this->flatItemWriter = $this->createMock(\Magento\Catalog\Model\Indexer\Product\Flat\Action\Indexer::class); - $this->flatTableBuilder = $this->createMock( - \Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder::class - ); - $this->productIndexerHelper = $this->createMock(\Magento\Catalog\Helper\Product\Flat\Indexer::class); - $statusAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class) + ->willReturn($this->connectionMock); + $this->storeMock = $this->createMock(Store::class); + $this->storeMock->method('getId') + ->willReturn('store_id_1'); + $this->flatItemEraserMock = $this->createMock(Eraser::class); + $this->flatItemWriterMock = $this->createMock(Indexer::class); + $this->flatTableBuilderMock = $this->createMock(FlatTableBuilder::class); + $this->productIndexerHelperMock = $this->createMock(FlatIndexerHelper::class); + $statusAttributeMock = $this->getMockBuilder(Attribute::class) ->disableOriginalConstructor() ->getMock(); - $this->productIndexerHelper->expects($this->any())->method('getAttribute') + $this->productIndexerHelperMock->method('getAttribute') ->with('status') ->willReturn($statusAttributeMock); - $backendMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend::class) + $this->productWebsiteLinkMock = $this->createMock(Link::class); + $this->storeCollectionMock = $this->createMock(Collection::class); + $this->storeCollectionMock->method('getIterator') + ->willReturn(new \ArrayIterator([$this->storeMock])); + $storesCollectionFactory = $this->createMock(CollectionFactory::class); + $storesCollectionFactory->method('create') + ->willReturn($this->storeCollectionMock); + $backendMock = $this->getMockBuilder(AbstractBackend::class) ->disableOriginalConstructor() ->getMock(); - $backendMock->expects($this->any())->method('getTable')->willReturn($attributeTable); - $statusAttributeMock->expects($this->any())->method('getBackend')->willReturn($backendMock); - $statusAttributeMock->expects($this->any())->method('getId')->willReturn($statusId); - $selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + $backendMock->method('getTable') + ->willReturn(self::STUB_ATTRIBUTE_TABLE); + $statusAttributeMock->method('getBackend') + ->willReturn($backendMock); + $statusAttributeMock->method('getId') + ->willReturn(self::STUB_STATUS_ID); + + $selectMock = $this->getMockBuilder(Select::class) ->disableOriginalConstructor() ->getMock(); - $this->connection->expects($this->any())->method('select')->willReturn($selectMock); + $this->connectionMock->method('select') + ->willReturn($selectMock); $selectMock->method('from') ->willReturnSelf(); $selectMock->method('joinLeft') ->willReturnSelf(); - $selectMock->expects($this->any())->method('where')->willReturnSelf(); - $selectMock->expects($this->any())->method('order')->willReturnSelf(); - $selectMock->expects($this->any())->method('limit')->willReturnSelf(); + $selectMock->method('where') + ->willReturnSelf(); + $selectMock->method('order') + ->willReturnSelf(); + $selectMock->method('limit') + ->willReturnSelf(); $pdoMock = $this->createMock(\Zend_Db_Statement_Pdo::class); - $this->connection->expects($this->any())->method('query')->with($selectMock)->willReturn($pdoMock); - $pdoMock->expects($this->any())->method('fetchColumn')->willReturn('1'); - - $metadataPool = $this->createMock(\Magento\Framework\EntityManager\MetadataPool::class); - $productMetadata = $this->getMockBuilder(\Magento\Framework\EntityManager\EntityMetadataInterface::class) + $this->connectionMock->method('query') + ->with($selectMock) + ->willReturn($pdoMock); + $pdoMock->method('fetchColumn') + ->willReturn('1'); + + $metadataPool = $this->createMock(MetadataPool::class); + $productMetadata = $this->getMockBuilder(EntityMetadataInterface::class) ->getMockForAbstractClass(); - $metadataPool->expects($this->any())->method('getMetadata')->with(ProductInterface::class) + $metadataPool->method('getMetadata')->with(ProductInterface::class) ->willReturn($productMetadata); - $productMetadata->expects($this->any())->method('getLinkField')->willReturn('entity_id'); + $productMetadata->method('getLinkField')->willReturn('entity_id'); $this->model = $objectManager->getObject( - \Magento\Catalog\Model\Indexer\Product\Flat\Action\Row::class, + Row::class, [ - 'resource' => $this->resource, - 'storeManager' => $this->storeManager, - 'productHelper' => $this->productIndexerHelper, - 'flatItemEraser' => $this->flatItemEraser, - 'flatItemWriter' => $this->flatItemWriter, - 'flatTableBuilder' => $this->flatTableBuilder, + 'resource' => $this->resourceMock, + 'productHelper' => $this->productIndexerHelperMock, + 'flatItemEraser' => $this->flatItemEraserMock, + 'flatItemWriter' => $this->flatItemWriterMock, + 'flatTableBuilder' => $this->flatTableBuilderMock, + 'productWebsiteLink' => $this->productWebsiteLinkMock, + 'storeCollectionFactory' => $storesCollectionFactory, ] ); @@ -134,34 +176,75 @@ protected function setUp() } /** - * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage We can't rebuild the index for an undefined product. + * Execute with id null + * + * @return void */ - public function testExecuteWithEmptyId() + public function testExecuteWithEmptyId(): void { + $this->expectException(LocalizedException::class); + $this->expectExceptionMessage('We can\'t rebuild the index for an undefined product.'); + $this->model->execute(null); } - public function testExecuteWithNonExistingFlatTablesCreatesTables() + /** + * Execute flat table not exist + * + * @return void + */ + public function testExecuteWithNonExistingFlatTablesCreatesTables(): void { - $this->productIndexerHelper->expects($this->any())->method('getFlatTableName') + $this->productIndexerHelperMock->expects($this->once())->method('getFlatTableName') ->willReturn('store_flat_table'); - $this->connection->expects($this->any())->method('isTableExists')->with('store_flat_table') + $this->connectionMock->expects($this->once()) + ->method('isTableExists') + ->with('store_flat_table') ->willReturn(false); - $this->flatItemEraser->expects($this->never())->method('removeDeletedProducts'); - $this->flatTableBuilder->expects($this->once())->method('build')->with('store_id_1', ['product_id_1']); - $this->flatItemWriter->expects($this->once())->method('write')->with('store_id_1', 'product_id_1'); + $this->flatItemEraserMock->expects($this->never()) + ->method('removeDeletedProducts'); + $this->flatTableBuilderMock->expects($this->once()) + ->method('build') + ->with('store_id_1', ['product_id_1']); + $this->flatItemWriterMock->expects($this->once()) + ->method('write') + ->with('store_id_1', 'product_id_1'); + $this->productWebsiteLinkMock->expects($this->once()) + ->method('getWebsiteIdsByProductId') + ->willReturn([]); + $this->storeCollectionMock->expects($this->once()) + ->method('addWebsiteFilter') + ->willReturnSelf(); + $this->model->execute('product_id_1'); } - public function testExecuteWithExistingFlatTablesCreatesTables() + /** + * Execute flat table exist + * + * @return void + */ + public function testExecuteWithExistingFlatTablesCreatesTables(): void { - $this->productIndexerHelper->expects($this->any())->method('getFlatTableName') + $this->productIndexerHelperMock->expects($this->once()) + ->method('getFlatTableName') ->willReturn('store_flat_table'); - $this->connection->expects($this->any())->method('isTableExists')->with('store_flat_table') + $this->connectionMock->expects($this->once()) + ->method('isTableExists') + ->with('store_flat_table') ->willReturn(true); - $this->flatItemEraser->expects($this->once())->method('removeDeletedProducts'); - $this->flatTableBuilder->expects($this->never())->method('build')->with('store_id_1', ['product_id_1']); + $this->flatItemEraserMock->expects($this->once()) + ->method('removeDeletedProducts'); + $this->flatTableBuilderMock->expects($this->never()) + ->method('build') + ->with('store_id_1', ['product_id_1']); + $this->productWebsiteLinkMock->expects($this->once()) + ->method('getWebsiteIdsByProductId') + ->willReturn([]); + $this->storeCollectionMock->expects($this->once()) + ->method('addWebsiteFilter') + ->willReturnSelf(); + $this->model->execute('product_id_1'); } } From 416d61a69d94c8e3041cb18b9acc6cd512eea164 Mon Sep 17 00:00:00 2001 From: Vadim Malesh <51680850+engcom-Charlie@users.noreply.github.com> Date: Thu, 26 Mar 2020 18:43:18 +0200 Subject: [PATCH 4/4] removed redundant condition --- .../Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php index c05dbc60783fc..2b31177fdd0a1 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php @@ -107,7 +107,7 @@ public function __construct( */ public function execute($id = null) { - if (!isset($id) || $id === null) { + if (!isset($id)) { throw new LocalizedException(__('We can\'t rebuild the index for an undefined product.')); } $ids = [$id];