diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php index 6eda8dd0b61ee..377e19a22a31a 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php @@ -5,15 +5,26 @@ */ namespace Magento\CatalogUrlRewrite\Observer; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\CatalogUrlRewrite\Model\ProductScopeRewriteGenerator; use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; -use Magento\Framework\App\ObjectManager; +use Magento\Framework\Event\Observer; +use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException; +use Magento\UrlRewrite\Model\Storage\DeleteEntitiesFromStores; use Magento\UrlRewrite\Model\UrlPersistInterface; use Magento\Framework\Event\ObserverInterface; +use Magento\Store\Model\StoreManagerInterface; /** * Class ProductProcessUrlRewriteSavingObserver + * + * Observer to update the Rewrite URLs for a product. + * This observer is triggered on the save function when making changes + * to the products website on the Product Edit page. */ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface { @@ -32,30 +43,62 @@ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface */ private $productUrlPathGenerator; + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var ProductScopeRewriteGenerator + */ + private $productScopeRewriteGenerator; + + /** + * @var DeleteEntitiesFromStores + */ + private $deleteEntitiesFromStores; + + /** + * @var CollectionFactory + */ + private $collectionFactory; + /** * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator * @param UrlPersistInterface $urlPersist - * @param ProductUrlPathGenerator|null $productUrlPathGenerator + * @param ProductUrlPathGenerator $productUrlPathGenerator + * @param StoreManagerInterface $storeManager + * @param ProductScopeRewriteGenerator $productScopeRewriteGenerator + * @param DeleteEntitiesFromStores $deleteEntitiesFromStores + * @param CollectionFactory $collectionFactory */ public function __construct( ProductUrlRewriteGenerator $productUrlRewriteGenerator, UrlPersistInterface $urlPersist, - ProductUrlPathGenerator $productUrlPathGenerator = null + ProductUrlPathGenerator $productUrlPathGenerator, + StoreManagerInterface $storeManager, + ProductScopeRewriteGenerator $productScopeRewriteGenerator, + DeleteEntitiesFromStores $deleteEntitiesFromStores, + CollectionFactory $collectionFactory ) { $this->productUrlRewriteGenerator = $productUrlRewriteGenerator; $this->urlPersist = $urlPersist; - $this->productUrlPathGenerator = $productUrlPathGenerator ?: ObjectManager::getInstance() - ->get(ProductUrlPathGenerator::class); + $this->productUrlPathGenerator = $productUrlPathGenerator; + $this->storeManager = $storeManager; + $this->productScopeRewriteGenerator = $productScopeRewriteGenerator; + $this->deleteEntitiesFromStores = $deleteEntitiesFromStores; + $this->collectionFactory = $collectionFactory; } /** * Generate urls for UrlRewrite and save it in storage * - * @param \Magento\Framework\Event\Observer $observer + * @param Observer $observer * @return void - * @throws \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException + * @throws UrlAlreadyExistsException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function execute(\Magento\Framework\Event\Observer $observer) + public function execute(Observer $observer) { /** @var Product $product */ $product = $observer->getEvent()->getProduct(); @@ -65,11 +108,49 @@ public function execute(\Magento\Framework\Event\Observer $observer) || $product->getIsChangedWebsites() || $product->dataHasChangedFor('visibility') ) { - if ($product->isVisibleInSiteVisibility()) { - $product->unsUrlPath(); - $product->setUrlPath($this->productUrlPathGenerator->getUrlPath($product)); + //Refresh rewrite urls + $product->unsUrlPath(); + $product->setUrlPath($this->productUrlPathGenerator->getUrlPath($product)); + if (!empty($this->productUrlRewriteGenerator->generate($product))) { $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); } + + $storeIdsToRemove = []; + $productWebsiteMap = array_flip($product->getWebsiteIds()); + $storeVisibilities = $this->collectionFactory->create() + ->getAllAttributeValues(ProductInterface::VISIBILITY); + if ($this->productScopeRewriteGenerator->isGlobalScope($product->getStoreId())) { + //Remove any rewrite URLs for websites the product is not in, or is not visible in. Global Scope. + foreach ($this->storeManager->getStores() as $store) { + $websiteId = $store->getWebsiteId(); + $storeId = $store->getStoreId(); + if (!isset($productWebsiteMap[$websiteId])) { + $storeIdsToRemove[] = $storeId; + continue; + } + //Check the visibility of the product in each store. + if (isset($storeVisibilities[$product->getId()][$storeId]) + && ($storeVisibilities[$product->getId()][$storeId] === Visibility::VISIBILITY_NOT_VISIBLE)) { + $storeIdsToRemove[] = $storeId; + } + } + } else { + //Only remove rewrite for current scope + $websiteId = $product->getStore()->getWebsiteId(); + $storeId = $product->getStoreId(); + if (!isset($productWebsiteMap[$websiteId]) || + (isset($storeVisibilities[$product->getId()][$storeId]) + && ($storeVisibilities[$product->getId()][$storeId] === Visibility::VISIBILITY_NOT_VISIBLE))) { + $storeIdsToRemove[] = $storeId; + } + } + if (count($storeIdsToRemove)) { + $this->deleteEntitiesFromStores->execute( + $storeIdsToRemove, + [$product->getId()], + ProductUrlRewriteGenerator::ENTITY_TYPE + ); + } } } } diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php deleted file mode 100644 index 44b47faf3d4b8..0000000000000 --- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php +++ /dev/null @@ -1,104 +0,0 @@ -productUrlRewriteGenerator = $productUrlRewriteGenerator; - $this->urlPersist = $urlPersist; - $this->productRepository = $productRepository; - $this->request = $request; - $this->storeWebsiteRelation = $storeWebsiteRelation ?: - ObjectManager::getInstance()->get(StoreWebsiteRelationInterface::class); - } - - /** - * Generate urls for UrlRewrite and save it in storage - * - * @param \Magento\Framework\Event\Observer $observer - * @return void - */ - public function execute(\Magento\Framework\Event\Observer $observer) - { - foreach ($observer->getEvent()->getProducts() as $productId) { - $product = $this->productRepository->getById( - $productId, - false, - $this->request->getParam('store_id', Store::DEFAULT_STORE_ID) - ); - - if (!empty($this->productUrlRewriteGenerator->generate($product))) { - if ($this->request->getParam('remove_website_ids')) { - foreach ($this->request->getParam('remove_website_ids') as $webId) { - foreach ($this->storeWebsiteRelation->getStoreByWebsiteId($webId) as $storeId) { - $this->urlPersist->deleteByData([ - UrlRewrite::ENTITY_ID => $product->getId(), - UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, - UrlRewrite::STORE_ID => $storeId - ]); - } - } - } - if ($product->getVisibility() != Visibility::VISIBILITY_NOT_VISIBLE) { - $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); - } - } - } - } -} diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/ProductProcessUrlRewriteRemovingPlugin.php b/app/code/Magento/CatalogUrlRewrite/Plugin/ProductProcessUrlRewriteRemovingPlugin.php new file mode 100644 index 0000000000000..629649897b9de --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/ProductProcessUrlRewriteRemovingPlugin.php @@ -0,0 +1,128 @@ +productRepository = $productRepository; + $this->storeWebsiteRelation = $storeWebsiteRelation; + $this->urlPersist = $urlPersist; + $this->productUrlRewriteGenerator = $productUrlRewriteGenerator; + $this->deleteEntitiesFromStores = $deleteEntitiesFromStores; + } + + /** + * Function afterUpdateWebsites + * + * @param Action $subject + * @param void $result + * @param array $productIds + * @param array $websiteIds + * @param string $type + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + public function afterUpdateWebsites( + Action $subject, + $result, + $productIds, + $websiteIds, + $type + ) { + foreach ($productIds as $productId) { + /* @var Product $product */ + $product = $this->productRepository->getById( + $productId, + false, + Store::DEFAULT_STORE_ID, + true + ); + + // Refresh all existing URLs for the product + if (!empty($this->productUrlRewriteGenerator->generate($product))) { + if ($product->isVisibleInSiteVisibility()) { + $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); + } + } + } + + $storeIdsToRemove = []; + // Remove the URLs for products in $productIds array + // from all stores that belong to websites in $websiteIds array + if ($type === "remove" && $websiteIds && $productIds) { + foreach ($websiteIds as $webId) { + foreach ($this->storeWebsiteRelation->getStoreByWebsiteId($webId) as $storeid) { + $storeIdsToRemove[] = $storeid; + } + } + if (count($storeIdsToRemove)) { + $this->deleteEntitiesFromStores->execute( + $storeIdsToRemove, + $productIds, + ProductUrlRewriteGenerator::ENTITY_TYPE + ); + } + } + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml index cb969ac2d329e..5d02e2075430e 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml index a7b18dcd8a8c9..62ef26145619b 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml index d67ff6fe0bace..d61a4bd077d9c 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/RewriteStoreLevelUrlKeyOfChildCategoryTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/StorefrontCategoryAccessibleWhenSuffixIsNullTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/StorefrontCategoryAccessibleWhenSuffixIsNullTest.xml index 99037a5c89af1..d0e7828b6cc32 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/StorefrontCategoryAccessibleWhenSuffixIsNullTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/StorefrontCategoryAccessibleWhenSuffixIsNullTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductProcessUrlRewriteSavingObserverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductProcessUrlRewriteSavingObserverTest.php index 39317b42af989..602bfabcd45f2 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductProcessUrlRewriteSavingObserverTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductProcessUrlRewriteSavingObserverTest.php @@ -6,169 +6,508 @@ namespace Magento\CatalogUrlRewrite\Test\Unit\Observer; +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\CatalogUrlRewrite\Model\ProductScopeRewriteGenerator; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; +use Magento\Store\Api\StoreWebsiteRelationInterface; +use Magento\Store\Model\Store; +use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException; +use Magento\UrlRewrite\Model\Storage\DeleteEntitiesFromStores; +use Magento\UrlRewrite\Model\UrlPersistInterface; +use Magento\Catalog\Model\Product; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Model\Website; +use Magento\CatalogUrlRewrite\Observer\ProductProcessUrlRewriteSavingObserver; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** * Class ProductProcessUrlRewriteSavingObserverTest * + * Tests the ProductProcessUrlRewriteSavingObserver to ensure the + * replace method (refresh existing URLs) and deleteByData (remove + * old URLs) are called the correct number of times. + * * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class ProductProcessUrlRewriteSavingObserverTest extends \PHPUnit\Framework\TestCase +class ProductProcessUrlRewriteSavingObserverTest extends TestCase { /** - * @var \Magento\UrlRewrite\Model\UrlPersistInterface|\PHPUnit_Framework_MockObject_MockObject + * @var UrlPersistInterface|MockObject + */ + private $urlPersist; + + /** + * @var Event|MockObject */ - protected $urlPersist; + private $event; /** - * @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject + * @var Observer|MockObject */ - protected $event; + private $observer; /** - * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject + * @var Product|MockObject */ - protected $observer; + private $product; /** - * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + * @var ProductUrlRewriteGenerator|MockObject */ - protected $product; + private $productUrlRewriteGenerator; /** - * @var \Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator|\PHPUnit_Framework_MockObject_MockObject + * @var ProductScopeRewriteGenerator|MockObject */ - protected $productUrlRewriteGenerator; + private $productScopeRewriteGenerator; /** * @var ObjectManager */ - protected $objectManager; + private $objectManager; + + /** + * @var ProductProcessUrlRewriteSavingObserver + */ + private $model; + + /** + * @var StoreManagerInterface|MockObject + */ + private $storeManager; + + /** + * @var array + */ + private $websites; + + /** + * @var array + */ + private $stores; + + /** + * @var StoreWebsiteRelationInterface|MockObject + */ + private $storeWebsiteRelation; + + /** + * @var DeleteEntitiesFromStores|MockObject + */ + private $deleteEntitiesFromStores; + + /** + * @var Collection|MockObject + */ + private $productCollection; /** - * @var \Magento\CatalogUrlRewrite\Observer\ProductProcessUrlRewriteSavingObserver + * @var CollectionFactory|MockObject */ - protected $model; + private $collectionFactory; /** * Set up + * Website_ID = 0 -> Store_ID = 0 + * Website_ID = 1 -> Store_ID = 1 + * Website_ID = 2 -> Store_ID = 2 & 5 */ protected function setUp() { - $this->urlPersist = $this->createMock(\Magento\UrlRewrite\Model\UrlPersistInterface::class); - $this->product = $this->createPartialMock(\Magento\Catalog\Model\Product::class, [ - 'getId', - 'dataHasChangedFor', - 'isVisibleInSiteVisibility', - 'getIsChangedWebsites', - 'getIsChangedCategories', - 'getStoreId' - ]); - $this->product->expects($this->any())->method('getId')->will($this->returnValue(3)); - $this->event = $this->createPartialMock(\Magento\Framework\Event::class, ['getProduct']); - $this->event->expects($this->any())->method('getProduct')->willReturn($this->product); - $this->observer = $this->createPartialMock(\Magento\Framework\Event\Observer::class, ['getEvent']); + $this->objectManager = new ObjectManager($this); + + $this->urlPersist = $this->createMock(UrlPersistInterface::class); + + $this->websites[0] = $this->initialiseWebsite(0); + $this->websites[1] = $this->initialiseWebsite(1); + $this->websites[2] = $this->initialiseWebsite(2); + + $this->stores[0] = $this->initialiseStore(0, 0); + $this->stores[1] = $this->initialiseStore(1, 1); + $this->stores[2] = $this->initialiseStore(2, 2); + $this->stores[5] = $this->initialiseStore(5, 2); + + $this->product = $this->initialiseProduct(); + + $this->collectionFactory = $this->createPartialMock( + CollectionFactory::class, + ['create'] + ); + $this->productCollection = $this->createPartialMock( + Collection::class, + ['getAllAttributeValues'] + ); + $this->collectionFactory->expects($this->any()) + ->method('create') + ->willReturn($this->productCollection); + + $this->deleteEntitiesFromStores = $this->createPartialMock( + DeleteEntitiesFromStores::class, + ['execute'] + ); + + $this->event = $this->createPartialMock(Event::class, ['getProduct']); + $this->event->expects($this->any()) + ->method('getProduct') + ->willReturn($this->product); + + $this->observer = $this->createPartialMock(Observer::class, ['getEvent']); $this->observer->expects($this->any())->method('getEvent')->willReturn($this->event); + $this->productUrlRewriteGenerator = $this->createPartialMock( - \Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator::class, + ProductUrlRewriteGenerator::class, ['generate'] ); - $this->productUrlRewriteGenerator->expects($this->any()) - ->method('generate') - ->will($this->returnValue([3 => 'rewrite'])); - $this->objectManager = new ObjectManager($this); + $this->productScopeRewriteGenerator = $this->createPartialMock( + ProductScopeRewriteGenerator::class, + ['isGlobalScope'] + ); + $this->productScopeRewriteGenerator->expects($this->any()) + ->method('isGlobalScope') + ->will($this->returnValueMap([ + [null, true], + [0, true], + [1, false], + [2, false], + [5, false], + ])); + + $this->storeManager = $this->getMockBuilder(StoreManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->storeManager->expects($this->any()) + ->method('getWebsites') + ->will($this->returnValue([$this->websites[1], $this->websites[2]])); + $this->storeManager->expects($this->any()) + ->method('getStores') + ->will($this->returnValue([$this->stores[1], $this->stores[2], $this->stores[5]])); + + $this->storeWebsiteRelation = $this->createPartialMock( + StoreWebsiteRelationInterface::class, + ['getStoreByWebsiteId'] + ); + $this->storeWebsiteRelation->expects($this->any()) + ->method('getStoreByWebsiteId') + ->will($this->returnValueMap([[1, [1]], [2, [2, 5]]])); + $this->model = $this->objectManager->getObject( - \Magento\CatalogUrlRewrite\Observer\ProductProcessUrlRewriteSavingObserver::class, + ProductProcessUrlRewriteSavingObserver::class, [ 'productUrlRewriteGenerator' => $this->productUrlRewriteGenerator, - 'urlPersist' => $this->urlPersist + 'urlPersist' => $this->urlPersist, + 'storeManager' => $this->storeManager, + 'storeWebsiteRelation' => $this->storeWebsiteRelation, + 'deleteEntitiesFromStores' => $this->deleteEntitiesFromStores, + 'productScopeRewriteGenerator' => $this->productScopeRewriteGenerator, + 'collectionFactory' => $this->collectionFactory ] ); } + /** + * Initialise product for test + * + * @return MockObject + */ + public function initialiseProduct() + { + $product = $this->createPartialMock( + Product::class, + [ + 'getId', + 'dataHasChangedFor', + 'isVisibleInSiteVisibility', + 'getIsChangedWebsites', + 'getIsChangedCategories', + 'getStoreId', + 'getWebsiteIds', + 'getStore' + ] + ); + $product->expects($this->any())->method('getId')->will($this->returnValue(1)); + return $product; + } + + /** + * Initialise website for test + * + * @param $websiteId + * @return MockObject + */ + public function initialiseWebsite($websiteId) + { + $website = $this->createPartialMock(Website::class, ['getWebsiteId']); + $website->expects($this->any())->method('getWebsiteId')->willReturn($websiteId); + return $website; + } + + /** + * Initialise store for test + * + * @param $storeId + * @return mixed + */ + public function initialiseStore($storeId, $websiteId) + { + $store = $this->createPartialMock(Store::class, ['getStoreId','getWebsiteId']); + $store->expects($this->any())->method('getStoreId')->willReturn($storeId); + $store->expects($this->any())->method('getWebsiteId')->willReturn($websiteId); + return $store; + } + /** * Data provider * * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function urlKeyDataProvider() { return [ - 'url changed' => [ + //url has changed, so we would expect to see a replace issued + //and the urls removed from the stores the product is not in + //i.e stores belonging to website 2 + 'global_scope_url_changed' => [ + 'productScope' => 0, 'isChangedUrlKey' => true, 'isChangedVisibility' => false, 'isChangedWebsites' => false, 'isChangedCategories' => false, - 'visibilityResult' => true, + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_BOTH, + 1 => Product\Visibility::VISIBILITY_BOTH, + 2 => Product\Visibility::VISIBILITY_BOTH, + 5 => Product\Visibility::VISIBILITY_BOTH, + ], + ], + 'productInWebsites' => [1], 'expectedReplaceCount' => 1, + 'expectedRemoves' => [2, 5], ], - 'no chnages' => [ + //Nothing has changed, so no replaces or removes + 'global_scope_no_changes' => [ + 'productScope' => 0, 'isChangedUrlKey' => false, 'isChangedVisibility' => false, 'isChangedWebsites' => false, 'isChangedCategories' => false, - 'visibilityResult' => true, - 'expectedReplaceCount' => 0 + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_BOTH, + 1 => Product\Visibility::VISIBILITY_BOTH, + 2 => Product\Visibility::VISIBILITY_BOTH, + 5 => Product\Visibility::VISIBILITY_BOTH, + ], + ], + 'productInWebsites' => [1], + 'expectedReplaceCount' => 0, + 'expectedRemoves' => [], ], - 'visibility changed' => [ + //Product passed in had global scope set, but the visibility + //at local scope for store 2 is false. Expect to see refresh + //of urls and removal from store 2 + 'global_scope_visibility_changed_local' => [ + 'productScope' => 0, 'isChangedUrlKey' => false, 'isChangedVisibility' => true, 'isChangedWebsites' => false, 'isChangedCategories' => false, - 'visibilityResult' => true, - 'expectedReplaceCount' => 1 + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_BOTH, + 1 => Product\Visibility::VISIBILITY_BOTH, + 2 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 5 => Product\Visibility::VISIBILITY_BOTH, + ], + ], + 'productInWebsites' => [1, 2], + 'expectedReplaceCount' => 1, + 'expectedRemoves' => [2], ], - 'websites changed' => [ + //Product passed in had global scope set, but the visibility + //for all stores is false. Expect to see removal from stores 1,2 and 5 + 'global_scope_visibility_changed_global' => [ + 'productScope' => 0, + 'isChangedUrlKey' => false, + 'isChangedVisibility' => true, + 'isChangedWebsites' => false, + 'isChangedCategories' => false, + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 1 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 2 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 5 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + ], + ], + 'productInWebsites' => [1, 2], + 'expectedReplaceCount' => 0, + 'expectedRemoves' => [1, 2, 5], + ], + //Product has changed websites. Now in websites 1 and 2 + //We would expect to see a replace but no removals as the + //product is in all stores + 'global_scope_websites_changed' => [ + 'productScope' => 0, 'isChangedUrlKey' => false, 'isChangedVisibility' => false, 'isChangedWebsites' => true, 'isChangedCategories' => false, - 'visibilityResult' => true, - 'expectedReplaceCount' => 1 + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_BOTH, + 1 => Product\Visibility::VISIBILITY_BOTH, + 2 => Product\Visibility::VISIBILITY_BOTH, + 5 => Product\Visibility::VISIBILITY_BOTH, + ], + ], + 'productInWebsites' => [1, 2], + 'expectedReplaceCount' => 1, + 'expectedRemoves' => [], ], - 'categories changed' => [ + //Global scope, all visible, categories changed. + //Expect to see replace and no removals. + 'global_scope_categories_changed' => [ + 'productScope' => 0, 'isChangedUrlKey' => false, 'isChangedVisibility' => false, 'isChangedWebsites' => false, 'isChangedCategories' => true, - 'visibilityResult' => true, - 'expectedReplaceCount' => 1 + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_BOTH, + 1 => Product\Visibility::VISIBILITY_BOTH, + 2 => Product\Visibility::VISIBILITY_BOTH, + 5 => Product\Visibility::VISIBILITY_BOTH, + ], + ], + 'productInWebsites' => [1, 2], + 'expectedReplaceCount' => 1, + 'expectedRemoves' => [], ], - 'url changed invisible' => [ + //Global scope, url key has changed but products are + //invisible in all stores, therefore remove any urls if + //they exist. + 'global_scope_url_changed_invisible' => [ + 'productScope' => 0, 'isChangedUrlKey' => true, 'isChangedVisibility' => false, 'isChangedWebsites' => false, 'isChangedCategories' => false, - 'visibilityResult' => false, - 'expectedReplaceCount' => 0 + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 1 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 2 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 5 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + ], + ], + 'productInWebsites' => [1, 2], + 'expectedReplaceCount' => 1, + 'expectedRemoves' => [1, 2, 5], + ], + //local scope tests should only adjust URLs for local scope + //Even if there are changes to the same product in other stores + //they should be ignored. Here product in store 2 has been set + //visible. Do not expect to see any removals for the other stores. + 'local_scope_visibility_changed_local_1' => [ + 'productScope' => 2, + 'isChangedUrlKey' => false, + 'isChangedVisibility' => true, + 'isChangedWebsites' => false, + 'isChangedCategories' => false, + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 1 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 2 => Product\Visibility::VISIBILITY_BOTH, + 5 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + ], + ], + 'productInWebsites' => [1, 2], + 'expectedReplaceCount' => 1, + 'expectedRemoves' => [], + ], + //Local scope, so only expecting to operate on store 2. + //Product has been set invisible, removal expected. + 'local_scope_visibility_changed_local_2' => [ + 'productScope' => 2, + 'isChangedUrlKey' => false, + 'isChangedVisibility' => true, + 'isChangedWebsites' => false, + 'isChangedCategories' => false, + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_BOTH, + 1 => Product\Visibility::VISIBILITY_BOTH, + 2 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 5 => Product\Visibility::VISIBILITY_BOTH, + ], + ], + 'productInWebsites' => [1, 2], + 'expectedReplaceCount' => 0, + 'expectedRemoves' => [2], + ], + //Local scope, so only operate on store 5. + //Visibility is false, so see only removal from + //store 5. + 'local_scope_visibility_changed_global' => [ + 'productScope' => 5, + 'isChangedUrlKey' => false, + 'isChangedVisibility' => true, + 'isChangedWebsites' => false, + 'isChangedCategories' => false, + 'visibility' => [ + 1 => [ + 0 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 1 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 2 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + 5 => Product\Visibility::VISIBILITY_NOT_VISIBLE, + ], + ], + 'productInWebsites' => [1, 2], + 'expectedReplaceCount' => 0, + 'expectedRemoves' => [5], ], ]; } /** + * @param int $productScope * @param bool $isChangedUrlKey * @param bool $isChangedVisibility * @param bool $isChangedWebsites * @param bool $isChangedCategories - * @param bool $visibilityResult + * @param array $visibility + * @param int $productInWebsites * @param int $expectedReplaceCount + * @param array $expectedRemoves + * @throws UrlAlreadyExistsException * * @dataProvider urlKeyDataProvider */ public function testExecuteUrlKey( + $productScope, $isChangedUrlKey, $isChangedVisibility, $isChangedWebsites, $isChangedCategories, - $visibilityResult, - $expectedReplaceCount + $visibility, + $productInWebsites, + $expectedReplaceCount, + $expectedRemoves ) { - $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(12)); - + $this->product->expects($this->any()) + ->method('getWebsiteIds') + ->will($this->returnValue($productInWebsites)); $this->product->expects($this->any()) ->method('dataHasChangedFor') ->will($this->returnValueMap( @@ -177,7 +516,6 @@ public function testExecuteUrlKey( ['url_key', $isChangedUrlKey] ] )); - $this->product->expects($this->any()) ->method('getIsChangedWebsites') ->will($this->returnValue($isChangedWebsites)); @@ -185,14 +523,31 @@ public function testExecuteUrlKey( $this->product->expects($this->any()) ->method('getIsChangedCategories') ->will($this->returnValue($isChangedCategories)); - $this->product->expects($this->any()) - ->method('isVisibleInSiteVisibility') - ->will($this->returnValue($visibilityResult)); + ->method('getStoreId') + ->willReturn($productScope); + $this->product->expects($this->any()) + ->method('getStore') + ->willReturn($this->stores[$productScope]); + + $this->productCollection->expects($this->any()) + ->method('getAllAttributeValues') + ->will($this->returnValue($visibility)); + $this->productUrlRewriteGenerator->expects($this->any()) + ->method('generate') + ->will($this->returnValue($expectedReplaceCount > 0 ? ['test'] : [])); $this->urlPersist->expects($this->exactly($expectedReplaceCount)) ->method('replace') - ->with([3 => 'rewrite']); + ->with($expectedReplaceCount > 0 ? ['test'] : []); + + $this->deleteEntitiesFromStores->expects($this->any()) + ->method('execute') + ->with( + $expectedRemoves, + [1], + ProductUrlRewriteGenerator::ENTITY_TYPE + ); $this->model->execute($this->observer); } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/ProductProcessUrlRewriteRemovingPluginTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/ProductProcessUrlRewriteRemovingPluginTest.php new file mode 100644 index 0000000000000..16375da5fdf72 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/ProductProcessUrlRewriteRemovingPluginTest.php @@ -0,0 +1,342 @@ + Store_ID = 1 + * Website_ID = 2 -> Store_ID = 2 & 5 + */ + protected function setUp() + { + $this->urlPersist = $this->createMock(UrlPersistInterface::class); + $this->productUrlRewriteGenerator = $this->createPartialMock( + ProductUrlRewriteGenerator::class, + ['generate'] + ); + + $this->storeManager = $this->createMock(StoreManagerInterface::class); + $this->website1 = $this->createPartialMock(Website::class, ['getWebsiteId']); + $this->website1->expects($this->any())->method('getWebsiteId')->willReturn(1); + $this->website2 = $this->createPartialMock(Website::class, ['getWebsiteId']); + $this->website2->expects($this->any())->method('getWebsiteId')->willReturn(2); + $this->storeManager->expects($this->any()) + ->method('getWebsites') + ->will($this->returnValue([$this->website1, $this->website2])); + + $this->storeWebsiteRelation = $this->createPartialMock( + StoreWebsiteRelationInterface::class, + ['getStoreByWebsiteId'] + ); + $this->storeWebsiteRelation->expects($this->any()) + ->method('getStoreByWebsiteId') + ->will($this->returnValueMap([[1, [1]], [2, [2, 5]]])); + + $this->product1 = $this->createPartialMock( + Product::class, + ['getWebsiteIds', 'isVisibleInSiteVisibility'] + ); + $this->product2 = $this->createPartialMock( + Product::class, + ['getWebsiteIds', 'isVisibleInSiteVisibility'] + ); + $this->product3 = $this->createPartialMock( + Product::class, + ['getWebsiteIds', 'isVisibleInSiteVisibility'] + ); + + $this->productRepository = $this->getMockForAbstractClass(ProductRepositoryInterface::class); + $this->productRepository->expects($this->any()) + ->method('getById') + ->will($this->returnValueMap([ + [1, false, 0, true, $this->product1], + [2, false, 0, true, $this->product2], + [3, false, 0, true, $this->product3] + ])); + + $this->deleteEntitiesFromStores = $this->createPartialMock( + DeleteEntitiesFromStores::class, + ['execute'] + ); + + $this->subject = $this->createMock( + Action::class + ); + + $this->objectManager = new ObjectManager($this); + $this->plugin = $this->objectManager->getObject( + ProductProcessUrlRewriteRemovingPlugin::class, + [ + 'productRepository' => $this->productRepository, + 'storeWebsiteRelation' => $this->storeWebsiteRelation, + 'urlPersist' => $this->urlPersist, + 'productUrlRewriteGenerator' => $this->productUrlRewriteGenerator, + 'deleteEntitiesFromStores' => $this->deleteEntitiesFromStores + + ] + ); + } + + /** + * Data provider + * + * @return array + */ + public function afterUpdateWebsitesDataProvider() + { + return [ + 'add_new_websites_1' => [ + 'products' => [ + '1' => ['visibilityResult' => true, 'websiteids' => [1]], + '2' => ['visibilityResult' => true, 'websiteids' => [1]], + '3' => ['visibilityResult' => true, 'websiteids' => [1]], + ], + 'productids' => [1,2,3], + 'type' => 'add', + 'websiteids' => [2], + 'expectedReplaceCount' => 3, + 'expectedStoreRemovals' => [], + 'expectedDeleteCount' => 0, + 'rewrites' => [true] + ], + 'add_new_websites_2' => [ + 'products' => [ + '1' => ['visibilityResult' => true, 'websiteids' => [1]], + '2' => ['visibilityResult' => true, 'websiteids' => [1]], + '3' => ['visibilityResult' => true, 'websiteids' => [1]], + ], + 'productids' => [1,2,3], + 'type' => 'add', + 'websiteids' => [2], + 'expectedReplaceCount' => 3, + 'expectedStoreRemovals' => [], + 'expectedDeleteCount' => 0, + 'rewrites' => [true] + ], + 'remove_all' => [ + 'products' => [ + '1' => ['visibilityResult' => true, 'websiteids' => [1,2]], + '2' => ['visibilityResult' => true, 'websiteids' => [1,2]], + '3' => ['visibilityResult' => true, 'websiteids' => [1,2]], + ], + 'productids' => [1,2,3], + 'type' => 'remove', + 'websiteids' => [1,2], + 'expectedReplaceCount' => 0, + 'expectedStoreRemovals' => [1,2,5], + 'expectedDeleteCount' => 1, + 'rewrites' => [] + ], + 'remove_single' => [ + 'products' => [ + '1' => ['visibilityResult' => true, 'websiteids' => [1,2]], + '2' => ['visibilityResult' => true, 'websiteids' => [1,2]], + '3' => ['visibilityResult' => true, 'websiteids' => [1,2]], + ], + 'productids' => [1,2,3], + 'type' => 'remove', + 'websiteids' => [2], + 'expectedReplaceCount' => 0, + 'expectedStoreRemovals' => [2,5], + 'expectedDeleteCount' => 1, + 'rewrites' => [] + ], + 'not_visible_add_1' => [ + 'products' => [ + '1' => ['visibilityResult' => false, 'websiteids' => [1]], + '2' => ['visibilityResult' => false, 'websiteids' => [1]], + '3' => ['visibilityResult' => false, 'websiteids' => [1]], + ], + 'productids' => [1,2,3], + 'type' => 'add', + 'websiteids' => [2], + 'expectedReplaceCount' => 0, + 'expectedStoreRemovals' => [], + 'expectedDeleteCount' => 0, + 'rewrites' => [true] + ], + 'not_visible_add_2' => [ + 'products' => [ + '1' => ['visibilityResult' => false, 'websiteids' => [1]], + '2' => ['visibilityResult' => false, 'websiteids' => [1]], + '3' => ['visibilityResult' => true, 'websiteids' => [1]], + ], + 'productids' => [1,2,3], + 'type' => 'add', + 'websiteids' => [2], + 'expectedReplaceCount' => 1, + 'expectedStoreRemovals' => [], + 'expectedDeleteCount' => 0, + 'rewrites' => [true] + ], + + ]; + } + + /** + * @param array $products + * @param array $productids + * @param string $type + * @param array $websiteids + * @param int $expectedReplaceCount + * @param array $expectedStoreRemovals + * @param int $expectedDeleteCount + * @param array $rewrites + * + * @dataProvider afterUpdateWebsitesDataProvider + */ + public function testAfterUpdateWebsites( + $products, + $productids, + $type, + $websiteids, + $expectedReplaceCount, + $expectedStoreRemovals, + $expectedDeleteCount, + $rewrites + ) { + + $this->productUrlRewriteGenerator->expects($this->any()) + ->method('generate') + ->will($this->returnValue($rewrites)); + + $this->product1->expects($this->any()) + ->method('getWebsiteIds') + ->will($this->returnValue($products['1']['websiteids'])); + $this->product2->expects($this->any()) + ->method('getWebsiteIds') + ->will($this->returnValue($products['2']['websiteids'])); + $this->product3->expects($this->any()) + ->method('getWebsiteIds') + ->will($this->returnValue($products['3']['websiteids'])); + + $this->product1->expects($this->any()) + ->method('isVisibleInSiteVisibility') + ->will($this->returnValue($products['1']['visibilityResult'])); + $this->product2->expects($this->any()) + ->method('isVisibleInSiteVisibility') + ->will($this->returnValue($products['2']['visibilityResult'])); + $this->product3->expects($this->any()) + ->method('isVisibleInSiteVisibility') + ->will($this->returnValue($products['3']['visibilityResult'])); + + $this->urlPersist->expects($this->exactly($expectedReplaceCount)) + ->method('replace') + ->with($rewrites); + + $this->deleteEntitiesFromStores->expects($this->exactly($expectedDeleteCount)) + ->method('execute') + ->with( + $expectedStoreRemovals, + $productids, + ProductUrlRewriteGenerator::ENTITY_TYPE + ); + + $this->plugin->afterUpdateWebsites( + $this->subject, + null, + $productids, + $websiteids, + $type + ); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml deleted file mode 100644 index 9c4a8aaf41231..0000000000000 --- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/app/code/Magento/CatalogUrlRewrite/etc/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/di.xml index 5fb7d33546d60..6efaa5dd8517e 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/di.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/di.xml @@ -70,4 +70,8 @@ + + + diff --git a/app/code/Magento/MediaGallery/Model/Asset.php b/app/code/Magento/MediaGallery/Model/Asset.php index f6e1c00044a79..8e232ff0336d9 100644 --- a/app/code/Magento/MediaGallery/Model/Asset.php +++ b/app/code/Magento/MediaGallery/Model/Asset.php @@ -24,6 +24,7 @@ class Asset extends AbstractExtensibleModel implements AssetInterface private const CONTENT_TYPE = 'content_type'; private const WIDTH = 'width'; private const HEIGHT = 'height'; + private const SIZE = 'size'; private const CREATED_AT = 'created_at'; private const UPDATED_AT = 'updated_at'; @@ -89,6 +90,14 @@ public function getHeight(): int return (int) $this->getData(self::HEIGHT); } + /** + * @inheritdoc + */ + public function getSize(): int + { + return (int) $this->getData(self::SIZE); + } + /** * @inheritdoc */ diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/DataExtractorTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/DataExtractorTest.php index 7d57f32449f56..f70e4ccdae22c 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/DataExtractorTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/DataExtractorTest.php @@ -9,10 +9,9 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\MediaGallery\Model\Asset; +use Magento\MediaGallery\Model\DataExtractor; use Magento\MediaGallery\Model\Keyword; use Magento\MediaGalleryApi\Api\Data\AssetInterface; -use Magento\MediaGalleryApi\Api\Data\KeywordInterface; -use Magento\MediaGallery\Model\DataExtractor; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -54,8 +53,27 @@ public function testExtractData(string $class, $interfaceClass, array $expectedD 'data' => $data, ] ); - $receivedData = $this->dataExtractor->extract($model, $interfaceClass); - $this->checkValues($expectedData, $receivedData, $model); + if ($interfaceClass) { + $receivedData = $this->dataExtractor->extract($model, $interfaceClass); + $this->checkAssetValues($expectedData, $receivedData, $model); + } else { + $receivedData = $this->dataExtractor->extract($model); + $this->checkKeyWordValues($expectedData, $receivedData, $model); + } + } + + /** + * @param array $expectedData + * @param array $data + * @param object $model + */ + private function checkAssetValues(array $expectedData, array $data, $model) + { + foreach ($expectedData as $expectedDataKey => $expectedDataItem) { + $this->assertEquals($data[$expectedDataKey] ?? null, $model->{$expectedDataItem['method']}()); + $this->assertEquals($data[$expectedDataKey] ?? null, $expectedDataItem['value']); + } + $this->assertEquals(array_keys($expectedData), array_keys($data)); } /** @@ -63,13 +81,13 @@ public function testExtractData(string $class, $interfaceClass, array $expectedD * @param array $data * @param object $model */ - protected function checkValues(array $expectedData, array $data, $model) + private function checkKeyWordValues(array $expectedData, array $data, $model) { foreach ($expectedData as $expectedDataKey => $expectedDataItem) { $this->assertEquals($data[$expectedDataKey] ?? null, $model->{$expectedDataItem['method']}()); $this->assertEquals($data[$expectedDataKey] ?? null, $expectedDataItem['value']); } - $this->assertEquals(array_keys($expectedData), array_keys($expectedData)); + $this->assertEquals(array_keys($expectedData), array_keys(array_slice($data, 0, 2))); } /** @@ -102,13 +120,17 @@ public function assetProvider() 'value' => 'content_type', 'method' => 'getContentType', ], + 'height' => [ + 'value' => 4, + 'method' => 'getHeight', + ], 'width' => [ 'value' => 3, 'method' => 'getWidth', ], - 'height' => [ - 'value' => 4, - 'method' => 'getHeight', + 'size' => [ + 'value' => 300, + 'method' => 'getSize', ], 'created_at' => [ 'value' => '2019-11-28 10:40:09', @@ -122,7 +144,7 @@ public function assetProvider() ], 'Keyword conversion without interface' => [ Keyword::class, - null, + '', [ 'id' => [ 'value' => 2, diff --git a/app/code/Magento/MediaGallery/etc/db_schema.xml b/app/code/Magento/MediaGallery/etc/db_schema.xml index fac1342528f2c..8bcad28de2a8e 100644 --- a/app/code/Magento/MediaGallery/etc/db_schema.xml +++ b/app/code/Magento/MediaGallery/etc/db_schema.xml @@ -14,6 +14,7 @@ + diff --git a/app/code/Magento/MediaGallery/etc/db_schema_whitelist.json b/app/code/Magento/MediaGallery/etc/db_schema_whitelist.json index 10db10d5dd5db..9e187e6dea4a5 100644 --- a/app/code/Magento/MediaGallery/etc/db_schema_whitelist.json +++ b/app/code/Magento/MediaGallery/etc/db_schema_whitelist.json @@ -8,6 +8,7 @@ "content_type": true, "width": true, "height": true, + "size": true, "created_at": true, "updated_at": true }, @@ -53,4 +54,4 @@ "MEDIA_GALLERY_ASSET_KEYWORD_ASSET_ID_MEDIA_GALLERY_ASSET_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/MediaGalleryApi/Api/Data/AssetInterface.php b/app/code/Magento/MediaGalleryApi/Api/Data/AssetInterface.php index affae296ca530..0f4b78a6dc603 100644 --- a/app/code/Magento/MediaGalleryApi/Api/Data/AssetInterface.php +++ b/app/code/Magento/MediaGalleryApi/Api/Data/AssetInterface.php @@ -65,6 +65,13 @@ public function getHeight(): int; */ public function getWidth(): int; + /** + * Retrieve asset file size in bytes + * + * @return int + */ + public function getSize(): int; + /** * Get created at * diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DeleteEntitiesFromStores.php b/app/code/Magento/UrlRewrite/Model/Storage/DeleteEntitiesFromStores.php new file mode 100644 index 0000000000000..98ea968751182 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Model/Storage/DeleteEntitiesFromStores.php @@ -0,0 +1,68 @@ +connection = $resource->getConnection(); + $this->resource = $resource; + } + + /** + * Function execute + * + * Deletes multiple URL Rewrites from database + * + * @param array $storeIds + * @param array $entityIds + * @param int $entityType + */ + public function execute($storeIds, $entityIds, $entityType) + { + $select = $this->connection->select(); + $select->from($this->resource->getTableName(DbStorage::TABLE_NAME)); + + $select->where( + $this->connection->quoteIdentifier( + UrlRewrite::STORE_ID + ) . ' IN (' . $this->connection->quote($storeIds, 'INTEGER') . ')' . + ' AND ' . $this->connection->quoteIdentifier( + UrlRewrite::ENTITY_ID + ) . ' IN (' . $this->connection->quote($entityIds, 'INTEGER') . ')' . + ' AND ' . $this->connection->quoteIdentifier( + UrlRewrite::ENTITY_TYPE + ) . ' = ' . $this->connection->quote($entityType) + ); + $select = $select->deleteFromSelect($this->resource->getTableName(DbStorage::TABLE_NAME)); + $this->connection->query($select); + } +} diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminAutoUpdateURLRewriteWhenCategoryIsDeletedTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminAutoUpdateURLRewriteWhenCategoryIsDeletedTest.xml index eae8c7f0838c4..089f74411ac58 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminAutoUpdateURLRewriteWhenCategoryIsDeletedTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminAutoUpdateURLRewriteWhenCategoryIsDeletedTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategory2Test.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategory2Test.xml index 7244ed1d6b534..734b8bb667674 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategory2Test.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategory2Test.xml @@ -16,7 +16,7 @@ - + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategoryTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategoryTest.xml index cd17d169804db..d337da37e0d2a 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategoryTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategoryTest.xml @@ -15,7 +15,7 @@ - + Use AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategory2Test instead diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddNoRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddNoRedirectTest.xml index 339e078faa5a4..2d5f70f4e7328 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddNoRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddNoRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddPermanentRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddPermanentRedirectTest.xml index 546637f2e548d..cf963bea12fa6 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddPermanentRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddPermanentRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddTemporaryRedirectTest.xml index 2ea04625b7d3d..401ce09f1a149 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCategoryUrlRewriteAndAddTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCMSPageUrlRewriteAndAddPermanentRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCMSPageUrlRewriteAndAddPermanentRedirectTest.xml index d0a744a168ce3..b6007d63290b8 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCMSPageUrlRewriteAndAddPermanentRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCMSPageUrlRewriteAndAddPermanentRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCMSPageUrlRewriteAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCMSPageUrlRewriteAndAddTemporaryRedirectTest.xml index 4327b02d396f9..33e1969be38ff 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCMSPageUrlRewriteAndAddTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCMSPageUrlRewriteAndAddTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCategoryUrlRewriteAndAddPermanentRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCategoryUrlRewriteAndAddPermanentRedirectTest.xml index 676c7bd95bbdb..1c6c1572b3206 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCategoryUrlRewriteAndAddPermanentRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomCategoryUrlRewriteAndAddPermanentRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomProductUrlRewriteAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomProductUrlRewriteAndAddTemporaryRedirectTest.xml index c39bae9fd2ff2..3191de550bd52 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomProductUrlRewriteAndAddTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateCustomProductUrlRewriteAndAddTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductURLRewriteAndAddNoRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductURLRewriteAndAddNoRedirectTest.xml index 36c25d9a21685..c34dce4ab0b91 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductURLRewriteAndAddNoRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductURLRewriteAndAddNoRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductURLRewriteWithCategoryAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductURLRewriteWithCategoryAndAddTemporaryRedirectTest.xml index 92a2b6cac6b16..26bc86bdabae7 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductURLRewriteWithCategoryAndAddTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductURLRewriteWithCategoryAndAddTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductUrLRewriteAndAddPermanentRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductUrLRewriteAndAddPermanentRedirectTest.xml index b7e0d3bb6b4dc..5276cac8625ec 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductUrLRewriteAndAddPermanentRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductUrLRewriteAndAddPermanentRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductUrLRewriteAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductUrLRewriteAndAddTemporaryRedirectTest.xml index ce17e0de10d56..2136918fa6186 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductUrLRewriteAndAddTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductUrLRewriteAndAddTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPageNoRedirectUrlRewriteTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPageNoRedirectUrlRewriteTest.xml index a65efce1a48ea..e26a283861ecd 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPageNoRedirectUrlRewriteTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPageNoRedirectUrlRewriteTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPagePermanentRedirectUrlRewriteTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPagePermanentRedirectUrlRewriteTest.xml index fa19b2a30c2cd..86f7f84f9f1a5 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPagePermanentRedirectUrlRewriteTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPagePermanentRedirectUrlRewriteTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPageTemporaryRedirectUrlRewriteTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPageTemporaryRedirectUrlRewriteTest.xml index 2bed25aa3f39d..d04cafc3602b6 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPageTemporaryRedirectUrlRewriteTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCMSPageTemporaryRedirectUrlRewriteTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCategoryUrlRewriteTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCategoryUrlRewriteTest.xml index b781a8297499c..2e753e5fca7d8 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCategoryUrlRewriteTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCategoryUrlRewriteTest.xml @@ -14,6 +14,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithNoRedirectsTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithNoRedirectsTest.xml index d58560e40533e..c8ef5470eef3a 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithNoRedirectsTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithNoRedirectsTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithPermanentRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithPermanentRedirectTest.xml index 989aa277f7de1..e1228c47b9030 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithPermanentRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithPermanentRedirectTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithTemporaryRedirectTest.xml index a81c00506c671..1efd063a23708 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteCmsPageUrlRewriteWithTemporaryRedirectTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteProductUrlRewriteTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteProductUrlRewriteTest.xml index 8ebad9656e7af..80fe34a3099f1 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteProductUrlRewriteTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminDeleteProductUrlRewriteTest.xml @@ -14,6 +14,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminMarketingUrlRewritesNavigateMenuTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminMarketingUrlRewritesNavigateMenuTest.xml index 51561cfcb220f..0111a35508fd9 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminMarketingUrlRewritesNavigateMenuTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminMarketingUrlRewritesNavigateMenuTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddAspxRequestPathTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddAspxRequestPathTest.xml index 21b0486bd1aad..d47b700dab790 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddAspxRequestPathTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddAspxRequestPathTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddNoRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddNoRedirectTest.xml index 7edeba336a7e9..5a9aa4df336e0 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddNoRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddNoRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddPermanentRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddPermanentRedirectTest.xml index b226925748f78..788d29a4d4f9f 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddPermanentRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddPermanentRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddTemporaryRedirectTest.xml index 3147fcc848b0b..3d890854f5e09 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCategoryUrlRewriteAndAddTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithNoRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithNoRedirectTest.xml index c47419eee28e0..95b509ac38a8a 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithNoRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithNoRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithPermanentReirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithPermanentReirectTest.xml index 510b2f5607df7..da97bc5988512 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithPermanentReirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithPermanentReirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithTemporaryRedirectTest.xml index b696811cfa8c9..5ac0330ab80b2 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageRewriteEntityWithTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddNoRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddNoRedirectTest.xml index b04d417cf7efa..b5fa9267c581b 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddNoRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddNoRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddPermanentRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddPermanentRedirectTest.xml index 138b5f280d5f2..f9eb150ad6113 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddPermanentRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddPermanentRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddTemporaryRedirectTest.xml index d996f2e3c7bb9..34318b3dd8ac0 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCmsPageUrlRewriteAndAddTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateProductUrlRewriteAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateProductUrlRewriteAndAddTemporaryRedirectTest.xml index e70896b7de04f..0c1298672db51 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateProductUrlRewriteAndAddTemporaryRedirectTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateProductUrlRewriteAndAddTemporaryRedirectTest.xml @@ -15,6 +15,7 @@ + diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteTest.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteTest.php index f8fe68c2e0a2d..b0ecd58745444 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteTest.php @@ -85,6 +85,7 @@ public function productDataProvider(): array 'sku' => 'test-product', 'name' => 'test product', 'price' => 150, + 'website_ids' => [1] ], 'expected_data' => [ [ @@ -104,6 +105,7 @@ public function productDataProvider(): array 'name' => 'test product', 'price' => 150, 'url_key' => 'test-product-url-key', + 'website_ids' => [1] ], 'expected_data' => [ [ @@ -123,6 +125,7 @@ public function productDataProvider(): array 'name' => 'test product', 'price' => 150, 'url_key' => 'test-product-url-key', + 'website_ids' => [1] ], 'expected_data' => [], ], diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php index c72a58197b1fd..76508f2066b54 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserverTest.php @@ -5,25 +5,46 @@ */ namespace Magento\CatalogUrlRewrite\Observer; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Framework\ObjectManagerInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; -use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Store\Model\Store; +use PHPUnit\Framework\TestCase; /** * @magentoAppArea adminhtml * @magentoDbIsolation disabled */ -class ProductProcessUrlRewriteSavingObserverTest extends \PHPUnit\Framework\TestCase +class ProductProcessUrlRewriteSavingObserverTest extends TestCase { - /** @var \Magento\Framework\ObjectManagerInterface */ - protected $objectManager; + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; /** * Set up */ protected function setUp() { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->objectManager = Bootstrap::getObjectManager(); + $this->storeManager = $this->objectManager->get(StoreManagerInterface::class); + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); } /** @@ -32,8 +53,8 @@ protected function setUp() */ private function getActualResults(array $filter) { - /** @var \Magento\UrlRewrite\Model\UrlFinderInterface $urlFinder */ - $urlFinder = $this->objectManager->get(\Magento\UrlRewrite\Model\UrlFinderInterface::class); + /** @var UrlFinderInterface $urlFinder */ + $urlFinder = $this->objectManager->get(UrlFinderInterface::class); $actualResults = []; foreach ($urlFinder->findAllByData($filter) as $url) { $actualResults[] = [ @@ -53,16 +74,14 @@ private function getActualResults(array $filter) */ public function testUrlKeyHasChangedInGlobalContext() { - /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository*/ - $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); - /** @var \Magento\Catalog\Model\Product $product*/ - $product = $productRepository->get('product1'); + $testStore1 = $this->storeManager->getStore('default'); + $testStore4 = $this->storeManager->getStore('test'); - /** @var StoreManagerInterface $storeManager */ - $storeManager = $this->objectManager->get(StoreManagerInterface::class); - $storeManager->setCurrentStore(0); + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + + /** @var Product $product*/ + $product = $this->productRepository->get('product1'); - $testStore = $storeManager->getStore('test'); $productFilter = [ UrlRewrite::ENTITY_TYPE => 'product', ]; @@ -73,14 +92,14 @@ public function testUrlKeyHasChangedInGlobalContext() 'target_path' => "catalog/product/view/id/" . $product->getId(), 'is_auto_generated' => 1, 'redirect_type' => 0, - 'store_id' => 1, + 'store_id' => $testStore1->getId(), ], [ 'request_path' => "product-1.html", 'target_path' => "catalog/product/view/id/" . $product->getId(), 'is_auto_generated' => 1, 'redirect_type' => 0, - 'store_id' => $testStore->getId(), + 'store_id' => $testStore4->getId(), ], ]; $actual = $this->getActualResults($productFilter); @@ -91,7 +110,7 @@ public function testUrlKeyHasChangedInGlobalContext() $product->setData('save_rewrites_history', true); $product->setUrlKey('new-url'); $product->setUrlPath('new-path'); - $product->save(); + $this->productRepository->save($product); $expected = [ [ @@ -99,28 +118,28 @@ public function testUrlKeyHasChangedInGlobalContext() 'target_path' => "catalog/product/view/id/" . $product->getId(), 'is_auto_generated' => 1, 'redirect_type' => 0, - 'store_id' => 1, + 'store_id' => $testStore1->getId(), ], [ 'request_path' => "new-url.html", 'target_path' => "catalog/product/view/id/" . $product->getId(), 'is_auto_generated' => 1, 'redirect_type' => 0, - 'store_id' => $testStore->getId(), + 'store_id' => $testStore4->getId(), ], [ 'request_path' => "product-1.html", 'target_path' => "new-url.html", 'is_auto_generated' => 0, 'redirect_type' => 301, - 'store_id' => 1, + 'store_id' => $testStore1->getId(), ], [ 'request_path' => "product-1.html", 'target_path' => "new-url.html", 'is_auto_generated' => 0, 'redirect_type' => 301, - 'store_id' => $testStore->getId(), + 'store_id' => $testStore4->getId(), ], ]; @@ -136,16 +155,13 @@ public function testUrlKeyHasChangedInGlobalContext() */ public function testUrlKeyHasChangedInStoreviewContextWithPermanentRedirection() { - /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository*/ - $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); - /** @var \Magento\Catalog\Model\Product $product*/ - $product = $productRepository->get('product1'); + $testStore1 = $this->storeManager->getStore('default'); + $testStore4 = $this->storeManager->getStore('test'); - /** @var StoreManagerInterface $storeManager */ - $storeManager = $this->objectManager->get(StoreManagerInterface::class); - $storeManager->setCurrentStore(1); + $this->storeManager->setCurrentStore($testStore1); - $testStore = $storeManager->getStore('test'); + /** @var Product $product*/ + $product = $this->productRepository->get('product1'); $productFilter = [ UrlRewrite::ENTITY_TYPE => 'product', @@ -154,7 +170,7 @@ public function testUrlKeyHasChangedInStoreviewContextWithPermanentRedirection() $product->setData('save_rewrites_history', true); $product->setUrlKey('new-url'); $product->setUrlPath('new-path'); - $product->save(); + $this->productRepository->save($product); $expected = [ [ @@ -162,21 +178,21 @@ public function testUrlKeyHasChangedInStoreviewContextWithPermanentRedirection() 'target_path' => "catalog/product/view/id/" . $product->getId(), 'is_auto_generated' => 1, 'redirect_type' => 0, - 'store_id' => 1, + 'store_id' => $testStore1->getId(), ], [ 'request_path' => "product-1.html", 'target_path' => "catalog/product/view/id/" . $product->getId(), 'is_auto_generated' => 1, 'redirect_type' => 0, - 'store_id' => $testStore->getId(), + 'store_id' => $testStore4->getId(), ], [ 'request_path' => "product-1.html", 'target_path' => "new-url.html", 'is_auto_generated' => 0, 'redirect_type' => 301, - 'store_id' => 1, + 'store_id' => $testStore1->getId(), ], ]; @@ -192,16 +208,13 @@ public function testUrlKeyHasChangedInStoreviewContextWithPermanentRedirection() */ public function testUrlKeyHasChangedInStoreviewContextWithoutPermanentRedirection() { - /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository*/ - $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); - /** @var \Magento\Catalog\Model\Product $product*/ - $product = $productRepository->get('product1'); + $testStore1 = $this->storeManager->getStore('default'); + $testStore4 = $this->storeManager->getStore('test'); - /** @var StoreManagerInterface $storeManager */ - $storeManager = $this->objectManager->get(StoreManagerInterface::class); - $storeManager->setCurrentStore(1); + $this->storeManager->setCurrentStore(1); - $testStore = $storeManager->getStore('test'); + /** @var Product $product*/ + $product = $this->productRepository->get('product1'); $productFilter = [ UrlRewrite::ENTITY_TYPE => 'product', @@ -210,7 +223,7 @@ public function testUrlKeyHasChangedInStoreviewContextWithoutPermanentRedirectio $product->setData('save_rewrites_history', false); $product->setUrlKey('new-url'); $product->setUrlPath('new-path'); - $product->save(); + $this->productRepository->save($product); $expected = [ [ @@ -218,17 +231,401 @@ public function testUrlKeyHasChangedInStoreviewContextWithoutPermanentRedirectio 'target_path' => "catalog/product/view/id/" . $product->getId(), 'is_auto_generated' => 1, 'redirect_type' => 0, - 'store_id' => 1, + 'store_id' => $testStore1->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore4->getId(), + ], + ]; + + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + } + + /** + * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php + * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php + * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testAddAndRemoveProductFromWebsite() + { + $testStore1 = $this->storeManager->getStore('default'); + $testStore2 = $this->storeManager->getStore('fixture_second_store'); + $testStore3 = $this->storeManager->getStore('fixture_third_store'); + $testStore4 = $this->storeManager->getStore('test'); + + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + + /** @var Product $product*/ + $product = $this->productRepository->get('product1'); + + $productFilter = [ + UrlRewrite::ENTITY_TYPE => 'product', + ]; + + //Product in 1st website. Should result in being in 1st and 4th stores. + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore1->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore4->getId(), + ] + ]; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + + //Add product to websites corresponding to all 4 stores. + //Rewrites should not be present as the product is hidden + //at the global scope. + $product->setWebsiteIds( + array_unique( + [ + $testStore1->getWebsiteId(), + $testStore2->getWebsiteId(), + $testStore3->getWebsiteId(), + $testStore4->getWebsiteId() + ] + ) + ); + $this->productRepository->save($product); + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore1->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore2->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore3->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore4->getId(), + ] + ]; + + //Add product to websites corresponding to stores 2 and 3. + $product->setWebsiteIds( + array_unique( + [ + $testStore2->getWebsiteId(), + $testStore3->getWebsiteId(), + ] + ) + ); + $this->productRepository->save($product); + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore2->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore3->getId(), + ] + ]; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + } + + /** + * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php + * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testChangeVisibilityGlobalScope() + { + $testStore1 = $this->storeManager->getStore('default'); + $testStore2 = $this->storeManager->getStore('fixture_second_store'); + $testStore3 = $this->storeManager->getStore('fixture_third_store'); + $testStore4 = $this->storeManager->getStore('test'); + + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + + /** @var Product $product*/ + $product = $this->productRepository->get('product1'); + + $productFilter = [ + UrlRewrite::ENTITY_TYPE => 'product', + ]; + + //Product in 1st website. Should result in being in 1st and 4th stores. + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore1->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore4->getId(), + ] + ]; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + + //Set product to be not visible at global scope + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + $product->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE); + $this->productRepository->save($product); + $expected = []; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + + //Add product to websites corresponding to all 4 stores. + //Rewrites should not be present as the product is hidden + //at the global scope. + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + $product->setWebsiteIds( + array_unique( + [ + $testStore1->getWebsiteId(), + $testStore2->getWebsiteId(), + $testStore3->getWebsiteId(), + $testStore4->getWebsiteId() + ] + ) + ); + $this->productRepository->save($product); + $expected = []; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + + //Set product to be visible at global scope + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + $product->setVisibility(Visibility::VISIBILITY_BOTH); + $this->productRepository->save($product); + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore1->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore2->getId(), ], [ 'request_path' => "product-1.html", 'target_path' => "catalog/product/view/id/" . $product->getId(), 'is_auto_generated' => 1, 'redirect_type' => 0, - 'store_id' => $testStore->getId(), + 'store_id' => $testStore3->getId(), ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore4->getId(), + ] ]; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + } + + /** + * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php + * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_rewrite_multistore.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testChangeVisibilityLocalScope() + { + $testStore1 = $this->storeManager->getStore('default'); + $testStore2 = $this->storeManager->getStore('fixture_second_store'); + $testStore3 = $this->storeManager->getStore('fixture_third_store'); + $testStore4 = $this->storeManager->getStore('test'); + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + + /** @var Product $product*/ + $product = $this->productRepository->get('product1'); + + $productFilter = [ + UrlRewrite::ENTITY_TYPE => 'product', + ]; + + //Product in 1st website. Should result in being in 1st and 4th stores. + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore1->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore4->getId(), + ] + ]; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + + //Set product to be not visible at store 4 scope + //Rewrite should only be present for store 1 + $this->storeManager->setCurrentStore($testStore4); + $product = $this->productRepository->get('product1'); + $product->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE); + $this->productRepository->save($product); + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore1->getId(), + ] + ]; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + + //Add product to websites corresponding to all 4 stores. + //Rewrites should be present for stores 1,2 and 3. + //No rewrites should be present for store 4 as that is not visible + //at local scope. + $this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID); + $product = $this->productRepository->get('product1'); + $product->setWebsiteIds( + array_unique( + [ + $testStore1->getWebsiteId(), + $testStore2->getWebsiteId(), + $testStore3->getWebsiteId(), + $testStore4->getWebsiteId() + ] + ) + ); + $this->productRepository->save($product); + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore1->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore2->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore3->getId(), + ] + ]; + $actual = $this->getActualResults($productFilter); + foreach ($expected as $row) { + $this->assertContains($row, $actual); + } + + //Set product to be visible at store 4 scope only + $this->storeManager->setCurrentStore($testStore4); + $product = $this->productRepository->get('product1'); + $product->setVisibility(Visibility::VISIBILITY_BOTH); + $this->productRepository->save($product); + $expected = [ + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore1->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore2->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore3->getId(), + ], + [ + 'request_path' => "product-1.html", + 'target_path' => "catalog/product/view/id/" . $product->getId(), + 'is_auto_generated' => 1, + 'redirect_type' => 0, + 'store_id' => $testStore4->getId(), + ] + ]; $actual = $this->getActualResults($productFilter); foreach ($expected as $row) { $this->assertContains($row, $actual);