diff --git a/app/code/Magento/Catalog/Pricing/Price/MinimalPriceCalculatorInterface.php b/app/code/Magento/Catalog/Pricing/Price/MinimalPriceCalculatorInterface.php
new file mode 100644
index 0000000000000..de31b1d5b51a9
--- /dev/null
+++ b/app/code/Magento/Catalog/Pricing/Price/MinimalPriceCalculatorInterface.php
@@ -0,0 +1,32 @@
+calculator = $calculator;
+ }
+
+ /**
+ * Get raw value of "as low as" as a minimal among tier prices.
+ *
+ * @param SaleableInterface $saleableItem
+ * @return float|null
+ */
+ public function getValue(SaleableInterface $saleableItem)
+ {
+ /** @var TierPrice $price */
+ $price = $saleableItem->getPriceInfo()->getPrice(TierPrice::PRICE_CODE);
+ $tierPriceList = $price->getTierPriceList();
+
+ $tierPrices = [];
+ foreach ($tierPriceList as $tierPrice) {
+ /** @var AmountInterface $price */
+ $price = $tierPrice['price'];
+ $tierPrices[] = $price->getValue();
+ }
+
+ return $tierPrices ? min($tierPrices) : null;
+ }
+
+ /**
+ * Return calculated amount object that keeps "as low as" value.
+ *
+ * @param SaleableInterface $saleableItem
+ * @return AmountInterface|null
+ */
+ public function getAmount(SaleableInterface $saleableItem)
+ {
+ $value = $this->getValue($saleableItem);
+
+ return $value === null ? null : $this->calculator->getAmount($value, $saleableItem);
+ }
+}
diff --git a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
index bab93e08f2753..afe3e0f7374a7 100644
--- a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
+++ b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
@@ -8,40 +8,49 @@
use Magento\Catalog\Pricing\Price;
use Magento\Framework\App\ObjectManager;
-use Magento\Framework\Module\Manager;
-use Magento\Framework\Pricing\Render;
use Magento\Framework\Pricing\Render\PriceBox as BasePriceBox;
-use Magento\Msrp\Pricing\Price\MsrpPrice;
-use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface;
-use Magento\Framework\View\Element\Template\Context;
use Magento\Framework\Pricing\SaleableInterface;
use Magento\Framework\Pricing\Price\PriceInterface;
use Magento\Framework\Pricing\Render\RendererPool;
+use Magento\Msrp\Pricing\Price\MsrpPrice;
+use Magento\Framework\View\Element\Template\Context;
/**
- * Class for final_price rendering
+ * Class for final_price rendering.
*
* @method bool getUseLinkForAsLowAs()
* @method bool getDisplayMinimalPrice()
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class FinalPriceBox extends BasePriceBox
{
/**
- * @var SalableResolverInterface
+ * Interface resolver provided to check is product available for sale.
+ *
+ * @var \Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface
*/
private $salableResolver;
- /** @var Manager */
+ /**
+ * Module statuses manager.
+ *
+ * @var \Magento\Framework\Module\Manager
+ */
private $moduleManager;
+ /**
+ * Shows minimal value of Tier Prices.
+ *
+ * @var \Magento\Catalog\Pricing\Price\MinimalPriceCalculatorInterface
+ */
+ private $minimalPriceCalculator;
+
/**
* @param Context $context
* @param SaleableInterface $saleableItem
* @param PriceInterface $price
* @param RendererPool $rendererPool
* @param array $data
- * @param SalableResolverInterface $salableResolver
+ * @param \Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface $salableResolver
*/
public function __construct(
Context $context,
@@ -49,11 +58,11 @@ public function __construct(
PriceInterface $price,
RendererPool $rendererPool,
array $data = [],
- SalableResolverInterface $salableResolver = null
+ \Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface $salableResolver = null
) {
parent::__construct($context, $saleableItem, $price, $rendererPool, $data);
- $this->salableResolver = $salableResolver ?: \Magento\Framework\App\ObjectManager::getInstance()
- ->get(SalableResolverInterface::class);
+ $this->salableResolver = $salableResolver ?: ObjectManager::getInstance()
+ ->get(\Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface::class);
}
/**
@@ -116,7 +125,7 @@ private function isMsrpPriceApplicable()
}
/**
- * Wrap with standard required container
+ * Wrap with standard required container.
*
* @param string $html
* @return string
@@ -130,17 +139,21 @@ protected function wrapResult($html)
}
/**
- * Render minimal amount
+ * Render minimal amount.
*
* @return string
*/
public function renderAmountMinimal()
{
- /** @var \Magento\Catalog\Pricing\Price\FinalPrice $price */
- $price = $this->getPriceType(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE);
$id = $this->getPriceId() ? $this->getPriceId() : 'product-minimal-price-' . $this->getSaleableItem()->getId();
+ $amount = $this->getMinimalPriceCalculator()->getAmount($this->getSaleableItem());
+
+ if ($amount === null) {
+ return '';
+ }
+
return $this->renderAmount(
- $price->getMinimalPrice(),
+ $amount,
[
'display_label' => __('As low as'),
'price_id' => $id,
@@ -151,7 +164,7 @@ public function renderAmountMinimal()
}
/**
- * Define if the special price should be shown
+ * Define if the special price should be shown.
*
* @return bool
*/
@@ -163,23 +176,25 @@ public function hasSpecialPrice()
}
/**
- * Define if the minimal price should be shown
+ * Define if the minimal price should be shown.
*
* @return bool
*/
public function showMinimalPrice()
{
+ $minTierPrice = $this->getMinimalPriceCalculator()->getValue($this->getSaleableItem());
+
/** @var Price\FinalPrice $finalPrice */
$finalPrice = $this->getPriceType(Price\FinalPrice::PRICE_CODE);
$finalPriceValue = $finalPrice->getAmount()->getValue();
- $minimalPriceAValue = $finalPrice->getMinimalPrice()->getValue();
+
return $this->getDisplayMinimalPrice()
- && $minimalPriceAValue
- && $minimalPriceAValue < $finalPriceValue;
+ && $minTierPrice !== null
+ && $minTierPrice < $finalPriceValue;
}
/**
- * Get Key for caching block content
+ * Get Key for caching block content.
*
* @return string
*/
@@ -203,19 +218,19 @@ public function getCacheKeyInfo()
/**
* @deprecated
- * @return Manager
+ * @return \Magento\Framework\Module\Manager
*/
private function getModuleManager()
{
if ($this->moduleManager === null) {
- $this->moduleManager = ObjectManager::getInstance()->get(Manager::class);
+ $this->moduleManager = ObjectManager::getInstance()->get(\Magento\Framework\Module\Manager::class);
}
return $this->moduleManager;
}
/**
- * Get flag that price rendering should be done for the list of products
- * By default (if flag is not set) is false
+ * Get flag that price rendering should be done for the list of products.
+ * By default (if flag is not set) is false.
*
* @return bool
*/
@@ -224,4 +239,18 @@ public function isProductList()
$isProductList = $this->getData('is_product_list');
return $isProductList === true;
}
+
+ /**
+ * @deprecated
+ * @return \Magento\Catalog\Pricing\Price\MinimalPriceCalculatorInterface
+ */
+ private function getMinimalPriceCalculator()
+ {
+ if ($this->minimalPriceCalculator == null) {
+ $this->minimalPriceCalculator = ObjectManager::getInstance()
+ ->get(\Magento\Catalog\Pricing\Price\MinimalPriceCalculatorInterface::class);
+ }
+
+ return $this->minimalPriceCalculator;
+ }
}
diff --git a/app/code/Magento/Catalog/Setup/UpgradeData.php b/app/code/Magento/Catalog/Setup/UpgradeData.php
index 9961441cd5bda..b3a30d8fa21da 100644
--- a/app/code/Magento/Catalog/Setup/UpgradeData.php
+++ b/app/code/Magento/Catalog/Setup/UpgradeData.php
@@ -5,13 +5,10 @@
*/
namespace Magento\Catalog\Setup;
-use Magento\Catalog\Api\Data\ProductAttributeInterface;
-use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Setup\EavSetup;
-use Magento\Eav\Setup\EavSetupFactory;
/**
* Upgrade Data script
@@ -29,20 +26,32 @@ class UpgradeData implements UpgradeDataInterface
/**
* EAV setup factory
*
- * @var EavSetupFactory
+ * @var \Magento\Eav\Setup\EavSetupFactory
*/
private $eavSetupFactory;
+ /**
+ * Attributes cache management.
+ *
+ * @var \Magento\Eav\Model\Entity\AttributeCache
+ */
+ private $attributeCache;
+
/**
* Init
*
* @param CategorySetupFactory $categorySetupFactory
- * @param EavSetupFactory $eavSetupFactory
+ * @param \Magento\Eav\Setup\EavSetupFactory $eavSetupFactory
+ * @param \Magento\Eav\Model\Entity\AttributeCache $attributeCache
*/
- public function __construct(CategorySetupFactory $categorySetupFactory, EavSetupFactory $eavSetupFactory)
- {
+ public function __construct(
+ CategorySetupFactory $categorySetupFactory,
+ \Magento\Eav\Setup\EavSetupFactory $eavSetupFactory,
+ \Magento\Eav\Model\Entity\AttributeCache $attributeCache
+ ) {
$this->categorySetupFactory = $categorySetupFactory;
$this->eavSetupFactory = $eavSetupFactory;
+ $this->attributeCache = $attributeCache;
}
/**
@@ -87,7 +96,7 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
if (version_compare($context->getVersion(), '2.0.2') < 0) {
// set new resource model paths
- /** @var \Magento\Catalog\Setup\CategorySetup $categorySetup */
+ /** @var CategorySetup $categorySetup */
$categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
$categorySetup->updateEntityType(
\Magento\Catalog\Model\Category::ENTITY,
@@ -128,69 +137,75 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
}
if (version_compare($context->getVersion(), '2.0.3') < 0) {
- /** @var \Magento\Catalog\Setup\CategorySetup $categorySetup */
+ /** @var CategorySetup $categorySetup */
$categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
$categorySetup->updateAttribute(3, 54, 'default_value', 1);
}
if (version_compare($context->getVersion(), '2.0.4') < 0) {
- /** @var \Magento\Catalog\Setup\CategorySetup $categorySetup */
+ $mediaBackendType = 'static';
+ $mediaBackendModel = null;
+ /** @var CategorySetup $categorySetup */
$categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
$categorySetup->updateAttribute(
'catalog_product',
'media_gallery',
'backend_type',
- 'static'
+ $mediaBackendType
);
$categorySetup->updateAttribute(
'catalog_product',
'media_gallery',
- 'backend_model'
+ 'backend_model',
+ $mediaBackendModel
);
+
+ $this->changeMediaGalleryAttributeInCache($mediaBackendType, $mediaBackendModel);
}
if (version_compare($context->getVersion(), '2.0.5', '<')) {
- /** @var \Magento\Catalog\Setup\CategorySetup $categorySetup */
+ /** @var CategorySetup $categorySetup */
$categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
//Product Details tab
$categorySetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'status',
'frontend_label',
'Enable Product',
5
);
$categorySetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'name',
'frontend_label',
'Product Name'
);
+ $attributeSetId = $categorySetup->getDefaultAttributeSetId(\Magento\Catalog\Model\Product::ENTITY);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Product Details',
'visibility',
80
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Product Details',
'news_from_date',
90
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Product Details',
'news_to_date',
100
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Product Details',
'country_of_manufacture',
110
@@ -198,27 +213,27 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
//Content tab
$categorySetup->addAttributeGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Content',
15
);
$categorySetup->updateAttributeGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Content',
'tab_group_code',
'basic'
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Content',
'description'
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Content',
'short_description',
100
@@ -226,39 +241,39 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
//Images tab
$groupId = (int)$categorySetup->getAttributeGroupByCode(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'image-management',
'attribute_group_id'
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
$groupId,
'image',
1
);
$categorySetup->updateAttributeGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
$groupId,
'attribute_group_name',
'Images'
);
$categorySetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'image',
'frontend_label',
'Base'
);
$categorySetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'small_image',
'frontend_label',
'Small'
);
$categorySetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'image',
'frontend_input_renderer',
null
@@ -266,13 +281,13 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
//Design tab
$categorySetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'page_layout',
'frontend_label',
'Layout'
);
$categorySetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'custom_layout_update',
'frontend_label',
'Layout Update XML',
@@ -281,56 +296,56 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
//Schedule Design Update tab
$categorySetup->addAttributeGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Schedule Design Update',
55
);
$categorySetup->updateAttributeGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Schedule Design Update',
'tab_group_code',
'advanced'
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Schedule Design Update',
'custom_design_from',
20
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Schedule Design Update',
'custom_design_to',
30
);
$categorySetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'custom_design',
'frontend_label',
'New Theme',
40
);
$categorySetup->addAttributeToGroup(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- 'Default',
+ \Magento\Catalog\Model\Product::ENTITY,
+ $attributeSetId,
'Schedule Design Update',
'custom_design'
);
$categorySetup->addAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'custom_layout',
[
'type' => 'varchar',
'label' => 'New Layout',
'input' => 'select',
- 'source' => 'Magento\Catalog\Model\Product\Attribute\Source\Layout',
+ 'source' => \Magento\Catalog\Model\Product\Attribute\Source\Layout::class,
'required' => false,
'sort_order' => 50,
- 'global' => ScopedAttributeInterface::SCOPE_STORE,
+ 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
'group' => 'Schedule Design Update',
'is_used_in_grid' => true,
'is_visible_in_grid' => false,
@@ -338,13 +353,13 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
]
);
}
-
+
if (version_compare($context->getVersion(), '2.0.7') < 0) {
/** @var EavSetup $eavSetup */
- $eavSetup= $this->eavSetupFactory->create(['setup' => $setup]);
+ $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
$eavSetup->updateAttribute(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
+ \Magento\Catalog\Model\Product::ENTITY,
'meta_description',
[
'note' => 'Maximum 255 chars. Meta Description should optimally be between 150-160 characters'
@@ -353,7 +368,7 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
}
if (version_compare($context->getVersion(), '2.1.3') < 0) {
- /** @var \Magento\Catalog\Setup\CategorySetup $categorySetup */
+ /** @var CategorySetup $categorySetup */
$categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
$this->changePriceAttributeDefaultScope($categorySetup);
}
@@ -362,7 +377,7 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface
}
/**
- * @param \Magento\Catalog\Setup\CategorySetup $categorySetup
+ * @param CategorySetup $categorySetup
* @return void
*/
private function changePriceAttributeDefaultScope($categorySetup)
@@ -379,4 +394,30 @@ private function changePriceAttributeDefaultScope($categorySetup)
}
}
+
+ /**
+ * Change media_gallery attribute metadata in cache.
+ *
+ * @param string $mediaBackendType
+ * @param string $mediaBackendModel
+ * @return void
+ */
+ private function changeMediaGalleryAttributeInCache($mediaBackendType, $mediaBackendModel)
+ {
+ // need to do, because media_gallery has backend model in cache.
+ $catalogProductAttributes = $this->attributeCache->getAttributes(
+ \Magento\Catalog\Model\Product::ENTITY,
+ '0-0'
+ );
+
+ if (is_array($catalogProductAttributes)) {
+ /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $catalogProductAttribute */
+ foreach ($catalogProductAttributes as $catalogProductAttribute) {
+ if ($catalogProductAttribute->getAttributeCode() == 'media_gallery') {
+ $catalogProductAttribute->setBackendModel($mediaBackendModel);
+ $catalogProductAttribute->setBackendType($mediaBackendType);
+ }
+ }
+ }
+ }
}
diff --git a/app/code/Magento/Catalog/Test/Unit/Pricing/Price/MinimalTierPriceCalculatorTest.php b/app/code/Magento/Catalog/Test/Unit/Pricing/Price/MinimalTierPriceCalculatorTest.php
new file mode 100644
index 0000000000000..a649d3500c965
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Pricing/Price/MinimalTierPriceCalculatorTest.php
@@ -0,0 +1,112 @@
+price = $this->getMock(TierPrice::class, [], [], '', false);
+ $this->priceInfo = $this->getMockForAbstractClass(PriceInfoInterface::class);
+ $this->saleable = $this->getMockForAbstractClass(SaleableInterface::class);
+
+ $this->objectManager = new ObjectManager($this);
+
+ $this->calculator = $this->getMockForAbstractClass(CalculatorInterface::class);
+ $this->object = $this->objectManager->getObject(
+ MinimalTierPriceCalculator::class,
+ ['calculator' => $this->calculator]
+ );
+ }
+
+ private function getValueTierPricesExistShouldReturnMinTierPrice()
+ {
+ $minPrice = 5;
+ $notMinPrice = 10;
+
+ $minAmount = $this->getMockForAbstractClass(AmountInterface::class);
+ $minAmount->expects($this->once())->method('getValue')->willReturn($minPrice);
+
+ $notMinAmount = $this->getMockForAbstractClass(AmountInterface::class);
+ $notMinAmount->expects($this->once())->method('getValue')->willReturn($notMinPrice);
+ $tierPriceList = [
+ [
+ 'price' => $minAmount
+ ],
+ [
+ 'price' => $notMinAmount
+ ]
+ ];
+
+ $this->price->expects($this->once())->method('getTierPriceList')->willReturn($tierPriceList);
+
+ $this->priceInfo->expects($this->once())->method('getPrice')->with(TierPrice::PRICE_CODE)
+ ->willReturn($this->price);
+
+ $this->saleable->expects($this->once())->method('getPriceInfo')->willReturn($this->priceInfo);
+
+ return $minPrice;
+ }
+
+ public function testGetValueTierPricesExistShouldReturnMinTierPrice()
+ {
+ $minPrice = $this->getValueTierPricesExistShouldReturnMinTierPrice();
+ $this->assertEquals($minPrice, $this->object->getValue($this->saleable));
+ }
+
+ public function testGetGetAmountMinTierPriceExistShouldReturnAmountObject()
+ {
+ $minPrice = $this->getValueTierPricesExistShouldReturnMinTierPrice();
+
+ $amount = $this->getMockForAbstractClass(AmountInterface::class);
+
+ $this->calculator->expects($this->once())
+ ->method('getAmount')
+ ->with($minPrice, $this->saleable)
+ ->willReturn($amount);
+
+ $this->assertSame($amount, $this->object->getAmount($this->saleable));
+ }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
index f2455661cf2d6..0b1690c8f73f1 100644
--- a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
@@ -9,6 +9,10 @@
use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface;
use Magento\Framework\Module\Manager;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Catalog\Pricing\Price\MinimalPriceCalculatorInterface;
+use Magento\Framework\Pricing\Amount\AmountInterface;
+use Magento\Framework\Pricing\Render\Amount;
+use Magento\Catalog\Pricing\Price\FinalPrice;
/**
* Class FinalPriceBoxTest
@@ -72,6 +76,11 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
/** @var Manager|\PHPUnit_Framework_MockObject_MockObject */
private $moduleManager;
+ /**
+ * @var MinimalPriceCalculatorInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $minimalPriceCalculator;
+
/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
@@ -168,7 +177,7 @@ protected function setUp()
$this->price = $this->getMock(\Magento\Framework\Pricing\Price\PriceInterface::class);
$this->price->expects($this->any())
->method('getPriceCode')
- ->will($this->returnValue(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE));
+ ->will($this->returnValue(FinalPrice::PRICE_CODE));
$this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -176,6 +185,10 @@ protected function setUp()
->disableOriginalConstructor()
->getMockForAbstractClass();
+ $this->minimalPriceCalculator =$this->getMockBuilder(MinimalPriceCalculatorInterface::class)
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
+
$this->object = $this->objectManager->getObject(
\Magento\Catalog\Pricing\Render\FinalPriceBox::class,
[
@@ -184,7 +197,8 @@ protected function setUp()
'rendererPool' => $this->rendererPool,
'price' => $this->price,
'data' => ['zone' => 'test_zone', 'list_category_page' => true],
- 'salableResolver' => $this->salableResolverMock
+ 'salableResolver' => $this->salableResolverMock,
+ 'minimalPriceCalculator' => $this->minimalPriceCalculator
]
);
@@ -316,12 +330,18 @@ public function testRenderMsrpNotRegisteredException()
public function testRenderAmountMinimal()
{
- $priceType = $this->getMock(\Magento\Catalog\Pricing\Price\FinalPrice::class, [], [], '', false);
- $amount = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Amount\AmountInterface::class);
$priceId = 'price_id';
$html = 'html';
$this->object->setData('price_id', $priceId);
+ $this->product->expects($this->never())->method('getId');
+
+ $amount = $this->getMockForAbstractClass(AmountInterface::class);
+
+ $this->minimalPriceCalculator->expects($this->once())->method('getAmount')
+ ->with($this->product)
+ ->willReturn($amount);
+
$arguments = [
'zone' => 'test_zone',
'list_category_page' => true,
@@ -331,24 +351,15 @@ public function testRenderAmountMinimal()
'skip_adjustments' => true,
];
- $amountRender = $this->getMock(\Magento\Framework\Pricing\Render\Amount::class, ['toHtml'], [], '', false);
+ $amountRender = $this->getMock(Amount::class, ['toHtml'], [], '', false);
$amountRender->expects($this->once())
->method('toHtml')
- ->will($this->returnValue($html));
-
- $this->priceInfo->expects($this->once())
- ->method('getPrice')
- ->with(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)
- ->will($this->returnValue($priceType));
-
- $priceType->expects($this->once())
- ->method('getMinimalPrice')
- ->will($this->returnValue($amount));
+ ->willReturn($html);
$this->rendererPool->expects($this->once())
->method('createAmountRender')
->with($amount, $this->product, $this->price, $arguments)
- ->will($this->returnValue($amountRender));
+ ->willReturn($amountRender);
$this->assertEquals($html, $this->object->renderAmountMinimal());
}
@@ -362,9 +373,9 @@ public function testRenderAmountMinimal()
public function testHasSpecialPrice($regularPrice, $finalPrice, $expectedResult)
{
$regularPriceType = $this->getMock(\Magento\Catalog\Pricing\Price\RegularPrice::class, [], [], '', false);
- $finalPriceType = $this->getMock(\Magento\Catalog\Pricing\Price\FinalPrice::class, [], [], '', false);
- $regularPriceAmount = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Amount\AmountInterface::class);
- $finalPriceAmount = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Amount\AmountInterface::class);
+ $finalPriceType = $this->getMock(FinalPrice::class, [], [], '', false);
+ $regularPriceAmount = $this->getMockForAbstractClass(AmountInterface::class);
+ $finalPriceAmount = $this->getMockForAbstractClass(AmountInterface::class);
$regularPriceAmount->expects($this->once())
->method('getValue')
@@ -386,7 +397,7 @@ public function testHasSpecialPrice($regularPrice, $finalPrice, $expectedResult)
->will($this->returnValue($regularPriceType));
$this->priceInfo->expects($this->at(1))
->method('getPrice')
- ->with(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)
+ ->with(FinalPrice::PRICE_CODE)
->will($this->returnValue($finalPriceType));
$this->assertEquals($expectedResult, $this->object->hasSpecialPrice());
@@ -403,35 +414,30 @@ public function hasSpecialPriceProvider()
public function testShowMinimalPrice()
{
- $finalPrice = 10.0;
$minimalPrice = 5.0;
- $displayMininmalPrice = 2.0;
-
- $this->object->setDisplayMinimalPrice($displayMininmalPrice);
+ $finalPrice = 10.0;
+ $displayMininmalPrice = true;
- $finalPriceType = $this->getMock(\Magento\Catalog\Pricing\Price\FinalPrice::class, [], [], '', false);
+ $this->minimalPriceCalculator->expects($this->once())->method('getValue')->with($this->product)
+ ->willReturn($minimalPrice);
- $finalPriceAmount = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Amount\AmountInterface::class);
- $minimalPriceAmount = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Amount\AmountInterface::class);
+ $finalPriceAmount = $this->getMockForAbstractClass(AmountInterface::class);
$finalPriceAmount->expects($this->once())
->method('getValue')
->will($this->returnValue($finalPrice));
- $minimalPriceAmount->expects($this->once())
- ->method('getValue')
- ->will($this->returnValue($minimalPrice));
- $finalPriceType->expects($this->at(0))
+ $finalPriceType = $this->getMock(FinalPrice::class, [], [], '', false);
+ $finalPriceType->expects($this->once())
->method('getAmount')
->will($this->returnValue($finalPriceAmount));
- $finalPriceType->expects($this->at(1))
- ->method('getMinimalPrice')
- ->will($this->returnValue($minimalPriceAmount));
$this->priceInfo->expects($this->once())
->method('getPrice')
- ->with(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)
- ->will($this->returnValue($finalPriceType));
+ ->with(FinalPrice::PRICE_CODE)
+ ->willReturn($finalPriceType);
+
+ $this->object->setDisplayMinimalPrice($displayMininmalPrice);
$this->assertTrue($this->object->showMinimalPrice());
}
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index ae1bc9c524c8e..44a65b6697d0c 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -807,4 +807,5 @@
+
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index cbcbbd66897b1..ac5fe77c2498f 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -1249,7 +1249,7 @@ protected function _saveProductAttributes(array $attributesData)
$linkId = $this->_connection->fetchOne(
$this->_connection->select()
->from($this->getResource()->getTable('catalog_product_entity'))
- ->where('sku = ?', $sku)
+ ->where('sku = ?', (string)$sku)
->columns($this->getProductEntityLinkField())
);
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php
index 206ad612900a9..93892eb8156d8 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php
@@ -47,7 +47,8 @@ public function execute(\Magento\Framework\Event\Observer $observer)
{
/** @var Category $category */
$category = $observer->getEvent()->getCategory();
- if ($category->getUrlKey() !== false) {
+ $useDefaultAttribute = !$category->isObjectNew() && !empty($category->getData('use_default')['url_key']);
+ if ($category->getUrlKey() !== false && !$useDefaultAttribute) {
$category->setUrlKey($this->categoryUrlPathGenerator->getUrlKey($category))
->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category));
if (!$category->isObjectNew()) {
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/CategoryUrlPathAutogeneratorObserverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/CategoryUrlPathAutogeneratorObserverTest.php
index a6fdc41cd11ee..db153f6cb0a4a 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/CategoryUrlPathAutogeneratorObserverTest.php
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/CategoryUrlPathAutogeneratorObserverTest.php
@@ -37,16 +37,34 @@ class CategoryUrlPathAutogeneratorObserverTest extends \PHPUnit_Framework_TestCa
protected function setUp()
{
$this->observer = $this->getMock(
- 'Magento\Framework\Event\Observer',
- ['getEvent', 'getCategory'],
+ \Magento\Framework\Event\Observer::class,
+ [
+ 'getEvent',
+ 'getCategory'
+ ],
+ [],
+ '',
+ false
+ );
+ $this->categoryResource = $this->getMock(
+ \Magento\Catalog\Model\ResourceModel\Category::class,
+ [],
[],
'',
false
);
- $this->categoryResource = $this->getMock('Magento\Catalog\Model\ResourceModel\Category', [], [], '', false);
$this->category = $this->getMock(
- 'Magento\Catalog\Model\Category',
- ['setUrlKey', 'setUrlPath', 'dataHasChangedFor', 'isObjectNew', 'getResource', 'getUrlKey', 'getStoreId'],
+ \Magento\Catalog\Model\Category::class,
+ [
+ 'setUrlKey',
+ 'setUrlPath',
+ 'dataHasChangedFor',
+ 'isObjectNew',
+ 'getResource',
+ 'getUrlKey',
+ 'getStoreId',
+ 'getData'
+ ],
[],
'',
false
@@ -55,18 +73,18 @@ protected function setUp()
$this->observer->expects($this->any())->method('getEvent')->willReturnSelf();
$this->observer->expects($this->any())->method('getCategory')->willReturn($this->category);
$this->categoryUrlPathGenerator = $this->getMock(
- 'Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator',
+ \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator::class,
[],
[],
'',
false
);
$this->childrenCategoriesProvider = $this->getMock(
- 'Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider'
+ \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider::class
);
$this->storeViewService = $this->getMock(
- 'Magento\CatalogUrlRewrite\Service\V1\StoreViewService',
+ \Magento\CatalogUrlRewrite\Service\V1\StoreViewService::class,
[],
[],
'',
@@ -74,7 +92,7 @@ protected function setUp()
);
$this->categoryUrlPathAutogeneratorObserver = (new ObjectManagerHelper($this))->getObject(
- 'Magento\CatalogUrlRewrite\Observer\CategoryUrlPathAutogeneratorObserver',
+ \Magento\CatalogUrlRewrite\Observer\CategoryUrlPathAutogeneratorObserver::class,
[
'categoryUrlPathGenerator' => $this->categoryUrlPathGenerator,
'childrenCategoriesProvider' => $this->childrenCategoriesProvider,
@@ -90,7 +108,7 @@ public function testSetCategoryUrlAndCategoryPath()
$this->category->expects($this->once())->method('setUrlKey')->with('urk_key')->willReturnSelf();
$this->categoryUrlPathGenerator->expects($this->once())->method('getUrlPath')->willReturn('url_path');
$this->category->expects($this->once())->method('setUrlPath')->with('url_path')->willReturnSelf();
- $this->category->expects($this->once())->method('isObjectNew')->willReturn(true);
+ $this->category->expects($this->exactly(2))->method('isObjectNew')->willReturn(true);
$this->categoryUrlPathAutogeneratorObserver->execute($this->observer);
}
@@ -114,7 +132,7 @@ public function testUrlKeyAndUrlPathUpdating()
$this->category->expects($this->once())->method('setUrlKey')->with('url_key')->willReturnSelf();
$this->category->expects($this->once())->method('setUrlPath')->with('url_path')->willReturnSelf();
// break code execution
- $this->category->expects($this->once())->method('isObjectNew')->willReturn(true);
+ $this->category->expects($this->exactly(2))->method('isObjectNew')->willReturn(true);
$this->categoryUrlPathAutogeneratorObserver->execute($this->observer);
}
@@ -128,7 +146,7 @@ public function testUrlPathAttributeNoUpdatingIfCategoryIsNew()
$this->category->expects($this->any())->method('setUrlKey')->willReturnSelf();
$this->category->expects($this->any())->method('setUrlPath')->willReturnSelf();
- $this->category->expects($this->once())->method('isObjectNew')->willReturn(true);
+ $this->category->expects($this->exactly(2))->method('isObjectNew')->willReturn(true);
$this->categoryResource->expects($this->never())->method('saveAttribute');
$this->categoryUrlPathAutogeneratorObserver->execute($this->observer);
@@ -142,7 +160,7 @@ public function testUrlPathAttributeUpdating()
$this->category->expects($this->any())->method('getUrlKey')->willReturn('not_formatted_url_key');
$this->category->expects($this->any())->method('setUrlKey')->willReturnSelf();
$this->category->expects($this->any())->method('setUrlPath')->willReturnSelf();
- $this->category->expects($this->once())->method('isObjectNew')->willReturn(false);
+ $this->category->expects($this->exactly(2))->method('isObjectNew')->willReturn(false);
$this->categoryResource->expects($this->once())->method('saveAttribute')->with($this->category, 'url_path');
@@ -162,7 +180,7 @@ public function testChildrenUrlPathAttributeNoUpdatingIfParentUrlPathIsNotChange
$this->category->expects($this->any())->method('getUrlKey')->willReturn('not_formatted_url_key');
$this->category->expects($this->any())->method('setUrlKey')->willReturnSelf();
$this->category->expects($this->any())->method('setUrlPath')->willReturnSelf();
- $this->category->expects($this->once())->method('isObjectNew')->willReturn(false);
+ $this->category->expects($this->exactly(2))->method('isObjectNew')->willReturn(false);
// break code execution
$this->category->expects($this->once())->method('dataHasChangedFor')->with('url_path')->willReturn(false);
@@ -177,7 +195,7 @@ public function testChildrenUrlPathAttributeUpdatingForSpecificStore()
$this->category->expects($this->any())->method('getUrlKey')->willReturn('not_formatted_url_key');
$this->category->expects($this->any())->method('setUrlKey')->willReturnSelf();
$this->category->expects($this->any())->method('setUrlPath')->willReturnSelf();
- $this->category->expects($this->any())->method('isObjectNew')->willReturn(false);
+ $this->category->expects($this->exactly(2))->method('isObjectNew')->willReturn(false);
$this->category->expects($this->any())->method('dataHasChangedFor')->willReturn(true);
// only for specific store
$this->category->expects($this->atLeastOnce())->method('getStoreId')->willReturn(1);
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
index 61f423f77cee8..006fce54465ac 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
@@ -9,6 +9,10 @@
use Magento\Catalog\Model\Product\Pricing\Renderer\SalableResolverInterface;
use Magento\Framework\Module\Manager;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Catalog\Pricing\Price\MinimalPriceCalculatorInterface;
+use Magento\Framework\Pricing\Amount\AmountInterface;
+use Magento\Framework\Pricing\Render\Amount;
+use Magento\Catalog\Pricing\Price\FinalPrice;
/**
* Class FinalPriceBoxTest
@@ -72,6 +76,11 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
/** @var Manager|\PHPUnit_Framework_MockObject_MockObject */
private $moduleManager;
+ /**
+ * @var MinimalPriceCalculatorInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $minimalPriceCalculator;
+
/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
@@ -89,12 +98,12 @@ protected function setUp()
->method('getPriceInfo')
->will($this->returnValue($this->priceInfo));
- $eventManager = $this->getMock('Magento\Framework\Event\Test\Unit\ManagerStub', [], [], '', false);
+ $eventManager = $this->getMock(\Magento\Framework\Event\Test\Unit\ManagerStub::class, [], [], '', false);
$config = $this->getMock('Magento\Store\Model\Store\Config', [], [], '', false);
- $this->layout = $this->getMock('Magento\Framework\View\Layout', [], [], '', false);
+ $this->layout = $this->getMock(\Magento\Framework\View\Layout::class, [], [], '', false);
- $this->priceBox = $this->getMock('Magento\Framework\Pricing\Render\PriceBox', [], [], '', false);
- $this->logger = $this->getMock('Psr\Log\LoggerInterface');
+ $this->priceBox = $this->getMock(\Magento\Framework\Pricing\Render\PriceBox::class, [], [], '', false);
+ $this->logger = $this->getMock(\Psr\Log\LoggerInterface::class);
$this->layout->expects($this->any())->method('getBlock')->willReturn($this->priceBox);
@@ -117,8 +126,8 @@ protected function setUp()
->getMockForAbstractClass();
$storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
- $scopeConfigMock = $this->getMockForAbstractClass('Magento\Framework\App\Config\ScopeConfigInterface');
- $context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false);
+ $scopeConfigMock = $this->getMockForAbstractClass(\Magento\Framework\App\Config\ScopeConfigInterface::class);
+ $context = $this->getMock(\Magento\Framework\View\Element\Template\Context::class, [], [], '', false);
$context->expects($this->any())
->method('getEventManager')
->will($this->returnValue($eventManager));
@@ -150,11 +159,11 @@ protected function setUp()
->method('getUrlBuilder')
->will($this->returnValue($urlBuilder));
- $this->rendererPool = $this->getMockBuilder('Magento\Framework\Pricing\Render\RendererPool')
+ $this->rendererPool = $this->getMockBuilder(\Magento\Framework\Pricing\Render\RendererPool::class)
->disableOriginalConstructor()
->getMock();
- $this->price = $this->getMock('Magento\Framework\Pricing\Price\PriceInterface');
+ $this->price = $this->getMock(\Magento\Framework\Pricing\Price\PriceInterface::class);
$this->price->expects($this->any())
->method('getPriceCode')
->will($this->returnValue(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE));
@@ -165,15 +174,18 @@ protected function setUp()
->disableOriginalConstructor()
->getMockForAbstractClass();
+ $this->minimalPriceCalculator = $this->getMockForAbstractClass(MinimalPriceCalculatorInterface::class);
+
$this->object = $this->objectManager->getObject(
- 'Magento\Catalog\Pricing\Render\FinalPriceBox',
+ \Magento\Catalog\Pricing\Render\FinalPriceBox::class,
[
'context' => $context,
'saleableItem' => $this->product,
'rendererPool' => $this->rendererPool,
'price' => $this->price,
'data' => ['zone' => 'test_zone', 'list_category_page' => true],
- 'salableResolver' => $this->salableResolverMock
+ 'salableResolver' => $this->salableResolverMock,
+ 'minimalPriceCalculator' => $this->minimalPriceCalculator
]
);
@@ -191,7 +203,7 @@ protected function setUp()
public function testRenderMsrpDisabled()
{
- $priceType = $this->getMock('Magento\Msrp\Pricing\Price\MsrpPrice', [], [], '', false);
+ $priceType = $this->getMock(\Magento\Msrp\Pricing\Price\MsrpPrice::class, [], [], '', false);
$this->moduleManager->expects(self::once())
->method('isEnabled')
@@ -223,7 +235,7 @@ public function testRenderMsrpDisabled()
public function testRenderMsrpEnabled()
{
- $priceType = $this->getMock('Magento\Msrp\Pricing\Price\MsrpPrice', [], [], '', false);
+ $priceType = $this->getMock(\Magento\Msrp\Pricing\Price\MsrpPrice::class, [], [], '', false);
$this->moduleManager->expects(self::once())
->method('isEnabled')
@@ -250,7 +262,7 @@ public function testRenderMsrpEnabled()
->with($this->equalTo($this->product))
->will($this->returnValue(true));
- $priceBoxRender = $this->getMockBuilder('Magento\Framework\Pricing\Render\PriceBox')
+ $priceBoxRender = $this->getMockBuilder(\Magento\Framework\Pricing\Render\PriceBox::class)
->disableOriginalConstructor()
->getMock();
$priceBoxRender->expects($this->once())
@@ -305,12 +317,19 @@ public function testRenderMsrpNotRegisteredException()
public function testRenderAmountMinimal()
{
- $priceType = $this->getMock('Magento\Catalog\Pricing\Price\FinalPrice', [], [], '', false);
- $amount = $this->getMockForAbstractClass('Magento\Framework\Pricing\Amount\AmountInterface');
$priceId = 'price_id';
$html = 'html';
+
$this->object->setData('price_id', $priceId);
+ $this->product->expects($this->never())->method('getId');
+
+ $amount = $this->getMockForAbstractClass(AmountInterface::class);
+
+ $this->minimalPriceCalculator->expects($this->once())->method('getAmount')
+ ->with($this->product)
+ ->willReturn($amount);
+
$arguments = [
'zone' => 'test_zone',
'list_category_page' => true,
@@ -320,24 +339,15 @@ public function testRenderAmountMinimal()
'skip_adjustments' => true,
];
- $amountRender = $this->getMock('Magento\Framework\Pricing\Render\Amount', ['toHtml'], [], '', false);
+ $amountRender = $this->getMock(Amount::class, ['toHtml'], [], '', false);
$amountRender->expects($this->once())
->method('toHtml')
- ->will($this->returnValue($html));
-
- $this->priceInfo->expects($this->once())
- ->method('getPrice')
- ->with(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)
- ->will($this->returnValue($priceType));
-
- $priceType->expects($this->once())
- ->method('getMinimalPrice')
- ->will($this->returnValue($amount));
+ ->willReturn($html);
$this->rendererPool->expects($this->once())
->method('createAmountRender')
->with($amount, $this->product, $this->price, $arguments)
- ->will($this->returnValue($amountRender));
+ ->willReturn($amountRender);
$this->assertEquals($html, $this->object->renderAmountMinimal());
}
@@ -350,10 +360,10 @@ public function testRenderAmountMinimal()
*/
public function testHasSpecialPrice($regularPrice, $finalPrice, $expectedResult)
{
- $regularPriceType = $this->getMock('Magento\Catalog\Pricing\Price\RegularPrice', [], [], '', false);
- $finalPriceType = $this->getMock('Magento\Catalog\Pricing\Price\FinalPrice', [], [], '', false);
- $regularPriceAmount = $this->getMockForAbstractClass('Magento\Framework\Pricing\Amount\AmountInterface');
- $finalPriceAmount = $this->getMockForAbstractClass('Magento\Framework\Pricing\Amount\AmountInterface');
+ $regularPriceType = $this->getMock(\Magento\Catalog\Pricing\Price\RegularPrice::class, [], [], '', false);
+ $finalPriceType = $this->getMock(\Magento\Catalog\Pricing\Price\FinalPrice::class, [], [], '', false);
+ $regularPriceAmount = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Amount\AmountInterface::class);
+ $finalPriceAmount = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Amount\AmountInterface::class);
$regularPriceAmount->expects($this->once())
->method('getValue')
@@ -392,35 +402,31 @@ public function hasSpecialPriceProvider()
public function testShowMinimalPrice()
{
- $finalPrice = 10.0;
$minimalPrice = 5.0;
- $displayMininmalPrice = 2.0;
-
- $this->object->setDisplayMinimalPrice($displayMininmalPrice);
+ $finalPrice = 10.0;
+ $displayMininmalPrice = true;
- $finalPriceType = $this->getMock('Magento\Catalog\Pricing\Price\FinalPrice', [], [], '', false);
+ $this->minimalPriceCalculator->expects($this->once())->method('getValue')->with($this->product)
+ ->willReturn($minimalPrice);
- $finalPriceAmount = $this->getMockForAbstractClass('Magento\Framework\Pricing\Amount\AmountInterface');
- $minimalPriceAmount = $this->getMockForAbstractClass('Magento\Framework\Pricing\Amount\AmountInterface');
+ $finalPriceAmount = $this->getMockForAbstractClass(AmountInterface::class);
$finalPriceAmount->expects($this->once())
->method('getValue')
->will($this->returnValue($finalPrice));
- $minimalPriceAmount->expects($this->once())
- ->method('getValue')
- ->will($this->returnValue($minimalPrice));
- $finalPriceType->expects($this->at(0))
+ $finalPriceType = $this->getMock(FinalPrice::class, [], [], '', false);
+
+ $finalPriceType->expects($this->once())
->method('getAmount')
->will($this->returnValue($finalPriceAmount));
- $finalPriceType->expects($this->at(1))
- ->method('getMinimalPrice')
- ->will($this->returnValue($minimalPriceAmount));
$this->priceInfo->expects($this->once())
->method('getPrice')
- ->with(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)
- ->will($this->returnValue($finalPriceType));
+ ->with(FinalPrice::PRICE_CODE)
+ ->willReturn($finalPriceType);
+
+ $this->object->setDisplayMinimalPrice($displayMininmalPrice);
$this->assertTrue($this->object->showMinimalPrice());
}
diff --git a/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Indexer.php b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Indexer.php
new file mode 100644
index 0000000000000..0cf4f2bca24d5
--- /dev/null
+++ b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Indexer.php
@@ -0,0 +1,35 @@
+transport = $transport;
+ }
+
+ /**
+ * Creates Website folder in root directory.
+ *
+ * @param string $websiteCode
+ * @throws \Exception
+ */
+ public function create($websiteCode)
+ {
+ $curl = $this->transport;
+ $curl->addOption(CURLOPT_HEADER, 1);
+ $curl->write($this->prepareUrl($websiteCode), [], CurlInterface::GET);
+ $curl->read();
+ $curl->close();
+ }
+
+ /**
+ * Prepare url.
+ *
+ * @param string $websiteCode
+ * @return string
+ */
+ private function prepareUrl($websiteCode)
+ {
+ return $_ENV['app_frontend_url'] . self::URL . '?website_code=' . urlencode($websiteCode);
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
index be4c15784208b..7efc2bf12371b 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleProduct.xml
@@ -90,7 +90,7 @@
-
+
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml
index e4c57688bbd66..e6a6abdc338bd 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml
@@ -17,7 +17,9 @@
- bundle_dynamic_with_category
- - Main Website
+ -
+
- default
+
- default_dynamic
@@ -44,7 +46,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
- Yes
@@ -83,7 +87,9 @@
Yes
Together
- - Main Website
+ -
+
- default
+
- Yes
@@ -117,7 +123,9 @@
1
No
- - Main Website
+ -
+
- default
+
- default_subcategory
@@ -137,7 +145,9 @@
- bundle_dynamic_with_category
- - Main Website
+ -
+
- default
+
- default_subcategory
@@ -162,7 +172,9 @@
1
No
- - Main Website
+ -
+
- default
+
Separately
@@ -193,7 +205,9 @@
Yes
Together
- - Main Website
+ -
+
- default
+
- Yes
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.php
index d0d208d5faf7b..1dc96e39ca026 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.php
@@ -53,9 +53,14 @@ public function fill(FixtureInterface $fixture, SimpleElement $element = null)
$storeSwitcherBlock->find($this->dropdownBlock, Locator::SELECTOR_CSS, 'liselectstore')->setValue($store);
$modalElement = $this->browser->find($this->confirmModal);
/** @var \Magento\Ui\Test\Block\Adminhtml\Modal $modal */
- $modal = $this->blockFactory->create('Magento\Ui\Test\Block\Adminhtml\Modal', ['element' => $modalElement]);
+ $modal = $this->blockFactory->create(
+ \Magento\Ui\Test\Block\Adminhtml\Modal::class,
+ ['element' => $modalElement]
+ );
$modal->acceptAlert();
+ $modal->waitModalWindowToDisappear();
}
+
return parent::fill($fixture, $element);
}
}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
index 09240d9cf319b..6fa3b543f38c5 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
@@ -24,7 +24,7 @@
input[name='name']
- [name="use_default[]"][value="name"]
+ [name="use_default[name]"]
checkbox
@@ -90,6 +90,10 @@
input
input[name='url_key']
+
+ checkbox
+ input[name='use_default[url_key]']
+
input
input[name='meta_title']
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/PageActions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/PageActions.php
index 3bf28dd49164a..3adee2a605e96 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/PageActions.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/PageActions.php
@@ -7,12 +7,18 @@
namespace Magento\Catalog\Test\Block\Adminhtml\Category\Edit;
use Magento\Backend\Test\Block\FormPageActions;
+use Magento\Mtf\Client\Locator;
/**
* Category page actions.
*/
class PageActions extends FormPageActions
{
+ /**
+ * Top page element to implement a scrolling in case of floating blocks overlay.
+ */
+ const TOP_ELEMENT_TO_SCROLL = 'header.page-header';
+
/**
* Locator for "OK" button in warning block
*
@@ -20,6 +26,20 @@ class PageActions extends FormPageActions
*/
protected $warningBlock = '.ui-widget-content .ui-dialog-buttonset button:first-child';
+ /**
+ * Change Store View selector.
+ *
+ * @var string
+ */
+ protected $storeChangeButton = '#store-change-button';
+
+ /**
+ * Selector for confirm.
+ *
+ * @var string
+ */
+ protected $confirmModal = '.confirm._show[data-role=modal]';
+
/**
* Click on "Save" button
*
@@ -33,4 +53,23 @@ public function save()
$warningBlock->click();
}
}
+
+ /**
+ * Select Store View.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function selectStoreView($name)
+ {
+ $this->browser->find(self::TOP_ELEMENT_TO_SCROLL)->hover();
+ $this->_rootElement->find($this->storeChangeButton)->click();
+ $this->waitForElementVisible($name, Locator::SELECTOR_LINK_TEXT);
+ $this->_rootElement->find($name, Locator::SELECTOR_LINK_TEXT)->click();
+ $element = $this->browser->find($this->confirmModal);
+ /** @var \Magento\Ui\Test\Block\Adminhtml\Modal $modal */
+ $modal = $this->blockFactory->create(\Magento\Ui\Test\Block\Adminhtml\Modal::class, ['element' => $element]);
+ $modal->acceptAlert();
+ $this->waitForElementVisible($this->storeChangeButton);
+ }
}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
index 729aa0ed0be66..7046c2e22b9dc 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
@@ -40,6 +40,9 @@ class Price extends \Magento\Catalog\Test\Block\AbstractPriceBlock
],
'price_including_tax' => [
'selector' => '.price-including-tax .price'
+ ],
+ 'minimal_price' => [
+ 'selector' => '.minimal-price-link'
]
];
@@ -161,4 +164,14 @@ public function isOldPriceVisible()
{
return $this->getTypePriceElement('old_price')->isVisible();
}
+
+ /**
+ * This method returns if the special price is visible.
+ *
+ * @return bool
+ */
+ public function isMinimalPriceVisible()
+ {
+ return $this->getTypePriceElement('minimal_price')->isVisible();
+ }
}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryForm.php
index 4db4a9b12696a..c7a9cdd94a060 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryForm.php
@@ -27,7 +27,8 @@ class AssertCategoryForm extends AbstractAssertForm
*/
protected $skippedFixtureFields = [
'parent_id',
- 'id'
+ 'id',
+ 'store_id',
];
/**
@@ -45,7 +46,10 @@ public function processAssert(
) {
$catalogCategoryIndex->open();
$catalogCategoryIndex->getTreeCategories()->selectCategory($category, true);
-
+ if ($category->hasData('store_id')) {
+ $storeName = $category->getStoreId()['source']->getName();
+ $catalogCategoryEdit->getFormPageActions()->selectStoreView($storeName);
+ }
$fixtureData = $this->prepareFixtureData($category->getData());
$formData = $catalogCategoryEdit->getEditForm()->getData($category);
$error = $this->verifyData($this->sortData($fixtureData), $this->sortData($formData));
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
index 2fd1f97140ed4..5f920b452d3a0 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
@@ -76,7 +76,7 @@
-
+
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
index c113aff5e0d9d..be34fe83d87a7 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
@@ -78,7 +78,7 @@
-
+
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml
index 61a8981b0f3af..e35932a2c5ae4 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml
@@ -20,7 +20,7 @@
-
+
@@ -41,6 +41,7 @@
+
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/WebsiteIds.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/WebsiteIds.php
new file mode 100644
index 0000000000000..ede8093ebd6f2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/WebsiteIds.php
@@ -0,0 +1,144 @@
+fixtureFactory = $fixtureFactory;
+ $this->params = $params;
+ $this->fixtureData = $data;
+ }
+
+ /**
+ * Return prepared data set.
+ *
+ * @param string $key [optional]
+ * @return mixed
+ * @throws \Exception
+ */
+ public function getData($key = null)
+ {
+ if (empty($this->fixtureData)) {
+ throw new \Exception("Data must be set");
+ }
+
+ foreach ($this->fixtureData as $dataset) {
+ if (is_array($dataset) && isset($dataset['websites'])) {
+ foreach ($dataset['websites'] as $website) {
+ $this->websites[] = $website;
+ }
+ } else {
+ $this->createStore($dataset);
+ }
+ }
+
+ return parent::getData($key);
+ }
+
+ /**
+ * Create store.
+ *
+ * @param array|object $dataset
+ * @return void
+ */
+ private function createStore($dataset)
+ {
+ if ($dataset instanceof Store) {
+ $store = $dataset;
+ } elseif (is_array($dataset)) {
+ $store = isset($dataset['store']) ? $dataset['store'] :
+ (isset($dataset['dataset']) ? $this->fixtureFactory->createByCode('store', $dataset) : null);
+ }
+ if (isset($store)) {
+ $this->setWebsiteStoreData($store);
+ }
+ }
+
+ /**
+ * Set website and store data.
+ *
+ * @param Store $store
+ * @return void
+ */
+ private function setWebsiteStoreData(Store $store)
+ {
+ if (!$store->getStoreId()) {
+ $store->persist();
+ }
+ $website = $store->getDataFieldConfig('group_id')['source']
+ ->getStoreGroup()->getDataFieldConfig('website_id')['source']->getWebsite();
+ $this->data[] = $website->getName();
+ $this->websites[] = $website;
+ $this->stores[] = $store;
+ }
+
+ /**
+ * Return stores.
+ *
+ * @return array
+ */
+ public function getStores()
+ {
+ return $this->stores;
+ }
+
+ /**
+ * Return website codes.
+ *
+ * @return array
+ */
+ public function getWebsites()
+ {
+ return $this->websites;
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
index 8087e6363c718..2440f6e800a18 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
@@ -415,12 +415,25 @@ protected function prepareCategory()
protected function prepareWebsites()
{
if (!empty($this->fields['product']['website_ids'])) {
- foreach ($this->fields['product']['website_ids'] as $key => $website) {
- $website = isset($this->mappingData['website_ids'][$website])
- ? $this->mappingData['website_ids'][$website]
- : $website;
- $this->fields['product']['website_ids'][$key] = $website;
+ if (isset($this->fixture->getDataFieldConfig('website_ids')['source'])) {
+ $webSitesSource = $this->fixture->getDataFieldConfig('website_ids')['source'];
+
+ foreach ($webSitesSource->getWebsites() as $key => $website) {
+ $this->fields['product']['website_ids'][$key] = $website->getWebsiteId();
+ }
+
+ } else {
+ foreach ($this->fields['product']['website_ids'] as $key => $website) {
+ $website = isset($this->mappingData['website_ids'][$website])
+ ? $this->mappingData['website_ids'][$website]
+ : $website;
+ $this->fields['product']['website_ids'][$key] = $website;
+ }
}
+ } else {
+ $website = \Magento\Mtf\ObjectManagerFactory::getObjectManager()
+ ->create(\Magento\Store\Test\Fixture\Website::class, ['dataset' => 'default']);
+ $this->fields['product']['website_ids'][] = $website->getWebsiteId();
}
}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
index 7a8a629ca765b..f2ce59cc091d2 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml
@@ -26,7 +26,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
@@ -55,7 +57,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
@@ -84,7 +88,9 @@
- default_subcategory
- - Main Website
+ -
+
- default
+
- simple_order_default
@@ -111,7 +117,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
product-10-dollar-%isolation%
@@ -139,7 +147,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
product-20-dollar-%isolation%
@@ -159,7 +169,9 @@
- 560
- - Main Website
+ -
+
- default
+
Catalog, Search
@@ -186,7 +198,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
@@ -214,7 +228,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
@@ -239,7 +255,9 @@
- 100
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -266,7 +284,9 @@
product_40_dollar
simple-product-%isolation%
- - Main Website
+ -
+
- default
+
@@ -291,7 +311,9 @@
simple_with_category
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -316,7 +338,9 @@
- default_subcategory
- - Main Website
+ -
+
- default
+
simple_with_category
simple-product-%isolation%
@@ -340,7 +364,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
@@ -361,7 +387,9 @@
This item has weight
100
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -389,7 +417,9 @@
1
Yes
- - Main Website
+ -
+
- default
+
- Yes
@@ -417,7 +447,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -446,7 +478,9 @@
- default_subcategory
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -469,7 +503,9 @@
9
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -495,7 +531,9 @@
<p>dfj_full</p>
Yes
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
@@ -519,7 +557,9 @@
<p>Simple with Weight 0.1</p>
Yes
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
@@ -543,7 +583,9 @@
<p>Simple with Weight 150.1</p>
Yes
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
@@ -568,7 +610,9 @@
Yes
<p>abc_short</p>
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
@@ -590,7 +634,9 @@
- 100
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -657,7 +703,9 @@
- default_subcategory
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -678,7 +726,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- two_options
@@ -711,7 +761,9 @@
- simple_drop_down_with_one_option_percent_price
- - Main Website
+ -
+
- default
+
- default_subcategory
@@ -760,7 +812,9 @@
- 100
- - Main Website
+ -
+
- default
+
simple-product-%isolation%
@@ -784,7 +838,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
@@ -812,7 +868,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
@@ -841,7 +899,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Not Visible Individually
@@ -869,7 +929,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
@@ -907,7 +969,9 @@
simple-product-%isolation%
- - Main Website
+ -
+
- default
+
@@ -930,7 +994,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
@@ -965,7 +1031,9 @@
- more_is_cheaper
- - Main Website
+ -
+
- default
+
@@ -989,7 +1057,9 @@
- default_anchor_subcategory
- - Main Website
+ -
+
- default
+
simple_with_category
simple-product-%isolation%
@@ -1006,7 +1076,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Simple Product With Fpt %isolation%
sku_simple_product_%isolation%
@@ -1042,7 +1114,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Simple Product With Fpt %isolation%
sku_simple_product_%isolation%
@@ -1082,7 +1156,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.xml
index fb564aa36328a..c485e1d3b9669 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.xml
@@ -13,7 +13,9 @@
Yes
- - Main Website
+ -
+
- default
+
virtual-product%isolation%
Catalog, Search
@@ -47,7 +49,9 @@
This item has no weight
- - Main Website
+ -
+
- default
+
@@ -65,7 +69,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
@@ -75,7 +81,9 @@
Yes
- - Main Website
+ -
+
- default
+
virtual-product%isolation%
Catalog, Search
@@ -102,7 +110,9 @@
Yes
- - Main Website
+ -
+
- default
+
virtual-product%isolation%
Catalog, Search
@@ -131,7 +141,9 @@
Yes
- - Main Website
+ -
+
- default
+
virtual-product%isolation%
Catalog, Search
@@ -155,7 +167,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
virtual-product%isolation%
Virtual product %isolation%
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Category.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Category.xml
index 88f2670684816..46a7b9b22cf21 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Category.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Category.xml
@@ -17,6 +17,17 @@
+
+ Category%isolation%
+ custom%isolation%
+ Yes
+ Yes
+
+ - default_category
+
+ Yes
+
+
Default Category
1
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
index e4516d83075f3..3b942758eeb8c 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
@@ -34,5 +34,21 @@
- 1
+
+
+ - default
+ - 0
+ - Website
+ - 1
+
+
+
+
+ - default
+ - 0
+ - Global
+ - 0
+
+
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php
index 24db0bf77a42f..e5bf7085fdb9b 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php
@@ -61,14 +61,12 @@ class UpdateCategoryEntityTest extends Injectable
/**
* Inject page end prepare default category
*
- * @param Category $initialCategory
* @param CatalogCategoryIndex $catalogCategoryIndex
* @param CatalogCategoryEdit $catalogCategoryEdit
* @param FixtureFactory $fixtureFactory
- * @return array
+ * @return void
*/
public function __inject(
- Category $initialCategory,
CatalogCategoryIndex $catalogCategoryIndex,
CatalogCategoryEdit $catalogCategoryEdit,
FixtureFactory $fixtureFactory
@@ -76,8 +74,6 @@ public function __inject(
$this->fixtureFactory = $fixtureFactory;
$this->catalogCategoryIndex = $catalogCategoryIndex;
$this->catalogCategoryEdit = $catalogCategoryEdit;
- $initialCategory->persist();
- return ['initialCategory' => $initialCategory];
}
/**
@@ -89,6 +85,7 @@ public function __inject(
*/
public function test(Category $category, Category $initialCategory)
{
+ $initialCategory->persist();
$this->catalogCategoryIndex->open();
$this->catalogCategoryIndex->getTreeCategories()->selectCategory($initialCategory);
$this->catalogCategoryEdit->getEditForm()->fill($category);
@@ -110,11 +107,16 @@ protected function prepareCategory(Category $category, Category $initialCategory
? $category->getDataFieldConfig('parent_id')['source']->getParentCategory()
: $initialCategory->getDataFieldConfig('parent_id')['source']->getParentCategory();
+ $rewriteData = ['parent_id' => ['source' => $parentCategory]];
+ if ($category->hasData('store_id')) {
+ $rewriteData['store_id'] = ['source' => $category->getDataFieldConfig('store_id')['source']->getStore()];
+ }
+
$data = [
'data' => array_merge(
$initialCategory->getData(),
$category->getData(),
- ['parent_id' => ['source' => $parentCategory]]
+ $rewriteData
)
];
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.xml
index 2ed97cfd61834..773dcda5d045d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.xml
@@ -51,5 +51,14 @@
+
+
+ default_with_custom_url
+ default_category
+ custom
+ Yes
+
+
+
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertDiscountInShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertDiscountInShoppingCart.php
index 468ecc2395ef6..c063e27836161 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertDiscountInShoppingCart.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertDiscountInShoppingCart.php
@@ -8,6 +8,7 @@
use Magento\Checkout\Test\Fixture\Cart;
use Magento\Checkout\Test\Page\CheckoutCart;
+use Magento\Customer\Test\Fixture\Customer;
use Magento\Mtf\Constraint\AbstractConstraint;
/**
@@ -20,12 +21,21 @@ class AssertDiscountInShoppingCart extends AbstractConstraint
/**
* Assert that discount is equal to expected.
*
+ * @param Customer $customer
* @param CheckoutCart $checkoutCart
* @param Cart $cart
* @return void
*/
- public function processAssert(CheckoutCart $checkoutCart, Cart $cart)
- {
+ public function processAssert(
+ Customer $customer,
+ CheckoutCart $checkoutCart,
+ Cart $cart
+ ) {
+ $loginStep = $this->objectManager->create(
+ \Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep::class,
+ ['customer' => $customer]
+ );
+ $loginStep->run();
$checkoutCart->open();
$checkoutCart->getTotalsBlock()->waitForUpdatedTotals();
\PHPUnit_Framework_Assert::assertEquals(
@@ -33,6 +43,7 @@ public function processAssert(CheckoutCart $checkoutCart, Cart $cart)
$checkoutCart->getTotalsBlock()->getDiscount(),
'Discount amount in the shopping cart not equals to discount amount from fixture.'
);
+ $loginStep->cleanUp();
}
/**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
index cf101cde54916..c02a109e75c90 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
@@ -10,9 +10,16 @@
to_maintain:yes
Verify cms page grid sorting
+ 2
+ cmsPage
+ default
+
+ - -
+ - -
+
- ID
- - Created
+ - URL Key
Magento\Cms\Test\Page\Adminhtml\CmsPageIndex
getCmsPageGridBlock
@@ -29,7 +36,7 @@
default
- ID
- - Created
+ - Identifier
Magento\Cms\Test\Page\Adminhtml\CmsBlockIndex
getCmsBlockGrid
diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Fixture/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Config/Test/Fixture/ConfigData.xml
index 9f9174731a599..fa3338eb80170 100644
--- a/dev/tests/functional/tests/app/Magento/Config/Test/Fixture/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/Config/Test/Fixture/ConfigData.xml
@@ -14,7 +14,7 @@
repository_class="Magento\Config\Test\Repository\ConfigData"
handler_interface="Magento\Config\Test\Handler\ConfigData\ConfigDataInterface"
class="Magento\Config\Test\Fixture\ConfigData">
-
+
diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Fixture/ConfigData/Section.php b/dev/tests/functional/tests/app/Magento/Config/Test/Fixture/ConfigData/Section.php
new file mode 100644
index 0000000000000..b25a7c383fa52
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Config/Test/Fixture/ConfigData/Section.php
@@ -0,0 +1,199 @@
+fixtureFactory = $fixtureFactory;
+ $this->params = $params;
+ $this->fixtureData = $data;
+ }
+
+ /**
+ * Return prepared data set.
+ *
+ * @param string $key [optional]
+ * @return mixed
+ */
+ public function getData($key = null)
+ {
+ if ($this->data === null) {
+ if (isset($this->fixtureData['scope']['scope_type'])) {
+ $this->scopeData = $this->fixtureData['scope'];
+ $this->scopeType = $this->fixtureData['scope']['scope_type'];
+ $this->setLevel = $this->fixtureData['scope']['set_level'];
+ $this->prepareScopeData();
+ unset($this->fixtureData['scope']);
+ }
+ $this->data = $this->replacePlaceholders($this->fixtureData);
+ }
+
+ return parent::getData($key);
+ }
+
+ /**
+ * Replace placeholders in parameters array.
+ *
+ * @param array $data
+ * @return array
+ */
+ private function replacePlaceholders(array $data)
+ {
+ foreach ($data as &$params) {
+ $params = array_map(function ($value) {
+ if (is_string($value)) {
+ $value = str_replace(
+ '{{basic_url_to_secure}}',
+ preg_replace('/(http[s]?)/', 'https', $_ENV['app_frontend_url']),
+ $value
+ );
+ $value = str_replace(
+ '{{basic_url_to_unsecure}}',
+ preg_replace('/(http[s]?)/', 'http', $_ENV['app_frontend_url']),
+ $value
+ );
+ }
+ return $value;
+ }, $params);
+ }
+
+ return $data;
+ }
+
+ /**
+ * Prepare scope data.
+ *
+ * @return void
+ * @throws \Exception
+ */
+ private function prepareScopeData()
+ {
+ if (isset($this->scopeData['dataset'])) {
+ /** @var Store|Website $store */
+ $this->scope = $this->fixtureFactory->createByCode(
+ $this->scopeType,
+ ['dataset' => $this->scopeData['dataset']]
+ );
+ if (!$this->scope->hasData($this->scopeType . '_id')) {
+ $this->scope->persist();
+ }
+ } elseif (isset($this->scopeData['fixture'])) {
+ $this->scope = $this->scopeData['fixture'];
+ } else {
+ throw new \Exception('Parameters "dataset" and "fixture" aren\'t identify.');
+ }
+
+ $this->prepareScope();
+ }
+
+ /**
+ * Prepare scope.
+ *
+ * @return void
+ * @throws \Exception
+ */
+ private function prepareScope()
+ {
+ if ($this->setLevel == self::STORE_CODE && $this->scopeType == self::WEBSITE_CODE) {
+ throw new \Exception('Store level can\'t set to ["scope_type" = "website"].');
+ } elseif ($this->setLevel == self::WEBSITE_CODE && $this->scopeType == self::STORE_CODE) {
+ $this->scopeType = $this->setLevel;
+ $this->scope = $this->scope
+ ->getDataFieldConfig('group_id')['source']->getStoreGroup()
+ ->getDataFieldConfig('website_id')['source']->getWebsite();
+ }
+ }
+
+ /**
+ * Return Store View or Website fixture.
+ *
+ * @return Store|Website
+ */
+ public function getScope()
+ {
+ return $this->scope;
+ }
+
+ /**
+ * Get get scope type [website|store].
+ *
+ * @return string
+ */
+ public function getScopeType()
+ {
+ return $this->scopeType;
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Handler/ConfigData/Curl.php b/dev/tests/functional/tests/app/Magento/Config/Test/Handler/ConfigData/Curl.php
index c34f5951c03b3..50f11310abc3a 100644
--- a/dev/tests/functional/tests/app/Magento/Config/Test/Handler/ConfigData/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Config/Test/Handler/ConfigData/Curl.php
@@ -10,6 +10,9 @@
use Magento\Mtf\Handler\Curl as AbstractCurl;
use Magento\Mtf\Util\Protocol\CurlTransport;
use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
+use Magento\Config\Test\Fixture\ConfigData\Section;
+use Magento\Store\Test\Fixture\Store;
+use Magento\Store\Test\Fixture\Website;
/**
* Setting config.
@@ -29,6 +32,13 @@ class Curl extends AbstractCurl implements ConfigDataInterface
],
];
+ /**
+ * FixtureInterface object.
+ *
+ * @var FixtureInterface
+ */
+ private $fixture;
+
/**
* Post request for setting configuration.
*
@@ -37,6 +47,7 @@ class Curl extends AbstractCurl implements ConfigDataInterface
*/
public function persist(FixtureInterface $fixture = null)
{
+ $this->fixture = $fixture;
$data = $this->prepareData($fixture);
foreach ($data as $scope => $item) {
$this->applyConfigSettings($item, $scope);
@@ -132,6 +143,26 @@ protected function applyConfigSettings(array $data, $section)
*/
protected function getUrl($section)
{
- return $_ENV['app_backend_url'] . 'admin/system_config/save/section/' . $section;
+ return $_ENV['app_backend_url'] . 'admin/system_config/save/section/' . $section . $this->getStoreViewUrl();
+ }
+
+ /**
+ * Get store view url.
+ *
+ * @return string
+ */
+ private function getStoreViewUrl()
+ {
+ $result = '';
+ /** @var Section $source */
+ $source = $this->fixture->getDataFieldConfig('section')['source'];
+ /** @var Store|Website $scope */
+ $scope = $source->getScope();
+ if ($scope !== null) {
+ $code = $source->getScopeType();
+ $result = $code . '/' . $scope->getData($code . '_id');
+ }
+
+ return $result ? '/' . $result : '';
}
}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductInCategory.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductInCategory.php
index 45bd430cb23eb..a6f9b9c48c4c8 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductInCategory.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductInCategory.php
@@ -41,5 +41,12 @@ protected function assertPrice(FixtureInterface $product, CatalogCategoryView $c
'Product special price on category page is not correct.'
);
}
+
+ if (!$product->hasData('tier_price')) {
+ \PHPUnit_Framework_Assert::assertNotTrue(
+ $priceBlock->isMinimalPriceVisible(),
+ 'Minimal price block mustn\'t be visible on category page.'
+ );
+ }
}
}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct.xml
index 70c613660d542..5964b0a66a976 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/ConfigurableProduct.xml
@@ -81,7 +81,7 @@
-
+
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
index 49a8fcd5a8bae..b57afacd2c308 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
@@ -29,7 +29,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -60,7 +62,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -92,7 +96,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -120,7 +126,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -152,7 +160,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -184,7 +194,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -214,7 +226,9 @@
- default
- - Main Website
+ -
+
- default
+
- default
@@ -242,7 +256,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -274,7 +290,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -302,7 +320,9 @@
- default_subcategory
- - Main Website
+ -
+
- default
+
- two_options_with_fixed_price
@@ -329,7 +349,9 @@
This item has weight
1
- - Main Website
+ -
+
- default
+
- two_variations_with_fixed_price
@@ -365,7 +387,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- custom_attribute_set
@@ -393,7 +417,9 @@
- default_subcategory
- - Main Website
+ -
+
- default
+
- two_options_by_one_dollar
@@ -409,5 +435,37 @@
- price_40
+
+
+ Configurable product %isolation%
+ test-configurable-product-%isolation%
+ sku_configurable_product_%isolation%
+
+ - taxable_goods
+
+ This item has weight
+ 1
+
+ -
+
- default
+
+ -
+
- custom_store
+
+
+
+ - default_subcategory
+
+
+ - two_options_ten_dollars
+
+
+ - custom_attribute_set
+
+
+ - 15
+ - price_15
+
+
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml
index 66a4748e71288..09899f446a76d 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml
@@ -662,5 +662,37 @@
+
+
+
+ -
+
-
+
-
+
- option_key_1_%isolation%
+ - 10
+ - Yes
+
+ -
+
- option_key_2_%isolation%
+ - 10
+ - Yes
+
+
+
+
+
+ - catalogProductAttribute::attribute_type_dropdown_two_options
+
+
+ -
+
- 10
+ - 1
+
+ -
+
- 20
+ - 2
+
+
+
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml
index ae055f628d907..74de6f99ade2c 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml
@@ -17,5 +17,9 @@
11
+
+ 15
+ 15
+
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductCustomWebsiteTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductCustomWebsiteTest.php
new file mode 100644
index 0000000000000..286b30d4510d1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductCustomWebsiteTest.php
@@ -0,0 +1,40 @@
+ Configuration > Catalog > Catalog > Price)
+ * 2. Create Additional Website, Store, Store View.
+ * 3. Create Configurable product with two variations, price for all variations is 10$ and assign it to both websites.
+ * 4. Open all simple products, which are assigned to configurable and change their price in Default Store View to 15$
+ * 5. Do reindex and clear magento cache
+ * 6. Open on storefront on main website category with configurable product
+ * 7. "As low as" price not shown for configurable product
+ *
+ * @group Configurable_Product_(MX)
+ * @ZephyrId MAGETWO-64720
+ */
+class UpdateConfigurableProductCustomWebsiteTest extends Scenario
+{
+ /* tags */
+ const MVP = 'yes';
+ const DOMAIN = 'MX';
+ /* end tags */
+
+ /**
+ * Test update Configurable product with custom website run.
+ *
+ * @return void
+ */
+ public function test()
+ {
+ $this->executeScenario();
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductCustomWebsiteTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductCustomWebsiteTest.xml
new file mode 100644
index 0000000000000..ca9456f7d6445
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductCustomWebsiteTest.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ price_per_website
+ configurableProduct::two_variations_two_websites
+ default
+ 15.00
+
+
+
+
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestStep/UpdateSimplesInConfigurablePerStoreStep.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestStep/UpdateSimplesInConfigurablePerStoreStep.php
new file mode 100644
index 0000000000000..4e7e0c4b61d83
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestStep/UpdateSimplesInConfigurablePerStoreStep.php
@@ -0,0 +1,134 @@
+indexer = $indexer;
+ $this->cache = $cache;
+ $this->store = $store;
+ $this->catalogProductEdit = $catalogProductEdit;
+ $this->productGrid = $productGrid;
+ $this->product = $product;
+ $this->updatedSimple = $updatedSimple;
+ }
+
+ /**
+ * Update simple products data in configurable for store.
+ *
+ * @return void
+ */
+ public function run()
+ {
+ if (!$this->store) {
+ return;
+ }
+
+ $simpleProductsArray = [];
+ $configurableAttributes = $this->product->getConfigurableAttributesData();
+
+ if (isset($configurableAttributes['matrix'])) {
+ foreach ($configurableAttributes['matrix'] as $matrixItem) {
+ $simpleProductsArray[] = $matrixItem['sku'];
+ }
+ }
+
+ foreach ($simpleProductsArray as $simpleProductSku) {
+ //open product
+ $filter = ['sku' => $simpleProductSku];
+ $this->productGrid->open();
+ $this->productGrid->getProductGrid()->searchAndOpen($filter);
+ //update
+ $this->catalogProductEdit->getFormPageActions()->changeStoreViewScope($this->store);
+ $this->catalogProductEdit->getProductForm()->fill($this->updatedSimple);
+ $this->catalogProductEdit->getFormPageActions()->save();
+ }
+
+ $this->indexer->reindex();
+ $this->cache->flush();
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/testcase.xml
index 837aeb382680c..f114a565bd394 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/etc/testcase.xml
@@ -13,4 +13,9 @@
+
+
+
+
+
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml
index 9640e19950b95..a1cb8d84ce8b4 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml
@@ -10,10 +10,17 @@
to_maintain:yes
Verify customer page grid sorting
+ 2
+ customer
+ default
- ID
- Customer Since
+
+ - -
+ - -
+
Magento\Customer\Test\Page\Adminhtml\CustomerIndex
getCustomerGridBlock
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.xml
index f8d16a9de0121..c7873aeb46994 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.xml
@@ -86,7 +86,7 @@
-
+
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.xml
index 42680d9f9377b..848401b881e45 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.xml
@@ -30,7 +30,9 @@
This item has no weight
- - Main Website
+ -
+
- default
+
- downloadable_default
@@ -54,7 +56,9 @@
Yes
Catalog, Search
- - Main Website
+ -
+
- default
+
- with_two_separately_links
@@ -81,7 +85,9 @@
Yes
Catalog, Search
- - Main Website
+ -
+
- default
+
- with_two_separately_links
@@ -112,7 +118,9 @@
Catalog, Search
- - Main Website
+ -
+
- default
+
- with_two_separately_links
@@ -142,7 +150,9 @@
Catalog, Search
- - Main Website
+ -
+
- default
+
- with_two_separately_links
@@ -176,7 +186,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
- downloadable_one_dollar_product_with_no_separated_link
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct.xml
index 4a0660e4d991f..0b934136929c1 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/GroupedProduct.xml
@@ -70,7 +70,7 @@
-
+
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
index 5b09e5f46c408..a8713fd3fec80 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/GroupedProduct.xml
@@ -26,7 +26,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -52,7 +54,9 @@
- Out of Stock
- - Main Website
+ -
+
- default
+
- default
@@ -82,7 +86,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
@@ -108,7 +114,9 @@
- In Stock
- - Main Website
+ -
+
- default
+
- default
diff --git a/dev/tests/functional/tests/app/Magento/Msrp/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Msrp/Test/Repository/CatalogProductSimple.xml
index 097187e1454ff..e8e6b987ef655 100644
--- a/dev/tests/functional/tests/app/Magento/Msrp/Test/Repository/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Msrp/Test/Repository/CatalogProductSimple.xml
@@ -27,7 +27,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
@@ -58,7 +60,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
- No
diff --git a/dev/tests/functional/tests/app/Magento/Msrp/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/Msrp/Test/Repository/ConfigurableProduct.xml
index b76ac44f92dd4..6225acda86698 100644
--- a/dev/tests/functional/tests/app/Magento/Msrp/Test/Repository/ConfigurableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Msrp/Test/Repository/ConfigurableProduct.xml
@@ -30,7 +30,9 @@
- one_variation_one_dollar
- - Main Website
+ -
+
- default
+
- custom_attribute_set
diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Repository/CatalogProductSimple.xml
index e822bf08044d5..8864204eab354 100755
--- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Repository/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/Repository/CatalogProductSimple.xml
@@ -26,7 +26,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-with-video-%isolation%
@@ -61,7 +63,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-with-video-%isolation%
diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.xml
index e3922e303d571..a21202d4c5738 100644
--- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.xml
@@ -52,8 +52,8 @@
test_type:extended_acceptance_test
product_with_video_vimeo
simple_product_with_category_%isolation%
- https://vimeo.com/21776334
- Foo Fighters - "Walk" - Official Music Video (HD)
+ https://vimeo.com/103756396
+ XO Stereo - Show And Tell OFFICIAL MUSIC VIDEO
play_if_base
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
index eee1eb7b5815a..9f53fac6e4441 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/Handler/Website/Curl.php
@@ -11,6 +11,11 @@
use Magento\Mtf\Util\Protocol\CurlInterface;
use Magento\Mtf\Util\Protocol\CurlTransport;
use Magento\Mtf\Util\Protocol\CurlTransport\BackendDecorator;
+use Magento\Store\Test\Fixture\Website as WebsiteFixture;
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\Config\DataInterface;
+use Magento\Mtf\System\Event\EventManagerInterface;
+use Magento\Mtf\Util\Command\Website;
/**
* Class Curl
@@ -18,6 +23,45 @@
*/
class Curl extends AbstractCurl implements WebsiteInterface
{
+ /**
+ * Website folder creation class instance.
+ *
+ * @var Website
+ */
+ private $website;
+
+ /**
+ * Website fixture.
+ *
+ * @var WebsiteFixture
+ */
+ private $fixture;
+
+ /**
+ * Fixture factory.
+ *
+ * @var FixtureFactory
+ */
+ private $fixtureFactory;
+
+ /**
+ * @constructor
+ * @param DataInterface $configuration
+ * @param EventManagerInterface $eventManager
+ * @param Website $website
+ * @param FixtureFactory $fixtureFactory
+ */
+ public function __construct(
+ DataInterface $configuration,
+ EventManagerInterface $eventManager,
+ Website $website,
+ FixtureFactory $fixtureFactory
+ ) {
+ parent::__construct($configuration, $eventManager);
+ $this->website = $website;
+ $this->fixtureFactory = $fixtureFactory;
+ }
+
/**
* POST request for creating Website
*
@@ -37,7 +81,19 @@ public function persist(FixtureInterface $fixture = null)
throw new \Exception("Website entity creating by curl handler was not successful! Response: $response");
}
- return ['website_id' => $this->getWebSiteIdByWebsiteName($fixture->getName())];
+ $websiteId = $this->getWebSiteIdByWebsiteName($fixture->getName());
+
+ // Update website fixture data.
+ $this->fixture = $this->fixtureFactory->createByCode(
+ 'website',
+ ['data' => array_merge($fixture->getData(), ['website_id' => $websiteId])]
+ );
+ $data['website']['website_id'] = $websiteId;
+ // Creates Website folder in root directory.
+ $this->website->create($data['website']['code']);
+ $this->setConfiguration($data);
+
+ return ['website_id' => $websiteId];
}
/**
@@ -85,4 +141,24 @@ protected function prepareData(FixtureInterface $fixture)
return $data;
}
+
+ /**
+ * Set Website configuration Base url.
+ *
+ * @param array $data
+ * @return void
+ * @throws \Exception
+ */
+ private function setConfiguration(array $data)
+ {
+ $configData = [
+ 'web/unsecure/base_link_url' => [
+ 'value' => '{{unsecure_base_url}}websites/' . $data['website']['code'] . '/',
+ ],
+ 'scope' => ['fixture' => $this->fixture, 'scope_type' => 'website', 'set_level' => 'website']
+ ];
+
+ $configFixture = $this->fixtureFactory->createByCode('configData', ['data' => $configData]);
+ $configFixture->persist();
+ }
}
diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml
index 098f28965d65d..175209ab36c4a 100644
--- a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml
@@ -32,7 +32,9 @@
- default_subcategory
- - Main Website
+ -
+
- default
+
- custom_attribute_set
diff --git a/dev/tests/functional/utils/website.php b/dev/tests/functional/utils/website.php
new file mode 100644
index 0000000000000..0ed76714e1bab
--- /dev/null
+++ b/dev/tests/functional/utils/website.php
@@ -0,0 +1,32 @@
+objectManager = Bootstrap::getObjectManager();
+
+ $this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
+
+ $this->appState = $this->objectManager->get(State::class);
+ $this->appState->setAreaCode(Area::AREA_FRONTEND);
+
+ $this->phtml = $this->objectManager->create(Php::class);
+
+ $this->templateEnginePool = $this->objectManager->get(TemplateEnginePool::class);
+
+ $enginesReflection = new \ReflectionProperty(
+ $this->templateEnginePool,
+ 'engines'
+ );
+ $enginesReflection->setAccessible(true);
+ $enginesReflection->setValue($this->templateEnginePool, ['phtml' => $this->phtml]);
+
+ $this->rendererPool = $this->objectManager->create(RendererPool::class);
+
+ $this->rendererPool->setData(
+ [
+ 'default' =>
+ [
+ 'default_amount_render_class' => Amount::class,
+ 'default_amount_render_template' => 'Magento_Catalog::product/price/amount/default.phtml'
+ ]
+ ]
+ );
+
+ $this->saleableItem = $this->productRepository->get('tier_prices');
+ $this->finalPrice = $this->objectManager->create(
+ FinalPrice::class,
+ [
+ 'saleableItem' => $this->saleableItem,
+ 'quantity' => null
+ ]
+ );
+
+ $this->finalPriceBox = $this->objectManager->create(
+ FinalPriceBox::class,
+ [
+ 'saleableItem' => $this->saleableItem,
+ 'price' => $this->finalPrice,
+ 'rendererPool' => $this->rendererPool
+ ]
+ );
+
+ $this->finalPriceBox->setData('price_id', 'test_price_id');
+ }
+
+ /**
+ * @magentoDataFixture Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
+ */
+ public function testRenderAmountMinimalProductWithTierPricesShouldShowMinTierPrice()
+ {
+ $result = $this->finalPriceBox->renderAmountMinimal();
+ $this->assertContains('$5.00', $result);
+ }
+
+ /**
+ * @magentoDataFixture Magento/Catalog/_files/product_different_store_prices.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
+ * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1
+ */
+ public function testProductSetDifferentStorePricesWithoutTierPriceShouldNotShowAsLowAs()
+ {
+ $this->assertEmpty($this->finalPriceBox->renderAmountMinimal());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_different_store_prices.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_different_store_prices.php
new file mode 100644
index 0000000000000..be0e890742102
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_different_store_prices.php
@@ -0,0 +1,58 @@
+create(IndexerRegistry::class);
+$indexer = $indexerRegistry->get('catalogsearch_fulltext');
+
+$indexer->reindexAll();
+
+/** @var $product Product */
+$product = $objectManager->create(Product::class);
+$product->isObjectNew(true);
+$product->setTypeId(Type::TYPE_SIMPLE)
+ ->setAttributeSetId(4)
+ ->setWebsiteIds([1])
+ ->setName('Simple Product')
+ ->setSku('tier_prices')
+ ->setPrice(10)
+ ->setWeight(1)
+ ->setShortDescription("Short description")
+ ->setTaxClassId(0)
+ ->setDescription('Description with html tag')
+ ->setMetaTitle('meta title')
+ ->setMetaKeyword('meta keyword')
+ ->setMetaDescription('meta description')
+ ->setVisibility(Visibility::VISIBILITY_BOTH)
+ ->setStatus(Status::STATUS_ENABLED)
+ ->setStockData(
+ [
+ 'use_config_manage_stock' => 1,
+ 'qty' => 100,
+ 'is_qty_decimal' => 0,
+ 'is_in_stock' => 1,
+ ]
+ );
+
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = $objectManager->create(ProductRepositoryInterface::class);
+$productRepository->save($product);
+
+$product->setStoreId($store->getId());
+$product->setPrice(15);
+$productRepository->save($product);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_different_store_prices_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_different_store_prices_rollback.php
new file mode 100644
index 0000000000000..4c4be750e7a5d
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_different_store_prices_rollback.php
@@ -0,0 +1,25 @@
+get(\Magento\Framework\Registry::class);
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+$repository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->
+create(\Magento\Catalog\Model\ProductRepository::class);
+try {
+ $product = $repository->get('tier_prices');
+ $product->delete();
+} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+ //Entity already deleted
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
+
+require __DIR__ . '/../../Store/_files/core_fixturestore_rollback.php';
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php
new file mode 100644
index 0000000000000..a5fad2e96e4a4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php
@@ -0,0 +1,75 @@
+reinitialize();
+
+/** @var \Magento\TestFramework\ObjectManager $objectManager */
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+$tierPrices = [];
+/** @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory */
+$tierPriceFactory = $objectManager->get(\Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class);
+$tierPrices[] = $tierPriceFactory->create(
+ [
+ 'data' => [
+ 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL,
+ 'qty' => 2,
+ 'value' => 8
+ ]
+ ]
+);
+$tierPrices[] = $tierPriceFactory->create(
+ [
+ 'data' => [
+ 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL,
+ 'qty' => 5,
+ 'value' => 5
+ ]
+ ]
+);
+$tierPrices[] = $tierPriceFactory->create(
+ [
+ 'data' => [
+ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID,
+ 'qty' => 3,
+ 'value' => 5
+ ]
+ ]
+);
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
+$product->isObjectNew(true);
+$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
+ ->setAttributeSetId(4)
+ ->setWebsiteIds([1])
+ ->setName('Simple Product')
+ ->setSku('tier_prices')
+ ->setPrice(10)
+ ->setWeight(1)
+ ->setShortDescription("Short description")
+ ->setTaxClassId(0)
+ ->setTierPrices($tierPrices)
+ ->setDescription('Description with html tag')
+ ->setMetaTitle('meta title')
+ ->setMetaKeyword('meta keyword')
+ ->setMetaDescription('meta description')
+ ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
+ ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
+ ->setStockData(
+ [
+ 'use_config_manage_stock' => 1,
+ 'qty' => 100,
+ 'is_qty_decimal' => 0,
+ 'is_in_stock' => 1,
+ ]
+ );
+
+/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepositoryFactory */
+$productRepositoryFactory = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+$productRepositoryFactory->save($product);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_has_tier_price_show_as_low_as_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_has_tier_price_show_as_low_as_rollback.php
new file mode 100644
index 0000000000000..310b5445e9718
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_has_tier_price_show_as_low_as_rollback.php
@@ -0,0 +1,23 @@
+get(\Magento\Framework\Registry::class);
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+$repository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+ ->create(\Magento\Catalog\Model\ProductRepository::class);
+try {
+ $product = $repository->get('tier_prices');
+ $product->delete();
+} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+ //Entity already deleted
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php
index 615c40498c94f..ec28cab76b87a 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php
@@ -7,8 +7,14 @@
use Magento\CatalogImportExport\Model\AbstractProductExportImportTestCase;
+/**
+ * Configurable product import test.
+ */
class ConfigurableTest extends AbstractProductExportImportTestCase
{
+ /**
+ * @return array
+ */
public function exportImportDataProvider()
{
return [
@@ -21,6 +27,15 @@ public function exportImportDataProvider()
],
['_cache_instance_products', '_cache_instance_configurable_attributes'],
],
+ 'configurable-product-12345' => [
+ [
+ 'Magento/ConfigurableProduct/_files/product_configurable_12345.php'
+ ],
+ [
+ '12345',
+ ],
+ ['_cache_instance_products', '_cache_instance_configurable_attributes'],
+ ],
];
}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/Import/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/Import/Product/Type/ConfigurableTest.php
index 8792e95736a34..210369c8ac6af 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/Import/Product/Type/ConfigurableTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/Import/Product/Type/ConfigurableTest.php
@@ -6,21 +6,17 @@
namespace Magento\ConfigurableImportExport\Model\Import\Product\Type;
use Magento\Catalog\Api\ProductRepositoryInterface;
-use Magento\Framework\App\Bootstrap;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\ImportExport\Model\Import;
/**
+ * Product type configurable import test.
+ *
* @magentoAppArea adminhtml
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ConfigurableTest extends \PHPUnit_Framework_TestCase
{
- /**
- * Configurable product test Name
- */
- const TEST_PRODUCT_NAME = 'Configurable 1';
-
/**
* Configurable product test Type
*/
@@ -31,13 +27,6 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
*/
protected $model;
- /**
- * Configurable product options SKU list
- *
- * @var array
- */
- protected $optionSkuList = ['Configurable 1-Option 1', 'Configurable 1-Option 2'];
-
/**
* @var \Magento\Framework\ObjectManagerInterface
*/
@@ -59,13 +48,35 @@ protected function setUp()
}
/**
+ * @return array
+ */
+ public function configurableImportDataProvider()
+ {
+ return [
+ 'Configurable 1' => [
+ __DIR__ . '/../../_files/import_configurable.csv',
+ 'Configurable 1',
+ ['Configurable 1-Option 1', 'Configurable 1-Option 2'],
+ ],
+ '12345' => [
+ __DIR__ . '/../../_files/import_configurable_12345.csv',
+ '12345',
+ ['Configurable 1-Option 1', 'Configurable 1-Option 2'],
+ ],
+ ];
+ }
+
+ /**
+ * @param string $pathToFile Path to import file
+ * @param string $productName Name/sku of configurable product
+ * @param array $optionSkuList Name of variations for configurable product
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
* @magentoAppArea adminhtml
+ * @dataProvider configurableImportDataProvider
*/
- public function testConfigurableImport()
+ public function testConfigurableImport($pathToFile, $productName, $optionSkuList)
{
// import data from CSV file
- $pathToFile = __DIR__ . '/../../_files/import_configurable.csv';
$filesystem = $this->objectManager->create(
\Magento\Framework\Filesystem::class
);
@@ -92,23 +103,23 @@ public function testConfigurableImport()
/** @var \Magento\Catalog\Model\ResourceModel\Product $resource */
$resource = $this->objectManager->get(\Magento\Catalog\Model\ResourceModel\Product::class);
- $productId = $resource->getIdBySku(self::TEST_PRODUCT_NAME);
+ $productId = $resource->getIdBySku($productName);
$this->assertTrue(is_numeric($productId));
/** @var \Magento\Catalog\Model\Product $product */
$product = $this->objectManager->get(ProductRepositoryInterface::class)->getById($productId);
$this->assertFalse($product->isObjectNew());
- $this->assertEquals(self::TEST_PRODUCT_NAME, $product->getName());
+ $this->assertEquals($productName, $product->getName());
$this->assertEquals(self::TEST_PRODUCT_TYPE, $product->getTypeId());
$optionCollection = $product->getTypeInstance()->getConfigurableOptions($product);
foreach ($optionCollection as $option) {
foreach ($option as $optionData) {
- $this->assertContains($optionData['sku'], $this->optionSkuList);
+ $this->assertContains($optionData['sku'], $optionSkuList);
}
}
- $optionIdList = $resource->getProductsIdsBySkus($this->optionSkuList);
+ $optionIdList = $resource->getProductsIdsBySkus($optionSkuList);
foreach ($optionIdList as $optionId) {
$this->assertArrayHasKey($optionId, $product->getExtensionAttributes()->getConfigurableProductLinks());
}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/Import/_files/import_configurable_12345.csv b/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/Import/_files/import_configurable_12345.csv
new file mode 100644
index 0000000000000..02cfb46e920ca
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/Import/_files/import_configurable_12345.csv
@@ -0,0 +1,4 @@
+sku,store_view_code,attribute_set_code,product_type,name,description,short_description,weight,product_online,tax_class_name,visibility,price,url_key,display_product_options_in,map_price,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,configurable_variations,configurable_variation_labels,associated_skus
+Configurable 1-Option 1,,Default,simple,Configurable 1-Option 1,,,,1,Taxable Goods,Not Visible Individually,10,configurable-1-option-1,Block after Info Column,,"attribute_with_option=Option Label,has_options=0,quantity_and_stock_status=In Stock,required_options=0,test_configurable=Option 1",99999,0,0,0,0,1,1,0,0,0,1,,1,1,0,0,1,0,0,0,1,,,
+Configurable 1-Option 2,,Default,simple,Configurable 1-Option 2,,,,1,Taxable Goods,Not Visible Individually,10,configurable-1-option-2,Block after Info Column,,"has_options=0,quantity_and_stock_status=In Stock,required_options=0,test_configurable=Option 2",99999,0,0,0,0,1,1,0,0,0,1,,1,1,0,0,1,0,0,0,1,,,
+12345,,Default,configurable,12345,,,,1,Taxable Goods,"Catalog, Search",10,12345,Block after Info Column,,"has_options=1,quantity_and_stock_status=In Stock,required_options=0",0,0,0,0,0,1,1,0,0,0,1,,1,0,0,0,1,0,0,0,1,"sku=Configurable 1-Option 1,test_configurable=Option 1|sku=Configurable 1-Option 2,test_configurable=Option 2",test_configurable=test_configurable,
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345.php
new file mode 100644
index 0000000000000..d2fd3bd6fccc2
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345.php
@@ -0,0 +1,133 @@
+reinitialize();
+
+require __DIR__ . '/configurable_attribute.php';
+
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = Bootstrap::getObjectManager()
+ ->create(ProductRepositoryInterface::class);
+
+/** @var $installer CategorySetup */
+$installer = Bootstrap::getObjectManager()->create(CategorySetup::class);
+
+/* Create simple products per each option value*/
+/** @var AttributeOptionInterface[] $options */
+$options = $attribute->getOptions();
+
+$attributeValues = [];
+$attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default');
+$associatedProductIds = [];
+$productIds = [30, 40];
+array_shift($options); //remove the first option which is empty
+
+foreach ($options as $option) {
+ /** @var $product Product */
+ $product = Bootstrap::getObjectManager()->create(Product::class);
+ $productId = array_shift($productIds);
+ $product->setTypeId(Type::TYPE_SIMPLE)
+ ->setId($productId)
+ ->setAttributeSetId($attributeSetId)
+ ->setWebsiteIds([1])
+ ->setName('Configurable Option' . $option->getLabel())
+ ->setSku('simple_' . $productId)
+ ->setPrice($productId)
+ ->setTestConfigurable($option->getValue())
+ ->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE)
+ ->setStatus(Status::STATUS_ENABLED)
+ ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]);
+
+ $product = $productRepository->save($product);
+
+ /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */
+ $stockItem = Bootstrap::getObjectManager()->create(\Magento\CatalogInventory\Model\Stock\Item::class);
+ $stockItem->load($productId, 'product_id');
+
+ if (!$stockItem->getProductId()) {
+ $stockItem->setProductId($productId);
+ }
+ $stockItem->setUseConfigManageStock(1);
+ $stockItem->setQty(1000);
+ $stockItem->setIsQtyDecimal(0);
+ $stockItem->setIsInStock(1);
+ $stockItem->save();
+
+ $attributeValues[] = [
+ 'label' => 'test',
+ 'attribute_id' => $attribute->getId(),
+ 'value_index' => $option->getValue(),
+ ];
+ $associatedProductIds[] = $product->getId();
+}
+
+/** @var $product Product */
+$product = Bootstrap::getObjectManager()->create(Product::class);
+
+/** @var Factory $optionsFactory */
+$optionsFactory = Bootstrap::getObjectManager()->create(Factory::class);
+
+$configurableAttributesData = [
+ [
+ 'attribute_id' => $attribute->getId(),
+ 'code' => $attribute->getAttributeCode(),
+ 'label' => $attribute->getStoreLabel(),
+ 'position' => '0',
+ 'values' => $attributeValues,
+ ],
+];
+
+$configurableOptions = $optionsFactory->create($configurableAttributesData);
+
+$extensionConfigurableAttributes = $product->getExtensionAttributes();
+$extensionConfigurableAttributes->setConfigurableProductOptions($configurableOptions);
+$extensionConfigurableAttributes->setConfigurableProductLinks($associatedProductIds);
+
+$product->setExtensionAttributes($extensionConfigurableAttributes);
+
+// Remove any previously created product with the same id.
+/** @var \Magento\Framework\Registry $registry */
+$registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+try {
+ $productToDelete = $productRepository->getById(11);
+ $productRepository->delete($productToDelete);
+
+ /** @var \Magento\Quote\Model\ResourceModel\Quote\Item $itemResource */
+ $itemResource = Bootstrap::getObjectManager()->get(\Magento\Quote\Model\ResourceModel\Quote\Item::class);
+ $itemResource->getConnection()->delete(
+ $itemResource->getMainTable(),
+ 'product_id = ' . $productToDelete->getId()
+ );
+} catch (\Exception $e) {
+ // Nothing to remove
+}
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
+
+$product->setTypeId(Configurable::TYPE_CODE)
+ ->setId(11)
+ ->setAttributeSetId($attributeSetId)
+ ->setWebsiteIds([1])
+ ->setName('Configurable Product 12345')
+ ->setSku('12345')
+ ->setVisibility(Visibility::VISIBILITY_BOTH)
+ ->setStatus(Status::STATUS_ENABLED)
+ ->setStockData(['use_config_manage_stock' => 1, 'is_in_stock' => 1]);
+
+$productRepository->save($product);
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345_rollback.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345_rollback.php
new file mode 100644
index 0000000000000..c40bd7692bbdc
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345_rollback.php
@@ -0,0 +1,35 @@
+get(\Magento\Framework\Registry::class);
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+
+foreach (['simple_30', 'simple_40', '12345'] as $sku) {
+ try {
+ $product = $productRepository->get($sku, false, null, true);
+
+ $stockStatus = $objectManager->create(\Magento\CatalogInventory\Model\Stock\Status::class);
+ $stockStatus->load($product->getEntityId(), 'product_id');
+ $stockStatus->delete();
+
+ $productRepository->delete($product);
+ } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+ //Product already removed
+ }
+}
+
+require __DIR__ . '/configurable_attribute_rollback.php';
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);