diff --git a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductStoreFilter.php b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductStoreFilter.php new file mode 100644 index 0000000000000..7465ced6ab2d8 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductStoreFilter.php @@ -0,0 +1,28 @@ +addStoreFilter($filter->getValue()); + return true; + } +} diff --git a/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductWebsiteFilter.php b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductWebsiteFilter.php new file mode 100644 index 0000000000000..eafb8c745ab24 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductWebsiteFilter.php @@ -0,0 +1,32 @@ +getValue(); + if (strpos($value, ',') !== false) { + $value = explode(',', $value); + } + /** @var Collection $collection */ + $collection->addWebsiteFilter($value); + return true; + } +} diff --git a/app/code/Magento/Catalog/Model/Product/Copier.php b/app/code/Magento/Catalog/Model/Product/Copier.php index 920b27d37affb..176a15c895261 100644 --- a/app/code/Magento/Catalog/Model/Product/Copier.php +++ b/app/code/Magento/Catalog/Model/Product/Copier.php @@ -54,12 +54,15 @@ public function copy(\Magento\Catalog\Model\Product $product) $product->getWebsiteIds(); $product->getCategoryIds(); + /** @var \Magento\Framework\EntityManager\EntityMetadataInterface $metadata */ + $metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class); + /** @var \Magento\Catalog\Model\Product $duplicate */ $duplicate = $this->productFactory->create(); $duplicate->setData($product->getData()); $duplicate->setOptions([]); $duplicate->setIsDuplicate(true); - $duplicate->setOriginalId($product->getEntityId()); + $duplicate->setOriginalLinkId($product->getData($metadata->getLinkField())); $duplicate->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED); $duplicate->setCreatedAt(null); $duplicate->setUpdatedAt(null); @@ -81,7 +84,6 @@ public function copy(\Magento\Catalog\Model\Product $product) } } while (!$isDuplicateSaved); $this->getOptionRepository()->duplicate($product, $duplicate); - $metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class); $product->getResource()->duplicate( $product->getData($metadata->getLinkField()), $duplicate->getData($metadata->getLinkField()) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php index 98c4a3d82bddc..41cd55a7546df 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php @@ -297,7 +297,7 @@ protected function duplicate($product) $this->resourceModel->duplicate( $this->getAttribute()->getAttributeId(), isset($mediaGalleryData['duplicate']) ? $mediaGalleryData['duplicate'] : [], - $product->getOriginalId(), + $product->getOriginalLinkId(), $product->getData($this->metadata->getLinkField()) ); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductWebsiteFilterTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductWebsiteFilterTest.php new file mode 100644 index 0000000000000..41aa85751f316 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductWebsiteFilterTest.php @@ -0,0 +1,44 @@ +model = new ProductWebsiteFilter(); + } + + public function testApply() + { + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterMock */ + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var Collection|\PHPUnit_Framework_MockObject_MockObject $collectionMock */ + $collectionMock = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn('1,2'); + + $collectionMock->expects($this->once()) + ->method('addWebsiteFilter') + ->with(['1', '2']); + + $this->assertTrue($this->model->apply($filterMock, $collectionMock)); + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php index 661f032b2a086..8978af9edc409 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php @@ -98,7 +98,7 @@ public function testCopy() 'setOptions', 'getData', 'setIsDuplicate', - 'setOriginalId', + 'setOriginalLinkId', 'setStatus', 'setCreatedAt', 'setUpdatedAt', @@ -117,7 +117,7 @@ public function testCopy() $duplicateMock->expects($this->once())->method('setOptions')->with([]); $duplicateMock->expects($this->once())->method('setIsDuplicate')->with(true); - $duplicateMock->expects($this->once())->method('setOriginalId')->with(1); + $duplicateMock->expects($this->once())->method('setOriginalLinkId')->with(1); $duplicateMock->expects( $this->once() )->method( diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 5c8ab1eb49310..36eff7d298e4c 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -835,6 +835,8 @@ Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductCategoryFilter + Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductStoreFilter + Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductWebsiteFilter diff --git a/app/code/Magento/Deploy/composer.json b/app/code/Magento/Deploy/composer.json index 7404044ec1c0a..945363bd36401 100644 --- a/app/code/Magento/Deploy/composer.json +++ b/app/code/Magento/Deploy/composer.json @@ -3,7 +3,7 @@ "description": "N/A", "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", - "magento/framework": "100.*.*", + "magento/framework": "100.2.*", "magento/module-store": "100.2.*", "magento/module-require-js": "100.2.*", "magento/module-user": "100.2.*", 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 de03082189256..7f4b1a327024c 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -710,6 +710,132 @@ public function testGetList() $this->assertEquals($expectedResult, $response['items'][0]['custom_attributes'][$index]['value']); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_with_websites_and_stores.php + * @return void + */ + public function testGetListWithFilteringByWebsite() + { + $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(Website::class); + $website->load('test', 'code'); + $searchCriteria = [ + 'searchCriteria' => [ + 'filter_groups' => [ + [ + 'filters' => [ + [ + 'field' => 'website_id', + 'value' => $website->getId(), + 'condition_type' => 'eq', + ], + ], + ], + ], + 'current_page' => 1, + 'page_size' => 10, + ], + ]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($searchCriteria), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + $response = $this->_webApiCall($serviceInfo, $searchCriteria); + + $this->assertArrayHasKey('search_criteria', $response); + $this->assertArrayHasKey('total_count', $response); + $this->assertArrayHasKey('items', $response); + $this->assertTrue(count($response['items']) == 1); + $this->assertTrue(isset($response['items'][0]['sku'])); + $this->assertEquals('simple-2', $response['items'][0]['sku']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_with_websites_and_stores.php + * @dataProvider testGetListWithFilteringByStoreDataProvider + * + * @param array $searchCriteria + * @param array $skus + * @param int $expectedProductCount + * @return void + */ + public function testGetListWithFilteringByStore(array $searchCriteria, array $skus, $expectedProductCount = null) + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($searchCriteria), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + $response = $this->_webApiCall($serviceInfo, $searchCriteria); + + $this->assertArrayHasKey('search_criteria', $response); + $this->assertArrayHasKey('total_count', $response); + $this->assertArrayHasKey('items', $response); + if ($expectedProductCount) { + $this->assertTrue(count($response['items']) == $expectedProductCount); + } + + $isResultValid = false; + foreach ($skus as $sku) { + foreach ($response['items'] as $item) { + if ($item['sku'] == $sku) { + $isResultValid = true; + } + } + $this->assertTrue($isResultValid); + } + } + + public function testGetListWithFilteringByStoreDataProvider() + { + return [ + [ + [ + 'searchCriteria' => [ + 'filter_groups' => [ + [ + 'filters' => [ + [ + 'field' => 'store', + 'value' => 'fixture_second_store', + 'condition_type' => 'eq', + ], + ], + ], + ], + 'current_page' => 1, + 'page_size' => 10, + ], + ], + ['simple-2'], + 1, + ], + [ + [ + 'searchCriteria' => [ + 'filter_groups' => [], + 'current_page' => 1, + 'page_size' => 10, + ], + ], + ['simple-2', 'simple-1'], + null + ] + ]; + } + /** * @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php */ diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/ConfigureSecureUrlsTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/ConfigureSecureUrlsTest.php index e86236f860491..f8eafea130ee4 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/ConfigureSecureUrlsTest.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/ConfigureSecureUrlsTest.php @@ -93,20 +93,14 @@ class ConfigureSecureUrlsTest extends Injectable * * @param FixtureFactory $fixtureFactory * @param SystemConfigEdit $configurationAdminPage - * @param Cache $cache - * @param StaticContent $staticContent * @return void */ public function __inject( FixtureFactory $fixtureFactory, - SystemConfigEdit $configurationAdminPage, - Cache $cache, - StaticContent $staticContent + SystemConfigEdit $configurationAdminPage ) { $this->fixtureFactory = $fixtureFactory; $this->configurationAdminPage = $configurationAdminPage; - $this->cache = $cache; - $this->staticContent = $staticContent; } /** @@ -117,9 +111,6 @@ public function __inject( */ public function test($configData) { - $this->markTestSkipped( - 'MAGETWO-63197: ConfigureSecureUrlsTest is failing and next functional tests are also failing after it' - ); $data = [ 'web/secure/base_url' => [ 'scope' => 'default', @@ -138,7 +129,14 @@ public function test($configData) $this->configurationAdminPage->getPageActions()->save(); $_ENV['app_backend_url'] = str_replace('http', 'https', $_ENV['app_backend_url']); + $this->configurationAdminPage = $this->objectManager->create( + \Magento\Backend\Test\Page\Adminhtml\SystemConfigEdit::class + ); + + $this->cache = $this->objectManager->create(\Magento\Mtf\Util\Command\Cli\Cache::class); $this->cache->flush(['config', 'full_page']); + + $this->staticContent = $this->objectManager->create(\Magento\Mtf\Util\Command\Cli\StaticContent::class); $this->staticContent->deploy(); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_websites_and_stores.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_websites_and_stores.php new file mode 100644 index 0000000000000..9161221633b66 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_websites_and_stores.php @@ -0,0 +1,41 @@ +create(\Magento\Store\Model\Website::class); +/** @var $website \Magento\Store\Model\Website */ +$websiteId = $website->load('test', 'code')->getId(); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setAttributeSetId(4) + ->setWebsiteIds([$websiteId]) + ->setName('Simple Product on second website') + ->setSku('simple-2') + ->setPrice(10) + ->setDescription('Description with html tag') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setCategoryIds([2]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->save(); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Simple Product') + ->setSku('simple-1') + ->setPrice(10) + ->setDescription('Description with html tag') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setCategoryIds([2]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_websites_and_stores_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_websites_and_stores_rollback.php new file mode 100644 index 0000000000000..ae070745318cc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_websites_and_stores_rollback.php @@ -0,0 +1,31 @@ +create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +/** @var \Magento\Framework\Registry $registry */ +$registry = $objectManager->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); + +try { + foreach (['simple-2', 'simple-1'] as $sku) { + $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); diff --git a/lib/web/mage/gallery/gallery.js b/lib/web/mage/gallery/gallery.js index 205c998048e5c..db98a1cc39a30 100644 --- a/lib/web/mage/gallery/gallery.js +++ b/lib/web/mage/gallery/gallery.js @@ -301,7 +301,10 @@ define([ mainImageIndex = getMainImageIndex(config.data); if (mainImageIndex) { - this.settings.fotoramaApi.show(mainImageIndex); + this.settings.fotoramaApi.show({ + index: mainImageIndex, + time: 0 + }); } },