diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 21c12bf0a8b1a..75ec58ff90876 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -1317,7 +1317,7 @@ public function saveProductEntity(array $entityRowsIn, array $entityRowsUp)
$select = $this->_connection->select()->from(
$entityTable,
- $this->getNewSkuFieldsForSelect()
+ array_merge($this->getNewSkuFieldsForSelect(), $this->getOldSkuFieldsForSelect())
)->where(
'sku IN (?)',
array_keys($entityRowsIn)
@@ -1330,10 +1330,45 @@ public function saveProductEntity(array $entityRowsIn, array $entityRowsUp)
$this->skuProcessor->setNewSkuData($sku, $key, $value);
}
}
+
+ $this->updateOldSku($newProducts);
}
+
return $this;
}
+ /**
+ * Return additional data, needed to select.
+ * @return array
+ */
+ private function getOldSkuFieldsForSelect()
+ {
+ return ['type_id', 'attribute_set_id'];
+ }
+
+ /**
+ * Adds newly created products to _oldSku
+ * @param array $newProducts
+ * @return void
+ */
+ private function updateOldSku(array $newProducts)
+ {
+ $oldSkus = [];
+ foreach ($newProducts as $info) {
+ $typeId = $info['type_id'];
+ $sku = $info['sku'];
+ $oldSkus[$sku] = [
+ 'type_id' => $typeId,
+ 'attr_set_id' => $info['attribute_set_id'],
+ $this->getProductIdentifierField() => $info[$this->getProductIdentifierField()],
+ 'supported_type' => isset($this->_productTypeModels[$typeId]),
+ $this->getProductEntityLinkField() => $info[$this->getProductEntityLinkField()],
+ ];
+ }
+
+ $this->_oldSku = array_replace($this->_oldSku, $oldSkus);
+ }
+
/**
* Get new SKU fields for select
*
@@ -1718,6 +1753,7 @@ protected function _saveProducts()
['adapter' => $this, 'bunch' => $bunch]
);
}
+
return $this;
}
@@ -2452,6 +2488,7 @@ protected function _saveValidatedBunches()
{
$source = $this->_getSource();
$source->rewind();
+
while ($source->valid()) {
try {
$rowData = $source->current();
@@ -2465,6 +2502,7 @@ protected function _saveValidatedBunches()
$rowData = $this->_customFieldsMapping($rowData);
$this->validateRow($rowData, $source->key());
+
$source->next();
}
$this->checkUrlKeyDuplicates();
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php b/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php
new file mode 100644
index 0000000000000..16a296a355454
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php
@@ -0,0 +1,60 @@
+configurableOptionsProvider = $configurableOptionsProvider;
+ parent::__construct($context, $saleableItem, $price, $rendererPool, $data);
+ }
+
+ /**
+ * Define if the special price should be shown
+ *
+ * @return bool
+ */
+ public function hasSpecialPrice()
+ {
+ $product = $this->getSaleableItem();
+ foreach ($this->configurableOptionsProvider->getProducts($product) as $subProduct) {
+ $regularPrice = $subProduct->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getValue();
+ $finalPrice = $subProduct->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue();
+ if ($finalPrice < $regularPrice) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
new file mode 100644
index 0000000000000..4dbcfed531525
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
@@ -0,0 +1,137 @@
+context = $this->getMockBuilder(\Magento\Framework\View\Element\Template\Context::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->saleableItem = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->price = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class)
+ ->getMockForAbstractClass();
+
+ $this->rendererPool = $this->getMockBuilder(\Magento\Framework\Pricing\Render\RendererPool::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->configurableOptionsProvider = $this->getMockBuilder(ConfigurableOptionsProviderInterface::class)
+ ->getMockForAbstractClass();
+
+ $this->model = new FinalPriceBox(
+ $this->context,
+ $this->saleableItem,
+ $this->price,
+ $this->rendererPool,
+ $this->configurableOptionsProvider
+ );
+ }
+
+ /**
+ * @param float $regularPrice
+ * @param float $finalPrice
+ * @param bool $expected
+ * @dataProvider hasSpecialPriceDataProvider
+ */
+ public function testHasSpecialPrice(
+ $regularPrice,
+ $finalPrice,
+ $expected
+ ) {
+ $priceMockOne = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class)
+ ->getMockForAbstractClass();
+
+ $priceMockOne->expects($this->once())
+ ->method('getValue')
+ ->willReturn($regularPrice);
+
+ $priceMockTwo = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class)
+ ->getMockForAbstractClass();
+
+ $priceMockTwo->expects($this->once())
+ ->method('getValue')
+ ->willReturn($finalPrice);
+
+ $priceInfoMock = $this->getMockBuilder(\Magento\Framework\Pricing\PriceInfo\Base::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $priceInfoMock->expects($this->exactly(2))
+ ->method('getPrice')
+ ->willReturnMap([
+ [RegularPrice::PRICE_CODE, $priceMockOne],
+ [FinalPrice::PRICE_CODE, $priceMockTwo],
+ ]);
+
+ $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class)
+ ->setMethods(['getPriceInfo'])
+ ->getMockForAbstractClass();
+
+ $productMock->expects($this->exactly(2))
+ ->method('getPriceInfo')
+ ->willReturn($priceInfoMock);
+
+ $this->configurableOptionsProvider->expects($this->once())
+ ->method('getProducts')
+ ->with($this->saleableItem)
+ ->willReturn([$productMock]);
+
+ $this->assertEquals($expected, $this->model->hasSpecialPrice());
+ }
+
+ /**
+ * @return array
+ */
+ public function hasSpecialPriceDataProvider()
+ {
+ return [
+ [10., 20., false],
+ [10., 10., false],
+ [20., 10., true],
+ ];
+ }
+}
diff --git a/app/code/Magento/ConfigurableProduct/view/base/layout/catalog_product_prices.xml b/app/code/Magento/ConfigurableProduct/view/base/layout/catalog_product_prices.xml
new file mode 100644
index 0000000000000..47fe31681b5bf
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/view/base/layout/catalog_product_prices.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ -
+
-
+
- Magento\ConfigurableProduct\Pricing\Render\FinalPriceBox
+ - Magento_ConfigurableProduct::product/price/final_price.phtml
+
+
+
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/final_price.phtml b/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/final_price.phtml
new file mode 100644
index 0000000000000..5943b1ea2af5b
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/final_price.phtml
@@ -0,0 +1,60 @@
+
+
+getPriceType('regular_price');
+
+/** @var \Magento\Framework\Pricing\Price\PriceInterface $finalPriceModel */
+$finalPriceModel = $block->getPriceType('final_price');
+$idSuffix = $block->getIdSuffix() ? $block->getIdSuffix() : '';
+$schema = ($block->getZone() == 'item_view') ? true : false;
+?>
+hasSpecialPrice()): ?>
+
+ renderAmount($finalPriceModel->getAmount(), [
+ 'display_label' => __('Special Price'),
+ 'price_id' => $block->getPriceId('product-price-' . $idSuffix),
+ 'price_type' => 'finalPrice',
+ 'include_container' => true,
+ 'schema' => $schema
+ ]); ?>
+
+
+ renderAmount($priceModel->getAmount(), [
+ 'display_label' => __('Regular Price'),
+ 'price_id' => $block->getPriceId('old-price-' . $idSuffix),
+ 'price_type' => 'oldPrice',
+ 'include_container' => true,
+ 'skip_adjustments' => true
+ ]); ?>
+
+
+ renderAmount($finalPriceModel->getAmount(), [
+ 'price_id' => $block->getPriceId('product-price-' . $idSuffix),
+ 'price_type' => 'finalPrice',
+ 'include_container' => true,
+ 'schema' => $schema
+ ]); ?>
+
+
+showMinimalPrice()): ?>
+ getUseLinkForAsLowAs()):?>
+
+ renderAmountMinimal(); ?>
+
+
+
+ renderAmountMinimal(); ?>
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
index bd0314aacf711..7bea20e786201 100644
--- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
+++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
@@ -28,6 +28,7 @@ define([
'<% } %>',
mediaGallerySelector: '[data-gallery-role=gallery-placeholder]',
mediaGalleryInitial: null,
+ slyOldPriceSelector: '.sly-old-price',
onlyMainImg: false
},
@@ -248,6 +249,7 @@ define([
this._resetChildren(element);
}
this._reloadPrice();
+ this._displayRegularPriceBlock(this.simpleProduct);
this._changeProductImage();
},
@@ -444,7 +446,7 @@ define([
},
/**
- * Returns pracies for configured products
+ * Returns prices for configured products
*
* @param {*} config - Products configuration
* @returns {*}
@@ -487,6 +489,23 @@ define([
undefined :
_.first(config.allowedProducts);
+ },
+
+ /**
+ * Show or hide regular price block
+ *
+ * @param {*} optionId
+ * @private
+ */
+ _displayRegularPriceBlock: function (optionId) {
+ if (typeof optionId != 'undefined'
+ && this.options.spConfig.optionPrices[optionId].oldPrice.amount
+ != this.options.spConfig.optionPrices[optionId].finalPrice.amount
+ ) {
+ $(this.options.slyOldPriceSelector).show();
+ } else {
+ $(this.options.slyOldPriceSelector).hide();
+ }
}
});
diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml
index 41ffb74184bad..fdb9c3f317a4c 100644
--- a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml
+++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml
@@ -256,6 +256,10 @@
- Send Welcome Email From
- number
- select
+ - customer
+ -
+
- ${ $.provider }:data.customer.store_id
+
diff --git a/app/code/Magento/Wishlist/Helper/Data.php b/app/code/Magento/Wishlist/Helper/Data.php
index d64d1a185f0a2..736786e6e30b3 100644
--- a/app/code/Magento/Wishlist/Helper/Data.php
+++ b/app/code/Magento/Wishlist/Helper/Data.php
@@ -446,7 +446,13 @@ public function getSharedAddAllToCartUrl()
*/
protected function _getCartUrlParameters($item)
{
- return ['item' => is_string($item) ? $item : $item->getWishlistItemId()];
+ $params = [
+ 'item' => is_string($item) ? $item : $item->getWishlistItemId(),
+ ];
+ if ($item instanceof \Magento\Wishlist\Model\Item) {
+ $params['qty'] = $item->getQty();
+ }
+ return $params;
}
/**
diff --git a/app/code/Magento/Wishlist/Test/Unit/Helper/DataTest.php b/app/code/Magento/Wishlist/Test/Unit/Helper/DataTest.php
index 46054445620ac..ec6e959a3d4ca 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Helper/DataTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Helper/DataTest.php
@@ -124,6 +124,7 @@ protected function setUp()
->setMethods([
'getProduct',
'getWishlistItemId',
+ 'getQty',
])
->getMock();
@@ -217,6 +218,7 @@ public function testGetAddToCartParams()
$url = 'result url';
$storeId = 1;
$wishlistItemId = 1;
+ $wishlistItemQty = 1;
$this->wishlistItem->expects($this->once())
->method('getProduct')
@@ -224,6 +226,9 @@ public function testGetAddToCartParams()
$this->wishlistItem->expects($this->once())
->method('getWishlistItemId')
->willReturn($wishlistItemId);
+ $this->wishlistItem->expects($this->once())
+ ->method('getQty')
+ ->willReturn($wishlistItemQty);
$this->product->expects($this->once())
->method('isVisibleInSiteVisibility')
@@ -243,9 +248,13 @@ public function testGetAddToCartParams()
->with('wishlist/index/cart')
->willReturn($url);
+ $expected = [
+ 'item' => $wishlistItemId,
+ 'qty' => $wishlistItemQty,
+ ];
$this->postDataHelper->expects($this->once())
->method('getPostData')
- ->with($url, ['item' => $wishlistItemId])
+ ->with($url, $expected)
->willReturn($url);
$this->assertEquals($url, $this->model->getAddToCartParams($this->wishlistItem));
@@ -256,6 +265,7 @@ public function testGetAddToCartParamsWithReferer()
$url = 'result url';
$storeId = 1;
$wishlistItemId = 1;
+ $wishlistItemQty = 1;
$referer = 'referer';
$refererEncoded = 'referer_encoded';
@@ -265,6 +275,9 @@ public function testGetAddToCartParamsWithReferer()
$this->wishlistItem->expects($this->once())
->method('getWishlistItemId')
->willReturn($wishlistItemId);
+ $this->wishlistItem->expects($this->once())
+ ->method('getQty')
+ ->willReturn($wishlistItemQty);
$this->product->expects($this->once())
->method('isVisibleInSiteVisibility')
@@ -288,9 +301,14 @@ public function testGetAddToCartParamsWithReferer()
->with('wishlist/index/cart')
->willReturn($url);
+ $expected = [
+ 'item' => $wishlistItemId,
+ ActionInterface::PARAM_NAME_URL_ENCODED => $refererEncoded,
+ 'qty' => $wishlistItemQty,
+ ];
$this->postDataHelper->expects($this->once())
->method('getPostData')
- ->with($url, ['item' => $wishlistItemId, ActionInterface::PARAM_NAME_URL_ENCODED => $refererEncoded])
+ ->with($url, $expected)
->willReturn($url);
$this->assertEquals($url, $this->model->getAddToCartParams($this->wishlistItem, true));
@@ -363,6 +381,7 @@ public function testGetSharedAddToCartUrl()
$url = 'result url';
$storeId = 1;
$wishlistItemId = 1;
+ $wishlistItemQty = 1;
$this->wishlistItem->expects($this->once())
->method('getProduct')
@@ -370,6 +389,9 @@ public function testGetSharedAddToCartUrl()
$this->wishlistItem->expects($this->once())
->method('getWishlistItemId')
->willReturn($wishlistItemId);
+ $this->wishlistItem->expects($this->once())
+ ->method('getQty')
+ ->willReturn($wishlistItemQty);
$this->product->expects($this->once())
->method('isVisibleInSiteVisibility')
@@ -383,9 +405,13 @@ public function testGetSharedAddToCartUrl()
->with('wishlist/shared/cart')
->willReturn($url);
+ $exptected = [
+ 'item' => $wishlistItemId,
+ 'qty' => $wishlistItemQty,
+ ];
$this->postDataHelper->expects($this->once())
->method('getPostData')
- ->with($url, ['item' => $wishlistItemId])
+ ->with($url, $exptected)
->willReturn($url);
$this->assertEquals($url, $this->model->getSharedAddToCartUrl($this->wishlistItem));
diff --git a/app/code/Magento/Wishlist/view/frontend/web/wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/wishlist.js
index a4fdc178c704f..0d6e510e5f5e9 100644
--- a/app/code/Magento/Wishlist/view/frontend/web/wishlist.js
+++ b/app/code/Magento/Wishlist/view/frontend/web/wishlist.js
@@ -47,6 +47,7 @@ define([
event.preventDefault();
$.mage.dataPost().postData($(event.currentTarget).data('post-remove'));
}, this))
+ .on('click', this.options.addToCartSelector, $.proxy(this._beforeAddToCart, this))
.on('click', this.options.addAllToCartSelector, $.proxy(this._addAllWItemsToCart, this))
.on('focusin focusout', this.options.commentInputType, $.proxy(this._focusComment, this));
}
@@ -59,6 +60,27 @@ define([
});
},
+ /**
+ * Process data before add to cart
+ *
+ * - update item's qty value.
+ *
+ * @param {Event} event
+ * @private
+ */
+ _beforeAddToCart: function(event) {
+ var elem = $(event.currentTarget),
+ itemId = elem.data(this.options.dataAttribute),
+ qtyName = $.validator.format(this.options.nameFormat, itemId),
+ qtyValue = elem.parents().find('[name="' + qtyName + '"]').val(),
+ params = elem.data('post');
+
+ if (params) {
+ params.data = $.extend({}, params.data, {'qty': qtyValue});
+ elem.data('post', params);
+ }
+ },
+
/**
* Add wish list items to cart.
* @private
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 593ab70e100ff..42f490d76191a 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
@@ -134,11 +134,11 @@
xpath
- text
+ datepicker
input[name='custom_design_from']
- text
+ datepicker
input[name='custom_design_to']
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 e660b0ea05fab..2ccb804b073f9 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
@@ -413,12 +413,12 @@ protected function prepareWebsites()
{
if (!empty($this->fields['product']['website_ids'])) {
foreach ($this->fixture->getDataFieldConfig('website_ids')['source']->getWebsites() as $key => $website) {
- $this->fields['product']['website_ids'][$key] = $website->getWebsiteId();
+ $this->fields['product']['extension_attributes']['website_ids'][$key] = $website->getWebsiteId();
}
} else {
$website = \Magento\Mtf\ObjectManagerFactory::getObjectManager()
->create(\Magento\Store\Test\Fixture\Website::class, ['dataset' => 'default']);
- $this->fields['product']['website_ids'][] = $website->getWebsiteId();
+ $this->fields['product']['extension_attributes']['website_ids'][] = $website->getWebsiteId();
}
}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Webapi.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Webapi.php
index 4ec372ab7163b..4c3d344832f85 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Webapi.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Webapi.php
@@ -64,13 +64,6 @@ class Webapi extends AbstractWebApi implements CatalogProductSimpleInterface
'custom_attributes'
];
- /**
- * Website Ids for current Product.
- *
- * @var array
- */
- private $websiteIds = [];
-
/**
* @constructor
* @param DataInterface $configuration
@@ -102,8 +95,6 @@ public function persist(FixtureInterface $fixture = null)
$this->prepareData();
$this->convertData();
- //TODO: Change create and assign product to website flow using 1 request after MAGETWO-52812 delivery.
-
/** @var CatalogProductSimple $fixture */
$url = $_ENV['app_frontend_url'] . 'rest/all/V1/products';
$this->webapiTransport->write($url, $this->fields, CurlInterface::POST);
@@ -116,110 +107,9 @@ public function persist(FixtureInterface $fixture = null)
throw new \Exception("Product creation by webapi handler was not successful! Response: {$encodedResponse}");
}
- $this->assignToWebsites($response);
-
return $this->parseResponse($response);
}
- /**
- * Assign appropriate Websites to Product and unset all other.
- *
- * @param array $product
- * @return void
- */
- private function assignToWebsites($product)
- {
- $this->setWebsites($product);
- $this->unsetWebsites($product);
- }
-
- /**
- * Get all Websites.
- *
- * @return array
- * @throws \Exception
- */
- private function getAllWebsites()
- {
- $url = $_ENV['app_frontend_url'] . 'rest/V1/store/websites';
- $this->webapiTransport->write($url, [], CurlInterface::GET);
- $encodedResponse = $this->webapiTransport->read();
- $response = json_decode($encodedResponse, true);
- $this->webapiTransport->close();
-
- if (!isset($response[0]['id'])) {
- $this->eventManager->dispatchEvent(['webapi_failed'], [$response]);
- throw new \Exception(
- "Attempt to get all Websites by webapi handler was not successful! Response: {$encodedResponse}"
- );
- }
-
- return $response;
- }
-
- /**
- * Set appropriate Websites to Product.
- *
- * @param array $product
- * @return void
- * @throws \Exception
- */
- private function setWebsites($product)
- {
- foreach ($this->websiteIds as $id) {
- $url = $_ENV['app_frontend_url'] . 'rest/V1/products/' . $product['sku'] . '/websites';
- $productWebsiteLink = ['productWebsiteLink' => ['website_id' => $id, 'sku' => $product['sku']]];
- $this->webapiTransport->write($url, $productWebsiteLink, CurlInterface::POST);
- $encodedResponse = $this->webapiTransport->read();
- $response = json_decode($encodedResponse, true);
- $this->webapiTransport->close();
-
- if ($response !== true) {
- $this->eventManager->dispatchEvent(['webapi_failed'], [$response]);
- throw new \Exception(
- "Product addition to Website by webapi handler was not successful! Response: {$encodedResponse}"
- );
- }
- }
- }
-
- /**
- * Unset all Websites from Product except appropriate.
- *
- * @param array $product
- * @return void
- * @throws \Exception
- */
- private function unsetWebsites($product)
- {
- $allWebsites = $this->getAllWebsites();
- $websiteIds = [];
-
- foreach ($allWebsites as $website) {
- if ($website['code'] == 'admin') {
- continue;
- }
- $websiteIds[] = $website['id'];
- }
-
- $websiteIds = array_diff($websiteIds, $this->websiteIds);
-
- foreach ($websiteIds as $id) {
- $url = $_ENV['app_frontend_url'] . 'rest/V1/products/' . $product['sku'] . '/websites/' . $id;
- $this->webapiTransport->write($url, [], CurlInterface::DELETE);
- $encodedResponse = $this->webapiTransport->read();
- $response = json_decode($encodedResponse, true);
- $this->webapiTransport->close();
-
- if ($response !== true) {
- $this->eventManager->dispatchEvent(['webapi_failed'], [$response]);
- throw new \Exception(
- "Product deduction from Website by webapi handler was not successful! Response: {$encodedResponse}"
- );
- }
- }
- }
-
/**
* Prepare data for creating product request.
*
@@ -244,7 +134,6 @@ protected function prepareData()
protected function convertData()
{
$fields = [];
- $this->websiteIds = $this->fields['product']['website_ids'];
unset($this->fields['product']['website_ids']);
unset($this->fields['product']['checkout_data']);
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 23c13fb1206df..ecd68593b08cc 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
@@ -1215,7 +1215,9 @@
- taxable_goods
- - Main Website
+ -
+
- default
+
Catalog, Search
simple-product-%isolation%
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
index 402aa6ba0d318..bf5d5944aa3da 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php
@@ -61,6 +61,24 @@ public function prepareData(FixtureInterface $fixture)
return $data;
}
+ /**
+ * Preparation of websites data.
+ *
+ * @return void
+ */
+ protected function prepareWebsites()
+ {
+ if (!empty($this->fields['product']['website_ids'])) {
+ foreach ($this->fixture->getDataFieldConfig('website_ids')['source']->getWebsites() as $key => $website) {
+ $this->fields['product']['website_ids'][$key] = $website->getWebsiteId();
+ }
+ } else {
+ $website = \Magento\Mtf\ObjectManagerFactory::getObjectManager()
+ ->create(\Magento\Store\Test\Fixture\Website::class, ['dataset' => 'default']);
+ $this->fields['product']['website_ids'][] = $website->getWebsiteId();
+ }
+ }
+
/**
* Preparation of attribute set data.
*
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml
index 664f96cd4b42f..bb56a9edaf9a1 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/CustomerForm.xml
@@ -24,6 +24,9 @@
select
+
+ datepicker
+
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml
index 6997cca28fac0..248b26561af3a 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml
@@ -27,7 +27,7 @@
Doe%isolation%
S
JohnDoe%isolation%@example.com
- Mar 16, 2004
+ 03/16/2004
Male
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml
index ac63dcaf2805e..c2132672d900a 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml
@@ -16,7 +16,7 @@
Doe%isolation%
_Suffix%isolation%
JohnDoe%isolation%@example.com
- Aug 1, 1986
+ 08/01/1986
123456789001
Male
@@ -52,7 +52,7 @@
Doe%isolation%
_JaneSuffix%isolation%
Jane%isolation%@example.com
- Dec 1, 2000
+ 01/12/2000
987654321
Female
Prefix%isolation%_
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/Product/Grid.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/Product/Grid.php
new file mode 100644
index 0000000000000..9f7cc54fe88ca
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/Product/Grid.php
@@ -0,0 +1,29 @@
+ [
+ 'selector' => 'input[name="title"]',
+ ],
+ 'sku' => [
+ 'selector' => 'input[name="sku"]',
+ ],
+ ];
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/RatingElement.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/RatingElement.php
index 3ba4369fb0fcc..afadc1b0858ae 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/RatingElement.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit/RatingElement.php
@@ -34,7 +34,7 @@ class RatingElement extends SimpleElement
*
* @var string
*/
- protected $ratingByNumber = './/*[@id="rating_detail"]//*[contains(@class,"field-rating")][%d]';
+ protected $ratingByNumber = './/*[contains(@class,"field-rating")][%d]';
/**
* Set rating value
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Product/Edit/Section/Reviews.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Product/Edit/Section/Reviews.php
index 37ea3df90a89f..5b45f54600ceb 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Product/Edit/Section/Reviews.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Product/Edit/Section/Reviews.php
@@ -23,12 +23,12 @@ class Reviews extends Section
/**
* Returns product reviews grid.
*
- * @return \Magento\Review\Test\Block\Adminhtml\Product\Grid
+ * @return \Magento\Review\Test\Block\Adminhtml\Edit\Product\Grid
*/
public function getReviewsGrid()
{
return $this->blockFactory->create(
- \Magento\Review\Test\Block\Adminhtml\Product\Grid::class,
+ \Magento\Review\Test\Block\Adminhtml\Edit\Product\Grid::class,
['element' => $this->_rootElement->find($this->reviews)]
);
}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Product/Grid.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Product/Grid.php
index 55060e7a85db9..e1aa3b9d5a9a5 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Product/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Product/Grid.php
@@ -6,13 +6,20 @@
namespace Magento\Review\Test\Block\Adminhtml\Product;
-use Magento\Ui\Test\Block\Adminhtml\DataGrid;
+use Magento\Backend\Test\Block\Widget\Grid as AbstractGrid;
/**
* Review catalog product grid.
*/
-class Grid extends DataGrid
+class Grid extends AbstractGrid
{
+ /**
+ * First row selector
+ *
+ * @var string
+ */
+ protected $firstRowSelector = './/tbody/tr[1]';
+
/**
* Grid filter selectors
*
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.xml
index 1832618a7da64..348cd3429149a 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.xml
@@ -20,7 +20,7 @@
textarea
- #detailed_rating
+ #rating_detail
Magento\Review\Test\Block\Adminhtml\Edit\RatingElement
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/ReviewForm.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/ReviewForm.php
index 6bb20785adf91..91ab33e5ca321 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/ReviewForm.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/ReviewForm.php
@@ -37,14 +37,14 @@ class ReviewForm extends AbstractForm
*
* @var string
*/
- protected $rating = './/*[@id="%s_rating_label"]/span';
+ protected $rating = './/*[@id="%s_rating_label"]';
/**
* Selector for label of rating vote.
*
* @var string
*/
- protected $ratingVoteLabel = './div[contains(@class,"vote")]/label[contains(@id,"_%d_label")]';
+ protected $ratingVoteLabel = './following-sibling::div[contains(@class,"vote")]/label[contains(@id,"_%d_label")]';
/**
* Submit review form.
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php
index aeeff3480e4a6..9130c5285848e 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php
@@ -109,13 +109,14 @@ public function test(Review $review)
{
// Precondition:
$product = $review->getDataFieldConfig('entity_id')['source']->getEntity();
- $filter = ['id' => $product->getId()];
+ $filter = ['sku' => $product->getSku()];
$this->review = $review;
// Steps:
$this->reviewIndex->open();
$this->reviewIndex->getReviewActions()->addNew();
- $this->reviewEdit->getProductGrid()->searchAndOpen($filter);
+ $this->reviewEdit->getProductGrid()->search($filter);
+ $this->reviewEdit->getProductGrid()->openFirstRow();
$this->reviewEdit->getReviewForm()->fill($this->review);
$this->reviewEdit->getPageActions()->save();
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
index eae09d72a47b9..3fc6f044f8852 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
@@ -135,7 +135,7 @@ class DataGrid extends Grid
*
* @var string
*/
- protected $sortLink = "//th[contains(@class, '%s')]/span[contains(text(), '%s')]";
+ protected $sortLink = './/div[@data-role="grid-wrapper"]//th[contains(@class, "%s")]/span[contains(text(), "%s")]';
/**
* Current page input.
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
index a1762a065ba88..db5511bf9d8ff 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -14,6 +14,7 @@
*/
namespace Magento\CatalogImportExport\Model\Import;
+use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Category;
use Magento\Framework\App\Bootstrap;
@@ -557,7 +558,7 @@ protected function getOptionValues(\Magento\Catalog\Model\Product\Option $option
/**
* @magentoDataIsolation enabled
* @magentoDataFixture mediaImportImageFixture
- *
+ * @magentoAppIsolation enabled
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testSaveMediaImage()
@@ -732,6 +733,7 @@ public function testInvalidSkuLink()
/**
* @magentoDataFixture Magento/Catalog/_files/products_with_multiselect_attribute.php
* @magentoAppIsolation enabled
+ * @magentoDbIsolation enabled
*/
public function testValidateInvalidMultiselectValues()
{
@@ -1268,4 +1270,62 @@ public function testProductWithUseConfigSettings()
$this->assertEquals($manageStockUseConfig, $stockItem->getUseConfigManageStock());
}
}
+
+ /**
+ * @magentoDataFixture Magento/Store/_files/website.php
+ * @magentoDataFixture Magento/Store/_files/core_fixturestore.php
+ * @magentoDbIsolation enabled
+ * @magentoAppIsolation enabled
+ */
+ public function testProductWithMultipleStoresInDifferentBunches()
+ {
+ $products = [
+ 'simple1',
+ 'simple2',
+ 'simple3'
+ ];
+
+ $importExportData = $this->getMockBuilder(\Magento\ImportExport\Helper\Data::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $importExportData->expects($this->atLeastOnce())
+ ->method('getBunchSize')
+ ->willReturn(1);
+ $this->_model = $this->objectManager->create(
+ \Magento\CatalogImportExport\Model\Import\Product::class,
+ ['importExportData' => $importExportData]
+ );
+
+ $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
+ $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
+ $source = $this->objectManager->create(
+ \Magento\ImportExport\Model\Import\Source\Csv::class,
+ [
+ 'file' => __DIR__ . '/_files/products_to_import_with_multiple_store.csv',
+ 'directory' => $directory
+ ]
+ );
+ $errors = $this->_model->setParameters(
+ ['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
+ )->setSource(
+ $source
+ )->validateData();
+
+ $this->assertTrue($errors->getErrorsCount() == 0);
+
+ $this->_model->importData();
+ $productCollection = $this->objectManager
+ ->create(\Magento\Catalog\Model\ResourceModel\Product\Collection::class);
+ $this->assertCount(3, $productCollection->getItems());
+ $actualProductSkus = array_map(
+ function(ProductInterface $item) {
+ return $item->getSku();
+ },
+ $productCollection->getItems()
+ );
+ $this->assertEquals(
+ $products,
+ array_values($actualProductSkus)
+ );
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_multiple_store.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_multiple_store.csv
new file mode 100644
index 0000000000000..a4ad5adb7b0f4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_multiple_store.csv
@@ -0,0 +1,6 @@
+sku,product_type,store_view_code,name,price,attribute_set_code,categories
+simple1,simple,fixturestore,"simple 1",25,Default,"Default Category/Category 1"
+simple1,simple,,"simple 1",25,Default,"Default Category/Category 1"
+simple2,simple,fixturestore,"simple 2",34,Default,"Default Category/Category 1"
+simple2,simple,,"simple 2",34,Default,"Default Category/Category 1"
+simple3,simple,,"simple 3",58,Default,"Default Category/Category 1"
diff --git a/dev/tests/integration/testsuite/Magento/Theme/Model/Config/ValidatorTest.php b/dev/tests/integration/testsuite/Magento/Theme/Model/Config/ValidatorTest.php
index 16ca335beea7b..bb899fa6af598 100644
--- a/dev/tests/integration/testsuite/Magento/Theme/Model/Config/ValidatorTest.php
+++ b/dev/tests/integration/testsuite/Magento/Theme/Model/Config/ValidatorTest.php
@@ -12,7 +12,7 @@
*/
class ValidatorTest extends \PHPUnit_Framework_TestCase
{
- const TEMPLATE_CODE = 'fixture';
+ const TEMPLATE_CODE = 'email_exception_fixture';
/**
* @var \Magento\Theme\Model\Design\Config\Validator
@@ -44,7 +44,9 @@ protected function setUp()
$this->templateModel = $objectManager->create(\Magento\Email\Model\Template::class);
$this->templateModel->load(self::TEMPLATE_CODE, 'template_code');
-
+ $this->templateFactoryMock->expects($this->once())
+ ->method("create")
+ ->willReturn($this->templateModel);
$this->model = $objectManager->create(
\Magento\Theme\Model\Design\Config\Validator::class,
[ 'templateFactory' => $this->templateFactoryMock ]
@@ -58,9 +60,9 @@ protected function setUp()
*/
public function testValidateHasRecursiveReference()
{
- $this->templateFactoryMock->expects($this->once())
- ->method("create")
- ->willReturn($this->templateModel);
+ if (!$this->templateModel->getId()) {
+ $this->fail('Cannot load Template model');
+ }
$fieldConfig = [
'path' => 'design/email/header_template',
@@ -90,7 +92,7 @@ public function testValidateHasRecursiveReference()
->willReturn([$designElementMock]);
$designElementMock->expects($this->any())->method('getFieldConfig')->willReturn($fieldConfig);
$designElementMock->expects($this->once())->method('getPath')->willReturn($fieldConfig['path']);
- $designElementMock->expects($this->once())->method('getValue')->willReturn(1);
+ $designElementMock->expects($this->once())->method('getValue')->willReturn($this->templateModel->getId());
$this->model->validate($designConfigMock);
}
@@ -132,7 +134,7 @@ public function testValidateNoRecursiveReference()
->willReturn([$designElementMock]);
$designElementMock->expects($this->any())->method('getFieldConfig')->willReturn($fieldConfig);
$designElementMock->expects($this->once())->method('getPath')->willReturn($fieldConfig['path']);
- $designElementMock->expects($this->once())->method('getValue')->willReturn(1);
+ $designElementMock->expects($this->once())->method('getValue')->willReturn($this->templateModel->getId());
$this->model->validate($designConfigMock);
}