From a6f76f346596a80243596079f90fe0b78f7dc744 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Sun, 23 Feb 2020 19:43:40 +0100 Subject: [PATCH 01/23] #26986 API Functional Test to cover Pagination issue --- .../Api/ProductRepositoryInterfaceTest.php | 100 ++++++++++++++++-- 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 76107ebc6a13a..9f7db871a4ae6 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -8,19 +8,13 @@ namespace Magento\Catalog\Api; use Magento\Authorization\Model\Role; -use Magento\Authorization\Model\Rules; use Magento\Authorization\Model\RoleFactory; +use Magento\Authorization\Model\Rules; use Magento\Authorization\Model\RulesFactory; use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\Data\StockItemInterface; use Magento\Downloadable\Api\DomainManagerInterface; use Magento\Downloadable\Model\Link; -use Magento\Integration\Api\AdminTokenServiceInterface; -use Magento\Store\Model\Store; -use Magento\Store\Model\Website; -use Magento\Store\Model\WebsiteRepository; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\TestCase\WebapiAbstract; use Magento\Framework\Api\ExtensibleDataInterface; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteriaBuilder; @@ -28,6 +22,12 @@ use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; +use Magento\Integration\Api\AdminTokenServiceInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\Website; +use Magento\Store\Model\WebsiteRepository; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\WebapiAbstract; /** * Test for \Magento\Catalog\Api\ProductRepositoryInterface @@ -280,7 +280,7 @@ public function testCreateWithMultipleWebsites() $websitesData = [ 'website_ids' => [ 1, - (int) $website->getId(), + (int)$website->getId(), ] ]; $productBuilder[ProductInterface::EXTENSION_ATTRIBUTES_KEY] = $websitesData; @@ -1096,6 +1096,86 @@ public function testGetListWithFilteringByStoreDataProvider() ]; } + /** + * Test getList() method with pagination + * + * @param int $pageSize + * @param int $currentPage + * @param int $expectedCount + * + * @magentoAppIsolation enabled + * @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php + * @dataProvider productPaginationDataProvider + */ + public function testGetListPagination(int $pageSize, int $currentPage, int $expectedCount) + { + $fixtureProducts = 5; + + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $categoryFilter = $filterBuilder->setField('category_id') + ->setValue(333) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$categoryFilter]); + $searchCriteriaBuilder->setPageSize($pageSize); + $searchCriteriaBuilder->setCurrentPage($currentPage); + + $searchData = $searchCriteriaBuilder->create()->__toArray(); + $requestData = ['searchCriteria' => $searchData]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + + $searchResult = $this->_webApiCall($serviceInfo, $requestData); + + $this->assertEquals($fixtureProducts, $searchResult['total_count']); + $this->assertCount($expectedCount, $searchResult['items']); + } + + /** + * Keep in mind: Fixture contains 5 products + * + * @return array + */ + public function productPaginationDataProvider() + { + return [ + 'expect-all-items' => [ + 'pageSize' => 10, + 'currentPage' => 1, + 'expectedCount' => 5 + ], + 'expect-page=size-items' => [ + 'pageSize' => 2, + 'currentPage' => 1, + 'expectedCount' => 2 + ], + 'expect-less-than-pagesize-elements' => [ + 'pageSize' => 3, + 'currentPage' => 2, + 'expectedCount' => 2 + ], + 'expect-no-items' => [ + 'pageSize' => 100, + 'currentPage' => 99, + 'expectedCount' => 0 + ] + ]; + } + /** * Test getList() method with multiple filter groups and sorting and pagination * @@ -1133,7 +1213,7 @@ public function testGetListWithMultipleFilterGroupsAndSortingAndPagination() $sortOrder = $sortOrderBuilder->setField('meta_title')->setDirection(SortOrder::SORT_DESC)->create(); /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ - $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); $searchCriteriaBuilder->addFilters([$filter5]); @@ -1728,8 +1808,8 @@ private function assertMultiselectValue($productSku, $multiselectAttributeCode, * Test design settings authorization * * @magentoApiDataFixture Magento/User/_files/user_with_custom_role.php - * @throws \Throwable * @return void + * @throws \Throwable */ public function testSaveDesign(): void { From b254764a3c654b8ed48c36086864478bfb6c953e Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Sun, 23 Feb 2020 20:43:08 +0100 Subject: [PATCH 02/23] #26986 Remove "feature" that overrides the currentPage value --- .../Magento/Framework/Data/Collection.php | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php index c497c4de5a5e4..fc7dde9019aa6 100644 --- a/lib/internal/Magento/Framework/Data/Collection.php +++ b/lib/internal/Magento/Framework/Data/Collection.php @@ -6,7 +6,10 @@ namespace Magento\Framework\Data; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Data\Collection\EntityFactoryInterface; +use Magento\Framework\DataObject; +use Magento\Framework\Exception\AlreadyExistsException; use Magento\Framework\Option\ArrayInterface; /** @@ -25,7 +28,7 @@ class Collection implements \IteratorAggregate, \Countable, ArrayInterface, Coll /** * Collection items * - * @var \Magento\Framework\DataObject[] + * @var DataObject[] */ protected $_items = []; @@ -34,7 +37,7 @@ class Collection implements \IteratorAggregate, \Countable, ArrayInterface, Coll * * @var string */ - protected $_itemObjectClass = \Magento\Framework\DataObject::class; + protected $_itemObjectClass = DataObject::class; /** * Order configuration @@ -46,7 +49,7 @@ class Collection implements \IteratorAggregate, \Countable, ArrayInterface, Coll /** * Filters configuration * - * @var \Magento\Framework\DataObject[] + * @var DataObject[] */ protected $_filters = []; @@ -117,7 +120,7 @@ public function __construct(EntityFactoryInterface $entityFactory) */ public function addFilter($field, $value, $type = 'and') { - $filter = new \Magento\Framework\DataObject(); + $filter = new DataObject(); // implements ArrayAccess $filter['field'] = $field; $filter['value'] = $value; @@ -163,9 +166,9 @@ public function addFilter($field, $value, $type = 'and') * * @param string|array $field * @param string|int|array $condition - * @throws \Magento\Framework\Exception\LocalizedException if some error in the input could be detected. * @return $this * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @throws \Magento\Framework\Exception\LocalizedException if some error in the input could be detected. */ public function addFieldToFilter($field, $condition) { @@ -182,7 +185,7 @@ public function addFieldToFilter($field, $condition) * - array() -- get all filters * * @param string|string[] $field - * @return \Magento\Framework\DataObject|\Magento\Framework\DataObject[]|void + * @return DataObject|DataObject[]|void */ public function getFilter($field) { @@ -234,18 +237,16 @@ protected function _setIsLoaded($flag = true) /** * Get current collection page * - * @param int $displacement + * @param int $displacement * @return int */ public function getCurPage($displacement = 0) { if ($this->_curPage + $displacement < 1) { return 1; - } elseif ($this->_curPage + $displacement > $this->getLastPageNumber()) { - return $this->getLastPageNumber(); - } else { - return $this->_curPage + $displacement; } + + return $this->_curPage + $displacement; } /** @@ -260,9 +261,9 @@ public function getLastPageNumber() return 1; } elseif ($this->_pageSize) { return (int)ceil($collectionSize / $this->_pageSize); - } else { - return 1; } + + return 1; } /** @@ -292,7 +293,7 @@ public function getSize() /** * Retrieve collection first item * - * @return \Magento\Framework\DataObject + * @return DataObject */ public function getFirstItem() { @@ -309,7 +310,7 @@ public function getFirstItem() /** * Retrieve collection last item * - * @return \Magento\Framework\DataObject + * @return DataObject */ public function getLastItem() { @@ -325,7 +326,7 @@ public function getLastItem() /** * Retrieve collection items * - * @return \Magento\Framework\DataObject[] + * @return DataObject[] */ public function getItems() { @@ -336,7 +337,7 @@ public function getItems() /** * Retrieve field values from all items * - * @param string $colName + * @param string $colName * @return array */ public function getColumnValues($colName) @@ -353,8 +354,8 @@ public function getColumnValues($colName) /** * Search all items by field value * - * @param string $column - * @param mixed $value + * @param string $column + * @param array $value * @return array */ public function getItemsByColumnValue($column, $value) @@ -373,9 +374,9 @@ public function getItemsByColumnValue($column, $value) /** * Search first item by field value * - * @param string $column - * @param mixed $value - * @return \Magento\Framework\DataObject || null + * @param string $column + * @param string|int $value + * @return DataObject|null */ public function getItemByColumnValue($column, $value) { @@ -392,11 +393,11 @@ public function getItemByColumnValue($column, $value) /** * Adding item to item array * - * @param \Magento\Framework\DataObject $item + * @param DataObject $item * @return $this * @throws \Exception */ - public function addItem(\Magento\Framework\DataObject $item) + public function addItem(DataObject $item) { $itemId = $this->_getItemId($item); @@ -417,7 +418,7 @@ public function addItem(\Magento\Framework\DataObject $item) /** * Add item that has no id to collection * - * @param \Magento\Framework\DataObject $item + * @param DataObject $item * @return $this */ protected function _addItem($item) @@ -429,10 +430,10 @@ protected function _addItem($item) /** * Retrieve item id * - * @param \Magento\Framework\DataObject $item - * @return mixed + * @param DataObject $item + * @return string|int */ - protected function _getItemId(\Magento\Framework\DataObject $item) + protected function _getItemId(DataObject $item) { return $item->getId(); } @@ -454,7 +455,7 @@ public function getAllIds() /** * Remove item from collection by item key * - * @param mixed $key + * @param string $key * @return $this */ public function removeItemByKey($key) @@ -542,8 +543,8 @@ public function each($objMethod, $args = []) /** * Setting data for all collection items * - * @param mixed $key - * @param mixed $value + * @param string $key + * @param string|int|null $value * @return $this */ public function setDataToAll($key, $value = null) @@ -606,7 +607,7 @@ public function setOrder($field, $direction = self::SORT_ORDER_DESC) */ public function setItemObjectClass($className) { - if (!is_a($className, \Magento\Framework\DataObject::class, true)) { + if (!is_a($className, DataObject::class, true)) { throw new \InvalidArgumentException($className . ' does not extend \Magento\Framework\DataObject'); } $this->_itemObjectClass = $className; @@ -616,7 +617,7 @@ public function setItemObjectClass($className) /** * Retrieve collection empty item * - * @return \Magento\Framework\DataObject + * @return DataObject */ public function getNewEmptyItem() { @@ -748,8 +749,8 @@ public function toArray($arrRequiredFields = []) * Return items array * array( * $index => array( - * 'value' => mixed - * 'label' => mixed + * 'value' => string + * 'label' => string * ) * ) * @@ -815,8 +816,8 @@ protected function _toOptionHash($valueField = 'id', $labelField = 'name') /** * Retrieve item by id * - * @param mixed $idValue - * @return \Magento\Framework\DataObject + * @param string|int $idValue + * @return DataObject */ public function getItemById($idValue) { @@ -910,7 +911,7 @@ public function __sleep() */ public function __wakeup() { - $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $objectManager = ObjectManager::getInstance(); $this->_entityFactory = $objectManager->get(EntityFactoryInterface::class); } } From 11567f6004dbc6819c19bd42e95915dfbf3a046f Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Sun, 23 Feb 2020 21:23:10 +0100 Subject: [PATCH 03/23] Fix static tests (`@return` alignment) --- lib/internal/Magento/Framework/Data/Collection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php index fc7dde9019aa6..7c9cf02ac6a47 100644 --- a/lib/internal/Magento/Framework/Data/Collection.php +++ b/lib/internal/Magento/Framework/Data/Collection.php @@ -338,7 +338,7 @@ public function getItems() * Retrieve field values from all items * * @param string $colName - * @return array + * @return array */ public function getColumnValues($colName) { @@ -356,7 +356,7 @@ public function getColumnValues($colName) * * @param string $column * @param array $value - * @return array + * @return array */ public function getItemsByColumnValue($column, $value) { From e001493a7877e5f00a53ae1d34a98039b8e0313e Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Mon, 24 Feb 2020 14:49:16 +0100 Subject: [PATCH 04/23] #26986 Fix invalid value returned for "records found" section in Admin Panel --- .../ResourceModel/Product/Collection.php | 84 +++++++++++-------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index afbe279045a38..9fa664cfda0cc 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1013,9 +1013,9 @@ public function getMaxAttributeValue($attribute) $tableAlias = $attributeCode . '_max_value'; $fieldAlias = 'max_' . $attributeCode; $condition = 'e.entity_id = ' . $tableAlias . '.entity_id AND ' . $this->_getConditionSql( - $tableAlias . '.attribute_id', - $attribute->getId() - ); + $tableAlias . '.attribute_id', + $attribute->getId() + ); $select->join( [$tableAlias => $attribute->getBackend()->getTable()], @@ -1048,9 +1048,9 @@ public function getAttributeValueCountByRange($attribute, $range) $tableAlias = $attributeCode . '_range_count_value'; $condition = 'e.entity_id = ' . $tableAlias . '.entity_id AND ' . $this->_getConditionSql( - $tableAlias . '.attribute_id', - $attribute->getId() - ); + $tableAlias . '.attribute_id', + $attribute->getId() + ); $select->reset(\Magento\Framework\DB\Select::GROUP); $select->join( @@ -1088,9 +1088,9 @@ public function getAttributeValueCount($attribute) $select->reset(\Magento\Framework\DB\Select::GROUP); $condition = 'e.entity_id=' . $tableAlias . '.entity_id AND ' . $this->_getConditionSql( - $tableAlias . '.attribute_id', - $attribute->getId() - ); + $tableAlias . '.attribute_id', + $attribute->getId() + ); $select->join( [$tableAlias => $attribute->getBackend()->getTable()], @@ -1180,9 +1180,27 @@ protected function _getSelectCountSql(?Select $select = null, $resetLeftJoins = if ($resetLeftJoins) { $countSelect->resetJoinLeft(); } + + $this->removeEntityIdentifierFromGroupBy($countSelect); + return $countSelect; } + /** + * Using `entity_id` for `GROUP BY` causes COUNT() return {n} rows of value = 1 instead of 1 row of value {n} + * + * @param Select $select + * @throws \Zend_Db_Select_Exception + */ + private function removeEntityIdentifierFromGroupBy(Select $select): void + { + $groupBy = array_filter($select->getPart(Select::GROUP), function ($field) { + return false === strpos($field, $this->getIdFieldName()); + }); + + $select->setPart(Select::GROUP, $groupBy); + } + /** * Prepare statistics data * @@ -1766,28 +1784,28 @@ public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC) protected function _prepareProductLimitationFilters() { if (isset( - $this->_productLimitationFilters['visibility'] - ) && !isset( - $this->_productLimitationFilters['store_id'] - ) + $this->_productLimitationFilters['visibility'] + ) && !isset( + $this->_productLimitationFilters['store_id'] + ) ) { $this->_productLimitationFilters['store_id'] = $this->getStoreId(); } if (isset( - $this->_productLimitationFilters['category_id'] - ) && !isset( - $this->_productLimitationFilters['store_id'] - ) + $this->_productLimitationFilters['category_id'] + ) && !isset( + $this->_productLimitationFilters['store_id'] + ) ) { $this->_productLimitationFilters['store_id'] = $this->getStoreId(); } if (isset( - $this->_productLimitationFilters['store_id'] - ) && isset( - $this->_productLimitationFilters['visibility'] - ) && !isset( - $this->_productLimitationFilters['category_id'] - ) + $this->_productLimitationFilters['store_id'] + ) && isset( + $this->_productLimitationFilters['visibility'] + ) && !isset( + $this->_productLimitationFilters['category_id'] + ) ) { $this->_productLimitationFilters['category_id'] = $this->_storeManager->getStore( $this->_productLimitationFilters['store_id'] @@ -1820,12 +1838,12 @@ protected function _productLimitationJoinWebsite() 'int' ); } elseif (isset( - $filters['store_id'] - ) && (!isset( - $filters['visibility'] - ) && !isset( - $filters['category_id'] - )) && !$this->isEnabledFlat() + $filters['store_id'] + ) && (!isset( + $filters['visibility'] + ) && !isset( + $filters['category_id'] + )) && !$this->isEnabledFlat() ) { $joinWebsite = true; $websiteId = $this->_storeManager->getStore($filters['store_id'])->getWebsiteId(); @@ -1901,9 +1919,9 @@ protected function _productLimitationJoinPrice() /** * Join Product Price Table with left-join possibility * - * @see \Magento\Catalog\Model\ResourceModel\Product\Collection::_productLimitationJoinPrice() * @param bool $joinLeft * @return $this + * @see \Magento\Catalog\Model\ResourceModel\Product\Collection::_productLimitationJoinPrice() */ protected function _productLimitationPrice($joinLeft = false) { @@ -2334,8 +2352,8 @@ public function addPriceDataFieldFilter($comparisonFormat, $fields) * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) - * @since 101.0.1 * @throws \Magento\Framework\Exception\LocalizedException + * @since 101.0.1 */ public function addMediaGalleryData() { @@ -2360,7 +2378,7 @@ public function addMediaGalleryData() 'entity.' . $linkField . ' IN (?)', array_map( function ($item) use ($linkField) { - return (int) $item->getOrigData($linkField); + return (int)$item->getOrigData($linkField); }, $items ) @@ -2411,9 +2429,9 @@ private function getGalleryReadHandler() /** * Retrieve Media gallery resource. * + * @return \Magento\Catalog\Model\ResourceModel\Product\Gallery * @deprecated 101.0.1 * - * @return \Magento\Catalog\Model\ResourceModel\Product\Gallery */ private function getMediaGalleryResource() { From ecb3a8d393854ab1ab0543f541fd64d5c1941015 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Mon, 24 Feb 2020 15:53:34 +0100 Subject: [PATCH 05/23] #26986 Fix Static checks for Collection file --- .../ResourceModel/Product/Collection.php | 60 +++++++------------ 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 9fa664cfda0cc..e22b4b30b43f2 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -12,6 +12,7 @@ use Magento\Catalog\Model\Indexer\Product\Price\PriceTableResolver; use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Catalog\Model\Product\Gallery\ReadHandler as GalleryReadHandler; +use Magento\Catalog\Model\ResourceModel\Category; use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; use Magento\CatalogUrlRewrite\Model\Storage\DbStorage; @@ -23,7 +24,6 @@ use Magento\Framework\Indexer\DimensionFactory; use Magento\Store\Model\Indexer\WebsiteDimensionProvider; use Magento\Store\Model\Store; -use Magento\Catalog\Model\ResourceModel\Category; /** * Product collection @@ -1013,9 +1013,9 @@ public function getMaxAttributeValue($attribute) $tableAlias = $attributeCode . '_max_value'; $fieldAlias = 'max_' . $attributeCode; $condition = 'e.entity_id = ' . $tableAlias . '.entity_id AND ' . $this->_getConditionSql( - $tableAlias . '.attribute_id', - $attribute->getId() - ); + $tableAlias . '.attribute_id', + $attribute->getId() + ); $select->join( [$tableAlias => $attribute->getBackend()->getTable()], @@ -1048,9 +1048,9 @@ public function getAttributeValueCountByRange($attribute, $range) $tableAlias = $attributeCode . '_range_count_value'; $condition = 'e.entity_id = ' . $tableAlias . '.entity_id AND ' . $this->_getConditionSql( - $tableAlias . '.attribute_id', - $attribute->getId() - ); + $tableAlias . '.attribute_id', + $attribute->getId() + ); $select->reset(\Magento\Framework\DB\Select::GROUP); $select->join( @@ -1088,9 +1088,9 @@ public function getAttributeValueCount($attribute) $select->reset(\Magento\Framework\DB\Select::GROUP); $condition = 'e.entity_id=' . $tableAlias . '.entity_id AND ' . $this->_getConditionSql( - $tableAlias . '.attribute_id', - $attribute->getId() - ); + $tableAlias . '.attribute_id', + $attribute->getId() + ); $select->join( [$tableAlias => $attribute->getBackend()->getTable()], @@ -1783,30 +1783,19 @@ public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC) */ protected function _prepareProductLimitationFilters() { - if (isset( - $this->_productLimitationFilters['visibility'] - ) && !isset( - $this->_productLimitationFilters['store_id'] - ) - ) { + if (isset($this->_productLimitationFilters['visibility']) + && !isset($this->_productLimitationFilters['store_id'])) { $this->_productLimitationFilters['store_id'] = $this->getStoreId(); } - if (isset( - $this->_productLimitationFilters['category_id'] - ) && !isset( - $this->_productLimitationFilters['store_id'] - ) - ) { + + if (isset($this->_productLimitationFilters['category_id']) + && !isset($this->_productLimitationFilters['store_id'])) { $this->_productLimitationFilters['store_id'] = $this->getStoreId(); } - if (isset( - $this->_productLimitationFilters['store_id'] - ) && isset( - $this->_productLimitationFilters['visibility'] - ) && !isset( - $this->_productLimitationFilters['category_id'] - ) - ) { + + if (isset($this->_productLimitationFilters['store_id']) + && isset($this->_productLimitationFilters['visibility']) + && !isset($this->_productLimitationFilters['category_id'])) { $this->_productLimitationFilters['category_id'] = $this->_storeManager->getStore( $this->_productLimitationFilters['store_id'] )->getRootCategoryId(); @@ -1837,14 +1826,8 @@ protected function _productLimitationJoinWebsite() $filters['website_ids'], 'int' ); - } elseif (isset( - $filters['store_id'] - ) && (!isset( - $filters['visibility'] - ) && !isset( - $filters['category_id'] - )) && !$this->isEnabledFlat() - ) { + } elseif (isset($filters['store_id']) && !$this->isEnabledFlat() + && (!isset($filters['visibility']) && !isset($filters['category_id']))) { $joinWebsite = true; $websiteId = $this->_storeManager->getStore($filters['store_id'])->getWebsiteId(); $conditions[] = $this->getConnection()->quoteInto('product_website.website_id = ?', $websiteId, 'int'); @@ -2431,7 +2414,6 @@ private function getGalleryReadHandler() * * @return \Magento\Catalog\Model\ResourceModel\Product\Gallery * @deprecated 101.0.1 - * */ private function getMediaGalleryResource() { From 015c5fcc53b96efa460c05ec4047006fbf68e753 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Mon, 24 Feb 2020 15:57:59 +0100 Subject: [PATCH 06/23] #26986 Fix failing Functional Test (assert empty page) --- .../AssertStorefrontNoProductsFoundActionGroup.xml | 8 ++++++++ .../Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml | 2 +- ...inProductCategoryIndexerInUpdateOnScheduleModeTest.xml | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml new file mode 100644 index 0000000000000..422387313390d --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml index 7e6e79cd08c26..1e8ba0a3f944b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml @@ -157,7 +157,7 @@ - + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml index 2283a0e4d6158..cafacfd135df2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml @@ -89,7 +89,7 @@ - + @@ -128,7 +128,7 @@ - + From 18e43a8df8581586b7ba3110e3feebcd6e1910d7 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Mon, 24 Feb 2020 16:05:17 +0100 Subject: [PATCH 07/23] #26986 Fix failing Unit Tests --- .../Catalog/Model/ResourceModel/Product/Collection.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index e22b4b30b43f2..78cdac8e8a8a0 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1194,7 +1194,13 @@ protected function _getSelectCountSql(?Select $select = null, $resetLeftJoins = */ private function removeEntityIdentifierFromGroupBy(Select $select): void { - $groupBy = array_filter($select->getPart(Select::GROUP), function ($field) { + $originalGroupBy = $select->getPart(Select::GROUP); + + if (!is_array($originalGroupBy)) { + return; + } + + $groupBy = array_filter($originalGroupBy, function ($field) { return false === strpos($field, $this->getIdFieldName()); }); From 9d0ae13e97e6403766fe7eba7cde9946095866e5 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Mon, 24 Feb 2020 16:13:34 +0100 Subject: [PATCH 08/23] #26986 Fix failing Functional Test: Change of behaviour when loading non-existing page (eg. `999`) --- ...hUsingElasticSearch6WithNotAvailablePageTest.xml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml index b4eb436fc1b2a..40e32c93c7ed6 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml @@ -30,17 +30,6 @@ - - - - grabNumberOfLastPage - grabNumberOfCurrentPage - - - - - - - + From 2439e17df3ec42440f25efad2e2b2a7d3be0de5e Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Mon, 24 Feb 2020 23:22:11 +0100 Subject: [PATCH 09/23] #26986 Add missing PageSize to the ElasticSearch results. --- .../ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php index ce88fc290e23c..4519bfbe18530 100644 --- a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php +++ b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php @@ -80,6 +80,7 @@ public function resolve(): SearchCriteria $searchCriteria->setRequestName($this->searchRequestName); $searchCriteria->setSortOrders($this->orders); $searchCriteria->setCurrentPage($this->currentPage - 1); + $searchCriteria->setPageSize($this->size); return $searchCriteria; } From 14ea3358e08c26403d1a322f270daa55a4d2e033 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Tue, 25 Feb 2020 00:52:08 +0100 Subject: [PATCH 10/23] Add missing Copyright --- .../AssertStorefrontNoProductsFoundActionGroup.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml index 422387313390d..f0a4faeb68e4b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml @@ -1,5 +1,10 @@ - + From 0fe9cf207bc902350d5ebfc4b5a665679db6edc0 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Tue, 25 Feb 2020 01:06:30 +0100 Subject: [PATCH 11/23] #26986 Fix failing Functional Test: Do not display repeated products --- ...frontProductQuickSearchUsingElasticSearch6Test.xml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml index e763df7dd3227..09206c58734fc 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml @@ -30,6 +30,8 @@ Product Simple AAA + + @@ -57,11 +59,8 @@ - - - - - - + + + From dab0cda47e62d8b519fcac798f9221066615d7ec Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Tue, 25 Feb 2020 03:13:32 +0100 Subject: [PATCH 12/23] Fix failing test on ElasticSearch Suite --- .../StorefrontProductQuickSearchUsingElasticSearch6Test.xml | 3 +-- ...tQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml index 09206c58734fc..5f615c9d64f56 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml @@ -59,8 +59,7 @@ - - + diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml index 40e32c93c7ed6..90d736078b97c 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml @@ -26,10 +26,9 @@ - + - From c403c52ac09373dded105ec0c5d08772730df7b6 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Tue, 25 Feb 2020 12:46:09 +0100 Subject: [PATCH 13/23] Fix failing Functional Tests --- .../StorefrontProductQuickSearchUsingElasticSearch6Test.xml | 1 + ...uickSearchUsingElasticSearch6WithNotAvailablePageTest.xml | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml index 5f615c9d64f56..0905ac0e3a70f 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml @@ -60,6 +60,7 @@ + diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml index 90d736078b97c..1dceb21a7c95c 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml @@ -25,8 +25,9 @@ - - + + + From d7cdd7bf6f397119c83814d412ed02f8702cb7fb Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Tue, 25 Feb 2020 14:06:44 +0100 Subject: [PATCH 14/23] I have no idea why it should work --- .../Fulltext/Collection/SearchCriteriaResolver.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php index 4519bfbe18530..64ce76c729334 100644 --- a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php +++ b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php @@ -80,7 +80,9 @@ public function resolve(): SearchCriteria $searchCriteria->setRequestName($this->searchRequestName); $searchCriteria->setSortOrders($this->orders); $searchCriteria->setCurrentPage($this->currentPage - 1); - $searchCriteria->setPageSize($this->size); + if ($this->size) { + $searchCriteria->setPageSize($this->size); + } return $searchCriteria; } From 05f1a2b01bbc085b3b9db9db1217c317c1f1de42 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Fri, 28 Feb 2020 18:01:24 +0100 Subject: [PATCH 15/23] Redirect to first page after changing `product_list_limit` to value higher than current. --- .../frontend/web/js/product/list/toolbar.js | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 6589f7eb0ba48..41f670ecb082d 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -80,25 +80,49 @@ define([ ); }, - /** - * @param {String} paramName - * @param {*} paramValue - * @param {*} defaultValue - */ - changeUrl: function (paramName, paramValue, defaultValue) { + getUrlParams: function() { var decode = window.decodeURIComponent, urlPaths = this.options.url.split('?'), - baseUrl = urlPaths[0], urlParams = urlPaths[1] ? urlPaths[1].split('&') : [], - paramData = {}, - parameters, i, form, params, key, input, formKey; + params = {}, parameters, i; for (i = 0; i < urlParams.length; i++) { parameters = urlParams[i].split('='); - paramData[decode(parameters[0])] = parameters[1] !== undefined ? + params[decode(parameters[0])] = parameters[1] !== undefined ? decode(parameters[1].replace(/\+/g, '%20')) : ''; } + + return params; + }, + + getCurrentLimit: function() + { + var currentLimit = this.getUrlParams()[this.options.limit]; + + if (currentLimit === undefined) { + currentLimit = this.options.limitDefault; + } + + return currentLimit; + }, + + + /** + * @param {String} paramName + * @param {*} paramValue + * @param {*} defaultValue + */ + changeUrl: function (paramName, paramValue, defaultValue) { + var urlPaths = this.options.url.split('?'), + baseUrl = urlPaths[0], + paramData = this.getUrlParams(), + form, params, key, input, formKey; + + if (paramName === this.options.limit && paramValue > this.getCurrentLimit()) { + delete paramData['p']; + } + paramData[paramName] = paramValue; if (this.options.post) { @@ -130,6 +154,7 @@ define([ if (paramValue == defaultValue) { //eslint-disable-line eqeqeq delete paramData[paramName]; } + paramData = $.param(paramData); location.href = baseUrl + (paramData.length ? '?' + paramData : ''); } From f25de7bffe498d35d05064814cb3671a91208c09 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Fri, 28 Feb 2020 19:13:34 +0100 Subject: [PATCH 16/23] Introduce redirect pattern during change of limit --- .../frontend/web/js/product/list/toolbar.js | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 41f670ecb082d..15a300014def7 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -23,6 +23,7 @@ define([ direction: 'product_list_dir', order: 'product_list_order', limit: 'product_list_limit', + page: 'p', modeDefault: 'grid', directionDefault: 'asc', orderDefault: 'position', @@ -80,7 +81,7 @@ define([ ); }, - getUrlParams: function() { + getUrlParams: function () { var decode = window.decodeURIComponent, urlPaths = this.options.url.split('?'), urlParams = urlPaths[1] ? urlPaths[1].split('&') : [], @@ -96,17 +97,13 @@ define([ return params; }, - getCurrentLimit: function() - { - var currentLimit = this.getUrlParams()[this.options.limit]; - - if (currentLimit === undefined) { - currentLimit = this.options.limitDefault; - } - - return currentLimit; + getCurrentLimit: function () { + return this.getUrlParams()[this.options.limit] || this.options.limitDefault; }, + getCurrentPage: function () { + return this.getUrlParams()[this.options.page] || 1; + }, /** * @param {String} paramName @@ -117,10 +114,17 @@ define([ var urlPaths = this.options.url.split('?'), baseUrl = urlPaths[0], paramData = this.getUrlParams(), - form, params, key, input, formKey; + currentPage = this.getCurrentPage(), + form, params, key, input, formKey, newPage; + + if (currentPage > 1 && paramName === this.options.limit) { + newPage = Math.floor(this.getCurrentLimit() * this.getCurrentPage() / paramValue); - if (paramName === this.options.limit && paramValue > this.getCurrentLimit()) { - delete paramData['p']; + if (newPage > 1) { + paramData[this.options.page] = newPage; + } else { + delete paramData[this.options.page]; + } } paramData[paramName] = paramValue; From 51a18f657bbd17155792147dd1436faa377482e6 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Fri, 28 Feb 2020 19:37:05 +0100 Subject: [PATCH 17/23] Fix invalid redirect pattern --- .../Catalog/view/frontend/web/js/product/list/toolbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 15a300014def7..d039538582c57 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -118,7 +118,7 @@ define([ form, params, key, input, formKey, newPage; if (currentPage > 1 && paramName === this.options.limit) { - newPage = Math.floor(this.getCurrentLimit() * this.getCurrentPage() / paramValue); + newPage = Math.floor(this.getCurrentLimit() * (currentPage-1) / paramValue) + 1; if (newPage > 1) { paramData[this.options.page] = newPage; From 0bae5d5420efb58ac0be0abe317d01c3931e49c4 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Fri, 28 Feb 2020 20:40:32 +0100 Subject: [PATCH 18/23] Static Tests fix --- .../view/frontend/web/js/product/list/toolbar.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index d039538582c57..738a48b3fff8b 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -81,6 +81,9 @@ define([ ); }, + /** + * @private + */ getUrlParams: function () { var decode = window.decodeURIComponent, urlPaths = this.options.url.split('?'), @@ -97,10 +100,18 @@ define([ return params; }, + /** + * @returns {String} + * @private + */ getCurrentLimit: function () { return this.getUrlParams()[this.options.limit] || this.options.limitDefault; }, + /** + * @returns {String} + * @private + */ getCurrentPage: function () { return this.getUrlParams()[this.options.page] || 1; }, @@ -118,7 +129,7 @@ define([ form, params, key, input, formKey, newPage; if (currentPage > 1 && paramName === this.options.limit) { - newPage = Math.floor(this.getCurrentLimit() * (currentPage-1) / paramValue) + 1; + newPage = Math.floor(this.getCurrentLimit() * (currentPage - 1) / paramValue) + 1; if (newPage > 1) { paramData[this.options.page] = newPage; From f5aa61dfeec3a96be19948d54eaeb701fcfc7231 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Fri, 28 Feb 2020 22:18:50 +0100 Subject: [PATCH 19/23] One more static tests fix --- .../Catalog/view/frontend/web/js/product/list/toolbar.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 738a48b3fff8b..dfc0b4291cd6e 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -88,7 +88,8 @@ define([ var decode = window.decodeURIComponent, urlPaths = this.options.url.split('?'), urlParams = urlPaths[1] ? urlPaths[1].split('&') : [], - params = {}, parameters, i; + params = {}, + parameters, i; for (i = 0; i < urlParams.length; i++) { parameters = urlParams[i].split('='); From e8d3b78b81d7041d1952d4a8150a1970950a7147 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Sat, 29 Feb 2020 09:28:16 +0100 Subject: [PATCH 20/23] Fix Functional tests for pagination --- .../Test/Mftf/Data/CatalogStorefrontConfigData.xml | 8 ++++++++ ...rontProductQuickSearchUsingElasticSearch6Test.xml | 12 ++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml index be04c297cec25..f3ccc00192a43 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml @@ -69,4 +69,12 @@ catalog/frontend/grid_per_page_values 1,2 + + catalog/frontend/grid_per_page + 12 + + + catalog/frontend/grid_per_page + 1 + diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml index 0905ac0e3a70f..3cb06014234dc 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml @@ -30,6 +30,7 @@ Product Simple AAA + @@ -38,6 +39,7 @@ + @@ -60,7 +62,13 @@ - - + + + + + + + + From 11c3eeaf6d2cd5d096aac2952eb145eaf4a2ba49 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Wed, 25 Mar 2020 23:58:30 +0100 Subject: [PATCH 21/23] =?UTF-8?q?Reduce=20the=20complexity=20proudly=20int?= =?UTF-8?q?roduced=20`(=E2=95=AF=C2=B0=E2=96=A1=C2=B0)=E2=95=AF=EF=B8=B5?= =?UTF-8?q?=20=E2=94=BB=E2=94=81=E2=94=BB`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Api/ProductRepositoryInterfaceTest.php | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 09b7dd163e1ce..44f8dc5498cb8 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -389,65 +389,65 @@ public function testCreate($product) public function externalVideoDataProvider(): array { return [ - [ + 'youtube-external-video' => [ [ - [ - 'media_type' => 'external-video', - 'disabled' => false, - 'label' => 'Test Video Created', - 'types' => [], - 'position' => 1, - 'content' => [ - 'type' => 'image/png', - 'name' => 'thumbnail.png', - 'base64_encoded_data' => 'iVBORw0KGgoAAAANSUhEUgAAAP8AAADGCAMAAAAqo6adAAAAA1BMVEUAAP79f' - . '+LBAAAASElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - . 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA+BsYAAAF7hZJ0AAAAAElFTkSuQmCC', + 'media_type' => 'external-video', + 'disabled' => false, + 'label' => 'Test Video Created', + 'types' => [], + 'position' => 1, + 'content' => $this->getVideoThumbnailStub(), + 'extension_attributes' => [ + 'video_content' => [ + 'media_type' => 'external-video', + 'video_provider' => 'youtube', + 'video_url' => 'https://www.youtube.com/', + 'video_title' => 'Video title', + 'video_description' => 'Video description', + 'video_metadata' => 'Video meta', ], - 'extension_attributes' => [ - 'video_content' => [ - 'media_type' => 'external-video', - 'video_provider' => 'youtube', - 'video_url' => 'https://www.youtube.com/', - 'video_title' => 'Video title', - 'video_description' => 'Video description', - 'video_metadata' => 'Video meta', - ], - ], - ] + ], ] ], - [ + 'vimeo-external-video' => [ [ - [ - 'media_type' => 'external-video', - 'disabled' => false, - 'label' => 'Test Video Updated', - 'types' => [], - 'position' => 1, - 'content' => [ - 'type' => 'image/png', - 'name' => 'thumbnail.png', - 'base64_encoded_data' => 'iVBORw0KGgoAAAANSUhEUgAAAP8AAADGCAMAAAAqo6adAAAAA1BMVEUAAP79f' - . '+LBAAAASElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - . 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA+BsYAAAF7hZJ0AAAAAElFTkSuQmCC', - ], - 'extension_attributes' => [ - 'video_content' => [ - 'media_type' => 'external-video', - 'video_provider' => 'vimeo', - 'video_url' => 'https://www.vimeo.com/', - 'video_title' => 'Video title', - 'video_description' => 'Video description', - 'video_metadata' => 'Video meta', - ], + 'media_type' => 'external-video', + 'disabled' => false, + 'label' => 'Test Video Updated', + 'types' => [], + 'position' => 1, + 'content' => $this->getVideoThumbnailStub(), + 'extension_attributes' => [ + 'video_content' => [ + 'media_type' => 'external-video', + 'video_provider' => 'vimeo', + 'video_url' => 'https://www.vimeo.com/', + 'video_title' => 'Video title', + 'video_description' => 'Video description', + 'video_metadata' => 'Video meta', ], - ] + ], ] ] ]; } + /** + * Returns the array of data for Video thumbnail + * + * @return array|string[] + */ + private function getVideoThumbnailStub(): array + { + return [ + 'type' => 'image/png', + 'name' => 'thumbnail.png', + 'base64_encoded_data' => 'iVBORw0KGgoAAAANSUhEUgAAAP8AAADGCAMAAAAqo6adAAAAA1BMVEUAAP79f' + . '+LBAAAASElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + . 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA+BsYAAAF7hZJ0AAAAAElFTkSuQmCC', + ]; + } + /** * Test create/ update product with external video media gallery entry * @@ -463,7 +463,7 @@ public function testCreateWithExternalVideo(array $mediaGalleryData) ] ); - $simpleProductBaseData['media_gallery_entries'] = $mediaGalleryData; + $simpleProductBaseData['media_gallery_entries'] = [$mediaGalleryData]; $response = $this->saveProduct($simpleProductBaseData); $this->assertEquals( From 80cb06e283a030ac3872ca46c4be17104dd87e83 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Thu, 26 Mar 2020 09:40:43 +0100 Subject: [PATCH 22/23] =?UTF-8?q?Extract=20the=20problematic=20test=20to?= =?UTF-8?q?=20separate=20file=20`(=E2=95=AF=C2=B0=E2=96=A1=C2=B0)=E2=95=AF?= =?UTF-8?q?=EF=B8=B5=20=E2=94=BB=E2=94=81=E2=94=BB`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Api/ProductRepositoryInterfaceTest.php | 91 --------- .../ProductVideoExternalSourceTest.php | 174 ++++++++++++++++++ 2 files changed, 174 insertions(+), 91 deletions(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 44f8dc5498cb8..2512de3537f28 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -381,97 +381,6 @@ public function testCreate($product) $this->deleteProduct($product[ProductInterface::SKU]); } - /** - * Media gallery entries with external videos - * - * @return array - */ - public function externalVideoDataProvider(): array - { - return [ - 'youtube-external-video' => [ - [ - 'media_type' => 'external-video', - 'disabled' => false, - 'label' => 'Test Video Created', - 'types' => [], - 'position' => 1, - 'content' => $this->getVideoThumbnailStub(), - 'extension_attributes' => [ - 'video_content' => [ - 'media_type' => 'external-video', - 'video_provider' => 'youtube', - 'video_url' => 'https://www.youtube.com/', - 'video_title' => 'Video title', - 'video_description' => 'Video description', - 'video_metadata' => 'Video meta', - ], - ], - ] - ], - 'vimeo-external-video' => [ - [ - 'media_type' => 'external-video', - 'disabled' => false, - 'label' => 'Test Video Updated', - 'types' => [], - 'position' => 1, - 'content' => $this->getVideoThumbnailStub(), - 'extension_attributes' => [ - 'video_content' => [ - 'media_type' => 'external-video', - 'video_provider' => 'vimeo', - 'video_url' => 'https://www.vimeo.com/', - 'video_title' => 'Video title', - 'video_description' => 'Video description', - 'video_metadata' => 'Video meta', - ], - ], - ] - ] - ]; - } - - /** - * Returns the array of data for Video thumbnail - * - * @return array|string[] - */ - private function getVideoThumbnailStub(): array - { - return [ - 'type' => 'image/png', - 'name' => 'thumbnail.png', - 'base64_encoded_data' => 'iVBORw0KGgoAAAANSUhEUgAAAP8AAADGCAMAAAAqo6adAAAAA1BMVEUAAP79f' - . '+LBAAAASElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - . 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA+BsYAAAF7hZJ0AAAAAElFTkSuQmCC', - ]; - } - - /** - * Test create/ update product with external video media gallery entry - * - * @dataProvider externalVideoDataProvider - * @param array $mediaGalleryData - */ - public function testCreateWithExternalVideo(array $mediaGalleryData) - { - $simpleProductBaseData = $this->getSimpleProductData( - [ - ProductInterface::NAME => 'Product With Ext. Video', - ProductInterface::SKU => 'prod-with-ext-video' - ] - ); - - $simpleProductBaseData['media_gallery_entries'] = [$mediaGalleryData]; - - $response = $this->saveProduct($simpleProductBaseData); - $this->assertEquals( - $simpleProductBaseData['media_gallery_entries'][0]['extension_attributes'], - $response["media_gallery_entries"][0]["extension_attributes"] - ); - } - /** * @param array $fixtureProduct * diff --git a/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php b/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php new file mode 100644 index 0000000000000..33ccf6a8854c5 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php @@ -0,0 +1,174 @@ + [ + [ + 'media_type' => 'external-video', + 'disabled' => false, + 'label' => 'Test Video Created', + 'types' => [], + 'position' => 1, + 'content' => $this->getVideoThumbnailStub(), + 'extension_attributes' => [ + 'video_content' => [ + 'media_type' => 'external-video', + 'video_provider' => 'youtube', + 'video_url' => 'https://www.youtube.com/', + 'video_title' => 'Video title', + 'video_description' => 'Video description', + 'video_metadata' => 'Video meta', + ], + ], + ] + ], + 'vimeo-external-video' => [ + [ + 'media_type' => 'external-video', + 'disabled' => false, + 'label' => 'Test Video Updated', + 'types' => [], + 'position' => 1, + 'content' => $this->getVideoThumbnailStub(), + 'extension_attributes' => [ + 'video_content' => [ + 'media_type' => 'external-video', + 'video_provider' => 'vimeo', + 'video_url' => 'https://www.vimeo.com/', + 'video_title' => 'Video title', + 'video_description' => 'Video description', + 'video_metadata' => 'Video meta', + ], + ], + ] + ] + ]; + } + + /** + * Returns the array of data for Video thumbnail + * + * @return array|string[] + */ + private function getVideoThumbnailStub(): array + { + return [ + 'type' => 'image/png', + 'name' => 'thumbnail.png', + 'base64_encoded_data' => 'iVBORw0KGgoAAAANSUhEUgAAAP8AAADGCAMAAAAqo6adAAAAA1BMVEUAAP79f' + . '+LBAAAASElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + . 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA+BsYAAAF7hZJ0AAAAAElFTkSuQmCC', + ]; + } + + /** + * Test create/ update product with external video media gallery entry + * + * @dataProvider externalVideoDataProvider + * @param array $mediaGalleryData + */ + public function testCreateWithExternalVideo(array $mediaGalleryData) + { + $simpleProductBaseData = $this->getSimpleProductData( + [ + ProductInterface::NAME => 'Product With Ext. Video', + ProductInterface::SKU => 'prod-with-ext-video' + ] + ); + + $simpleProductBaseData['media_gallery_entries'] = [$mediaGalleryData]; + + $response = $this->saveProduct($simpleProductBaseData); + $this->assertEquals( + $simpleProductBaseData['media_gallery_entries'][0]['extension_attributes'], + $response["media_gallery_entries"][0]["extension_attributes"] + ); + } + + /** + * Get Simple Product Data + * + * @param array $productData + * @return array + */ + protected function getSimpleProductData($productData = []) + { + return [ + ProductInterface::SKU => isset($productData[ProductInterface::SKU]) + ? $productData[ProductInterface::SKU] : uniqid('sku-', true), + ProductInterface::NAME => isset($productData[ProductInterface::NAME]) + ? $productData[ProductInterface::NAME] : uniqid('sku-', true), + ProductInterface::VISIBILITY => 4, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 3.62, + ProductInterface::STATUS => 1, + ProductInterface::ATTRIBUTE_SET_ID => 4, + 'custom_attributes' => [ + ['attribute_code' => 'cost', 'value' => ''], + ['attribute_code' => 'description', 'value' => 'Description'], + ] + ]; + } + + /** + * Save Product + * + * @param $product + * @param string|null $storeCode + * @param string|null $token + * @return mixed + */ + protected function saveProduct($product, $storeCode = null, ?string $token = null) + { + if (isset($product['custom_attributes'])) { + foreach ($product['custom_attributes'] as &$attribute) { + if ($attribute['attribute_code'] == 'category_ids' + && !is_array($attribute['value']) + ) { + $attribute['value'] = [""]; + } + } + } + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'Save', + ], + ]; + if ($token) { + $serviceInfo['rest']['token'] = $serviceInfo['soap']['token'] = $token; + } + $requestData = ['product' => $product]; + + return $this->_webApiCall($serviceInfo, $requestData, null, $storeCode); + } +} From db71c464b0c803775c11c4988c47c4f929e32131 Mon Sep 17 00:00:00 2001 From: Lukasz Bajsarowicz Date: Thu, 26 Mar 2020 16:26:20 +0100 Subject: [PATCH 23/23] Add missing Copyright --- .../Magento/ProductVideo/ProductVideoExternalSourceTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php b/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php index 33ccf6a8854c5..7c38cf15545c6 100644 --- a/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php @@ -1,4 +1,8 @@