From 6267566ad9f93a60d4de7aa8e808ada6f7aa742a Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Mon, 18 Dec 2017 18:44:11 +0200 Subject: [PATCH] magento/magento2#7768: Adding 'is_saleable' attribute to sort of product collection causes exception and adding 'is_salable' has no effect. --- .../ResourceModel/Product/Collection.php | 2 +- .../ResourceModel/Product/CollectionTest.php | 36 +++++++++++++ ...ple_products_with_non_saleable_product.php | 52 +++++++++++++++++++ ...cts_with_non_saleable_product_rollback.php | 28 ++++++++++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product_rollback.php diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 58e8424663c83..3c94fbab92d61 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1670,7 +1670,7 @@ public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC) return $this; } elseif ($attribute == 'is_saleable') { - $this->getSelect()->order("is_saleable " . $dir); + $this->getSelect()->order("is_salable " . $dir); return $this; } 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 da47201fe6e38..caa0b2734bb20 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 @@ -124,4 +124,40 @@ public function testGetProductsWithTierPrice() $this->assertEquals(50, $tierPrices[2]->getExtensionAttributes()->getPercentageValue()); $this->assertEquals(5, $tierPrices[2]->getValue()); } + + /** + * Test addAttributeToSort() with attribute 'is_saleable' works properly on frontend. + * + * @dataProvider addAttributeToSortDataProvider + * @magentoDataFixture Magento/Catalog/_files/multiple_products_with_non_saleable_product.php + * @magentoConfigFixture current_store cataloginventory/options/show_out_of_stock 1 + * @magentoAppIsolation enabled + * @magentoAppArea frontend + */ + public function testAddAttributeToSort(string $productSku, string $order) + { + /** @var Collection $productCollection */ + $this->collection->addAttributeToSort('is_saleable', $order); + self::assertEquals(2, $this->collection->count()); + self::assertSame($productSku, $this->collection->getFirstItem()->getSku()); + } + + /** + * Provide test data for testAddAttributeToSort(). + * + * @return array + */ + public function addAttributeToSortDataProvider() + { + return [ + [ + 'product_sku' => 'simple_saleable', + 'order' => Collection::SORT_ORDER_DESC, + ], + [ + 'product_sku' => 'simple_not_saleable', + 'order' => Collection::SORT_ORDER_ASC, + ] + ]; + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product.php new file mode 100644 index 0000000000000..2286b2abffd0f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product.php @@ -0,0 +1,52 @@ +create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setAttributeSetId(4) + ->setName('Simple Product') + ->setSku('simple_saleable') + ->setTaxClassId('none') + ->setDescription('description') + ->setShortDescription('short description') + ->setOptionsContainer('container1') + ->setMsrpDisplayActualPriceType(\Magento\Msrp\Model\Product\Attribute\Source\Type::TYPE_IN_CART) + ->setPrice(10) + ->setWeight(1) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setWebsiteIds([1]) + ->setCateroryIds([]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->save(); + +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setAttributeSetId(4) + ->setName('Simple Product2') + ->setSku('simple_not_saleable') + ->setTaxClassId('none') + ->setDescription('description') + ->setShortDescription('short description') + ->setOptionsContainer('container1') + ->setMsrpDisplayActualPriceType(\Magento\Msrp\Model\Product\Attribute\Source\Type::TYPE_ON_GESTURE) + ->setPrice(20) + ->setWeight(1) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setWebsiteIds([1]) + ->setCateroryIds([]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 50, 'is_qty_decimal' => 0, 'is_in_stock' => 0]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product_rollback.php new file mode 100644 index 0000000000000..63fffd1894b03 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product_rollback.php @@ -0,0 +1,28 @@ +get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +foreach (['simple_saleable', 'simple_not_saleable'] as $sku) { + try { + $product = $productRepository->get($sku, false, null, true); + $productRepository->delete($product); + } catch (\Magento\Framework\Exception\NoSuchEntityException $exception) { + //Product already removed + } +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false);