From 07a5a0656794107b11001b18a276e58871d69300 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf Date: Tue, 7 Aug 2018 19:05:19 +0300 Subject: [PATCH 01/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Provide store id from product collection to product items --- .../Model/ResourceModel/Product/Collection.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 9b87515450a12..9f865447b8cfc 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -663,6 +663,7 @@ protected function _afterLoad() } $this->_prepareUrlDataObject(); + $this->prepareStoreId(); if (count($this)) { $this->_eventManager->dispatch('catalog_product_collection_load_after', ['collection' => $this]); @@ -671,6 +672,21 @@ protected function _afterLoad() return $this; } + /** + * Add Store ID to products from collection. + * + * @return void + */ + private function prepareStoreId() + { + if ($this->getStoreId() !== null) { + /** @var $item \Magento\Catalog\Model\Product */ + foreach ($this->_items as $item) { + $item->setStoreId($this->getStoreId()); + } + } + } + /** * Prepare Url Data object * From 9cae81a66895a8689c4f3915498b2cf159b50df1 Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan Date: Wed, 15 Aug 2018 18:54:29 +0400 Subject: [PATCH 02/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Add automated test --- .../CreateCartPriceRuleActionGroup.xml | 44 ++++ .../ActionGroup/CreateCustomerActionGroup.xml | 53 +++++ .../CreateNewOredrsActionGroup.xml | 36 +++ .../ActionGroup/CreateProductActionGroup.xml | 55 +++++ .../ActionGroup/CreateWebSiteActionGroup.xml | 67 ++++++ .../DeleteAllProductsActionGroup.xml | 20 ++ .../DeleteCartPriceRuleActionGroup.xml | 26 +++ .../ActionGroup/DeleteCustomerActionGroup.xml | 27 +++ .../ActionGroup/DeleteWebSiteActionGroup.xml | 25 ++ .../SetCatalogConfigurationsActionGroup.xml | 33 +++ .../Catalog/Test/Mftf/Data/TierPriceData.xml | 71 ++++++ .../Section/CreateCartPriceRuleSection.xml | 36 +++ .../Mftf/Section/CreateCustomerSection.xml | 61 +++++ .../Mftf/Section/CreateNewOrdersSection.xml | 29 +++ .../Mftf/Section/CreateProductSection.xml | 45 ++++ .../Mftf/Section/CreateWebSiteSection.xml | 35 +++ .../Mftf/Section/DeleteAllProductsSection.xml | 17 ++ .../SetCatalogConfigurationSection.xml | 28 +++ .../Test/CheckTierPricingOfProductsTest.xml | 216 ++++++++++++++++++ 19 files changed, 924 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCartPriceRuleActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCustomerActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateNewOredrsActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateProductActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateWebSiteActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteAllProductsActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCartPriceRuleActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCustomerActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteWebSiteActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/SetCatalogConfigurationsActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateCartPriceRuleSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateCustomerSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateNewOrdersSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateProductSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateWebSiteSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/DeleteAllProductsSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/SetCatalogConfigurationSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCartPriceRuleActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCartPriceRuleActionGroup.xml new file mode 100644 index 0000000000000..64fa98ed3ba0e --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCartPriceRuleActionGroup.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCustomerActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCustomerActionGroup.xml new file mode 100644 index 0000000000000..cfd0bd9c837f7 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCustomerActionGroup.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateNewOredrsActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateNewOredrsActionGroup.xml new file mode 100644 index 0000000000000..077325f83b98f --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateNewOredrsActionGroup.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateProductActionGroup.xml new file mode 100644 index 0000000000000..05a41b82d1bae --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateProductActionGroup.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateWebSiteActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateWebSiteActionGroup.xml new file mode 100644 index 0000000000000..875156a0f465c --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateWebSiteActionGroup.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteAllProductsActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteAllProductsActionGroup.xml new file mode 100644 index 0000000000000..7c394bd990048 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteAllProductsActionGroup.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCartPriceRuleActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCartPriceRuleActionGroup.xml new file mode 100644 index 0000000000000..93bd1a26e728b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCartPriceRuleActionGroup.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCustomerActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCustomerActionGroup.xml new file mode 100644 index 0000000000000..c1f617b29472f --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCustomerActionGroup.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteWebSiteActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteWebSiteActionGroup.xml new file mode 100644 index 0000000000000..f5bfcc64850ce --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteWebSiteActionGroup.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SetCatalogConfigurationsActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SetCatalogConfigurationsActionGroup.xml new file mode 100644 index 0000000000000..9ce3631fb2b27 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SetCatalogConfigurationsActionGroup.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml new file mode 100644 index 0000000000000..a222c4f09e055 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml @@ -0,0 +1,71 @@ + + + + + + secondWebsite + second + secondStore + second_store + secondStoreView + second_store_view + Retailer + Specific Coupon + ship + For shipment with matching items + Admin Shipping + $0.00 + $110.00 + $55.00 + $165.00 + $100.00 + $220.00 + + + Abgar + Abgaryan + m@m.com + Abgar + Abgaryan + Street + Yerevan + 9999 + 9999 + + + 5105105105105100 + 12 + 20 + 113 + + + prod1 + prod1 + 20 + 100 + + + prod2 + prod2 + 10 + 100 + + + prod3 + prod3 + 30 + 100 + + + prod4 + prod4 + 40 + 100 + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateCartPriceRuleSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateCartPriceRuleSection.xml new file mode 100644 index 0000000000000..78f4329b74c0c --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/CreateCartPriceRuleSection.xml @@ -0,0 +1,36 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateCustomerSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateCustomerSection.xml new file mode 100644 index 0000000000000..07766f2a0d74c --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/CreateCustomerSection.xml @@ -0,0 +1,61 @@ + + + + + +
+ + + + + + +
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + +
+
\ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateNewOrdersSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateNewOrdersSection.xml new file mode 100644 index 0000000000000..97d9e1e14b4ee --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/CreateNewOrdersSection.xml @@ -0,0 +1,29 @@ + + + + +
+ + + + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateProductSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateProductSection.xml new file mode 100644 index 0000000000000..68de458356cd9 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/CreateProductSection.xml @@ -0,0 +1,45 @@ + + + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+
\ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateWebSiteSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateWebSiteSection.xml new file mode 100644 index 0000000000000..06b13555d0491 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/CreateWebSiteSection.xml @@ -0,0 +1,35 @@ + + + + +
+ + + + + + +
+
+ + + + + +
+
+ + + + + + + +
+
\ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/DeleteAllProductsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/DeleteAllProductsSection.xml new file mode 100644 index 0000000000000..92f9fc7a5e452 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/DeleteAllProductsSection.xml @@ -0,0 +1,17 @@ + + + + +
+ + + + +
+
\ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/SetCatalogConfigurationSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/SetCatalogConfigurationSection.xml new file mode 100644 index 0000000000000..781038f66fe25 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/SetCatalogConfigurationSection.xml @@ -0,0 +1,28 @@ + + + + +
+ + + + + + + + + + +
+
+ + + +
+
\ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml new file mode 100644 index 0000000000000..f73b8ed3c01c1 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -0,0 +1,216 @@ + + + + + + + + + + <description value="Checking 'Tier Pricing' of Products and 'Price' (without discount) in the Order of B2B Store View"/> + <testCaseId value="MAGETWO-94111"/> + <severity value="CRITICAL"/> + <group value="Shopping Cart"/> + </annotations> + + <!--Login as admin--> + <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> + <actionGroup ref="GoToAllStores" stepKey="GoToAllStores"/> + <!--Create website, Sore adn Store View--> + <actionGroup ref="CreateWebsite" stepKey="AdminCreateWebsite"> + <argument name="newWebsiteName" value="{{testData.website}}"/> + <argument name="websiteCode" value="{{testData.code}}"/> + </actionGroup> + <actionGroup ref="CreateNewStore" stepKey="AdminCreateStore"> + <argument name="website" value="{{testData.website}}"/> + <argument name="storeGroupName" value="{{testData.store}}"/> + <argument name="storeGroupCode" value="{{testData.storeCode}}"/> + </actionGroup> + <actionGroup ref="CreateStoreView" stepKey="AdminCreateStoreView"> + <argument name="StoreGroup" value="{{testData.store}}"/> + <argument name="storeView" value="{{testData.storeView}}"/> + <argument name="storeViewCode" value="{{testData.storeViewCode}}"/> + </actionGroup> + <!--Set Configuration--> + <actionGroup ref="SetCatalogConfigurations" stepKey="SetCatalogConfigurations"/> + <!--Create 4 products--> + <actionGroup ref="GoToProductPage" stepKey="GoToProductPage1"/> + <actionGroup ref="CreateProduct" stepKey="CreateProduct"/> + <actionGroup ref="GoToProductPage" stepKey="GoToProductPage2"/> + <actionGroup ref="CreateProduct" stepKey="CreateProduct2"> + <argument name="product" value="Product2"/> + </actionGroup> + <actionGroup ref="GoToProductPage" stepKey="GoToProductPage3"/> + <actionGroup ref="CreateProduct" stepKey="CreateProduct3"> + <argument name="product" value="Product3"/> + </actionGroup> + <actionGroup ref="GoToProductPage" stepKey="GoToProductPage4"/> + <actionGroup ref="CreateProduct" stepKey="CreateProduct4"> + <argument name="product" value="Product4"/> + </actionGroup> + <!--Create Cart Price Rule--> + <actionGroup ref="CreateCartPriceRule" stepKey="CreateCartPriceRule"/> + <!--Create customer--> + <actionGroup ref="CreateCustomer" stepKey="CreateCustomer"/> + <!--Create new order--> + <actionGroup ref="CreateNewOrder" stepKey="CreateNewOrder"/> + <!--TEST CASE #1--> + <!--Add 3 products to order with specified quantity--> + <click selector="{{NewOrderSection.selectProduct(Product1.name)}}" stepKey="selectProduct1"/> + <click selector="{{NewOrderSection.selectProduct(Product2.name)}}" stepKey="selectProduct2"/> + <click selector="{{NewOrderSection.selectProduct(Product3.name)}}" stepKey="selectProduct3"/> + <fillField selector="{{NewOrderSection.setQuantity(Product1.name)}}" userInput="10" stepKey="AddProductQuantity1"/> + <fillField selector="{{NewOrderSection.setQuantity(Product2.name)}}" userInput="10" stepKey="AddProductQuantity2"/> + <fillField selector="{{NewOrderSection.setQuantity(Product3.name)}}" userInput="10" stepKey="AddProductQuantity3"/> + <click stepKey="addProductsToOrder" selector="{{NewOrderSection.addProductsToOrder}}"/> + <!--Verify discount and tier price values--> + <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice1"/> + <assertEquals stepKey="verifyPrice1"> + <expectedResult type="string">{{testData.price1}}</expectedResult> + <actualResult type="variable">$checkProductPrice1</actualResult> + </assertEquals> + + <grabTextFrom selector="{{NewOrderSection.productPrice(Product2.name)}}" stepKey="checkProductPrice2"/> + <assertEquals stepKey="verifyPrice2"> + <expectedResult type="string">{{testData.price2}}</expectedResult> + <actualResult type="variable">$checkProductPrice2</actualResult> + </assertEquals> + + <grabTextFrom selector="{{NewOrderSection.productPrice(Product3.name)}}" stepKey="checkProductPrice3"/> + <assertEquals stepKey="verifyPrice3"> + <expectedResult type="string">{{testData.price3}}</expectedResult> + <actualResult type="variable">$checkProductPrice3</actualResult> + </assertEquals> + <!--Edit order and verify values of discount and tier price--> + <actionGroup ref="EditOrder" stepKey="EditOrder"/> + <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice4"/> + <assertEquals stepKey="verifyPrice4"> + <expectedResult type="string">{{testData.price4}}</expectedResult> + <actualResult type="variable">$checkProductPrice4</actualResult> + </assertEquals> + + <grabTextFrom selector="{{NewOrderSection.productPrice(Product2.name)}}" stepKey="checkProductPrice5"/> + <assertEquals stepKey="verifyPrice5"> + <expectedResult type="string">{{testData.price2}}</expectedResult> + <actualResult type="variable">$checkProductPrice5</actualResult> + </assertEquals> + <grabTextFrom selector="{{NewOrderSection.productPrice(Product3.name)}}" stepKey="checkProductPrice6"/> + <assertEquals stepKey="verifyPrice6"> + <expectedResult type="string">{{testData.price3}}</expectedResult> + <actualResult type="variable">$checkProductPrice3</actualResult> + </assertEquals> + + <!--Remove products from order--> + <click selector="{{NewOrderSection.removeItems(Product1.name)}}" stepKey="clickToExpandAction1"/> + <click selector="{{NewOrderSection.removeAction(Product1.name)}}" stepKey="clickToRemove1"/> + <click selector="{{NewOrderSection.removeItems(Product2.name)}}" stepKey="clickToExpandAction2"/> + <click selector="{{NewOrderSection.removeAction(Product2.name)}}" stepKey="clickToRemove2"/> + <click selector="{{NewOrderSection.removeItems(Product3.name)}}" stepKey="clickToExpandAction3"/> + <click selector="{{NewOrderSection.removeAction(Product3.name)}}" stepKey="clickToRemove4"/> + <click selector="{{NewOrderSection.update}}" stepKey="ClickToUpdate"/> + <waitForPageLoad stepKey="WaitProductsDeleted"/> + + <!--TEST CASE #2--> + <!--Add 3 products to order with specified quantity--> + <scrollToTopOfPage stepKey="scrollToTopOfPage"/> + <click stepKey="clickToAddProduct" selector="{{NewOrderSection.addProducts}}"/> + <click selector="{{NewOrderSection.selectProduct(Product1.name)}}" stepKey="selectProduct5"/> + <click selector="{{NewOrderSection.selectProduct(Product2.name)}}" stepKey="selectProduct6"/> + <click selector="{{NewOrderSection.selectProduct(Product3.name)}}" stepKey="selectProduct7"/> + <fillField selector="{{NewOrderSection.setQuantity(Product1.name)}}" userInput="10" stepKey="AddProductQuantity5"/> + <fillField selector="{{NewOrderSection.setQuantity(Product2.name)}}" userInput="10" stepKey="AddProductQuantity6"/> + <fillField selector="{{NewOrderSection.setQuantity(Product3.name)}}" userInput="10" stepKey="AddProductQuantity7"/> + <click stepKey="addProductsToOrder1" selector="{{NewOrderSection.addProductsToOrder}}"/> + <!--Verify discount and tier price values--> + <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice7"/> + <assertEquals stepKey="verifyPrice7"> + <expectedResult type="string">{{testData.price1}}</expectedResult> + <actualResult type="variable">$checkProductPrice7</actualResult> + </assertEquals> + + <grabTextFrom selector="{{NewOrderSection.productPrice(Product2.name)}}" stepKey="checkProductPrice8"/> + <assertEquals stepKey="verifyPrice8"> + <expectedResult type="string">{{testData.price2}}</expectedResult> + <actualResult type="variable">$checkProductPrice8</actualResult> + </assertEquals> + + <grabTextFrom selector="{{NewOrderSection.productPrice(Product3.name)}}" stepKey="checkProductPrice9"/> + <assertEquals stepKey="verifyPrice9"> + <expectedResult type="string">{{testData.price3}}</expectedResult> + <actualResult type="variable">$checkProductPrice9</actualResult> + </assertEquals> + + <!--Add one more product and verify values--> + <click selector="{{NewOrderSection.addProducts}}" stepKey="clickToAddProduct1"/> + <click selector="{{NewOrderSection.selectProduct(Product4.name)}}" stepKey="selectProduct8"/> + <fillField selector="{{NewOrderSection.setQuantity(Product4.name)}}" userInput="10" stepKey="AddProductQuantity9"/> + <click selector="{{NewOrderSection.addProductsToOrder}}" stepKey="addProductsToOrder2"/> + <grabTextFrom selector="{{NewOrderSection.productPrice(Product4.name)}}" stepKey="checkProductPrice10"/> + <assertEquals stepKey="verifyPrice10"> + <expectedResult type="string">{{testData.price5}}</expectedResult> + <actualResult type="variable">$checkProductPrice10</actualResult> + </assertEquals> + + <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice12"/> + <assertEquals stepKey="verifyPrice12"> + <expectedResult type="string">{{testData.price1}}</expectedResult> + <actualResult type="variable">$checkProductPrice12</actualResult> + </assertEquals> + + <grabTextFrom selector="{{NewOrderSection.productPrice(Product2.name)}}" stepKey="checkProductPrice13"/> + <assertEquals stepKey="verifyPrice13"> + <expectedResult type="string">{{testData.price2}}</expectedResult> + <actualResult type="variable">$checkProductPrice13</actualResult> + </assertEquals> + + <grabTextFrom selector="{{NewOrderSection.productPrice(Product3.name)}}" stepKey="checkProductPrice14"/> + <assertEquals stepKey="verifyPrice14"> + <expectedResult type="string">{{testData.price3}}</expectedResult> + <actualResult type="variable">$checkProductPrice14</actualResult> + </assertEquals> + + <click selector="{{NewOrderSection.removeItems(Product1.name)}}" stepKey="clickToExpandAction5"/> + <click selector="{{NewOrderSection.removeAction(Product1.name)}}" stepKey="clickToRemove5"/> + <click selector="{{NewOrderSection.removeItems(Product2.name)}}" stepKey="clickToExpandAction6"/> + <click selector="{{NewOrderSection.removeAction(Product2.name)}}" stepKey="clickToRemove6"/> + <click selector="{{NewOrderSection.removeItems(Product3.name)}}" stepKey="clickToExpandAction7"/> + <click selector="{{NewOrderSection.removeAction(Product3.name)}}" stepKey="clickToRemove7"/> + <click selector="{{NewOrderSection.update}}" stepKey="ClickToUpdate1"/> + + <!--TEST CASE #3--> + <waitForPageLoad stepKey="WaitProductsDeleted1"/> + <scrollToTopOfPage stepKey="scrollToTopOfPage1"/> + <click selector="{{NewOrderSection.addProducts}}" stepKey="clickToAddProduct3" /> + <click selector="{{NewOrderSection.selectProduct(Product1.name)}}" stepKey="selectProduct9"/> + <fillField selector="{{NewOrderSection.setQuantity(Product1.name)}}" userInput="10" stepKey="AddProductQuantity10"/> + <click selector="{{NewOrderSection.addProductsToOrder}}" stepKey="addProductsToOrder3"/> + <fillField selector="{{NewOrderSection.applyCoupon}}" userInput="{{testData.cartCode}}" stepKey="AddCouponCode"/> + <click selector="{{NewOrderSection.update}}" stepKey="ClickToUpdate2"/> + <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice11"/> + <grabTextFrom selector="{{NewOrderSection.productPrice(Product4.name)}}" stepKey="checkProductPrice15"/> + <assertEquals stepKey="verifyPrice11"> + <expectedResult type="string">{{testData.price1}}</expectedResult> + <actualResult type="variable">$checkProductPrice11</actualResult> + </assertEquals> + <assertEquals stepKey="verifyPrice15"> + <expectedResult type="string">{{testData.price5}}</expectedResult> + <actualResult type="variable">$checkProductPrice15</actualResult> + </assertEquals> + + <actionGroup ref="DeleteCartPriceRule" stepKey="DeleteCartPriceRule"/> + <actionGroup ref="GoToAllStores" stepKey="GoToAllStores1"/> + <actionGroup ref="DeleteWebsite" stepKey="DeleteWebsite"> + <argument name="websiteName" value="{{testData.website}}"/> + </actionGroup> + <actionGroup ref="DeleteAllProducts" stepKey="DeleteAllProducts"/> + <actionGroup ref="DeleteCustomer" stepKey="DeleteCustomer"> + <argument name="lastName" value="NewCustomerData.LastName"/> + </actionGroup> + </test> +</tests> From f5b89ea7c4d2b21f0d675b484dc1de06ac8926c6 Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan <lusine_hakobyan@epam.com> Date: Wed, 15 Aug 2018 18:54:29 +0400 Subject: [PATCH 03/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Add automated test --- .../Test/CheckTierPricingOfProductsTest.xml | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml index f73b8ed3c01c1..7ae05337364d6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -69,7 +69,7 @@ <fillField selector="{{NewOrderSection.setQuantity(Product2.name)}}" userInput="10" stepKey="AddProductQuantity2"/> <fillField selector="{{NewOrderSection.setQuantity(Product3.name)}}" userInput="10" stepKey="AddProductQuantity3"/> <click stepKey="addProductsToOrder" selector="{{NewOrderSection.addProductsToOrder}}"/> - <!--Verify discount and tier price values--> + <!--Verify tier price values--> <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice1"/> <assertEquals stepKey="verifyPrice1"> <expectedResult type="string">{{testData.price1}}</expectedResult> @@ -87,7 +87,7 @@ <expectedResult type="string">{{testData.price3}}</expectedResult> <actualResult type="variable">$checkProductPrice3</actualResult> </assertEquals> - <!--Edit order and verify values of discount and tier price--> + <!--Edit order and verify values--> <actionGroup ref="EditOrder" stepKey="EditOrder"/> <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice4"/> <assertEquals stepKey="verifyPrice4"> @@ -127,7 +127,7 @@ <fillField selector="{{NewOrderSection.setQuantity(Product2.name)}}" userInput="10" stepKey="AddProductQuantity6"/> <fillField selector="{{NewOrderSection.setQuantity(Product3.name)}}" userInput="10" stepKey="AddProductQuantity7"/> <click stepKey="addProductsToOrder1" selector="{{NewOrderSection.addProductsToOrder}}"/> - <!--Verify discount and tier price values--> + <!--Verify tier price values--> <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice7"/> <assertEquals stepKey="verifyPrice7"> <expectedResult type="string">{{testData.price1}}</expectedResult> @@ -203,14 +203,16 @@ <actualResult type="variable">$checkProductPrice15</actualResult> </assertEquals> - <actionGroup ref="DeleteCartPriceRule" stepKey="DeleteCartPriceRule"/> - <actionGroup ref="GoToAllStores" stepKey="GoToAllStores1"/> - <actionGroup ref="DeleteWebsite" stepKey="DeleteWebsite"> - <argument name="websiteName" value="{{testData.website}}"/> - </actionGroup> - <actionGroup ref="DeleteAllProducts" stepKey="DeleteAllProducts"/> - <actionGroup ref="DeleteCustomer" stepKey="DeleteCustomer"> - <argument name="lastName" value="NewCustomerData.LastName"/> - </actionGroup> + <after> + <actionGroup ref="DeleteCartPriceRule" stepKey="DeleteCartPriceRule"/> + <actionGroup ref="GoToAllStores" stepKey="GoToAllStores1"/> + <actionGroup ref="DeleteWebsite" stepKey="DeleteWebsite"> + <argument name="websiteName" value="{{testData.website}}"/> + </actionGroup> + <actionGroup ref="DeleteAllProducts" stepKey="DeleteAllProducts"/> + <actionGroup ref="DeleteCustomer" stepKey="DeleteCustomer"> + <argument name="lastName" value="NewCustomerData.LastName"/> + </actionGroup> + </after> </test> </tests> From ba6859898de392102f01631facbc2590481b4271 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 20 Aug 2018 12:56:45 +0300 Subject: [PATCH 04/57] MAGETWO-91540: REST API extension_attributes for configurable products is empty when using search criteria on products - Add extension attributes to product collection - Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface cannot add extension attribute without join and type of array --- .../Catalog/Model/ProductRepository.php | 33 ++++++++++++++++++- .../Test/Unit/Model/ProductRepositoryTest.php | 12 ++++++- .../Api/ProductRepositoryInterfaceTest.php | 18 ++++++---- .../Magento/Catalog/_files/product_simple.php | 7 ++++ 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 4c0122694285d..708a23cb0cee3 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -18,6 +18,7 @@ use Magento\Framework\DB\Adapter\ConnectionException; use Magento\Framework\DB\Adapter\DeadlockException; use Magento\Framework\DB\Adapter\LockWaitException; +use Magento\Framework\EntityManager\Operation\Read\ReadExtensions; use Magento\Framework\Exception\CouldNotSaveException; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\LocalizedException; @@ -151,6 +152,11 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa */ private $serializer; + /** + * @var ReadExtensions + */ + private $readExtensions; + /** * ProductRepository constructor. * @param ProductFactory $productFactory @@ -176,6 +182,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa * @param CollectionProcessorInterface $collectionProcessor [optional] * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer * @param int $cacheLimit [optional] + * @param ReadExtensions|null $readExtensions * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -202,7 +209,8 @@ public function __construct( \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, CollectionProcessorInterface $collectionProcessor = null, \Magento\Framework\Serialize\Serializer\Json $serializer = null, - $cacheLimit = 1000 + $cacheLimit = 1000, + ReadExtensions $readExtensions = null ) { $this->productFactory = $productFactory; $this->collectionFactory = $collectionFactory; @@ -225,6 +233,8 @@ public function __construct( $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Framework\Serialize\Serializer\Json::class); $this->cacheLimit = (int)$cacheLimit; + $this->readExtensions = $readExtensions ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(ReadExtensions::class); } /** @@ -694,6 +704,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr $collection->load(); $collection->addCategoryIds(); + $this->addExtensionAttributes($collection); $searchResult = $this->searchResultsFactory->create(); $searchResult->setSearchCriteria($searchCriteria); $searchResult->setItems($collection->getItems()); @@ -714,6 +725,26 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr return $searchResult; } + /** + * Add extension attributes to loaded items. + * + * @param Collection $collection + * @return Collection + */ + private function addExtensionAttributes(Collection $collection) : Collection + { + $ids = array_keys($collection->getItems()); + if (empty($ids)) { + return $collection; + } + + foreach ($collection->getItems() as $item) { + $this->readExtensions->execute($item); + } + + return $collection; + } + /** * Helper function that adds a FilterGroup to the collection. * diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index 3fc3587637dad..eb404b7d88b56 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -11,6 +11,7 @@ use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\DB\Adapter\ConnectionException; +use Magento\Framework\EntityManager\Operation\Read\ReadExtensions; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Store\Api\Data\StoreInterface; @@ -159,6 +160,11 @@ class ProductRepositoryTest extends \PHPUnit\Framework\TestCase */ private $cacheLimit = 2; + /** + * @var ReadExtensions|\PHPUnit_Framework_MockObject_MockObject + */ + private $readExtensionsMock; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -271,6 +277,8 @@ function ($value) { } ) ); + $this->readExtensionsMock = $this->getMockBuilder(ReadExtensions::class) + ->disableOriginalConstructor()->getMock(); $this->model = $this->objectManager->getObject( \Magento\Catalog\Model\ProductRepository::class, @@ -294,7 +302,8 @@ function ($value) { 'mediaGalleryProcessor' => $this->mediaGalleryProcessor, 'collectionProcessor' => $this->collectionProcessorMock, 'serializer' => $this->serializerMock, - 'cacheLimit' => $this->cacheLimit + 'cacheLimit' => $this->cacheLimit, + 'readExtensions' => $this->readExtensionsMock, ] ); } @@ -747,6 +756,7 @@ public function testGetList() $collectionMock->expects($this->once())->method('load'); $collectionMock->expects($this->once())->method('addCategoryIds'); $collectionMock->expects($this->atLeastOnce())->method('getItems')->willReturn([$this->productMock]); + $this->readExtensionsMock->expects($this->once())->method('execute')->with($this->productMock); $collectionMock->expects($this->once())->method('getSize')->willReturn(128); $searchResultsMock = $this->createMock(\Magento\Catalog\Api\Data\ProductSearchResultsInterface::class); $searchResultsMock->expects($this->once())->method('setSearchCriteria')->with($searchCriteriaMock); diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index e140305db4dcd..1615ee1b63dd9 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -7,18 +7,19 @@ namespace Magento\Catalog\Api; use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Store\Model\Store; use Magento\CatalogInventory\Api\Data\StockItemInterface; -use Magento\Store\Model\Website; -use Magento\Store\Model\WebsiteRepository; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\Framework\Api\ExtensibleDataInterface; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SortOrder; use Magento\Framework\Api\SortOrderBuilder; -use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; +use Magento\Store\Model\Store; +use Magento\Store\Model\Website; +use Magento\Store\Model\WebsiteRepository; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\WebapiAbstract; /** * @magentoAppIsolation enabled @@ -787,6 +788,7 @@ public function testGetList() $this->assertTrue(count($response['items']) > 0); $this->assertNotNull($response['items'][0]['sku']); + $this->assertNotNull($response['items'][0][ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['website_ids']); $this->assertEquals('simple', $response['items'][0]['sku']); $index = null; @@ -845,6 +847,7 @@ public function testGetListWithFilteringByWebsite() $this->assertTrue(count($response['items']) == 1); $this->assertTrue(isset($response['items'][0]['sku'])); $this->assertEquals('simple-2', $response['items'][0]['sku']); + $this->assertNotNull($response['items'][0][ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['website_ids']); } /** @@ -991,6 +994,9 @@ public function testGetListWithMultipleFilterGroupsAndSortingAndPagination() $this->assertEquals(3, $searchResult['total_count']); $this->assertEquals(1, count($searchResult['items'])); $this->assertEquals('search_product_4', $searchResult['items'][0][ProductInterface::SKU]); + $this->assertNotNull( + $searchResult['items'][0][ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['website_ids'] + ); } /** diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index 1c8a4e64cdfdb..82fe2e1f30283 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -5,6 +5,7 @@ */ use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; +use Magento\Catalog\Api\Data\ProductExtensionInterfaceFactory; \Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize(); @@ -19,10 +20,15 @@ $tierPriceFactory = $objectManager->get(\Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class); /** @var $tpExtensionAttributes */ $tpExtensionAttributesFactory = $objectManager->get(ProductTierPriceExtensionFactory::class); +/** @var $productExtensionAttributes */ +$productExtensionAttributesFactory = $objectManager->get(ProductExtensionInterfaceFactory::class); $adminWebsite = $objectManager->get(\Magento\Store\Api\WebsiteRepositoryInterface::class)->get('admin'); $tierPriceExtensionAttributes1 = $tpExtensionAttributesFactory->create() ->setWebsiteId($adminWebsite->getId()); +$productExtensionAttributesWebsiteIds = $productExtensionAttributesFactory->create( + ['website_ids' => $adminWebsite->getId()] +); $tierPrices[] = $tierPriceFactory->create( [ @@ -82,6 +88,7 @@ ->setTaxClassId(0) ->setTierPrices($tierPrices) ->setDescription('Description with <b>html tag</b>') + ->setExtensionAttributes($productExtensionAttributesWebsiteIds) ->setMetaTitle('meta title') ->setMetaKeyword('meta keyword') ->setMetaDescription('meta description') From 9174be3bc2d6f91247a90f4dd89ce4df419d12eb Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Thu, 23 Aug 2018 14:54:24 +0300 Subject: [PATCH 05/57] MAGETWO-91594: Unable to finish import when one product divided between import "bunches" - Changing importData behavior for options and option titles --- .../Model/Import/Product/Option.php | 84 +++++++++++++++++-- 1 file changed, 77 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php index ae29fd2ef4bd4..dcfd817c553e7 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php @@ -333,6 +333,11 @@ class Option extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity */ private $optionTypeTitles; + /** + * @var array + */ + private $lastOptionTitle; + /** * @param \Magento\ImportExport\Model\ResourceModel\Import\Data $importData * @param ResourceConnection $resource @@ -1206,7 +1211,6 @@ private function addFileOptions($result, $optionRow) protected function _importData() { $this->_initProductsSku(); - $nextOptionId = $this->_resourceHelper->getNextAutoincrement($this->_tables['catalog_product_option']); $nextValueId = $this->_resourceHelper->getNextAutoincrement( $this->_tables['catalog_product_option_type_value'] @@ -1225,7 +1229,6 @@ protected function _importData() $parentCount = []; $childCount = []; $optionsToRemove = []; - foreach ($bunch as $rowNumber => $rowData) { if (isset($optionId, $valueId) && empty($rowData[PRODUCT::COL_STORE_VIEW_CODE])) { $nextOptionId = $optionId; @@ -1273,17 +1276,26 @@ protected function _importData() $parentCount, $childCount ); + $this->_collectOptionTitle($combinedData, $prevOptionId, $titles); + $this->checkOptionTitles( + $options, + $titles, + $combinedData, + $prevOptionId, + $optionId, + $products, + $prices + ); } } - $this->removeExistingOptions($products, $optionsToRemove); - $types = [ 'values' => $typeValues, 'prices' => $typePrices, 'titles' => $typeTitles, ]; + $this->setLastOptionTitle($titles); //Save prepared custom options data. $this->savePreparedCustomOptions( $products, @@ -1293,10 +1305,64 @@ protected function _importData() $types ); } - return true; } + /** + * If products were split up between bunches, + * this function will add needed option for option titles + * + * @param array $options + * @param array $titles + * @param array $combinedData + * @param int $prevOptionId + * @param int $optionId + * @param array $products + * @param array $prices + * @return void + */ + private function checkOptionTitles( + array &$options, + array &$titles, + array $combinedData, + int &$prevOptionId, + int &$optionId, + array $products, + array $prices + ) : void { + $titlesCount = count($titles); + if ($titlesCount > 0 && count($options) !== $titlesCount) { + $combinedData[Product::COL_STORE_VIEW_CODE] = ''; + $optionId--; + $option = $this->_collectOptionMainData( + $combinedData, + $prevOptionId, + $optionId, + $products, + $prices + ); + if ($option) { + $options[] = $option; + } + } + } + + /** + * Setting last Custom Option Title + * to use it later in _collectOptionTitle + * to set correct title for default store view + * + * @param array $titles + */ + private function setLastOptionTitle(array &$titles) : void + { + if (count($titles) > 0) { + end($titles); + $key = key($titles); + $this->lastOptionTitle[$key] = $titles[$key]; + } + } + /** * Remove all existing options if import behaviour is APPEND * in other case remove options for products with empty "custom_options" row only. @@ -1447,8 +1513,12 @@ protected function _collectOptionTitle(array $rowData, $prevOptionId, array &$ti $defaultStoreId = Store::DEFAULT_STORE_ID; if (!empty($rowData[self::COLUMN_TITLE])) { if (!isset($titles[$prevOptionId][$defaultStoreId])) { - // ensure default title is set - $titles[$prevOptionId][$defaultStoreId] = $rowData[self::COLUMN_TITLE]; + if (isset($this->lastOptionTitle[$prevOptionId])) { + $titles[$prevOptionId] = $this->lastOptionTitle[$prevOptionId]; + unset($this->lastOptionTitle); + } else { + $titles[$prevOptionId][$defaultStoreId] = $rowData[self::COLUMN_TITLE]; + } } $titles[$prevOptionId][$this->_rowStoreId] = $rowData[self::COLUMN_TITLE]; } From 97d1d283bc3db8426f3e7b94582236ecd1a21cf4 Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Tue, 28 Aug 2018 12:53:44 +0300 Subject: [PATCH 06/57] MAGETWO-91625: Elasticsearch for Chinese produce error - Updated es config --- app/code/Magento/Elasticsearch/etc/esconfig.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/etc/esconfig.xml b/app/code/Magento/Elasticsearch/etc/esconfig.xml index 0a87b58fd3a18..becd2e5852ec1 100644 --- a/app/code/Magento/Elasticsearch/etc/esconfig.xml +++ b/app/code/Magento/Elasticsearch/etc/esconfig.xml @@ -16,7 +16,7 @@ <fr_FR>french</fr_FR> <nl_NL>dutch</nl_NL> <pt_BR>portuguese</pt_BR> - <zh_Hans_CN>cjk</zh_Hans_CN> + <zh_Hans_CN>english</zh_Hans_CN> </stemmer> <stopwords_file> <default>stopwords.csv</default> From 1fec13204da2854529a4ea3ffcb44870ed275e93 Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Wed, 29 Aug 2018 17:59:50 +0300 Subject: [PATCH 07/57] MAGETWO-91625: Elasticsearch for Chinese produce error - Updated es config --- .../Magento/Elasticsearch/etc/esconfig.xml | 2 - .../etc/stopwords/stopwords_zh_Hans_CN.csv | 125 ------------------ 2 files changed, 127 deletions(-) delete mode 100644 app/code/Magento/Elasticsearch/etc/stopwords/stopwords_zh_Hans_CN.csv diff --git a/app/code/Magento/Elasticsearch/etc/esconfig.xml b/app/code/Magento/Elasticsearch/etc/esconfig.xml index becd2e5852ec1..e540251a3c726 100644 --- a/app/code/Magento/Elasticsearch/etc/esconfig.xml +++ b/app/code/Magento/Elasticsearch/etc/esconfig.xml @@ -16,7 +16,6 @@ <fr_FR>french</fr_FR> <nl_NL>dutch</nl_NL> <pt_BR>portuguese</pt_BR> - <zh_Hans_CN>english</zh_Hans_CN> </stemmer> <stopwords_file> <default>stopwords.csv</default> @@ -26,6 +25,5 @@ <fr_FR>stopwords_fr_FR.csv</fr_FR> <nl_NL>stopwords_nl_NL.csv</nl_NL> <pt_BR>stopwords_pt_BR.csv</pt_BR> - <zh_Hans_CN>stopwords_zh_Hans_CN.csv</zh_Hans_CN> </stopwords_file> </config> diff --git a/app/code/Magento/Elasticsearch/etc/stopwords/stopwords_zh_Hans_CN.csv b/app/code/Magento/Elasticsearch/etc/stopwords/stopwords_zh_Hans_CN.csv deleted file mode 100644 index 0b3ef8f89fb35..0000000000000 --- a/app/code/Magento/Elasticsearch/etc/stopwords/stopwords_zh_Hans_CN.csv +++ /dev/null @@ -1,125 +0,0 @@ -的 -一 -不 -在 -人 -有 -是 -为 -以 -于 -上 -他 -而 -后 -之 -来 -及 -了 -因 -下 -可 -到 -由 -这 -与 -也 -此 -但 -并 -个 -其 -已 -无 -小 -我 -们 -起 -最 -再 -今 -去 -好 -只 -又 -或 -很 -亦 -某 -把 -那 -你 -乃 -它 -吧 -被 -比 -别 -趁 -当 -从 -到 -得 -打 -凡 -儿 -尔 -该 -各 -给 -跟 -和 -何 -还 -即 -几 -既 -看 -据 -距 -靠 -啦 -了 -另 -么 -每 -们 -嘛 -拿 -哪 -那 -您 -凭 -且 -却 -让 -仍 -啥 -如 -若 -使 -谁 -虽 -随 -同 -所 -她 -哇 -嗡 -往 -哪 -些 -向 -沿 -哟 -用 -于 -咱 -则 -怎 -曾 -至 -致 -着 -诸 -自 \ No newline at end of file From 999d5f27b00fa07e5e07a3234e174b832f7fa873 Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan <lusine_hakobyan@epam.com> Date: Thu, 30 Aug 2018 14:43:00 +0400 Subject: [PATCH 08/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../ActionGroup/AdminProductActionGroup.xml | 62 ++++ .../CreateCartPriceRuleActionGroup.xml | 44 --- .../ActionGroup/CreateCustomerActionGroup.xml | 53 --- .../CreateNewOredrsActionGroup.xml | 36 -- .../ActionGroup/CreateProductActionGroup.xml | 55 --- .../ActionGroup/CreateWebSiteActionGroup.xml | 67 ---- .../DeleteAllProductsActionGroup.xml | 20 -- .../DeleteCartPriceRuleActionGroup.xml | 26 -- .../ActionGroup/DeleteCustomerActionGroup.xml | 27 -- .../ActionGroup/DeleteWebSiteActionGroup.xml | 25 -- .../SearchForProductOnBackendActionGroup.xml | 6 + .../SetCatalogConfigurationsActionGroup.xml | 33 -- .../Catalog/Test/Mftf/Data/TierPriceData.xml | 64 +--- .../Section/CreateCartPriceRuleSection.xml | 36 -- .../Mftf/Section/CreateCustomerSection.xml | 61 ---- .../Mftf/Section/CreateNewOrdersSection.xml | 29 -- .../Mftf/Section/CreateProductSection.xml | 45 --- .../Mftf/Section/CreateWebSiteSection.xml | 35 -- .../Mftf/Section/DeleteAllProductsSection.xml | 17 - .../SetCatalogConfigurationSection.xml | 28 -- .../Test/CheckTierPricingOfProductsTest.xml | 330 ++++++++++++------ .../CatalogPriceConfigurationActionGroup.xml | 28 ++ .../Test/Mftf/Section/CatalogSection.xml | 6 + ...AdminCustomerAccountInformationSection.xml | 4 + .../Section/AdminCustomerFiltersSection.xml | 1 + .../Test/Mftf/Section/OrdersGridSection.xml | 13 + .../AdminCartPriceRulesFormSection.xml | 4 + 27 files changed, 348 insertions(+), 807 deletions(-) delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCartPriceRuleActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCustomerActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateNewOredrsActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateProductActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateWebSiteActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteAllProductsActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCartPriceRuleActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCustomerActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteWebSiteActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/SetCatalogConfigurationsActionGroup.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateCartPriceRuleSection.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateCustomerSection.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateNewOrdersSection.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateProductSection.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/CreateWebSiteSection.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/DeleteAllProductsSection.xml delete mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/SetCatalogConfigurationSection.xml create mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/CatalogPriceConfigurationActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index bca6ae2b60bf3..37a2a99fa2262 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -173,6 +173,42 @@ <seeInField userInput="{{simpleProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="assertFieldUrlKey"/> </actionGroup> + <actionGroup name="ProductSetWebsite"> + <arguments> + <argument name="website" type="string"/> + </arguments> + <scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ScrollToWebsites"/> + <click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ClickTpOpenProductInWebsite"/> + <waitForPageLoad stepKey="waitForPageOpened"/> + <click selector="{{ProductInWebsitesSection.website(website)}}" stepKey="SelectWebsite"/> + <click selector="{{AdminProductFormAdvancedPricingSection.save}}" stepKey="clickSaveProduct"/> + <waitForPageLoad stepKey="waitForPageOpened1"/> + </actionGroup> + + <actionGroup name="ProductSetAdvancedPricing"> + <arguments> + <argument name="website" type="string" defaultValue=""/> + <argument name="group" type="string" defaultValue="Retailer"/> + <argument name="quantity" type="string" defaultValue="1"/> + <argument name="price" type="string" defaultValue="Discount"/> + <argument name="amount" type="string" defaultValue="45"/> + </arguments> + <click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickOnAdvancedPricingButton"/> + <maximizeWindow stepKey="maximizeWindow"/> + <waitForElement selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="waitForCustomerGroupPriceAddButton"/> + <click selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="addCustomerGroupAllGroupsQty1PriceDiscountAnd10percent"/> + <selectOption selector="{{AdminProductFormAdvancedPricingSection.productTierPriceWebsiteSelect('0')}}" userInput="{{website}}" stepKey="selectProductWebsiteValue"/> + <selectOption selector="{{AdminProductFormAdvancedPricingSection.productTierPriceCustGroupSelect('0')}}" userInput="{{group}}" stepKey="selectProductCustomGroupValue"/> + <fillField selector="{{AdminProductFormAdvancedPricingSection.productTierPriceQtyInput('0')}}" userInput="{{quantity}}" stepKey="fillProductTierPriceQtyInput"/> + <selectOption selector="{{AdminProductFormAdvancedPricingSection.productTierPriceValueTypeSelect('0')}}" userInput="{{price}}" stepKey="selectProductTierPriceValueType"/> + <fillField selector="{{AdminProductFormAdvancedPricingSection.productTierPricePercentageValuePriceInput('0')}}" userInput="{{amount}}" stepKey="selectProductTierPricePriceInput"/> + <click selector="{{AdminProductFormAdvancedPricingSection.doneButton}}" stepKey="clickDoneButton"/> + <waitForPageLoad stepKey="WaitForProductSave"/> + <click selector="{{AdminProductFormAdvancedPricingSection.save}}" stepKey="clickSaveProduct1"/> + <waitForPageLoad stepKey="WaitForProductSave1"/> + <see userInput="You saved the product." stepKey="seeSaveConfirmation"/> + </actionGroup> + <!--Assert text in Related, Up-Sell or Cross-Sell section in Admin Product page--> <actionGroup name="AssertTextInAdminProductRelatedUpSellCrossSellSection"> <arguments> @@ -196,4 +232,30 @@ <click selector="{{AdminProductFormAdvancedPricingSection.doneButton}}" stepKey="clickDone"/> <waitForElementNotVisible selector="{{AdminProductFormAdvancedPricingSection.specialPrice}}" stepKey="waitForCloseModalWindow"/> </actionGroup> + + <!--Select Product In Websites--> + <actionGroup name="SelectProductInWebsitesActionGroup"> + <arguments> + <argument name="website" type="string"/> + </arguments> + <scrollTo selector="{{CreateProductSection.productInWebsite}}" stepKey="ScrollToWebsites"/> + <click selector="{{CreateProductSection.productInWebsite}}" stepKey="ClickTpOpenProductInWebsite"/> + <waitForPageLoad stepKey="waitForPageOpened"/> + <click selector="{{CreateProductSection.isSelected(website)}}" stepKey="SelectWebsite"/> + <click selector="{{CreateProductSection.saveButton}}" stepKey="clickSaveProduct"/> + </actionGroup> + + <!--Switch to New Store view--> + <actionGroup name="SwitchToTheNewStoreView"> + <arguments> + <argument name="storeViewName" type="string"/> + </arguments> + <scrollTo selector="{{AdminProductContentSection.pageHeader}}" stepKey="scrollToUp"/> + <waitForElementVisible selector="{{AdminProductFormActionSection.changeStoreButton}}" stepKey="waitForElementBecomeVisible"/> + <click selector="{{AdminProductFormActionSection.changeStoreButton}}" stepKey="clickStoreviewSwitcher"/> + <click selector="{{AdminProductFormActionSection.selectStoreView(storeViewName)}}" stepKey="chooseStoreView"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="acceptStoreSwitchingMessage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> + </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCartPriceRuleActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCartPriceRuleActionGroup.xml deleted file mode 100644 index 64fa98ed3ba0e..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCartPriceRuleActionGroup.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="CreateCartPriceRule"> - <arguments> - <argument name="name" defaultValue="testData.ruleName"/> - <argument name="website" defaultValue="testData.website"/> - <argument name="customerGroup" defaultValue="testData.customerGroup"/> - <argument name="couponType" defaultValue="testData.couponType"/> - <argument name="shippingType" defaultValue="testData.shippingType"/> - </arguments> - <click selector="{{CartPriceRuleSection.market}}" stepKey="clickOnMarketing"></click> - <waitForPageLoad stepKey="waitForPageMarketingIsLoaded" /> - <click selector="{{CartPriceRuleSection.discount}}" stepKey="CreateDiscountSection" /> - <waitForPageLoad stepKey="waitForPageDiscountAccountIsLoaded"/> - <click selector="{{CartPriceRuleSection.add}}" stepKey="ClickToAddDiscount"/> - <waitForPageLoad stepKey="waitForPageDiscountPageIsLoaded"/> - <fillField selector="{{CartPriceRuleSection.ruleName}}" userInput="{{name}}" stepKey="setRuleName"/> - <click selector="{{CartPriceRuleSection.selectWebSite(website)}}" stepKey="clickToSelectWebsite"/> - <click selector="{{CartPriceRuleSection.customerGroup}}" stepKey="clickToSelectCustomerGroup"/> - <click selector="{{CartPriceRuleSection.customerGroupValue(customerGroup)}}" stepKey="SelectCustomerGroup"/> - <click selector="{{CartPriceRuleSection.coupon}}" stepKey="clickToExpandCoupons"/> - <click selector="{{CartPriceRuleSection.specificCoupon(couponType)}}" stepKey="clickToSelectCoupons"/> - <fillField selector="{{CartPriceRuleSection.code}}" userInput="{{testData.cartCode}}" stepKey="setCode"/> - <fillField selector="{{CartPriceRuleSection.userPerCustomer}}" userInput="0" stepKey="setUserPerCustomer"/> - <fillField selector="{{CartPriceRuleSection.userPerCoupon}}" userInput="0" stepKey="setUserPerCoupon"/> - <fillField selector="{{CartPriceRuleSection.priority}}" userInput="0" stepKey="setPriority"/> - <scrollTo selector="{{CartPriceRuleSection.actions}}" stepKey="ScrollToActions"/> - <conditionalClick selector="{{CartPriceRuleSection.actions}}" dependentSelector="{{CartPriceRuleSection.actionsState}}" visible="true" stepKey="clickToExpandActions"/> - <waitForPageLoad stepKey="waitForActionsLoaded"/> - <click selector="{{CartPriceRuleSection.freeShipping}}" stepKey="clickToSelectShippingMethod"/> - <click selector="{{CartPriceRuleSection.option(shippingType)}}" stepKey="clickToSelectShippingType"/> - <click selector="{{CartPriceRuleSection.save}}" stepKey="clickToSaveCartPriceRule"/> - <waitForPageLoad stepKey="waitForCartPriceRuleSaved"/> - <see userInput="You saved the rule." stepKey="RuleSaved"/> - </actionGroup> - -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCustomerActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCustomerActionGroup.xml deleted file mode 100644 index cfd0bd9c837f7..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateCustomerActionGroup.xml +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="CreateCustomer"> - <arguments> - <argument name="webSite" defaultValue="testData.website"/> - <argument name="storeView" defaultValue="testData.storeView"/> - <argument name="value" defaultValue="testData.customerGroup"/> - </arguments> - <click selector="{{AdminMenuSection.customers}}" stepKey="openCustomers"/> - <waitForPageLoad stepKey="waitForCatalogSubmenu"/> - <click selector="{{CustomersSubmenuSection.allCustomers}}" stepKey="clickOnAllCustomers"/> - <waitForPageLoad stepKey="waitForProductsPage"/> - <click selector="{{CustomersPageSection.addNewCustomerButton}}" stepKey="addNewCustomer"/> - <waitForPageLoad stepKey="waitForNewProductPage"/> - <click selector="{{NewCustomerPageSection.associateToWebsite}}" stepKey="AssociateToWebsite"/> - <click selector="{{NewCustomerPageSection.website(webSite)}}" stepKey="SetWebsite"/> - <click selector="{{NewCustomerPageSection.group}}" stepKey="Group"/> - <click selector="{{NewCustomerPageSection.groupValue(value)}}" stepKey="GroupValue"/> - - <fillField selector="{{NewCustomerPageSection.firstName}}" userInput="{{NewCustomerData.FirstName}}" stepKey="FillFirstName"/> - <fillField selector="{{NewCustomerPageSection.lastName}}" userInput="{{NewCustomerData.LastName}}" stepKey="FillLastName"/> - <fillField selector="{{NewCustomerPageSection.email}}" userInput="{{NewCustomerData.Email}}" stepKey="FillEmail"/> - <click selector="{{NewCustomerPageSection.storeView}}" stepKey="clickToSelectStore"/> - <click selector="{{NewCustomerPageSection.storeViewValue(storeView)}}" stepKey="clickToSelectStoreView"/> - <scrollToTopOfPage stepKey="scrollToAddresses"/> - <click selector="{{NewCustomerPageSection.addresses}}" stepKey="goToAddresses"/> - <waitForPageLoad stepKey="waitForAddresses"/> - <click selector="{{NewCustomerPageSection.addNewAddress}}" stepKey="AddNewAddress"/> - <waitForPageLoad stepKey="waitForAddressFields"/> - <click selector="{{NewCustomerPageSection.defaultBillingAddress}}" stepKey="thickBillingAddress"/> - <click selector="{{NewCustomerPageSection.defaultShippingAddress}}" stepKey="thickShippingAddress"/> - <fillField selector="{{NewCustomerPageSection.firstNameForAddress}}" userInput="{{NewCustomerData.AddressFirstName}}" stepKey="fillFirstNameForAddress"/> - <fillField selector="{{NewCustomerPageSection.lastNameForAddress}}" userInput="{{NewCustomerData.AddressLastName}}" stepKey="fillLastNameForAddress"/> - <fillField selector="{{NewCustomerPageSection.streetAddress}}" userInput="{{NewCustomerData.StreetAddress}}" stepKey="fillStreetAddress"/> - <fillField selector="{{NewCustomerPageSection.city}}" userInput="{{NewCustomerData.City}}" stepKey="fillCity"/> - <click selector="{{NewCustomerPageSection.country}}" stepKey="openCountry"/> - <waitForPageLoad stepKey="waitForCountryList"/> - <click selector="{{NewCustomerPageSection.countryArmenia}}" stepKey="chooseCountry"/> - <fillField selector="{{NewCustomerPageSection.zip}}" userInput="{{NewCustomerData.Zip}}" stepKey="fillZip"/> - <fillField selector="{{NewCustomerPageSection.phoneNumber}}" userInput="{{NewCustomerData.PhoneNumber}}" stepKey="fillPhoneNumber"/> - <waitForPageLoad stepKey="wait"/> - <click selector="{{NewCustomerPageSection.saveCustomer}}" stepKey="save"/> - <waitForPageLoad stepKey="waitForCustomersPage"/> - <waitForElementVisible selector="{{NewCustomerPageSection.createdSuccessMessage}}" stepKey="waitForSuccessfullyCreatedMessage"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateNewOredrsActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateNewOredrsActionGroup.xml deleted file mode 100644 index 077325f83b98f..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateNewOredrsActionGroup.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="CreateNewOrder"> - <arguments> - <argument name="customerName" defaultValue="NewCustomerData.LastName"/> - <argument name="store" defaultValue="testData.storeView"/> - <argument name="product" defaultValue="Product1.name"/> - </arguments> - <click selector="{{AdminMenuSection.sales}}" stepKey="GoToSales"/> - <waitForPageLoad stepKey="WaitForPageSalesOpened"/> - <click selector="{{NewOrderSection.orders}}" stepKey="ClickOnOrders"/> - <click selector="{{NewOrderSection.createNewOrder}}" stepKey="createNewOrder"/> - <waitForPageLoad stepKey="waitForCustomersList" time="3"/> - <click selector="{{NewOrderSection.customerName(customerName)}}" stepKey="chooseCustomer"/> - <waitForPageLoad stepKey="waitForOrderPage"/> - <click selector="{{NewOrderSection.website(store)}}" stepKey="ClickToSelectStore"/> - <waitForPageLoad stepKey="waitForPageOpened"/> - <click selector="{{NewOrderSection.addProducts}}" stepKey="clickToAddProduct"/> - </actionGroup> - - <actionGroup name="EditOrder"> - <arguments> - <argument name="product" defaultValue="Product1.name"/> - </arguments> - <click selector="{{NewOrderSection.customPrice(product)}}" stepKey="ClickOnCustomPrice"/> - <fillField selector="{{NewOrderSection.customQuantity(product)}}" userInput="5" stepKey="ClickOnQuantity"/> - <click selector="{{NewOrderSection.update}}" stepKey="ClickToUpdate"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateProductActionGroup.xml deleted file mode 100644 index 05a41b82d1bae..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateProductActionGroup.xml +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="GoToProductPage"> - <click selector="{{GoToProductPageSection.catalog}}" stepKey="clickOnCatalog" /> - <waitForPageLoad stepKey="waitForPage"/> - <click selector="{{GoToProductPageSection.product}}" stepKey="clickToSelectProductsItem" /> - <waitForPageLoad stepKey="waitForPageProducts"/> - </actionGroup> - - <actionGroup name="CreateProduct"> - <arguments> - <argument name="product" defaultValue="Product1"/> - <argument name="website" defaultValue="testData.website"/> - <argument name="group" type="string" defaultValue="Retailer"/> - <argument name="price" type="string" defaultValue="Discount"/> - </arguments> - <click selector="{{GoToProductPageSection.add}}" stepKey="clickToAddProduct"/> - <waitForPageLoad stepKey="WaitForProductPageIsLoaded"/> - <fillField selector="{{AdminProductFormSection.productName}}" userInput="{{product.name}}" stepKey="setNameForProduct"/> - <fillField selector="{{AdminProductFormSection.productSku}}" userInput="{{product.sku}}" stepKey="setSKUForProduct"/> - <fillField selector="{{AdminProductFormSection.productPrice}}" userInput="{{product.price}}" stepKey="setPriceForProduct"/> - <fillField selector="{{AdminProductFormSection.productQuantity}}" userInput="{{product.quantity}}" stepKey="setQuantityForProduct"/> - <scrollTo selector="{{CreateProductSection.productInWebsite}}" stepKey="ScrollToWebsites"/> - <click selector="{{CreateProductSection.productInWebsite}}" stepKey="ClickTpOpenProductInWebsite"/> - <waitForPageLoad stepKey="waitForPageOpened"/> - <click selector="{{CreateProductSection.isSelected(website)}}" stepKey="SelectWebsite"/> - <click selector="{{CreateProductSection.saveButton}}" stepKey="clickSaveProduct"/> - <scrollToTopOfPage stepKey="ScrollToTop"/> - <click selector="{{CreateProductSection.advancedPricing}}" stepKey="ClickToAdvancedPricing"/> - <maximizeWindow stepKey="maximizeWindow"/> - <click selector="{{CreateProductSection.addPricing}}" stepKey="ClickToAddPricing"/> - <click selector="{{CreateProductSection.selectWebsite}}" stepKey="ClickToSelectWebsite"/> - <click selector="{{CreateProductSection.websiteOption(website)}}" stepKey="ClickToSelectWebsiteOption"/> - <click selector="{{CreateProductSection.selectGroup}}" stepKey="ClickToSelectGroup"/> - <click selector="{{CreateProductSection.groupOption(group)}}" stepKey="ClickToSelectGroupOption"/> - <fillField selector="{{CreateProductSection.setQuantity}}" userInput="1" stepKey="SetQuantity"/> - <click selector="{{CreateProductSection.setPrice}}" stepKey="ClickToSelectPrice"/> - <click selector="{{CreateProductSection.priceOption(price)}}" stepKey="ClickToSelectPriceOption"/> - <click selector="{{CreateProductSection.setPrice}}" stepKey="ClickToSelectPrice1"/> - <fillField selector="{{CreateProductSection.discount}}" userInput="45" stepKey="TypeAmount"/> - <waitForPageLoad stepKey="WaitForPageLoaded"/> - <click selector="{{CreateProductSection.done1}}" stepKey="ClickToFinish"/> - <waitForPageLoad stepKey="WaitForProductSave"/> - <click selector="{{CreateProductSection.saveButton}}" stepKey="clickSaveProduct1"/> - <waitForPageLoad stepKey="WaitForProductSave1"/> - <see userInput="You saved the product." stepKey="seeSaveConfirmation"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateWebSiteActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateWebSiteActionGroup.xml deleted file mode 100644 index 875156a0f465c..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/CreateWebSiteActionGroup.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="GoToAllStores"> - <click stepKey="clickOnStoresFromDashboard" selector="{{CreateWebsite.stores}}"/> - <waitForPageLoad stepKey="waitForPageIsLoaded"/> - <click stepKey="chooseAllStoreItem" selector="{{CreateWebsite.allStores}}"/> - <waitForPageLoad stepKey="waitForStoresPageIsLoaded"/> - </actionGroup> - - <actionGroup name="CreateWebsite"> - <arguments> - <argument name="newWebsiteName" type="string"/> - <argument name="websiteCode" type="string"/> - </arguments> - <click selector="{{CreateWebsite.addWebSite}}" stepKey="clickOnCreateWebsiteButton"/> - <waitForPageLoad stepKey="waitFormToBeOpened"/> - <fillField selector="{{CreateWebsite.name}}" userInput="{{newWebsiteName}}" stepKey="enterWebsiteName" /> - <fillField selector="{{CreateWebsite.code}}" userInput="{{websiteCode}}" stepKey="enterWebsiteCode" /> - <click selector="{{CreateWebsite.save}}" stepKey="clickSaveWebsite" /> - <waitForPageLoad stepKey="WaitForWebsiteSaved"/> - <see userInput="You saved the website." stepKey="seeSavedMessage" /> - </actionGroup> - - <actionGroup name="CreateNewStore"> - <arguments> - <argument name="website" type="string"/> - <argument name="storeGroupName" type="string"/> - <argument name="storeGroupCode" type="string"/> - </arguments> - <click selector="{{CreateStore.create}}" stepKey="clickOnCreateStore"/> - <waitForPageLoad stepKey="waitFormToBeOpened"/> - <selectOption selector="{{CreateStore.storeGrpWebsiteDropdown}}" userInput="{{website}}" stepKey="selectWebsite" /> - <fillField selector="{{CreateStore.storeGrpNameTextField}}" userInput="{{storeGroupName}}" stepKey="enterStoreGroupName" /> - <fillField selector="{{CreateStore.storeGrpCodeTextField}}" userInput="{{storeGroupCode}}" stepKey="enterStoreGroupCode" /> - <selectOption selector="{{CreateStore.storeRootCategoryDropdown}}" userInput="Default Category" stepKey="chooseRootCategory" /> - <click selector="{{CreateWebsite.save}}" stepKey="clickSaveStoreGroup" /> - <waitForPageLoad stepKey="waitForStoreSaved"/> - <see userInput="You saved the store." stepKey="seeSavedMessage" /> - </actionGroup> - - <actionGroup name="CreateStoreView"> - <arguments> - <argument name="StoreGroup" type="string"/> - <argument name="storeView" type="string"/> - <argument name="storeViewCode" type="string"/> - </arguments> - <click selector="{{CreateStoreView.create}}" stepKey="clickOnCreateStoreView"/> - <waitForPageLoad stepKey="waitFormToBeOpened"/> - <selectOption selector="{{CreateStoreView.storeGrpDropdown}}" userInput="{{StoreGroup}}" stepKey="selectStore" /> - <fillField selector="{{CreateStoreView.storeNameTextField}}" userInput="{{storeView}}" stepKey="enterStoreViewName" /> - <fillField selector="{{CreateStoreView.storeCodeTextField}}" userInput="{{storeViewCode}}" stepKey="enterStoreViewCode" /> - <selectOption selector="{{CreateStoreView.statusDropdown}}" userInput="Enabled" stepKey="setStatus" /> - <click selector="{{CreateWebsite.save}}" stepKey="clickSaveStoreView" /> - <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> - <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> - <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> - <waitForPageLoad stepKey="WaitForStoreViewSaved"/> - <see userInput="You saved the store view." stepKey="seeSavedMessage" /> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteAllProductsActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteAllProductsActionGroup.xml deleted file mode 100644 index 7c394bd990048..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteAllProductsActionGroup.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="DeleteAllProducts"> - <click selector="{{GoToProductPageSection.catalog}}" stepKey="clickOnCatalog" /> - <waitForPageLoad stepKey="waitForPage"/> - <click selector="{{GoToProductPageSection.product}}" stepKey="clickToSelectProductsItem" /> - <waitForPageLoad stepKey="waitForPageProducts"/> - <click selector="{{DeleteAllProductsSection.allProducts}}" stepKey="ClickToSelectAllProducts"/> - <click selector="{{DeleteAllProductsSection.actions}}" stepKey="clickToExpandActions"/> - <click selector="{{DeleteAllProductsSection.delete}}" stepKey="clickToDelete"/> - <click selector="{{DeleteAllProductsSection.confirm}}" stepKey="clickToConfirm"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCartPriceRuleActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCartPriceRuleActionGroup.xml deleted file mode 100644 index 93bd1a26e728b..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCartPriceRuleActionGroup.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="DeleteCartPriceRule"> - <arguments> - <argument name="name" defaultValue="testData.ruleName"/> - </arguments> - <click selector="{{CartPriceRuleSection.market}}" stepKey="clickOnMarketing"></click> - <waitForPageLoad stepKey="waitForPageMarketingIsLoaded"/> - <click selector="{{CartPriceRuleSection.discount}}" stepKey="clockToSelectDiscountItem"/> - <waitForPageLoad stepKey="waitForPageDiscountIsLoaded"/> - <click selector="{{CartPriceRuleSection.couponCode(name)}}" stepKey="clickOnDiscount"/> - <waitForPageLoad stepKey="waitForPageDiscountAccountIsLoaded"/> - <click selector="{{CartPriceRuleSection.delete}}" stepKey="ClickToDeleteDiscount"/> - <waitForPageLoad stepKey="waitForDeleteConfirmation"/> - <click selector="{{CartPriceRuleSection.confirm}}" stepKey="clickToConfirm"/> - <waitForPageLoad stepKey="waitToDeleteRule"/> - <see userInput="You deleted the rule." stepKey="RuleIsDeleted"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCustomerActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCustomerActionGroup.xml deleted file mode 100644 index c1f617b29472f..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteCustomerActionGroup.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="DeleteCustomer"> - <arguments> - <argument name="lastName" defaultValue=""/> - </arguments> - <click selector="{{AdminMenuSection.customers}}" stepKey="openCustomers"/> - <waitForPageLoad stepKey="waitForCatalogSubmenu"/> - <click selector="{{CustomersSubmenuSection.allCustomers}}" stepKey="clickOnAllCustomers"/> - <waitForPageLoad stepKey="waitForProductsPage"/> - <click selector="{{CustomersPageSection.customerCheckbox(lastName)}}" stepKey="chooseCustomer"/> - <waitForAjaxLoad stepKey="waitForThick"/> - <click selector="{{CustomersPageSection.actions}}" stepKey="OpenActions"/> - <waitForAjaxLoad stepKey="waitForDelete"/> - <click selector="{{CustomersPageSection.delete}}" stepKey="ChooseDelete"/> - <waitForPageLoad stepKey="waitForDeleteItemPopup"/> - <click selector="{{CustomersPageSection.ok}}" stepKey="clickOnOk"/> - <waitForElementVisible selector="{{CustomersPageSection.deletedSuccessMessage}}" stepKey="waitForSuccessfullyDeletedMessage"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteWebSiteActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteWebSiteActionGroup.xml deleted file mode 100644 index f5bfcc64850ce..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteWebSiteActionGroup.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="DeleteWebsite"> - <arguments> - <argument name="websiteName" type="string"/> - </arguments> - <fillField stepKey="fillSearchWebsiteField" selector="{{AdminStoresGridSection.websiteFilterTextField}}" userInput="{{websiteName}}"/> - <click stepKey="clickSearchButton" selector="{{AdminStoresGridSection.searchButton}}"/> - <see stepKey="verifyThatCorrectWebsiteFound" selector="{{AdminStoresGridSection.websiteNameInFirstRow}}" userInput="{{websiteName}}"/> - <click stepKey="clickEditExistingStoreRow" selector="{{AdminStoresGridSection.websiteNameInFirstRow}}"/> - <waitForPageLoad stepKey="waitForStoreToLoad"/> - <click stepKey="clickDeleteWebsiteButtonOnEditWebsitePage" selector="{{AdminStoresMainActionsSection.deleteButton}}"/> - <selectOption stepKey="setCreateDbBackupToNo" selector="{{AdminStoresDeleteStoreGroupSection.createDbBackup}}" userInput="No"/> - <click stepKey="clickDeleteWebsiteButton" selector="{{AdminStoresDeleteStoreGroupSection.deleteStoreGroupButton}}"/> - <waitForElementVisible stepKey="waitForStoreGridToReload" selector="{{AdminStoresGridSection.websiteFilterTextField}}"/> - <see stepKey="seeSavedMessage" userInput="You deleted the website."/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SearchForProductOnBackendActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SearchForProductOnBackendActionGroup.xml index 5fbc9c5d7fcad..ec97c231f9438 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SearchForProductOnBackendActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SearchForProductOnBackendActionGroup.xml @@ -18,4 +18,10 @@ <fillField userInput="{{product.sku}}" selector="{{AdminProductFiltersSection.skuInput}}" stepKey="fillSkuFieldOnFiltersSection"/> <click selector="{{AdminProductFiltersSection.apply}}" stepKey="clickApplyFiltersButton"/> </actionGroup> + + <actionGroup name="ClearProductsFilterActionGroup"> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad time="30" stepKey="waitForProductsPageToLoad"/> + <conditionalClick selector="{{AdminProductFiltersSection.clearFiltersButton}}" dependentSelector="{{AdminProductFiltersSection.clearFiltersButton}}" visible="true" stepKey="cleanFiltersIfTheySet"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SetCatalogConfigurationsActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SetCatalogConfigurationsActionGroup.xml deleted file mode 100644 index 9ce3631fb2b27..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SetCatalogConfigurationsActionGroup.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="SetCatalogConfigurations"> - <arguments> - <argument name="website" type="string" defaultValue="Website"/> - <argument name="price" type="string" defaultValue="0"/> - </arguments> - <click selector="{{StoreConfigurationsSection.stores}}" stepKey="clickOnCreateWebsiteButton"/> - <waitForPageLoad stepKey="waitForStoresOpened"/> - <click selector="{{StoreConfigurationsSection.config}}" stepKey="clickToOpenConfigurations"/> - <waitForPageLoad stepKey="waitForConfigurationsOpened"/> - <scrollTo selector="{{StoreConfigurationsSection.catalog}}" stepKey="ScrollToCatalog"/> - <click selector="{{StoreConfigurationsSection.catalog}}" stepKey="ClickToCatalog"/> - <click selector="{{StoreConfigurationsSection.subCatalog}}" stepKey="ClickToSubCatalog"/> - <waitForPageLoad stepKey="waitForCatalogOpened"/> - <conditionalClick selector="{{StoreConfigurationsSection.price}}" dependentSelector="{{StoreConfigurationsSection.priceState}}" visible="false" stepKey="ClickToExpandPrice"/> - <waitForPageLoad stepKey="WaitForPriceOpens"/> - <click selector="{{StoreConfigurationsSection.priceScope}}" stepKey="ClickToSetCatalogPriceScope"/> - <click selector="{{StoreConfigurationsSection.priceScopeValue(website)}}" stepKey="ClickToSetCatalogPriceScopeValue"/> - <fillField selector="{{StoreConfigurationsSection.defaultProductPrice}}" userInput="{{price}}" stepKey="SetDefaultPrice"/> - <click selector="{{StoreConfigurationsSection.save}}" stepKey="ClickToSave"/> - <waitForPageLoad stepKey="WaitForWebsiteSaved"/> - <see userInput="You saved the configuration." stepKey="seeSavedMessage" /> - <click selector="{{StoreConfigurationsSection.price}}" stepKey="ClickToCollapsePrise"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml index a222c4f09e055..a563607f633c3 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml @@ -9,63 +9,15 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> <entity name="testData"> - <data key="website">secondWebsite</data> - <data key="code">second</data> - <data key="store">secondStore</data> - <data key="storeCode">second_store</data> - <data key="storeView">secondStoreView</data> - <data key="storeViewCode">second_store_view</data> - <data key="customerGroup">Retailer</data> - <data key="couponType">Specific Coupon</data> - <data key="cartCode">ship</data> - <data key="shippingType">For shipment with matching items</data> - <data key="ruleName">Admin Shipping</data> - <data key="discountValue">$0.00</data> - <data key="price1">$110.00</data> - <data key="price2">$55.00</data> - <data key="price3">$165.00</data> - <data key="price4">$100.00</data> - <data key="price5">$220.00</data> + <data key="goldenPrice1">$676.50</data> + <data key="goldenPrice2">$615.00</data> </entity> - <entity name="NewCustomerData" type="data"> - <data key="FirstName">Abgar</data> - <data key="LastName">Abgaryan</data> - <data key="Email">m@m.com</data> - <data key="AddressFirstName">Abgar</data> - <data key="AddressLastName">Abgaryan</data> - <data key="StreetAddress">Street</data> - <data key="City">Yerevan</data> - <data key="Zip">9999</data> - <data key="PhoneNumber">9999</data> + <entity name="CustomStore"> + <data key="name">secondStore</data> + <data key="code">second_store</data> </entity> - <entity name="PaymentAndShippingInfo" type="data"> - <data key="cardNumber">5105105105105100</data> - <data key="month">12</data> - <data key="year">20</data> - <data key="cvv">113</data> - </entity> - <entity name="Product1" type="product"> - <data key="name">prod1</data> - <data key="sku">prod1</data> - <data key="price">20</data> - <data key="quantity">100</data> - </entity> - <entity name="Product2" type="product"> - <data key="name">prod2</data> - <data key="sku">prod2</data> - <data key="price">10</data> - <data key="quantity">100</data> - </entity> - <entity name="Product3" type="product"> - <data key="name">prod3</data> - <data key="sku">prod3</data> - <data key="price">30</data> - <data key="quantity">100</data> - </entity> - <entity name="Product4" type="product"> - <data key="name">prod4</data> - <data key="sku">prod4</data> - <data key="price">40</data> - <data key="quantity">100</data> + <entity name="customStoreView"> + <data key="name">secondStoreView</data> + <data key="code">second_store_view</data> </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateCartPriceRuleSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateCartPriceRuleSection.xml deleted file mode 100644 index 78f4329b74c0c..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/Section/CreateCartPriceRuleSection.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="CartPriceRuleSection"> - <element name="market" type="button" selector="#menu-magento-backend-marketing"/> - <element name="discount" type="button" selector="//span[contains(text(), 'Cart Price Rules')]"/> - <element name="add" type="button" selector="#add"/> - <element name="ruleName" type="input" selector="//input[@name='name']"/> - <element name="selectWebSite" type="button" selector="//*[contains(text(), '{{arg1}}')]" parameterized="true"/> - <element name="customerGroup" type="button" selector="//select[@name='customer_group_ids']"/> - <element name="customerGroupValue" type="checkbox" selector="//select[@name='customer_group_ids']/option[contains(text(), '{{arg2}}')]" parameterized="true"/> - <element name="done" type="button" selector=".action-secondary"/> - <element name="coupon" type="button" selector="//*[@name='coupon_type']"/> - <element name="specificCoupon" type="button" selector="//*[text()='{{arg3}}']" parameterized="true"/> - <element name="code" type="input" selector="//*[@name='coupon_code']"/> - <element name="userPerCoupon" type="input" selector="//input[@name='uses_per_coupon']"/> - <element name="userPerCustomer" type="input" selector="//input[@name='uses_per_customer']"/> - <element name="priority" type="input" selector="//*[@name='sort_order']"/> - <element name="actions" type="button" selector="//*[text()='Actions']"/> - <element name="actionsState" type="button" selector="//div[@class='admin__fieldset-wrapper-content admin__collapsible-content _hide']/parent::div//span[text()='Actions']"/> - <element name="amount" type="input" selector="//*[@name='discount_amount']"/> - <element name="freeShipping" type="select" selector="//select[@name='simple_free_shipping']"/> - <element name="option" type="select" selector="//select[@name='simple_free_shipping']/option[text()='{{arg4}}']" parameterized="true"/> - <element name="save" type="button" selector="#save"/> - <element name="couponCode" type="button" selector="//td[contains(text(), '{{arg5}}')]" parameterized="true"/> - <element name="delete" type="button" selector="#delete"/> - <element name="confirm" type="button" selector=".action-primary.action-accept"/> - </section> -</sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateCustomerSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateCustomerSection.xml deleted file mode 100644 index 07766f2a0d74c..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/Section/CreateCustomerSection.xml +++ /dev/null @@ -1,61 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - - <section name="CustomersPageSection"> - <element name="addNewCustomerButton" type="button" selector="//*[@id='add']"/> - <element name="customerCheckbox" type="button" selector="//*[contains(text(),'{{args}}')]/parent::td/preceding-sibling::td/label[@class='data-grid-checkbox-cell-inner']" parameterized="true"/> - <element name="actions" type="button" selector="//div[@class='col-xs-2']/div[@class='action-select-wrap']/button[@class='action-select']"/> - <element name="delete" type="button" selector="//*[contains(@class,'admin__data-grid-header-row row row-gutter')]//*[text()='Delete']"/> - <element name="ok" type="button" selector="//button[@data-role='action']//span[text()='OK']"/> - <element name="deletedSuccessMessage" type="button" selector="//*[@class='message message-success success']"/> - </section> - - <section name="CustomersSubmenuSection"> - <element name="allCustomers" type="button" selector="//li[@id='menu-magento-customer-customer']//li[@data-ui-id='menu-magento-customer-customer-manage']"/> - </section> - <section name="NewCustomerPageSection"> - <element name="associateToWebsite" type="select" selector="//select[@name='customer[website_id]']"/> - <element name="website" type="select" selector="//select[contains(@name, 'website_id')]/option[text()='{{arg1}}']" parameterized="true"/> - <element name="group" type="select" selector=".admin__action-multiselect-text"/> - <element name="groupValue" type="select" selector="//option[text()='{{args2}}']" parameterized="true"/> - <element name="firstName" type="input" selector="//input[@name='customer[firstname]']"/> - <element name="lastName" type="input" selector="//input[@name='customer[lastname]']"/> - <element name="email" type="input" selector="//input[@name='customer[email]']"/> - <element name="addresses" type="button" selector="//a[@id='tab_address']"/> - <element name="addNewAddress" type="button" selector="//span[text()='Add New Addresses']"/> - <element name="defaultBillingAddress" type="button" selector="//label[text()='Default Billing Address']"/> - <element name="defaultShippingAddress" type="button" selector="//label[text()='Default Shipping Address']"/> - <element name="firstNameForAddress" type="button" selector="//input[contains(@name, 'address')][contains(@name, 'firstname')]"/> - <element name="lastNameForAddress" type="button" selector="//input[contains(@name, 'address')][contains(@name, 'lastname')]"/> - <element name="streetAddress" type="button" selector="//input[contains(@name, 'street')]"/> - <element name="city" type="input" selector="//input[contains(@name, 'city')]"/> - <element name="country" type="select" selector="//select[contains(@name, 'country_id')]"/> - <element name="countryArmenia" type="select" selector="//select[contains(@name, 'country_id')]//option[@data-title='Armenia']"/> - <element name="zip" type="input" selector="//input[contains(@name, 'postcode')]"/> - <element name="phoneNumber" type="input" selector="//input[contains(@name, 'telephone')]"/> - <element name="saveCustomer" type="button" selector="//button[@title='Save Customer']"/> - <element name="storeView" type="select" selector="//select[@name='customer[sendemail_store_id]']"/> - <element name="storeViewValue" type="select" selector="//select[@name='customer[sendemail_store_id]']/*[contains(text(), '{{args}}')]" parameterized="true"/> - <element name="createdSuccessMessage" type="button" selector="//div[@data-ui-id='messages-message-success']"/> - </section> - <section name="AdminMenuSection"> - <element name="dashboard" type="button" selector="//li[@id='menu-magento-backend-dashboard']"/> - <element name="sales" type="button" selector="//li[@id='menu-magento-sales-sales']"/> - <element name="catalog" type="button" selector="//li[@id='menu-magento-catalog-catalog']"/> - <element name="customers" type="button" selector="//li[@id='menu-magento-customer-customer']"/> - <element name="marketing" type="button" selector="//li[@id='//li[@id='menu-magento-backend-marketing']']"/> - <element name="content" type="button" selector="//li[@id='menu-magento-backend-content']"/> - <element name="reports" type="button" selector="//li[@id='menu-magento-reports-report']"/> - <element name="stores" type="button" selector="//li[@id='menu-magento-backend-stores']"/> - <element name="system" type="button" selector="//li[@id='menu-magento-backend-system']"/> - <element name="findPartners" type="button" selector="//li[@id='menu-magento-marketplace-partners']"/> - </section> -</sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateNewOrdersSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateNewOrdersSection.xml deleted file mode 100644 index 97d9e1e14b4ee..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/Section/CreateNewOrdersSection.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="NewOrderSection"> - <element name="orders" type="button" selector="//li[@data-ui-id='menu-magento-sales-sales-order']//span[text()='Orders']"/> - <element name="createNewOrder" type="button" selector="#add"/> - <element name="customerName" type="button" selector="//td[contains(text(), '{{arg1}}')]" parameterized="true"/> - <element name="website" type="radio" selector="//label[contains(text(), '{{arg2}}')]" parameterized="true"/> - <element name="addProducts" type="button" selector="//span[text()='Add Products']"/> - <element name="selectProduct" type="checkbox" selector="//td[contains(text(), '{{arg3}}')]/following-sibling::td[contains(@class, 'col-select col-in_products')]" parameterized="true"/> - <element name="setQuantity" type="checkbox" selector="//td[contains(text(), '{{arg4}}')]/following-sibling::td[contains(@class, 'col-qty')]/input" parameterized="true"/> - <element name="addProductsToOrder" type="button" selector="//span[text()='Add Selected Product(s) to Order']"/> - <element name="customPrice" type="checkbox" selector="//span[text()='{{arg5}}']/parent::td/following-sibling::td/div//span[contains(text(),'Custom Price')]" parameterized="true"/> - <element name="customQuantity" type="input" selector="//span[text()='{{arg6}}']/parent::td/following-sibling::td[@class='col-qty']/input" parameterized="true"/> - <element name="update" type="button" selector="//span[text()='Update Items and Quantities']"/> - <element name="discount" type="text" selector="//span[text()='{{arg7}}']/parent::td/following-sibling::td[@class='col-discount col-price']/span" parameterized="true"/> - <element name="productPrice" type="text" selector="//span[text()='{{arg8}}']/parent::td/following-sibling::td[@class='col-price col-row-subtotal']/span" parameterized="true"/> - <element name="removeItems" type="select" selector="//span[text()='{{arg9}}']/parent::td/following-sibling::td/select[@class='admin__control-select']" parameterized="true"/> - <element name="removeAction" type="select" selector="//span[text()='{{arg10}}']/parent::td/following-sibling::td/select[@class='admin__control-select']/option[text()='Remove']" parameterized="true"/> - <element name="applyCoupon" type="input" selector="#coupons:code"/> - </section> -</sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateProductSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateProductSection.xml deleted file mode 100644 index 68de458356cd9..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/Section/CreateProductSection.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="GoToProductPageSection"> - <element name="catalog" type="button" selector="#menu-magento-catalog-catalog"/> - <element name="product" type="button" selector="//span[contains(text(), 'Products')]"/> - <element name="add" type="button" selector="#add_new_product-button"/> - </section> - <section name="CreateProductSection"> - <element name="productInWebsite" type="button" selector="//span[text()='Product in Websites']"/> - <element name="website" type="checkbox" selector="//label[text()='{{arg1}}']" parameterized="true"/> - <element name="isSelected" type="checkbox" selector="//label[text()='{{arg2}}']/parent::div/input[@value=0]" parameterized="true"/> - <element name="productInSharedCatalog" type="button" selector="//span[text()='Product In Shared Catalogs']"/> - <element name="sharedCatalog" type="select" selector=".admin__action-multiselect.action-select"/> - <element name="catalogList" type="select" selector="//div[@name='product[shared_catalog]']"/> - <element name="catalog" type="select" selector="//span[text()='{{arg3}}']" parameterized="true"/> - <element name="done" type="button" selector="//button[@class='action-secondary']"/> - <element name="save" type="button" selector="#save-button"/> - <element name="advancedPricing" type="text" selector="//span[text()='Advanced Pricing']"/> - <element name="addPricing" type="button" selector="//span[text()='Add']"/> - <element name="selectWebsite" type="select" selector="//select[@name='product[tier_price][0][website_id]']"/> - <element name="websiteOption" type="select" selector="//select[@name='product[tier_price][0][website_id]']/option[contains(text(), {{arg4}})]" parameterized="true"/> - <element name="selectGroup" type="select" selector="//select[@name='product[tier_price][0][cust_group]']"/> - <element name="groupOption" type="select" selector="//select[@name='product[tier_price][0][cust_group]']/option[text()='{{arg5}}']" parameterized="true"/> - <element name="setQuantity" type="input" selector="//input[@name='product[tier_price][0][price_qty]']"/> - <element name="setPrice" type="select" selector="//select[@name='product[tier_price][0][value_type]']"/> - <element name="priceOption" type="select" selector="//select[@name='product[tier_price][0][value_type]']/option[text()='{{arg6}}']" parameterized="true"/> - <element name="discount" type="input" selector="//div/input[@name='product[tier_price][0][percentage_value]']"/> - <element name="done1" type="button" selector="//aside[7]//button/span[text()='Done']|//aside[6]//button/span[text()='Done']"/> - <element name="saveButton" type="button" selector="#save-button"/> - </section> - <section name="DeleteCreatedProduct"> - <element name="createdProductID" type="select" selector="//*[@id='container']//*[text()='{{arg1}}']/parent::td/parent::tr//label[contains(@class, 'data-grid-checkbox-cell-inner')]" parameterized="true"/> - <element name="actionSelectBox" type="button" selector="//*[@class='admin__data-grid-header-row row row-gutter']//*[text()='Actions']"/> - <element name="deleteButton" type="button" selector="//*[@class='admin__data-grid-header-row row row-gutter']//*[text()='Delete']"/> - <element name="okButton" type="button" selector=".action-primary.action-accept"/> - </section> -</sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/CreateWebSiteSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/CreateWebSiteSection.xml deleted file mode 100644 index 06b13555d0491..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/Section/CreateWebSiteSection.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="CreateWebsite"> - <element name="stores" selector="#menu-magento-backend-stores" type="button"/> - <element name="allStores" selector="//span[contains(text(), 'All Stores')]" type="button"/> - <element name="addWebSite" selector="#add" type="button"/> - <element name="name" selector="#website_name" type="input"/> - <element name="code" selector="#website_code" type="input"/> - <element name="save" selector="#save" type="button"/> - </section> - <section name="CreateStore"> - <element name="create" selector="#add_group" type="button"/> - <element name="storeGrpWebsiteDropdown" selector="#group_website_id" type="select"/> - <element name="storeGrpNameTextField" selector="#group_name" type="input"/> - <element name="storeGrpCodeTextField" selector="#group_code" type="input"/> - <element name="storeRootCategoryDropdown" selector="#group_root_category_id" type="select"/> - </section> - <section name="CreateStoreView"> - <element name="create" selector="#add_store" type="button"/> - <element name="storeNameTextField" selector="#store_name" type="input"/> - <element name="storeCodeTextField" selector="#store_code" type="input"/> - <element name="statusDropdown" selector="#store_is_active" type="select"/> - <element name="storeGrpDropdown" selector="#store_group_id" type="select"/> - <element name="sortOrderTextField" selector="#store_sort_order" type="input"/> - <element name="acceptNewStoreViewCreation" selector=".action-primary.action-accept" type="button"/> - </section> -</sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/DeleteAllProductsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/DeleteAllProductsSection.xml deleted file mode 100644 index 92f9fc7a5e452..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/Section/DeleteAllProductsSection.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="DeleteAllProductsSection"> - <element name="allProducts" type="button" selector="//div[@data-role='grid-wrapper']//button/preceding-sibling::label"/> - <element name="actions" type="button" selector="//div[@class='col-xs-2']//button"/> - <element name="delete" type="button" selector="//div[@class='col-xs-2']//span[text()='Delete']"/> - <element name="confirm" type="button" selector=".action-primary.action-accept"/> - </section> -</sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/SetCatalogConfigurationSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/SetCatalogConfigurationSection.xml deleted file mode 100644 index 781038f66fe25..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/Section/SetCatalogConfigurationSection.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> - <section name="StoreConfigurationsSection"> - <element name="stores" type="button" selector="#menu-magento-backend-stores"/> - <element name="config" type="button" selector="//li[@data-ui-id='menu-magento-config-system-config']//span"/> - <element name="catalog" type="button" selector="//div[contains(@class, 'admin__page-nav-title')]/strong[text()='Catalog']"/> - <element name="subCatalog" type="button" selector="//ul[contains(@class, 'admin__page-nav-items items')]//span[text()='Catalog']"/> - <element name="price" type="button" selector="#catalog_price-head"/> - <element name="priceState" type="button" selector="//a[@id='catalog_price-head' and @class='open']"/> - <element name="priceScope" type="select" selector="#catalog_price_scope"/> - <element name="priceScopeValue" type="select" selector="//select[@id='catalog_price_scope']/option[text()='{{args}}']" parameterized="true"/> - <element name="defaultProductPrice" type="input" selector="#catalog_price_default_product_price"/> - <element name="save" type="button" selector="#save"/> - </section> - <section name="SelectStore"> - <element name="defaultConfig" type="button" selector="#store-change-button"/> - <element name="b2bstore" type="text" selector="//a[contains(text(), '{{args}}')]" parameterized="true"/> - <element name="confirm" type="button" selector=".action-primary.action-accept"/> - </section> -</sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml index 7ae05337364d6..c79b7a0b5a616 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -19,199 +19,301 @@ <group value="Shopping Cart"/> </annotations> + <before> + <createData entity="_defaultCategory" stepKey="category"/> + <createData entity="SimpleProduct" stepKey="product1"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="SimpleProduct" stepKey="product2"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="SimpleProduct" stepKey="product3"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="SimpleProduct" stepKey="product4"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="customer"/> + </before> <!--Login as admin--> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> - <actionGroup ref="GoToAllStores" stepKey="GoToAllStores"/> <!--Create website, Sore adn Store View--> - <actionGroup ref="CreateWebsite" stepKey="AdminCreateWebsite"> - <argument name="newWebsiteName" value="{{testData.website}}"/> - <argument name="websiteCode" value="{{testData.code}}"/> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="AdminCreateWebsite"> + <argument name="newWebsiteName" value="secondWebsite"/> + <argument name="websiteCode" value="second_website"/> </actionGroup> - <actionGroup ref="CreateNewStore" stepKey="AdminCreateStore"> - <argument name="website" value="{{testData.website}}"/> - <argument name="storeGroupName" value="{{testData.store}}"/> - <argument name="storeGroupCode" value="{{testData.storeCode}}"/> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="AdminCreateStore"> + <argument name="website" value="secondWebsite"/> + <argument name="storeGroupName" value="secondStore"/> + <argument name="storeGroupCode" value="second_store"/> </actionGroup> - <actionGroup ref="CreateStoreView" stepKey="AdminCreateStoreView"> - <argument name="StoreGroup" value="{{testData.store}}"/> - <argument name="storeView" value="{{testData.storeView}}"/> - <argument name="storeViewCode" value="{{testData.storeViewCode}}"/> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="AdminCreateStoreView"> + <argument name="StoreGroup" value="CustomStore"/> + <argument name="customStore" value="customStoreView"/> </actionGroup> <!--Set Configuration--> - <actionGroup ref="SetCatalogConfigurations" stepKey="SetCatalogConfigurations"/> - <!--Create 4 products--> - <actionGroup ref="GoToProductPage" stepKey="GoToProductPage1"/> - <actionGroup ref="CreateProduct" stepKey="CreateProduct"/> - <actionGroup ref="GoToProductPage" stepKey="GoToProductPage2"/> - <actionGroup ref="CreateProduct" stepKey="CreateProduct2"> - <argument name="product" value="Product2"/> - </actionGroup> - <actionGroup ref="GoToProductPage" stepKey="GoToProductPage3"/> - <actionGroup ref="CreateProduct" stepKey="CreateProduct3"> - <argument name="product" value="Product3"/> - </actionGroup> - <actionGroup ref="GoToProductPage" stepKey="GoToProductPage4"/> - <actionGroup ref="CreateProduct" stepKey="CreateProduct4"> - <argument name="product" value="Product4"/> + <actionGroup ref="CatalogPriceConfigurations" stepKey="SetCatalogConfigurations"/> + + <!--Set advanced pricing for all 4 products--> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct1"> + <argument name="product" value="$$product1$$"/> + </actionGroup> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct1"> + <argument name="product" value="$$product1$$"/> + </actionGroup> + <actionGroup ref="ProductSetWebsite" stepKey="ProductSetWebsite"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + <actionGroup ref="ProductSetAdvancedPricing" stepKey="ProductSetAdvancedPricing1"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct2"> + <argument name="product" value="$$product2$$"/> + </actionGroup> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct2"> + <argument name="product" value="$$product2$$"/> + </actionGroup> + <actionGroup ref="ProductSetWebsite" stepKey="ProductSetWebsite2"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + <actionGroup ref="ProductSetAdvancedPricing" stepKey="ProductSetAdvancedPricing2"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct3"> + <argument name="product" value="$$product3$$"/> </actionGroup> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct3"> + <argument name="product" value="$$product3$$"/> + </actionGroup> + <actionGroup ref="ProductSetWebsite" stepKey="ProductSetWebsite3"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + <actionGroup ref="ProductSetAdvancedPricing" stepKey="ProductSetAdvancedPricing3"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct4"> + <argument name="product" value="$$product4$$"/> + </actionGroup> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct4"> + <argument name="product" value="$$product4$$"/> + </actionGroup> + <actionGroup ref="ProductSetWebsite" stepKey="ProductSetWebsite4"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + <actionGroup ref="ProductSetAdvancedPricing" stepKey="ProductSetAdvancedPricing4"> + <argument name="website" value="secondWebsite"/> + </actionGroup> + <actionGroup ref="ClearProductsFilterActionGroup" stepKey="ClearProductsFilterActionGroup"/> + + <!--Edit customer info--> + <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="OpenEditCustomerFrom"> + <argument name="customer" value="$$customer$$"/> + </actionGroup> + <click selector="{{AdminCustomerAccountInformationSection.accountInformationButton}}" stepKey="ClickOnAccountInformationSection"/> + <waitForPageLoad stepKey="waitForPageOpened1"/> + <selectOption selector="{{AdminCustomerAccountInformationSection.group}}" userInput="Retailer" stepKey="Group"/> + <selectOption selector="{{AdminCustomerAccountInformationSection.storeView}}" userInput="secondStoreView" stepKey="clickToSelectStore"/> + <click selector="{{AdminCustomerAccountInformationSection.saveCustomer}}" stepKey="save"/> + <waitForPageLoad stepKey="waitForCustomersPage"/> + <see userInput="You saved the customer." stepKey="CustomerIsSaved"/> + + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="navigateToCustomers"/> + <waitForPageLoad stepKey="waitForPageLoad1" /> + <click selector="{{AdminCustomerFiltersSection.clearAll}}" stepKey="ClearFilters"/> + <waitForPageLoad stepKey="waitForFiltersClear"/> + <!--Create Cart Price Rule--> - <actionGroup ref="CreateCartPriceRule" stepKey="CreateCartPriceRule"/> - <!--Create customer--> - <actionGroup ref="CreateCustomer" stepKey="CreateCustomer"/> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForPriceList"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <waitForPageLoad stepKey="waitForPageDiscountPageIsLoaded"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="ship" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="secondWebsite" stepKey="selectWebsites"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" userInput="Retailer" stepKey="selectCustomerGroup"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="ship" stepKey="setCode"/> + <fillField selector="{{AdminCartPriceRulesFormSection.userPerCustomer}}" userInput="0" stepKey="setUserPerCustomer"/> + <fillField selector="{{AdminCartPriceRulesFormSection.userPerCoupon}}" userInput="0" stepKey="setUserPerCoupon"/> + <fillField selector="{{AdminCartPriceRulesFormSection.priority}}" userInput="0" stepKey="setPriority"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.freeShipping}}" userInput="For shipment with matching items" stepKey="selectFreeShippingType"/> + <click selector="{{AdminCartPriceRulesFormSection.saveAndContinue}}" stepKey="clickSaveAndContinueButton"/> + <waitForPageLoad stepKey="waitForCartPriceRuleSaved"/> + <see userInput="You saved the rule." stepKey="RuleSaved"/> + <!--Create new order--> - <actionGroup ref="CreateNewOrder" stepKey="CreateNewOrder"/> + <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="CreateNewOrder"> + <argument name="customer" value="Simple_US_Customer"/> + </actionGroup> + <click selector="{{OrdersGridSection.website('secondStoreView')}}" stepKey="ClickToSelectStore"/> + <waitForPageLoad stepKey="waitForPageOpened"/> + <click selector="{{OrdersGridSection.addProducts}}" stepKey="clickToAddProduct"/> + <waitForPageLoad stepKey="waitForProductsOpened"/> <!--TEST CASE #1--> <!--Add 3 products to order with specified quantity--> - <click selector="{{NewOrderSection.selectProduct(Product1.name)}}" stepKey="selectProduct1"/> - <click selector="{{NewOrderSection.selectProduct(Product2.name)}}" stepKey="selectProduct2"/> - <click selector="{{NewOrderSection.selectProduct(Product3.name)}}" stepKey="selectProduct3"/> - <fillField selector="{{NewOrderSection.setQuantity(Product1.name)}}" userInput="10" stepKey="AddProductQuantity1"/> - <fillField selector="{{NewOrderSection.setQuantity(Product2.name)}}" userInput="10" stepKey="AddProductQuantity2"/> - <fillField selector="{{NewOrderSection.setQuantity(Product3.name)}}" userInput="10" stepKey="AddProductQuantity3"/> - <click stepKey="addProductsToOrder" selector="{{NewOrderSection.addProductsToOrder}}"/> + <click selector="{{OrdersGridSection.selectProduct($$product1.name$$)}}" stepKey="selectProduct1"/> + <fillField selector="{{OrdersGridSection.setQuantity($$product1.name$$)}}" userInput="10" stepKey="AddProductQuantity1"/> + + <click selector="{{OrdersGridSection.selectProduct($$product2.name$$)}}" stepKey="selectProduct2"/> + <fillField selector="{{OrdersGridSection.setQuantity($$product2.name$$)}}" userInput="10" stepKey="AddProductQuantity2"/> + + <click selector="{{OrdersGridSection.selectProduct($$product3.name$$)}}" stepKey="selectProduct3"/> + <fillField selector="{{OrdersGridSection.setQuantity($$product3.name$$)}}" userInput="10" stepKey="AddProductQuantity3"/> + <click stepKey="addProductsToOrder" selector="{{OrdersGridSection.addProductsToOrder}}"/> <!--Verify tier price values--> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice1"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice1"/> <assertEquals stepKey="verifyPrice1"> - <expectedResult type="string">{{testData.price1}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice1</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product2.name)}}" stepKey="checkProductPrice2"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product2.name$$)}}" stepKey="checkProductPrice2"/> <assertEquals stepKey="verifyPrice2"> - <expectedResult type="string">{{testData.price2}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice2</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product3.name)}}" stepKey="checkProductPrice3"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product3.name$$)}}" stepKey="checkProductPrice3"/> <assertEquals stepKey="verifyPrice3"> - <expectedResult type="string">{{testData.price3}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice3</actualResult> </assertEquals> + <!--Edit order and verify values--> - <actionGroup ref="EditOrder" stepKey="EditOrder"/> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice4"/> + <waitForPageLoad stepKey="waitForPgeLoaded2"/> + <click selector="{{OrdersGridSection.customPrice($$product1.name$$)}}" stepKey="ClickOnCustomPrice"/> + <fillField selector="{{OrdersGridSection.customQuantity($$product1.name$$)}}" userInput="5" stepKey="ClickOnQuantity"/> + <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice4"/> <assertEquals stepKey="verifyPrice4"> - <expectedResult type="string">{{testData.price4}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice2}}</expectedResult> <actualResult type="variable">$checkProductPrice4</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product2.name)}}" stepKey="checkProductPrice5"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product2.name$$)}}" stepKey="checkProductPrice5"/> <assertEquals stepKey="verifyPrice5"> - <expectedResult type="string">{{testData.price2}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice5</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product3.name)}}" stepKey="checkProductPrice6"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product3.name$$)}}" stepKey="checkProductPrice6"/> <assertEquals stepKey="verifyPrice6"> - <expectedResult type="string">{{testData.price3}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice3</actualResult> </assertEquals> <!--Remove products from order--> - <click selector="{{NewOrderSection.removeItems(Product1.name)}}" stepKey="clickToExpandAction1"/> - <click selector="{{NewOrderSection.removeAction(Product1.name)}}" stepKey="clickToRemove1"/> - <click selector="{{NewOrderSection.removeItems(Product2.name)}}" stepKey="clickToExpandAction2"/> - <click selector="{{NewOrderSection.removeAction(Product2.name)}}" stepKey="clickToRemove2"/> - <click selector="{{NewOrderSection.removeItems(Product3.name)}}" stepKey="clickToExpandAction3"/> - <click selector="{{NewOrderSection.removeAction(Product3.name)}}" stepKey="clickToRemove4"/> - <click selector="{{NewOrderSection.update}}" stepKey="ClickToUpdate"/> + <selectOption selector="{{OrdersGridSection.removeItems($$product1.name$$)}}" userInput="Remove" stepKey="clickToRemove1"/> + <selectOption selector="{{OrdersGridSection.removeItems($$product2.name$$)}}" userInput="Remove" stepKey="clickToRemove2"/> + <selectOption selector="{{OrdersGridSection.removeItems($$product3.name$$)}}" userInput="Remove" stepKey="clickToRemove3"/> + + <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate1"/> <waitForPageLoad stepKey="WaitProductsDeleted"/> <!--TEST CASE #2--> <!--Add 3 products to order with specified quantity--> <scrollToTopOfPage stepKey="scrollToTopOfPage"/> - <click stepKey="clickToAddProduct" selector="{{NewOrderSection.addProducts}}"/> - <click selector="{{NewOrderSection.selectProduct(Product1.name)}}" stepKey="selectProduct5"/> - <click selector="{{NewOrderSection.selectProduct(Product2.name)}}" stepKey="selectProduct6"/> - <click selector="{{NewOrderSection.selectProduct(Product3.name)}}" stepKey="selectProduct7"/> - <fillField selector="{{NewOrderSection.setQuantity(Product1.name)}}" userInput="10" stepKey="AddProductQuantity5"/> - <fillField selector="{{NewOrderSection.setQuantity(Product2.name)}}" userInput="10" stepKey="AddProductQuantity6"/> - <fillField selector="{{NewOrderSection.setQuantity(Product3.name)}}" userInput="10" stepKey="AddProductQuantity7"/> - <click stepKey="addProductsToOrder1" selector="{{NewOrderSection.addProductsToOrder}}"/> + <click stepKey="clickToAddProduct1" selector="{{OrdersGridSection.addProducts}}"/> + <click selector="{{OrdersGridSection.selectProduct($$product1.name$$)}}" stepKey="selectProduct5"/> + <fillField selector="{{OrdersGridSection.setQuantity($$product1.name$$)}}" userInput="10" stepKey="AddProductQuantity5"/> + + <click selector="{{OrdersGridSection.selectProduct($$product2.name$$)}}" stepKey="selectProduct6"/> + <fillField selector="{{OrdersGridSection.setQuantity($$product2.name$$)}}" userInput="10" stepKey="AddProductQuantity6"/> + + <click selector="{{OrdersGridSection.selectProduct($$product3.name$$)}}" stepKey="selectProduct7"/> + <fillField selector="{{OrdersGridSection.setQuantity($$product3.name$$)}}" userInput="10" stepKey="AddProductQuantity7"/> + <click stepKey="addProductsToOrder1" selector="{{OrdersGridSection.addProductsToOrder}}"/> <!--Verify tier price values--> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice7"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice7"/> <assertEquals stepKey="verifyPrice7"> - <expectedResult type="string">{{testData.price1}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice7</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product2.name)}}" stepKey="checkProductPrice8"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product2.name$$)}}" stepKey="checkProductPrice8"/> <assertEquals stepKey="verifyPrice8"> - <expectedResult type="string">{{testData.price2}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice8</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product3.name)}}" stepKey="checkProductPrice9"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product3.name$$)}}" stepKey="checkProductPrice9"/> <assertEquals stepKey="verifyPrice9"> - <expectedResult type="string">{{testData.price3}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice9</actualResult> </assertEquals> <!--Add one more product and verify values--> - <click selector="{{NewOrderSection.addProducts}}" stepKey="clickToAddProduct1"/> - <click selector="{{NewOrderSection.selectProduct(Product4.name)}}" stepKey="selectProduct8"/> - <fillField selector="{{NewOrderSection.setQuantity(Product4.name)}}" userInput="10" stepKey="AddProductQuantity9"/> - <click selector="{{NewOrderSection.addProductsToOrder}}" stepKey="addProductsToOrder2"/> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product4.name)}}" stepKey="checkProductPrice10"/> + <waitForPageLoad stepKey="waitForPgeLoaded3"/> + <click selector="{{OrdersGridSection.addProducts}}" stepKey="clickToAddProduct2"/> + <click selector="{{OrdersGridSection.selectProduct($$product4.name$$)}}" stepKey="selectProduct8"/> + <fillField selector="{{OrdersGridSection.setQuantity($$product4.name$$)}}" userInput="10" stepKey="AddProductQuantity9"/> + <click selector="{{OrdersGridSection.addProductsToOrder}}" stepKey="addProductsToOrder2"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product4.name$$)}}" stepKey="checkProductPrice10"/> <assertEquals stepKey="verifyPrice10"> - <expectedResult type="string">{{testData.price5}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice10</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice12"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice11"/> + <assertEquals stepKey="verifyPrice11"> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <actualResult type="variable">$checkProductPrice11</actualResult> + </assertEquals> + + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product2.name$$)}}" stepKey="checkProductPrice12"/> <assertEquals stepKey="verifyPrice12"> - <expectedResult type="string">{{testData.price1}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice12</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product2.name)}}" stepKey="checkProductPrice13"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product3.name$$)}}" stepKey="checkProductPrice13"/> <assertEquals stepKey="verifyPrice13"> - <expectedResult type="string">{{testData.price2}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice13</actualResult> </assertEquals> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product3.name)}}" stepKey="checkProductPrice14"/> - <assertEquals stepKey="verifyPrice14"> - <expectedResult type="string">{{testData.price3}}</expectedResult> - <actualResult type="variable">$checkProductPrice14</actualResult> - </assertEquals> - - <click selector="{{NewOrderSection.removeItems(Product1.name)}}" stepKey="clickToExpandAction5"/> - <click selector="{{NewOrderSection.removeAction(Product1.name)}}" stepKey="clickToRemove5"/> - <click selector="{{NewOrderSection.removeItems(Product2.name)}}" stepKey="clickToExpandAction6"/> - <click selector="{{NewOrderSection.removeAction(Product2.name)}}" stepKey="clickToRemove6"/> - <click selector="{{NewOrderSection.removeItems(Product3.name)}}" stepKey="clickToExpandAction7"/> - <click selector="{{NewOrderSection.removeAction(Product3.name)}}" stepKey="clickToRemove7"/> - <click selector="{{NewOrderSection.update}}" stepKey="ClickToUpdate1"/> + <selectOption selector="{{OrdersGridSection.removeItems($$product1.name$$)}}" userInput="Remove" stepKey="clickToRemove4"/> + <selectOption selector="{{OrdersGridSection.removeItems($$product2.name$$)}}" userInput="Remove" stepKey="clickToRemove5"/> + <selectOption selector="{{OrdersGridSection.removeItems($$product3.name$$)}}" userInput="Remove" stepKey="clickToRemove6"/> + <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate2"/> <!--TEST CASE #3--> <waitForPageLoad stepKey="WaitProductsDeleted1"/> <scrollToTopOfPage stepKey="scrollToTopOfPage1"/> - <click selector="{{NewOrderSection.addProducts}}" stepKey="clickToAddProduct3" /> - <click selector="{{NewOrderSection.selectProduct(Product1.name)}}" stepKey="selectProduct9"/> - <fillField selector="{{NewOrderSection.setQuantity(Product1.name)}}" userInput="10" stepKey="AddProductQuantity10"/> - <click selector="{{NewOrderSection.addProductsToOrder}}" stepKey="addProductsToOrder3"/> - <fillField selector="{{NewOrderSection.applyCoupon}}" userInput="{{testData.cartCode}}" stepKey="AddCouponCode"/> - <click selector="{{NewOrderSection.update}}" stepKey="ClickToUpdate2"/> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product1.name)}}" stepKey="checkProductPrice11"/> - <grabTextFrom selector="{{NewOrderSection.productPrice(Product4.name)}}" stepKey="checkProductPrice15"/> - <assertEquals stepKey="verifyPrice11"> - <expectedResult type="string">{{testData.price1}}</expectedResult> - <actualResult type="variable">$checkProductPrice11</actualResult> + <click selector="{{OrdersGridSection.addProducts}}" stepKey="clickToAddProduct4" /> + <click selector="{{OrdersGridSection.selectProduct($$product1.name$$)}}" stepKey="selectProduct9"/> + <fillField selector="{{OrdersGridSection.setQuantity($$product1.name$$)}}" userInput="10" stepKey="AddProductQuantity10"/> + <click selector="{{OrdersGridSection.addProductsToOrder}}" stepKey="addProductsToOrder3"/> + <fillField selector="{{OrdersGridSection.applyCoupon}}" userInput="ship" stepKey="AddCouponCode"/> + <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate3"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice14"/> + <grabTextFrom selector="{{OrdersGridSection.productPrice($$product4.name$$)}}" stepKey="checkProductPrice15"/> + <assertEquals stepKey="verifyPrice14"> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <actualResult type="variable">$checkProductPrice14</actualResult> </assertEquals> <assertEquals stepKey="verifyPrice15"> - <expectedResult type="string">{{testData.price5}}</expectedResult> + <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice15</actualResult> </assertEquals> <after> - <actionGroup ref="DeleteCartPriceRule" stepKey="DeleteCartPriceRule"/> - <actionGroup ref="GoToAllStores" stepKey="GoToAllStores1"/> - <actionGroup ref="DeleteWebsite" stepKey="DeleteWebsite"> - <argument name="websiteName" value="{{testData.website}}"/> + <deleteData createDataKey="product1" stepKey="deleteProduct1"/> + <deleteData createDataKey="product2" stepKey="deleteProduct2"/> + <deleteData createDataKey="product3" stepKey="deleteProduct3"/> + <deleteData createDataKey="product4" stepKey="deleteProduct4"/> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <deleteData createDataKey="customer" stepKey="deleteCustomer"/> + <actionGroup ref="CatalogPriceConfigurations" stepKey="SetCatalogConfigurations"> + <argument name="website" value="Global"/> + </actionGroup> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="DeleteWebsite"> + <argument name="websiteName" value="secondWebsite"/> </actionGroup> - <actionGroup ref="DeleteAllProducts" stepKey="DeleteAllProducts"/> - <actionGroup ref="DeleteCustomer" stepKey="DeleteCustomer"> - <argument name="lastName" value="NewCustomerData.LastName"/> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> + <argument name="ruleName" value="ship"/> </actionGroup> </after> </test> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/CatalogPriceConfigurationActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/CatalogPriceConfigurationActionGroup.xml new file mode 100644 index 0000000000000..19124971caf1f --- /dev/null +++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/CatalogPriceConfigurationActionGroup.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="CatalogPriceConfigurations"> + <arguments> + <argument name="website" type="string" defaultValue="Website"/> + <argument name="price" type="string" defaultValue="0"/> + </arguments> + <amOnPage url="{{CatalogConfigPage.url}}" stepKey="GoToCatalogOptions"/> + <waitForPageLoad stepKey="waitForCatalogOpened"/> + <conditionalClick selector="{{CatalogSection.price}}" dependentSelector="{{CatalogSection.checkIfPriceExpand}}" visible="false" stepKey="ClickToExpandPrice"/> + <waitForPageLoad stepKey="WaitForPriceOpens"/> + <click selector="{{CatalogSection.catalogPriceScope}}" stepKey="ClickToSetCatalogPriceScope"/> + <click selector="{{CatalogSection.catalogPriceScopeValue(website)}}" stepKey="ClickToSetCatalogPriceScopeValue"/> + <fillField selector="{{CatalogSection.defaultProductPrice}}" userInput="{{price}}" stepKey="SetDefaultPrice"/> + <click selector="{{CatalogSection.save}}" stepKey="ClickToSave"/> + <waitForPageLoad stepKey="WaitForWebsiteSaved"/> + <see userInput="You saved the configuration." stepKey="seeSavedMessage" /> + <click selector="{{CatalogSection.price}}" stepKey="ClickToCollapsePrise"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Config/Test/Mftf/Section/CatalogSection.xml b/app/code/Magento/Config/Test/Mftf/Section/CatalogSection.xml index 78b9d1f72f66d..5cc2c53bf5bd7 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/CatalogSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/CatalogSection.xml @@ -11,5 +11,11 @@ <section name="CatalogSection"> <element name="storefront" type="select" selector="#catalog_frontend-head"/> <element name="CheckIfTabExpand" type="button" selector="#catalog_frontend-head:not(.open)"/> + <element name="price" type="button" selector="#catalog_price-head"/> + <element name="checkIfPriceExpand" type="button" selector="//a[@id='catalog_price-head' and @class='open']"/> + <element name="catalogPriceScope" type="select" selector="#catalog_price_scope"/> + <element name="catalogPriceScopeValue" type="select" selector="//select[@id='catalog_price_scope']/option[text()='{{args}}']" parameterized="true"/> + <element name="defaultProductPrice" type="input" selector="#catalog_price_default_product_price"/> + <element name="save" type="button" selector="#save"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml index 647cc6e3ee11f..0c52082e3d4ff 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml @@ -10,9 +10,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminCustomerAccountInformationSection"> <element name="accountInformationTitle" type="text" selector=".admin__page-nav-title"/> + <element name="accountInformationButton" selector="//a/span[text()='Account Information']"/> <element name="firstName" type="input" selector="input[name='customer[firstname]']"/> <element name="lastName" type="input" selector="input[name='customer[lastname]']"/> <element name="email" type="input" selector="input[name='customer[email]']"/> <element name="group" type="select" selector="[name='customer[group_id]']"/> + <element name="associateToWebsite" type="select" selector="//select[@name='customer[website_id]']"/> + <element name="saveCustomer" type="button" selector="//button[@title='Save Customer']"/> + <element name="storeView" type="select" selector="//select[@name='customer[sendemail_store_id]']"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml index 7d106a35f0e13..9991a214e26c0 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerFiltersSection.xml @@ -13,5 +13,6 @@ <element name="nameInput" type="input" selector="input[name=name]"/> <element name="emailInput" type="input" selector="input[name=email]"/> <element name="apply" type="button" selector="button[data-action=grid-filter-apply]" timeout="30"/> + <element name="clearAll" type="button" selector=".action-tertiary.action-clear"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml index f54fbf4cf4d53..b8b69d807a2a6 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/OrdersGridSection.xml @@ -16,5 +16,18 @@ <element name="submitSearch22" type="button" selector=".//*[@class="admin__data-grid-filters-wrap"]/parent::*/div[@class="data-grid-search-control-wrap"]/button"/> <element name="firstRow" type="button" selector="//*[@id='container']//tr[@class='data-row']//a[@class='action-menu-item']"/> <element name="createNewOrder" type="button" selector="button[title='Create New Order'"/> + + <element name="website" type="radio" selector="//label[contains(text(), '{{arg}}')]" parameterized="true"/> + <element name="addProducts" type="button" selector="//span[text()='Add Products']"/> + <element name="selectProduct" type="checkbox" selector="//td[contains(text(), '{{arg}}')]/following-sibling::td[contains(@class, 'col-select col-in_products')]" parameterized="true"/> + <element name="setQuantity" type="checkbox" selector="//td[contains(text(), '{{arg}}')]/following-sibling::td[contains(@class, 'col-qty')]/input" parameterized="true"/> + <element name="addProductsToOrder" type="button" selector="//span[text()='Add Selected Product(s) to Order']"/> + <element name="customPrice" type="checkbox" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td/div//span[contains(text(),'Custom Price')]" parameterized="true"/> + <element name="customQuantity" type="input" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td[@class='col-qty']/input" parameterized="true"/> + <element name="update" type="button" selector="//span[text()='Update Items and Quantities']"/> + <element name="discount" type="text" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td[@class='col-discount col-price']/span" parameterized="true"/> + <element name="productPrice" type="text" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td[@class='col-price col-row-subtotal']/span" parameterized="true"/> + <element name="removeItems" type="select" selector="//span[text()='{{arg}}']/parent::td/following-sibling::td/select[@class='admin__control-select']" parameterized="true"/> + <element name="applyCoupon" type="input" selector="#coupons:code"/> </section> </sections> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml index f31ff1a456898..58b85f67c751f 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml @@ -21,6 +21,9 @@ <element name="coupon" type="select" selector="select[name='coupon_type']"/> <element name="couponCode" type="input" selector="input[name='coupon_code']"/> <element name="useAutoGeneration" type="checkbox" selector="input[name='use_auto_generation']"/> + <element name="userPerCoupon" type="input" selector="//input[@name='uses_per_coupon']"/> + <element name="userPerCustomer" type="input" selector="//input[@name='uses_per_customer']"/> + <element name="priority" type="input" selector="//*[@name='sort_order']"/> <!-- Actions sub-form --> <element name="actionsHeader" type="button" selector="div[data-index='actions']" timeout="30"/> @@ -29,6 +32,7 @@ <element name="applyDiscountToShippingLabel" type="checkbox" selector="input[name='apply_to_shipping']+label"/> <element name="discountAmount" type="input" selector="input[name='discount_amount']"/> <element name="discountStep" type="input" selector="input[name='discount_step']"/> + <element name="freeShipping" type="select" selector="//select[@name='simple_free_shipping']"/> <!-- Manage Coupon Codes sub-form --> <element name="manageCouponCodesHeader" type="button" selector="div[data-index='manage_coupon_codes']" timeout="30"/> From 92e34d7bff3ebcf1b2c26f77aa968490e8c77696 Mon Sep 17 00:00:00 2001 From: Oleksandr_Hodzevych <Oleksandr_Hodzevych@epam.com> Date: Thu, 23 Aug 2018 21:39:25 +0300 Subject: [PATCH 09/57] MAGETWO-91760: Custom address attributes displays with wrong value on checkout - Fixed add label for custom attributes --- .../Block/AbstractResetCheckoutConfig.php | 105 +++++ .../ResetCheckoutConfigOnCartShipping.php | 32 ++ .../Block/ResetCheckoutConfigOnOnePage.php | 31 ++ .../ResetCheckoutConfigOnOnePageTest.php | 418 ++++++++++++++++++ app/code/Magento/Checkout/etc/di.xml | 6 + .../address-renderer/default.html | 9 +- .../address-renderer/default.html | 9 +- 7 files changed, 608 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php create mode 100644 app/code/Magento/Checkout/Plugin/Block/Cart/ResetCheckoutConfigOnCartShipping.php create mode 100644 app/code/Magento/Checkout/Plugin/Block/ResetCheckoutConfigOnOnePage.php create mode 100644 app/code/Magento/Checkout/Test/Unit/Plugin/Block/ResetCheckoutConfigOnOnePageTest.php diff --git a/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php b/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php new file mode 100644 index 0000000000000..7095ce7905df5 --- /dev/null +++ b/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Checkout\Plugin\Block; + +use Magento\Checkout\Block\Cart\Shipping; +use Magento\Checkout\Block\Onepage; + +/** + * Class AbstractResetCheckoutConfig + * Needed for reformat Customer Data address with custom attributes as options add labels for correct view on UI + */ +class AbstractResetCheckoutConfig +{ + /** + * @var \Magento\Eav\Api\AttributeOptionManagementInterface + */ + private $attributeOptionManager; + + /* + * @var \Magento\Framework\Json\Helper\Data + */ + private $serializer; + + /** + * @param \Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManager + * @param \Magento\Framework\Serialize\SerializerInterface + */ + public function __construct( + \Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManager, + \Magento\Framework\Serialize\SerializerInterface $serializer + ) + { + $this->attributeOptionManager = $attributeOptionManager; + $this->serializer = $serializer; + } + + /** + * After Get Checkout Config + * + * @param Onepage|Shipping $subject + * @param mixed $result + * @return string + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + protected function getSerializedCheckoutConfig($subject, $result) + { + $resultArray = $data = $this->serializer->unserialize($result); + $customerAddresses = $resultArray['customerData']['addresses']; + $hasAtLeastOneOptionAttribute = false; + + if (is_array($customerAddresses) && !empty($customerAddresses)) { + foreach ($customerAddresses as $customerAddressIndex => $customerAddress) { + if (!empty($customerAddress['custom_attributes'])) { + foreach ($customerAddress['custom_attributes'] as $customAttributeCode => $customAttribute) { + $attributeOptionLabels = $this->getAttributeLabels($customAttribute, $customAttributeCode); + + if (!empty($attributeOptionLabels)) { + $hasAtLeastOneOptionAttribute = true; + $resultArray['customerData']['addresses'][$customerAddressIndex]['custom_attributes'] + [$customAttributeCode]['label'] = implode(', ', $attributeOptionLabels); + } + } + } + } + } + + return $hasAtLeastOneOptionAttribute ? $this->serializer->serialize($resultArray) : $result; + } + + /** + * Get Labels by CustomAttribute and CustomAttributeCode + * + * @param $customAttribute + * @param $customAttributeCode + * @return array + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + private function getAttributeLabels($customAttribute, $customAttributeCode) + { + $attributeOptionLabels = []; + $customAttributeValues = explode(',', $customAttribute['value']); + $attributeOptions = $this->attributeOptionManager->getItems( + \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, + $customAttributeCode + ); + + if (!empty($attributeOptions)) { + foreach ($attributeOptions as $attributeOption) { + $attributeOptionValue = $attributeOption->getValue(); + if (in_array($attributeOptionValue, $customAttributeValues)) { + $attributeOptionLabels[] = $attributeOption->getLabel() ?? $attributeOptionValue; + } + } + } + + return $attributeOptionLabels; + } +} diff --git a/app/code/Magento/Checkout/Plugin/Block/Cart/ResetCheckoutConfigOnCartShipping.php b/app/code/Magento/Checkout/Plugin/Block/Cart/ResetCheckoutConfigOnCartShipping.php new file mode 100644 index 0000000000000..fed3f0abbfbee --- /dev/null +++ b/app/code/Magento/Checkout/Plugin/Block/Cart/ResetCheckoutConfigOnCartShipping.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Checkout\Plugin\Block\Cart; + +use Magento\Checkout\Block\Cart\Shipping; +use Magento\Checkout\Plugin\Block\AbstractResetCheckoutConfig; + +/** + * Class ResetCheckoutConfigOnCartShipping + * Needed for reformat Customer Data address with custom attributes as options add labels for correct view on ShippingUI + */ +class ResetCheckoutConfigOnCartShipping extends AbstractResetCheckoutConfig +{ + /** + * After Get Checkout Config + * + * @param Shipping $subject + * @param mixed $result + * @return string + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + public function afterGetSerializedCheckoutConfig(Shipping $subject, $result) + { + return $this->getSerializedCheckoutConfig($subject, $result); + } +} diff --git a/app/code/Magento/Checkout/Plugin/Block/ResetCheckoutConfigOnOnePage.php b/app/code/Magento/Checkout/Plugin/Block/ResetCheckoutConfigOnOnePage.php new file mode 100644 index 0000000000000..3d53b28ab61c2 --- /dev/null +++ b/app/code/Magento/Checkout/Plugin/Block/ResetCheckoutConfigOnOnePage.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Checkout\Plugin\Block; + +use Magento\Checkout\Block\Onepage; + +/** + * Class ResetCheckoutConfigOnOnePage + * Needed for reformat Customer Data address with custom attributes as options add labels for correct view on UI OnePage + */ +class ResetCheckoutConfigOnOnePage extends AbstractResetCheckoutConfig +{ + /** + * After Get Checkout Config + * + * @param Onepage $subject + * @param mixed $result + * @return string + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + public function afterGetSerializedCheckoutConfig(Onepage $subject, $result) + { + return $this->getSerializedCheckoutConfig($subject, $result); + } +} diff --git a/app/code/Magento/Checkout/Test/Unit/Plugin/Block/ResetCheckoutConfigOnOnePageTest.php b/app/code/Magento/Checkout/Test/Unit/Plugin/Block/ResetCheckoutConfigOnOnePageTest.php new file mode 100644 index 0000000000000..656fa628b042b --- /dev/null +++ b/app/code/Magento/Checkout/Test/Unit/Plugin/Block/ResetCheckoutConfigOnOnePageTest.php @@ -0,0 +1,418 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Checkout\Test\Unit\Plugin\Block; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class ResetCheckoutConfigOnOnePageTest extends \PHPUnit\Framework\TestCase +{ + + /** + * @var \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage + */ + private $resetCheckoutConfigOnOnePage; + + /** + * @var \Magento\Eav\Api\AttributeOptionManagementInterface + */ + private $attributeOptionManagerMock; + + /** + * @var \Magento\Framework\Serialize\SerializerInterface + */ + private $serializerMock; + + /** + * @var \Magento\Checkout\Block\Onepage + */ + private $onePageMock; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + private $objectManagerHelper; + + protected function setUp() + { + + $this->attributeOptionManagerMock = $this->createMock( + \Magento\Eav\Api\AttributeOptionManagementInterface::class + ); + + $this->serializerMock = $this->createMock( + \Magento\Framework\Serialize\SerializerInterface::class + ); + + $this->onePageMock = $this->createMock(\Magento\Checkout\Block\Onepage::class); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + + $this->resetCheckoutConfigOnOnePage = $this->objectManagerHelper->getObject( + \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::class, + [ + 'attributeOptionManager' => $this->attributeOptionManagerMock, + 'serializer' => $this->serializerMock + ] + ); + } + + /** + * Test for reformat serialized checkout config with empty Result for Onepage + * + * @covers \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::afterGetSerializedCheckoutConfig() + * @return void + */ + public function testAfterGetSerializedCheckoutConfigWithEmptyResults() + { + $result = $this->resetCheckoutConfigOnOnePage->afterGetSerializedCheckoutConfig( + $this->onePageMock, json_encode([]) + ); + + $this->assertEquals( + $result, + '[]' + ); + } + + /** + * Test for reformat serialized checkout config with only options custom attributes in custom address for Onepage + * + * @covers \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::afterGetSerializedCheckoutConfig() + * @return void + */ + public function testAfterGetSerializedCheckoutConfigWithOnlyOptionsCustomAttributesInCustomAddressResults() + { + $textAttributeCode = 'text'; + $textAttributeValue = 'some text'; + $dropAttributeCode = 'dropnew'; + $dropAttributeValue1 = 15; + $dropAttributeLabel1 = 'drop 1'; + $dropAttributeValue2 = 16; + $dropAttributeLabel2 = 'drop 2'; + $multiDropAttributeValue1 = 17; + $multiDropAttributeLabel1 = 'multidrop 1'; + $multiDropAttributeValue2 = 18; + $multiDropAttributeLabel2 = 'multidrop 2'; + $multiDropAttributeCode = 'multidrop'; + $mockCheckoutConfig = [ + 'customerData' => [ + 'addresses' => [ + [ + 'custom_attributes' => [ + $dropAttributeCode => [ + 'attribute_code' => $dropAttributeCode, + 'value' => "$dropAttributeValue1", + ], + $textAttributeCode => [ + 'attribute_code' => $textAttributeCode, + 'value' => $textAttributeValue, + ], + $multiDropAttributeCode => [ + 'attribute_code' => $multiDropAttributeCode, + 'value' => "$multiDropAttributeValue1,$multiDropAttributeValue2", + ] + ] + ] + ] + ] + ]; + + $expectedCheckoutConfig = [ + 'customerData' => [ + 'addresses' => [ + [ + 'custom_attributes' => [ + $dropAttributeCode => [ + 'attribute_code' => $dropAttributeCode, + 'value' => $dropAttributeValue1, + 'label' => $dropAttributeLabel1 + ], + $textAttributeCode => [ + 'attribute_code' => $textAttributeCode, + 'value' => $textAttributeValue, + ], + $multiDropAttributeCode => [ + 'attribute_code' => $multiDropAttributeCode, + 'value' => "$multiDropAttributeValue1,$multiDropAttributeValue2", + 'label' => "$multiDropAttributeLabel1, $multiDropAttributeLabel2" + ] + ] + ] + ] + ] + ]; + + $attributeOptionDropNew1 = $this->getMockBuilder( + \Magento\Eav\Api\Data\AttributeOptionInterface::class + ) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $attributeOptionDropNew2 = $this->getMockBuilder( + \Magento\Eav\Api\Data\AttributeOptionInterface::class + ) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $attributeOptionMultidropDropNew1 = $this->getMockBuilder( + \Magento\Eav\Api\Data\AttributeOptionInterface::class + ) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $attributeOptionMultidropDropNew2 = $this->getMockBuilder( + \Magento\Eav\Api\Data\AttributeOptionInterface::class + ) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $this->serializerMock->expects($this->once()) + ->method('unserialize') + ->with( + json_encode($mockCheckoutConfig) + ) + ->willReturn($mockCheckoutConfig); + + $this->serializerMock->expects($this->once()) + ->method('serialize') + ->with( + $expectedCheckoutConfig + ) + ->willReturn(json_encode($expectedCheckoutConfig)); + + $attributeOptionDropNew1->expects($this->once()) + ->method('getValue') + ->will($this->returnValue($dropAttributeValue1)); + $attributeOptionDropNew1->expects($this->once()) + ->method('getLabel') + ->will($this->returnValue($dropAttributeLabel1)); + + $attributeOptionDropNew2->expects($this->once()) + ->method('getValue') + ->will($this->returnValue($dropAttributeValue2)); + + $attributeOptionMultidropDropNew1->expects($this->once()) + ->method('getValue') + ->will($this->returnValue($multiDropAttributeValue1)); + $attributeOptionMultidropDropNew1->expects($this->once()) + ->method('getLabel') + ->will($this->returnValue($multiDropAttributeLabel1)); + + $attributeOptionMultidropDropNew2->expects($this->once()) + ->method('getValue') + ->will($this->returnValue($multiDropAttributeValue2)); + + $attributeOptionMultidropDropNew2->expects($this->once()) + ->method('getLabel') + ->will($this->returnValue($multiDropAttributeLabel2)); + + $this->attributeOptionManagerMock->expects($this->at(0)) + ->method('getItems') + ->with( + \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, + $dropAttributeCode + ) + ->will($this->returnValue([$attributeOptionDropNew1, $attributeOptionDropNew2])); + + $this->attributeOptionManagerMock->expects($this->at(1)) + ->method('getItems') + ->with( + \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, + $textAttributeCode + ) + ->will($this->returnValue(null)); + + $this->attributeOptionManagerMock->expects($this->at(2)) + ->method('getItems') + ->with( + \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, + $multiDropAttributeCode + ) + ->will($this->returnValue([$attributeOptionMultidropDropNew1, $attributeOptionMultidropDropNew2])); + + $this->resetCheckoutConfigOnOnePage = $this->objectManagerHelper->getObject( + \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::class, + [ + 'attributeOptionManager' => $this->attributeOptionManagerMock, + 'serializer' => $this->serializerMock + ] + ); + + $result = $this->resetCheckoutConfigOnOnePage->afterGetSerializedCheckoutConfig( + $this->onePageMock, json_encode($mockCheckoutConfig) + ); + + $this->assertEquals( + $result, + json_encode($expectedCheckoutConfig) + ); + } + + /** + * Test for reformat serialized checkout config with options + * and other custom attributes in custom address for Onepage + * + * @covers \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::afterGetSerializedCheckoutConfig() + * @return void + */ + public function testAfterGetSerializedCheckoutConfigWithOptionsAndOtherCustomAttributesInCustomAddressResults() + { + $dropAttributeCode = 'dropnew'; + $dropAttributeValue1 = 15; + $dropAttributeLabel1 = 'drop 1'; + $dropAttributeValue2 = 16; + $dropAttributeLabel2 = 'drop 2'; + $multiDropAttributeValue1 = 17; + $multiDropAttributeLabel1 = 'multidrop 1'; + $multiDropAttributeValue2 = 18; + $multiDropAttributeLabel2 = 'multidrop 2'; + $multiDropAttributeCode = 'multidrop'; + $mockCheckoutConfig = [ + 'customerData' => [ + 'addresses' => [ + [ + 'custom_attributes' => [ + $dropAttributeCode => [ + 'attribute_code' => $dropAttributeCode, + 'value' => "$dropAttributeValue1", + ], + $multiDropAttributeCode => [ + 'attribute_code' => $multiDropAttributeCode, + 'value' => "$multiDropAttributeValue1,$multiDropAttributeValue2", + ] + ] + ] + ] + ] + ]; + + $expectedCheckoutConfig = [ + 'customerData' => [ + 'addresses' => [ + [ + 'custom_attributes' => [ + $dropAttributeCode => [ + 'attribute_code' => $dropAttributeCode, + 'value' => $dropAttributeValue1, + 'label' => $dropAttributeLabel1 + ], + $multiDropAttributeCode => [ + 'attribute_code' => $multiDropAttributeCode, + 'value' => "$multiDropAttributeValue1,$multiDropAttributeValue2", + 'label' => "$multiDropAttributeLabel1, $multiDropAttributeLabel2" + ] + ] + ] + ] + ] + ]; + + $attributeOptionDropNew1 = $this->getMockBuilder( + \Magento\Eav\Api\Data\AttributeOptionInterface::class + ) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $attributeOptionDropNew2 = $this->getMockBuilder( + \Magento\Eav\Api\Data\AttributeOptionInterface::class + ) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $attributeOptionMultidropDropNew1 = $this->getMockBuilder( + \Magento\Eav\Api\Data\AttributeOptionInterface::class + ) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $attributeOptionMultidropDropNew2 = $this->getMockBuilder( + \Magento\Eav\Api\Data\AttributeOptionInterface::class + ) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $this->serializerMock->expects($this->once()) + ->method('unserialize') + ->with( + json_encode($mockCheckoutConfig) + ) + ->willReturn($mockCheckoutConfig); + + $this->serializerMock->expects($this->once()) + ->method('serialize') + ->with( + $expectedCheckoutConfig + ) + ->willReturn(json_encode($expectedCheckoutConfig)); + + $attributeOptionDropNew1->expects($this->once()) + ->method('getValue') + ->will($this->returnValue($dropAttributeValue1)); + $attributeOptionDropNew1->expects($this->once()) + ->method('getLabel') + ->will($this->returnValue($dropAttributeLabel1)); + + $attributeOptionDropNew2->expects($this->once()) + ->method('getValue') + ->will($this->returnValue($dropAttributeValue2)); + + $attributeOptionMultidropDropNew1->expects($this->once()) + ->method('getValue') + ->will($this->returnValue($multiDropAttributeValue1)); + $attributeOptionMultidropDropNew1->expects($this->once()) + ->method('getLabel') + ->will($this->returnValue($multiDropAttributeLabel1)); + + $attributeOptionMultidropDropNew2->expects($this->once()) + ->method('getValue') + ->will($this->returnValue($multiDropAttributeValue2)); + $attributeOptionMultidropDropNew2->expects($this->once()) + ->method('getLabel') + ->will($this->returnValue($multiDropAttributeLabel2)); + + $this->attributeOptionManagerMock->expects($this->at(0)) + ->method('getItems') + ->with( + \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, + $dropAttributeCode + ) + ->will($this->returnValue([$attributeOptionDropNew1, $attributeOptionDropNew2])); + + $this->attributeOptionManagerMock->expects($this->at(1)) + ->method('getItems') + ->with( + \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, + $multiDropAttributeCode + ) + ->will($this->returnValue([$attributeOptionMultidropDropNew1, $attributeOptionMultidropDropNew2])); + + $this->resetCheckoutConfigOnOnePage = $this->objectManagerHelper->getObject( + \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::class, + [ + 'attributeOptionManager' => $this->attributeOptionManagerMock, + 'serializer' => $this->serializerMock + ] + ); + + $result = $this->resetCheckoutConfigOnOnePage->afterGetSerializedCheckoutConfig( + $this->onePageMock, json_encode($mockCheckoutConfig) + ); + + $this->assertEquals( + $result, + json_encode($expectedCheckoutConfig) + ); + } +} diff --git a/app/code/Magento/Checkout/etc/di.xml b/app/code/Magento/Checkout/etc/di.xml index 71dfd12bb4779..267f144e7483d 100644 --- a/app/code/Magento/Checkout/etc/di.xml +++ b/app/code/Magento/Checkout/etc/di.xml @@ -52,4 +52,10 @@ <type name="Magento\Quote\Model\Quote"> <plugin name="clear_addresses_after_product_delete" type="Magento\Checkout\Plugin\Model\Quote\ResetQuoteAddresses"/> </type> + <type name="Magento\Checkout\Block\Onepage"> + <plugin name="deserialize_config_and_add_label_to_custom_options" type="Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage"/> + </type> + <type name="Magento\Checkout\Block\Cart\Shipping"> + <plugin name="deserialize_config_and_add_label_to_custom_options_shipping" type="Magento\Checkout\Plugin\Block\Cart\ResetCheckoutConfigOnCartShipping"/> + </type> </config> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index 2e268461d1eea..467aca8fd0558 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -16,7 +16,14 @@ <!-- ko foreach: { data: address().customAttributes, as: 'element' } --> <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } --> <!-- ko if: (typeof element[attribute] === "object") --> - <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- ko if: (element[attribute].label) --> + <!-- ko text: element[attribute].label --><!-- /ko --> + <!-- /ko --> + <!-- ko ifnot: (element[attribute].label) --> + <!-- ko if: (element[attribute].value) --> + <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- /ko --> + <!-- /ko --> <!-- /ko --> <!-- ko if: (typeof element[attribute] === "string") --> <!-- ko text: element[attribute] --><!-- /ko --> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index b66526f660af7..58a8ca66cafe1 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -16,7 +16,14 @@ <!-- ko foreach: { data: address().customAttributes, as: 'element' } --> <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } --> <!-- ko if: (typeof element[attribute] === "object") --> - <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- ko if: (element[attribute].label) --> + <!-- ko text: element[attribute].label --><!-- /ko --> + <!-- /ko --> + <!-- ko ifnot: (element[attribute].label) --> + <!-- ko if: (element[attribute].value) --> + <!-- ko text: element[attribute].value --><!-- /ko --> + <!-- /ko --> + <!-- /ko --> <!-- /ko --> <!-- ko if: (typeof element[attribute] === "string") --> <!-- ko text: element[attribute] --><!-- /ko --> From 144c72a3907f9493f8114f2a7ca517e3c7fd0eba Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Thu, 30 Aug 2018 20:28:15 +0300 Subject: [PATCH 10/57] MAGETWO-94407: [2.3.0] Cart Price Rule for configurable products - Add scope for product condition --- .../Magento/ConfigurableProduct/etc/di.xml | 7 + .../Model/Rule/Condition/Product.php | 125 ++++++++++++++++++ .../Model/Rule/Condition/Product/Combine.php | 42 ++++++ 3 files changed, 174 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index a16feacc4f993..6e300581341ff 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -220,4 +220,11 @@ </argument> </arguments> </type> + <type name="Magento\SalesRule\Model\Quote\ChildrenValidationLocator"> + <arguments> + <argument name="productTypeChildrenValidationMap" xsi:type="array"> + <item name="configurable" xsi:type="boolean">false</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php index d2e7cabe473f4..4fdc240ba6b65 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php @@ -25,6 +25,131 @@ protected function _addSpecialAttributes(array &$attributes) $attributes['quote_item_qty'] = __('Quantity in cart'); $attributes['quote_item_price'] = __('Price in cart'); $attributes['quote_item_row_total'] = __('Row total in cart'); + + $attributes['parent::category_ids'] = __('Category (Parent only)'); + $attributes['children::category_ids'] = __('Category (Children Only)'); + } + + /** + * Retrieve attribute + * + * @return string + */ + public function getAttribute() + { + $attribute = $this->getData('attribute'); + if (strpos($attribute, '::') !== false) { + list (, $attribute) = explode('::', $attribute); + } + return $attribute; + } + + /** + * @inheritdoc + */ + public function getAttributeName() + { + $attribute = $this->getAttribute(); + if ($this->getAttributeScope()) { + $attribute = $this->getAttributeScope() . '::' . $attribute; + } + return $this->getAttributeOption($attribute); + } + + /** + * @inheritdoc + */ + public function loadAttributeOptions() + { + $productAttributes = $this->_productResource->loadAllAttributes()->getAttributesByCode(); + + $attributes = []; + foreach ($productAttributes as $attribute) { + /* @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ + if (!$attribute->isAllowedForRuleCondition() || !$attribute->getDataUsingMethod( + $this->_isUsedForRuleProperty + ) + ) { + continue; + } + $frontLabel = $attribute->getFrontendLabel(); + $attributes[$attribute->getAttributeCode()] = $frontLabel; + $attributes['parent::' . $attribute->getAttributeCode()] = $frontLabel . __('(Parent Only)'); + $attributes['children::' . $attribute->getAttributeCode()] = $frontLabel . __('(Children Only)'); + } + + $this->_addSpecialAttributes($attributes); + + asort($attributes); + $this->setAttributeOption($attributes); + + return $this; + } + + /** + * @inheritdoc + */ + public function getAttributeElementHtml() + { + $html = parent::getAttributeElementHtml() . + $this->getAttributeScopeElement()->getHtml(); + return $html; + } + + /** + * Retrieve form element for scope element + * + * @return \Magento\Framework\Data\Form\Element\AbstractElement + */ + private function getAttributeScopeElement() + { + return $this->getForm()->addField( + $this->getPrefix() . '__' . $this->getId() . '__attribute_scope', + 'hidden', + [ + 'name' => $this->elementName . '[' . $this->getPrefix() . '][' . $this->getId() . '][attribute_scope]', + 'value' => $this->getAttributeScope(), + 'no_span' => true, + 'class' => 'hidden', + 'data-form-part' => $this->getFormName() + ] + ); + } + + /** + * Set attribute value + * + * @param $value + */ + public function setAttribute($value) + { + if (strpos($value, '::') !== false) { + list($scope, $attribute) = explode('::', $value); + $this->setData('attribute_scope', $scope); + $this->setData('attribute', $attribute); + } else { + $this->setData('attribute', $value); + } + } + + /** + * @inheritdoc + */ + public function loadArray($arr) + { + parent::loadArray($arr); + $this->setAttributeScope(isset($arr['attribute_scope']) ? $arr['attribute_scope'] : null); + return $this; + } + + /** + * @inheritdoc + */ + public function asArray(array $arrAttributes = []) + { + $out = parent::asArray($arrAttributes); + $out['attribute_scope'] = $this->getAttributeScope(); + return $out; } /** diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php index b5ac02e67b1e1..8180fb0d18798 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php @@ -85,4 +85,46 @@ public function collectValidatedAttributes($productCollection) } return $this; } + + /** + * @inheritdoc + */ + protected function _isValid($entity) + { + if (!$this->getConditions()) { + return true; + } + + $all = $this->getAggregator() === 'all'; + $true = (bool)$this->getValue(); + + foreach ($this->getConditions() as $cond) { + if ($entity instanceof \Magento\Framework\Model\AbstractModel) { + $attributeScope = $cond->getAttributeScope(); + if ($attributeScope === 'parent') { + $validateEntities = [$entity]; + } elseif ($attributeScope === 'children') { + $validateEntities = $entity->getChildren() ?: [$entity]; + } else { + $validateEntities = $entity->getChildren() ?: []; + $validateEntities[] = $entity; + } + $validated = !$true; + foreach ($validateEntities as $validateEntity) { + $validated = $cond->validate($validateEntity); + if ($validated === $true) { + break; + } + } + } else { + $validated = $cond->validateByEntityId($entity); + } + if ($all && $validated !== $true) { + return false; + } elseif (!$all && $validated === $true) { + return true; + } + } + return $all ? true : false; + } } From 45c0ee3f0edfb375e5670187ccee759fc276e428 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 31 Aug 2018 15:01:13 +0300 Subject: [PATCH 11/57] MAGETWO-64316: WebAPI: creating products with same name (url-key constraint) - Add class for custom creating url-key through web-api --- .../Model/WebapiProductUrlPathGenerator.php | 72 +++++++++++++++++++ .../CatalogUrlRewrite/etc/webapi_rest/di.xml | 10 +++ .../CatalogUrlRewrite/etc/webapi_soap/di.xml | 10 +++ .../Api/ProductRepositoryInterfaceTest.php | 56 +++++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/WebapiProductUrlPathGenerator.php create mode 100644 app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml create mode 100644 app/code/Magento/CatalogUrlRewrite/etc/webapi_soap/di.xml diff --git a/app/code/Magento/CatalogUrlRewrite/Model/WebapiProductUrlPathGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/WebapiProductUrlPathGenerator.php new file mode 100644 index 0000000000000..ae93b76b31579 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Model/WebapiProductUrlPathGenerator.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CatalogUrlRewrite\Model; + +use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; + +/** + * Class for creating product url through web-api. + */ +class WebapiProductUrlPathGenerator extends ProductUrlPathGenerator +{ + /** + * @var CollectionFactory + */ + private $collectionFactory; + + /** + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator + * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository + * @param CollectionFactory $collectionFactory + */ + public function __construct( + \Magento\Store\Model\StoreManagerInterface $storeManager, + \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, + \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator, + \Magento\Catalog\Api\ProductRepositoryInterface $productRepository, + CollectionFactory $collectionFactory + ) { + parent::__construct($storeManager, $scopeConfig, $categoryUrlPathGenerator, $productRepository); + $this->collectionFactory = $collectionFactory; + } + + /** + * @inheritdoc + */ + protected function prepareProductUrlKey(\Magento\Catalog\Model\Product $product) + { + $urlKey = $product->getUrlKey(); + if ($urlKey === '' || $urlKey === null) { + $urlKey = $this->prepareUrlKey($product->formatUrlKey($product->getName())); + } + return $product->formatUrlKey($urlKey); + } + + /** + * Crete url key if it does not exist yet. + * + * @param string $urlKey + * @return string + */ + private function prepareUrlKey(string $urlKey) : string + { + /** @var ProductCollection $collection */ + $collection = $this->collectionFactory->create(); + $collection->addFieldToFilter('url_key', ['like' => $urlKey]); + if ($collection->getSize() !== 0) { + $urlKey = $urlKey . '-1'; + $urlKey = $this->prepareUrlKey($urlKey); + } + + return $urlKey; + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml new file mode 100644 index 0000000000000..ac8beb362f0fb --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/etc/webapi_rest/di.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator" type="Magento\CatalogUrlRewrite\Model\WebapiProductUrlPathGenerator"/> +</config> diff --git a/app/code/Magento/CatalogUrlRewrite/etc/webapi_soap/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/webapi_soap/di.xml new file mode 100644 index 0000000000000..ac8beb362f0fb --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/etc/webapi_soap/di.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator" type="Magento\CatalogUrlRewrite\Model\WebapiProductUrlPathGenerator"/> +</config> diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index e140305db4dcd..a516ef575114e 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -156,6 +156,62 @@ private function loadWebsiteByCode($websiteCode) return $website; } + /** + * Test for check that 2 same product create and url_key save. + * + * @return void + */ + public function testSaveTwoSameProduct() + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'Save', + ], + ]; + + $product1 = [ + 'product' => [ + 'attribute_set_id' => 4, + 'name' => "Test API 1", + 'price' => 254.13, + 'sku' => '1234' + ] + ]; + $product2 = [ + 'product' => [ + 'attribute_set_id' => 4, + 'name' => "Test API 1", + 'price' => 254.13, + 'sku' => '1235' + ] + ]; + + $product1 = $this->_webApiCall($serviceInfo, $product1); + $response = $this->_webApiCall($serviceInfo, $product2); + + $index = null; + foreach ($response['custom_attributes'] as $key => $customAttribute) { + if ($customAttribute['attribute_code'] == 'url_key') { + $index = $key; + break; + } + } + + $this->assertArrayHasKey(ProductInterface::SKU, $response); + + $expectedResult = $product1['custom_attributes'][$index]['value'] . '-1'; + $this->assertEquals($expectedResult, $response['custom_attributes'][$index]['value']); + + $this->deleteProduct('1234'); + $this->deleteProduct('1235'); + } + /** * Test removing association between product and website 1 * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php From 232e5c0ead667df345683734f84ba436c6a041df Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Fri, 31 Aug 2018 23:21:22 +0300 Subject: [PATCH 12/57] MAGETWO-94406: [2.3.0] "Directory Data" and "Cart" sections are loaded twice after user logged in - Updated customer data reload --- .../view/frontend/web/js/view/minicart.js | 2 +- .../view/frontend/web/js/customer-data.js | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index a2f8c8c56ff33..bf8e4e59bdcc5 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -101,7 +101,7 @@ define([ self.isLoading(true); }); - if (cartData()['website_id'] !== window.checkout.websiteId) { + if ((cartData()['website_id'] !== window.checkout.websiteId) && !customerData.get('is-loading')) { customerData.reload(['cart'], false); } diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index ec21e45da6852..553067efe30ad 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -87,9 +87,16 @@ define([ } : []; parameters['update_section_id'] = updateSectionId; - return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) { - throw new Error(jqXHR); - }); + return $.getJSON(options.sectionLoadUrl, parameters) + .done( + function () { + if (_.isEmpty(sectionNames)) { + customerData.set('is_loading', false); + } + } + ).fail(function (jqXHR) { + throw new Error(jqXHR); + }); } }; @@ -199,7 +206,8 @@ define([ privateContent = $.cookieStorage.get(privateContentVersion), localPrivateContent = $.localStorage.get(privateContentVersion), needVersion = 'need_version', - expiredSectionNames = this.getExpiredSectionNames(); + expiredSectionNames = this.getExpiredSectionNames(), + isLoading = false; if (privateContent && !$.cookieStorage.isSet(privateContentVersion) && @@ -208,6 +216,7 @@ define([ $.cookieStorage.set(privateContentVersion, needVersion); $.localStorage.set(privateContentVersion, needVersion); this.reload([], false); + this.set('is_loading', true); } else if (localPrivateContent !== privateContent) { if (!$.cookieStorage.isSet(privateContentVersion)) { privateContent = needVersion; @@ -215,6 +224,7 @@ define([ } $.localStorage.set(privateContentVersion, privateContent); this.reload([], false); + this.set('is_loading', true); } else if (expiredSectionNames.length > 0) { _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) { buffer.notify(sectionName, sectionData); @@ -232,8 +242,9 @@ define([ if (!_.isEmpty(privateContent)) { countryData = this.get('directory-data'); + isLoading = this.get('is_loading'); - if (_.isEmpty(countryData())) { + if (_.isEmpty(countryData()) && !isLoading) { customerData.reload(['directory-data'], false); } } @@ -328,7 +339,6 @@ define([ */ reload: function (sectionNames, updateSectionId) { return dataProvider.getFromServer(sectionNames, updateSectionId).done(function (sections) { - $(document).trigger('customer-data-reload', [sectionNames]); buffer.update(sections); }); }, From a2a8b74eab892342f85eb2b987c5ae01d62a5b1b Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Sun, 2 Sep 2018 10:45:53 +0300 Subject: [PATCH 13/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Catalog/Test/Mftf/Data/TierPriceData.xml | 6 ++-- .../Test/CheckTierPricingOfProductsTest.xml | 32 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml index a563607f633c3..0aec1244d2650 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/TierPriceData.xml @@ -8,15 +8,15 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="testData"> + <entity name="testDataTierPrice" type="data"> <data key="goldenPrice1">$676.50</data> <data key="goldenPrice2">$615.00</data> </entity> - <entity name="CustomStore"> + <entity name="customStoreTierPrice" type="data"> <data key="name">secondStore</data> <data key="code">second_store</data> </entity> - <entity name="customStoreView"> + <entity name="customStoreView" type="data"> <data key="name">secondStoreView</data> <data key="code">second_store_view</data> </entity> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml index c79b7a0b5a616..fc12a532f36e6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -48,7 +48,7 @@ <argument name="storeGroupCode" value="second_store"/> </actionGroup> <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="AdminCreateStoreView"> - <argument name="StoreGroup" value="CustomStore"/> + <argument name="StoreGroup" value="customStoreTierPrice"/> <argument name="customStore" value="customStoreView"/> </actionGroup> <!--Set Configuration--> @@ -166,19 +166,19 @@ <!--Verify tier price values--> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice1"/> <assertEquals stepKey="verifyPrice1"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice1</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product2.name$$)}}" stepKey="checkProductPrice2"/> <assertEquals stepKey="verifyPrice2"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice2</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product3.name$$)}}" stepKey="checkProductPrice3"/> <assertEquals stepKey="verifyPrice3"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice3</actualResult> </assertEquals> @@ -189,18 +189,18 @@ <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice4"/> <assertEquals stepKey="verifyPrice4"> - <expectedResult type="string">{{testData.goldenPrice2}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice2}}</expectedResult> <actualResult type="variable">$checkProductPrice4</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product2.name$$)}}" stepKey="checkProductPrice5"/> <assertEquals stepKey="verifyPrice5"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice5</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product3.name$$)}}" stepKey="checkProductPrice6"/> <assertEquals stepKey="verifyPrice6"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice3</actualResult> </assertEquals> @@ -228,19 +228,19 @@ <!--Verify tier price values--> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice7"/> <assertEquals stepKey="verifyPrice7"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice7</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product2.name$$)}}" stepKey="checkProductPrice8"/> <assertEquals stepKey="verifyPrice8"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice8</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product3.name$$)}}" stepKey="checkProductPrice9"/> <assertEquals stepKey="verifyPrice9"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice9</actualResult> </assertEquals> @@ -252,25 +252,25 @@ <click selector="{{OrdersGridSection.addProductsToOrder}}" stepKey="addProductsToOrder2"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product4.name$$)}}" stepKey="checkProductPrice10"/> <assertEquals stepKey="verifyPrice10"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice10</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice11"/> <assertEquals stepKey="verifyPrice11"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice11</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product2.name$$)}}" stepKey="checkProductPrice12"/> <assertEquals stepKey="verifyPrice12"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice12</actualResult> </assertEquals> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product3.name$$)}}" stepKey="checkProductPrice13"/> <assertEquals stepKey="verifyPrice13"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice13</actualResult> </assertEquals> @@ -291,11 +291,11 @@ <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice14"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product4.name$$)}}" stepKey="checkProductPrice15"/> <assertEquals stepKey="verifyPrice14"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice14</actualResult> </assertEquals> <assertEquals stepKey="verifyPrice15"> - <expectedResult type="string">{{testData.goldenPrice1}}</expectedResult> + <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> <actualResult type="variable">$checkProductPrice15</actualResult> </assertEquals> From b2b9823da479e09d3a4695dd1f9386528247f1d5 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Sun, 2 Sep 2018 12:03:24 +0300 Subject: [PATCH 14/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Mftf/Section/AdminCustomerAccountInformationSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml index 0c52082e3d4ff..26776e19ac387 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminCustomerAccountInformationSection"> <element name="accountInformationTitle" type="text" selector=".admin__page-nav-title"/> - <element name="accountInformationButton" selector="//a/span[text()='Account Information']"/> + <element name="accountInformationButton" type="text" selector="//a/span[text()='Account Information']"/> <element name="firstName" type="input" selector="input[name='customer[firstname]']"/> <element name="lastName" type="input" selector="input[name='customer[lastname]']"/> <element name="email" type="input" selector="input[name='customer[email]']"/> From 80097417b82c87669e73c1c8b4782ce821b6184e Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Mon, 3 Sep 2018 12:46:55 +0300 Subject: [PATCH 15/57] MAGETWO-94406: [2.3.0] "Directory Data" and "Cart" sections are loaded twice after user logged in - Updated retrieve attribute collection --- .../view/frontend/web/js/view/minicart.js | 2 +- .../view/frontend/web/js/customer-data.js | 18 +++++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index bf8e4e59bdcc5..a2f8c8c56ff33 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -101,7 +101,7 @@ define([ self.isLoading(true); }); - if ((cartData()['website_id'] !== window.checkout.websiteId) && !customerData.get('is-loading')) { + if (cartData()['website_id'] !== window.checkout.websiteId) { customerData.reload(['cart'], false); } diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index 553067efe30ad..1d69602bc6e30 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -87,16 +87,9 @@ define([ } : []; parameters['update_section_id'] = updateSectionId; - return $.getJSON(options.sectionLoadUrl, parameters) - .done( - function () { - if (_.isEmpty(sectionNames)) { - customerData.set('is_loading', false); - } - } - ).fail(function (jqXHR) { - throw new Error(jqXHR); - }); + return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) { + throw new Error(jqXHR); + }); } }; @@ -216,7 +209,7 @@ define([ $.cookieStorage.set(privateContentVersion, needVersion); $.localStorage.set(privateContentVersion, needVersion); this.reload([], false); - this.set('is_loading', true); + isLoading = true; } else if (localPrivateContent !== privateContent) { if (!$.cookieStorage.isSet(privateContentVersion)) { privateContent = needVersion; @@ -224,7 +217,7 @@ define([ } $.localStorage.set(privateContentVersion, privateContent); this.reload([], false); - this.set('is_loading', true); + isLoading = true; } else if (expiredSectionNames.length > 0) { _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) { buffer.notify(sectionName, sectionData); @@ -242,7 +235,6 @@ define([ if (!_.isEmpty(privateContent)) { countryData = this.get('directory-data'); - isLoading = this.get('is_loading'); if (_.isEmpty(countryData()) && !isLoading) { customerData.reload(['directory-data'], false); From 34dfd6a918a3f9b36973e66031ab880979bd9c22 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Mon, 3 Sep 2018 16:21:02 +0300 Subject: [PATCH 16/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Test/Mftf/Test/CheckTierPricingOfProductsTest.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml index fc12a532f36e6..a3677ab08c02a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -183,10 +183,12 @@ </assertEquals> <!--Edit order and verify values--> - <waitForPageLoad stepKey="waitForPgeLoaded2"/> + <waitForPageLoad stepKey="waitForPageLoaded2"/> <click selector="{{OrdersGridSection.customPrice($$product1.name$$)}}" stepKey="ClickOnCustomPrice"/> <fillField selector="{{OrdersGridSection.customQuantity($$product1.name$$)}}" userInput="5" stepKey="ClickOnQuantity"/> + <waitForLoadingMaskToDisappear stepKey="wait1"/> <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate"/> + <waitForLoadingMaskToDisappear stepKey="wait2"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice4"/> <assertEquals stepKey="verifyPrice4"> <expectedResult type="string">{{testDataTierPrice.goldenPrice2}}</expectedResult> @@ -208,7 +210,7 @@ <selectOption selector="{{OrdersGridSection.removeItems($$product1.name$$)}}" userInput="Remove" stepKey="clickToRemove1"/> <selectOption selector="{{OrdersGridSection.removeItems($$product2.name$$)}}" userInput="Remove" stepKey="clickToRemove2"/> <selectOption selector="{{OrdersGridSection.removeItems($$product3.name$$)}}" userInput="Remove" stepKey="clickToRemove3"/> - + <waitForLoadingMaskToDisappear stepKey="wait3"/> <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate1"/> <waitForPageLoad stepKey="WaitProductsDeleted"/> @@ -277,6 +279,7 @@ <selectOption selector="{{OrdersGridSection.removeItems($$product1.name$$)}}" userInput="Remove" stepKey="clickToRemove4"/> <selectOption selector="{{OrdersGridSection.removeItems($$product2.name$$)}}" userInput="Remove" stepKey="clickToRemove5"/> <selectOption selector="{{OrdersGridSection.removeItems($$product3.name$$)}}" userInput="Remove" stepKey="clickToRemove6"/> + <waitForLoadingMaskToDisappear stepKey="wait4"/> <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate2"/> <!--TEST CASE #3--> @@ -287,6 +290,7 @@ <fillField selector="{{OrdersGridSection.setQuantity($$product1.name$$)}}" userInput="10" stepKey="AddProductQuantity10"/> <click selector="{{OrdersGridSection.addProductsToOrder}}" stepKey="addProductsToOrder3"/> <fillField selector="{{OrdersGridSection.applyCoupon}}" userInput="ship" stepKey="AddCouponCode"/> + <waitForLoadingMaskToDisappear stepKey="wait5"/> <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate3"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice14"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product4.name$$)}}" stepKey="checkProductPrice15"/> From 8034997eddfcd41aff2b131aad4c64c40094f7b8 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Mon, 3 Sep 2018 18:31:31 +0300 Subject: [PATCH 17/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 37a2a99fa2262..e100701e953c8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -197,6 +197,7 @@ <maximizeWindow stepKey="maximizeWindow"/> <waitForElement selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="waitForCustomerGroupPriceAddButton"/> <click selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="addCustomerGroupAllGroupsQty1PriceDiscountAnd10percent"/> + <waitForElement selector="{{AdminProductFormAdvancedPricingSection.productTierPriceCustGroupSelect('0')}}" stepKey="waitForSelectCustomerGroupNameAttribute2"/> <selectOption selector="{{AdminProductFormAdvancedPricingSection.productTierPriceWebsiteSelect('0')}}" userInput="{{website}}" stepKey="selectProductWebsiteValue"/> <selectOption selector="{{AdminProductFormAdvancedPricingSection.productTierPriceCustGroupSelect('0')}}" userInput="{{group}}" stepKey="selectProductCustomGroupValue"/> <fillField selector="{{AdminProductFormAdvancedPricingSection.productTierPriceQtyInput('0')}}" userInput="{{quantity}}" stepKey="fillProductTierPriceQtyInput"/> From c3d95bd176337ab3bfbba15ba8aa0a7783d1e06b Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Mon, 3 Sep 2018 19:37:25 +0300 Subject: [PATCH 18/57] MAGETWO-91760: Custom address attributes displays with wrong value on checkout - Fixed add label for custom attributes --- .../Checkout/Plugin/Block/AbstractResetCheckoutConfig.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php b/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php index 7095ce7905df5..69d4e2601e23b 100644 --- a/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php +++ b/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php @@ -51,7 +51,8 @@ public function __construct( protected function getSerializedCheckoutConfig($subject, $result) { $resultArray = $data = $this->serializer->unserialize($result); - $customerAddresses = $resultArray['customerData']['addresses']; + $customerAddresses = isset($resultArray['customerData']['addresses']) + ? $resultArray['customerData']['addresses'] : []; $hasAtLeastOneOptionAttribute = false; if (is_array($customerAddresses) && !empty($customerAddresses)) { From 7354ec9d13ece532080c2942fef3af2ebfa2ecc7 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Tue, 4 Sep 2018 09:21:11 +0300 Subject: [PATCH 19/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index e100701e953c8..4b1b799205de6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -194,7 +194,6 @@ <argument name="amount" type="string" defaultValue="45"/> </arguments> <click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickOnAdvancedPricingButton"/> - <maximizeWindow stepKey="maximizeWindow"/> <waitForElement selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="waitForCustomerGroupPriceAddButton"/> <click selector="{{AdminProductFormAdvancedPricingSection.customerGroupPriceAddButton}}" stepKey="addCustomerGroupAllGroupsQty1PriceDiscountAnd10percent"/> <waitForElement selector="{{AdminProductFormAdvancedPricingSection.productTierPriceCustGroupSelect('0')}}" stepKey="waitForSelectCustomerGroupNameAttribute2"/> From 851ed5cef6437789d4548496197b71d744c862aa Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Mon, 3 Sep 2018 17:27:11 +0300 Subject: [PATCH 20/57] MAGETWO-87974: Can't hide product images via hide_from_product_page attribute during import - Added possipility to show/hide existing images via import; - Added new field to export: show_on_product_page; --- .../Model/Export/Product.php | 13 ++++ .../Model/Import/Product.php | 77 ++++++++++++++++--- .../Import/Product/MediaGalleryProcessor.php | 34 ++++++-- 3 files changed, 107 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 23aa8d65ddb0d..62ef8c994de0b 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -734,6 +734,7 @@ protected function setHeaderColumns($customOptionsData, $stockItemRows) 'additional_images', 'additional_image_labels', 'hide_from_product_page', + 'show_on_product_page', 'custom_options' ] ); @@ -1198,6 +1199,7 @@ private function appendMultirowData(&$dataRow, $multiRawData) $additionalImages = []; $additionalImageLabels = []; $additionalImageIsDisabled = []; + $additionalImageIsEnabled = []; foreach ($multiRawData['mediaGalery'][$productLinkId] as $mediaItem) { if ((int)$mediaItem['_media_store_id'] === Store::DEFAULT_STORE_ID) { $additionalImages[] = $mediaItem['_media_image']; @@ -1205,6 +1207,8 @@ private function appendMultirowData(&$dataRow, $multiRawData) if ($mediaItem['_media_is_disabled'] == true) { $additionalImageIsDisabled[] = $mediaItem['_media_image']; + } else { + $additionalImageIsEnabled[] = $mediaItem['_media_image']; } } } @@ -1214,6 +1218,8 @@ private function appendMultirowData(&$dataRow, $multiRawData) implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageLabels); $dataRow['hide_from_product_page'] = implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageIsDisabled); + $dataRow['show_on_product_page'] = + implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageIsEnabled); $multiRawData['mediaGalery'][$productLinkId] = []; } foreach ($this->_linkTypeProvider->getLinkTypes() as $linkTypeName => $linkId) { @@ -1241,11 +1247,14 @@ private function appendMultirowData(&$dataRow, $multiRawData) $dataRow = $this->rowCustomizer->addData($dataRow, $productId); } else { $additionalImageIsDisabled = []; + $additionalImageIsEnabled = []; if (!empty($multiRawData['mediaGalery'][$productLinkId])) { foreach ($multiRawData['mediaGalery'][$productLinkId] as $mediaItem) { if ((int)$mediaItem['_media_store_id'] === $storeId) { if ($mediaItem['_media_is_disabled'] == true) { $additionalImageIsDisabled[] = $mediaItem['_media_image']; + } else { + $additionalImageIsEnabled[] = $mediaItem['_media_image']; } } } @@ -1254,6 +1263,10 @@ private function appendMultirowData(&$dataRow, $multiRawData) $dataRow['hide_from_product_page'] = implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageIsDisabled); } + if ($additionalImageIsEnabled) { + $dataRow['show_on_product_page'] = + implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageIsEnabled); + } } if (!empty($this->collectedMultiselectsData[$storeId][$productId])) { diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 6c3bef2a52b0c..657cc85cfa924 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -312,6 +312,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity self::COL_MEDIA_IMAGE => 'additional_images', '_media_image_label' => 'additional_image_labels', '_media_is_disabled' => 'hide_from_product_page', + '_media_is_enabled' => 'show_on_product_page', Product::COL_STORE => 'store_view_code', Product::COL_ATTR_SET => 'attribute_set_code', Product::COL_TYPE => 'product_type', @@ -1599,6 +1600,7 @@ protected function _saveProducts() $tierPrices = []; $mediaGallery = []; $labelsForUpdate = []; + $imagesForChangeVisibility = []; $uploadedImages = []; $previousType = null; $prevAttributeSet = null; @@ -1718,21 +1720,18 @@ protected function _saveProducts() } // 5. Media gallery phase - $disabledImages = []; list($rowImages, $rowLabels) = $this->getImagesFromRow($rowData); $storeId = !empty($rowData[self::COL_STORE]) ? $this->getStoreIdByCode($rowData[self::COL_STORE]) : Store::DEFAULT_STORE_ID; - if (isset($rowData['_media_is_disabled']) && strlen(trim($rowData['_media_is_disabled']))) { - $disabledImages = array_flip( - explode($this->getMultipleValueSeparator(), $rowData['_media_is_disabled']) - ); - if (empty($rowImages)) { - foreach (array_keys($disabledImages) as $disabledImage) { - $rowImages[self::COL_MEDIA_IMAGE][] = $disabledImage; - } + $imageHiddenStates = $this->getImagesHiddenStates($rowData); + foreach (array_keys($imageHiddenStates) as $image) { + if (array_key_exists($image, $existingImages[$rowSku])) { + $rowImages[self::COL_MEDIA_IMAGE][] = $image; + $uploadedImages[$image] = $image; } } + $rowData[self::COL_MEDIA_IMAGE] = []; /* @@ -1766,13 +1765,23 @@ protected function _saveProducts() if ($uploadedFile && !isset($mediaGallery[$storeId][$rowSku][$uploadedFile])) { if (isset($existingImages[$rowSku][$uploadedFile])) { + $currentFileData = $existingImages[$rowSku][$uploadedFile]; if (isset($rowLabels[$column][$columnImageKey]) && $rowLabels[$column][$columnImageKey] != - $existingImages[$rowSku][$uploadedFile]['label'] + $currentFileData['label'] ) { $labelsForUpdate[] = [ 'label' => $rowLabels[$column][$columnImageKey], - 'imageData' => $existingImages[$rowSku][$uploadedFile] + 'imageData' => $currentFileData + ]; + } + + if (array_key_exists($uploadedFile, $imageHiddenStates) + && $currentFileData['disabled'] != $imageHiddenStates[$uploadedFile] + ) { + $imagesForChangeVisibility[] = [ + 'disabled' => $imageHiddenStates[$uploadedFile], + 'imageData' => $currentFileData ]; } } else { @@ -1785,7 +1794,8 @@ protected function _saveProducts() ? $rowLabels[$column][$columnImageKey] : '', 'position' => ++$position, - 'disabled' => isset($disabledImages[$columnImage]) ? '1' : '0', + 'disabled' => isset($imageHiddenStates[$columnImage]) + ? $imageHiddenStates[$columnImage] : '0', 'value' => $uploadedFile, ]; } @@ -1905,6 +1915,8 @@ protected function _saveProducts() $mediaGallery )->_saveProductAttributes( $attributes + )->updateMediaGalleryVisibility( + $imagesForChangeVisibility )->updateMediaGalleryLabels( $labelsForUpdate ); @@ -1918,6 +1930,32 @@ protected function _saveProducts() return $this; } + /** + * Prepare array with image states (visible or hidden from product page) + * @param array $rowData + * @return array + */ + private function getImagesHiddenStates($rowData) + { + $statesArray = []; + $mappingArray = [ + '_media_is_disabled' => '1', + '_media_is_enabled' => '0' + ]; + + foreach ($mappingArray as $key => $value) { + if (isset($rowData[$key]) && strlen(trim($rowData[$key]))) { + $items = explode($this->getMultipleValueSeparator(), $rowData[$key]); + + foreach ($items as $item) { + $statesArray[$item] = $value; + } + } + } + + return $statesArray; + } + /** * @param array $rowData * @return array @@ -2835,6 +2873,21 @@ private function updateMediaGalleryLabels(array $labels) } } + /** + * Update 'disabled' field for media gallery entity + * + * @param array $images + * @return $this + */ + private function updateMediaGalleryVisibility(array $images) + { + if (!empty($images)) { + $this->mediaProcessor->updateMediaGalleryVisibility($images); + } + + return $this; + } + /** * Parse values from multiple attributes fields * diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php index ec7c6a1172996..4e74aba3f926c 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php @@ -152,14 +152,37 @@ public function saveMediaGallery(array $mediaGalleryData) * @return void */ public function updateMediaGalleryLabels(array $labels) + { + $this->updateMediaGalleryField($labels, 'label'); + } + + /** + * Update 'disabled' field for media gallery entity + * + * @param array $labels + * @return void + */ + public function updateMediaGalleryVisibility(array $images) + { + $this->updateMediaGalleryField($images, 'disabled'); + } + + /** + * Update value for requested field in media gallery entities + * + * @param array $data + * @param string $field + * @return void + */ + private function updateMediaGalleryField(array $data, $field) { $insertData = []; - foreach ($labels as $label) { - $imageData = $label['imageData']; + foreach ($data as $datum) { + $imageData = $datum['imageData']; - if ($imageData['label'] === null) { + if ($imageData[$field] === null) { $insertData[] = [ - 'label' => $label['label'], + $field => $datum[$field], $this->getProductEntityLinkField() => $imageData[$this->getProductEntityLinkField()], 'value_id' => $imageData['value_id'], 'store_id' => Store::DEFAULT_STORE_ID, @@ -168,7 +191,7 @@ public function updateMediaGalleryLabels(array $labels) $this->connection->update( $this->mediaGalleryValueTableName, [ - 'label' => $label['label'], + $field => $datum[$field], ], [ $this->getProductEntityLinkField() . ' = ?' => $imageData[$this->getProductEntityLinkField()], @@ -224,6 +247,7 @@ public function getExistingImages(array $bunch) ), [ 'label' => 'mgv.label', + 'disabled' => 'mgv.disabled', ] )->joinInner( ['pe' => $this->productEntityTableName], From 67acc7c761f01aa488136d04af56d752e769d4c0 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Tue, 4 Sep 2018 14:17:20 +0300 Subject: [PATCH 21/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities in the Order of B2B Store View. - Fix for review mtft tests --- .../Bundle/Model/ResourceModel/Selection/Collection.php | 8 +------- .../Catalog/Model/ResourceModel/Product/Collection.php | 6 ++++-- .../Model/ResourceModel/Review/Product/Collection.php | 9 +++++++++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php index e9295b22674bd..69f13a775561b 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php @@ -64,13 +64,7 @@ protected function _construct() */ public function _afterLoad() { - parent::_afterLoad(); - if ($this->getStoreId() && $this->_items) { - foreach ($this->_items as $item) { - $item->setStoreId($this->getStoreId()); - } - } - return $this; + return parent::_afterLoad(); } /** diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 9f865447b8cfc..6b3ab1638b8b6 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -675,9 +675,9 @@ protected function _afterLoad() /** * Add Store ID to products from collection. * - * @return void + * @return $this */ - private function prepareStoreId() + protected function prepareStoreId() { if ($this->getStoreId() !== null) { /** @var $item \Magento\Catalog\Model\Product */ @@ -685,6 +685,8 @@ private function prepareStoreId() $item->setStoreId($this->getStoreId()); } } + + return $this; } /** diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index 830354796907f..cf7b49a485837 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -540,6 +540,15 @@ protected function _afterLoad() return $this; } + /** + * Not add store ids to items + * + * @return $this + */ + protected function prepareStoreId() { + return $this; + } + /** * Add store data * From 0c0da5b5aecc314a610ea680d5bbaa32ae1dbf5d Mon Sep 17 00:00:00 2001 From: David Grigoryan <david_grigoryan@epam.com> Date: Tue, 4 Sep 2018 15:23:51 +0400 Subject: [PATCH 22/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Test/Mftf/Data/CatalogPriceData.xml | 33 +++++++++++++++++++ .../Test/Mftf/Metadata/catalog_price-meta.xml | 24 ++++++++++++++ .../Test/CheckTierPricingOfProductsTest.xml | 7 ++-- .../CatalogPriceConfigurationActionGroup.xml | 28 ---------------- 4 files changed, 59 insertions(+), 33 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_price-meta.xml delete mode 100644 app/code/Magento/Config/Test/Mftf/ActionGroup/CatalogPriceConfigurationActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceData.xml new file mode 100644 index 0000000000000..cad8a8cd03e0d --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceData.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="CatalogPriceScopeWebsite" type="catalog_price_config_state"> + <requiredEntity type="scope">scopeWebsite</requiredEntity> + <requiredEntity type="default_product_price">defaultProductPrice</requiredEntity> + </entity> + <entity name="scopeWebsite" type="scope"> + <data key="value">1</data> + </entity> + <entity name="defaultProductPrice" type="default_product_price"> + <data key="value">0</data> + </entity> + + <entity name="DefaultConfigCatalogPrice" type="catalog_price_config_state"> + <requiredEntity type="scope">scopeGlobal</requiredEntity> + <requiredEntity type="default_product_price">defaultProductPrice</requiredEntity> + </entity> + <entity name="scopeGlobal" type="scope"> + <data key="value">0</data> + </entity> + <entity name="defaultProductPrice" type="default_product_price"> + <data key="value"/> + </entity> + +</entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_price-meta.xml b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_price-meta.xml new file mode 100644 index 0000000000000..e16688ba0d37b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Metadata/catalog_price-meta.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CatalogPriceConfigState" dataType="catalog_price_config_state" type="create" auth="adminFormKey" url="/admin/system_config/save/section/catalog/" method="POST"> + <object key="groups" dataType="catalog_price_config_state"> + <object key="price" dataType="catalog_price_config_state"> + <object key="fields" dataType="catalog_price_config_state"> + <object key="scope" dataType="scope"> + <field key="value">string</field> + </object> + <object key="default_product_price" dataType="default_product_price"> + <field key="value">string</field> + </object> + </object> + </object> + </object> + </operation> +</operations> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml index c79b7a0b5a616..e13084b7b31fb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -52,8 +52,7 @@ <argument name="customStore" value="customStoreView"/> </actionGroup> <!--Set Configuration--> - <actionGroup ref="CatalogPriceConfigurations" stepKey="SetCatalogConfigurations"/> - + <createData entity="CatalogPriceScopeWebsite" stepKey="paymentMethodsSettingConfig"/> <!--Set advanced pricing for all 4 products--> <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct1"> <argument name="product" value="$$product1$$"/> @@ -306,9 +305,7 @@ <deleteData createDataKey="product4" stepKey="deleteProduct4"/> <deleteData createDataKey="category" stepKey="deleteCategory"/> <deleteData createDataKey="customer" stepKey="deleteCustomer"/> - <actionGroup ref="CatalogPriceConfigurations" stepKey="SetCatalogConfigurations"> - <argument name="website" value="Global"/> - </actionGroup> + <createData entity="DefaultConfigCatalogPrice" stepKey="defaultConfigCatalogPrice"/> <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="DeleteWebsite"> <argument name="websiteName" value="secondWebsite"/> </actionGroup> diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/CatalogPriceConfigurationActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/CatalogPriceConfigurationActionGroup.xml deleted file mode 100644 index 19124971caf1f..0000000000000 --- a/app/code/Magento/Config/Test/Mftf/ActionGroup/CatalogPriceConfigurationActionGroup.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> - <actionGroup name="CatalogPriceConfigurations"> - <arguments> - <argument name="website" type="string" defaultValue="Website"/> - <argument name="price" type="string" defaultValue="0"/> - </arguments> - <amOnPage url="{{CatalogConfigPage.url}}" stepKey="GoToCatalogOptions"/> - <waitForPageLoad stepKey="waitForCatalogOpened"/> - <conditionalClick selector="{{CatalogSection.price}}" dependentSelector="{{CatalogSection.checkIfPriceExpand}}" visible="false" stepKey="ClickToExpandPrice"/> - <waitForPageLoad stepKey="WaitForPriceOpens"/> - <click selector="{{CatalogSection.catalogPriceScope}}" stepKey="ClickToSetCatalogPriceScope"/> - <click selector="{{CatalogSection.catalogPriceScopeValue(website)}}" stepKey="ClickToSetCatalogPriceScopeValue"/> - <fillField selector="{{CatalogSection.defaultProductPrice}}" userInput="{{price}}" stepKey="SetDefaultPrice"/> - <click selector="{{CatalogSection.save}}" stepKey="ClickToSave"/> - <waitForPageLoad stepKey="WaitForWebsiteSaved"/> - <see userInput="You saved the configuration." stepKey="seeSavedMessage" /> - <click selector="{{CatalogSection.price}}" stepKey="ClickToCollapsePrise"/> - </actionGroup> -</actionGroups> From fde4906b5256c483de6015fa37ce3aea90843c17 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Wed, 5 Sep 2018 16:04:49 +0300 Subject: [PATCH 23/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Fix static tests --- .../Review/Model/ResourceModel/Review/Product/Collection.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index cf7b49a485837..99c963501a9d4 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -545,7 +545,8 @@ protected function _afterLoad() * * @return $this */ - protected function prepareStoreId() { + protected function prepareStoreId() + { return $this; } From 1483d420c18bf1db878f432cb5dca80462e7fab8 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Wed, 5 Sep 2018 09:21:20 -0500 Subject: [PATCH 24/57] MQE-1244: Bump MFTF version in Magento and deliver - Add skip tag to MC-201 --- .../Test/AdminRemoveDefaultImageDownloadableProductTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml index 3b10f60c97340..2019793b06a14 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml @@ -17,6 +17,9 @@ <severity value="MAJOR"/> <testCaseId value="MC-201"/> <group value="Downloadable"/> + <skip> + <issueId value="MAGETWO-94795"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From 49ba41ab6529f6891683ac9278da0a6147d5b705 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Wed, 5 Sep 2018 10:26:05 -0500 Subject: [PATCH 25/57] MQE-1244: Bump MFTF version in Magento - Bump MFTF version --- composer.json | 2 +- composer.lock | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index 64d4bcf3b4feb..3bb078a1a8b41 100644 --- a/composer.json +++ b/composer.json @@ -82,7 +82,7 @@ "zendframework/zend-view": "~2.10.0" }, "require-dev": { - "magento/magento2-functional-testing-framework": "2.3.5", + "magento/magento2-functional-testing-framework": "2.3.6", "friendsofphp/php-cs-fixer": "~2.12.0", "lusitanian/oauth": "~0.8.10", "pdepend/pdepend": "2.5.2", diff --git a/composer.lock b/composer.lock index 7af89dd62065b..424553ff2751f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "84697de5cc19e39e480943f1333aef0a", + "content-hash": "eb47aa23baa2410893fe2cbeb2c6ffcc", "packages": [ { "name": "braintree/braintree_php", @@ -460,16 +460,16 @@ }, { "name": "composer/xdebug-handler", - "version": "1.2.1", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373" + "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/e37cbd80da64afe314c72de8d2d2fec0e40d9373", - "reference": "e37cbd80da64afe314c72de8d2d2fec0e40d9373", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/b8e9745fb9b06ea6664d8872c4505fb16df4611c", + "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c", "shasum": "" }, "require": { @@ -500,7 +500,7 @@ "Xdebug", "performance" ], - "time": "2018-08-23T12:00:19+00:00" + "time": "2018-08-31T19:07:57+00:00" }, { "name": "container-interop/container-interop", @@ -1108,16 +1108,16 @@ }, { "name": "paragonie/sodium_compat", - "version": "v1.6.3", + "version": "v1.6.4", "source": { "type": "git", "url": "https://github.com/paragonie/sodium_compat.git", - "reference": "7d0549c3947eaea620f4e523f42ab236cf7fd304" + "reference": "3f2fd07977541b4d630ea0365ad0eceddee5179c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/7d0549c3947eaea620f4e523f42ab236cf7fd304", - "reference": "7d0549c3947eaea620f4e523f42ab236cf7fd304", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/3f2fd07977541b4d630ea0365ad0eceddee5179c", + "reference": "3f2fd07977541b4d630ea0365ad0eceddee5179c", "shasum": "" }, "require": { @@ -1186,7 +1186,7 @@ "secret-key cryptography", "side-channel resistant" ], - "time": "2018-06-06T17:30:29+00:00" + "time": "2018-08-29T22:02:48+00:00" }, { "name": "pelago/emogrifier", @@ -6349,16 +6349,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.5", + "version": "2.3.6", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "bb1518aab82464e25ff97874da939d13ba4b6fac" + "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/bb1518aab82464e25ff97874da939d13ba4b6fac", - "reference": "bb1518aab82464e25ff97874da939d13ba4b6fac", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/57021e12ded213a0031c4d4f6293e06ce6f144ce", + "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce", "shasum": "" }, "require": { @@ -6416,7 +6416,7 @@ "magento", "testing" ], - "time": "2018-08-21T16:57:34+00:00" + "time": "2018-09-05T15:17:20+00:00" }, { "name": "moontoast/math", From 199aa0a930a5e24ef145134e1ab6170ba45ada3c Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan <lusine_hakobyan@epam.com> Date: Thu, 6 Sep 2018 11:49:02 +0400 Subject: [PATCH 26/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Test/Mftf/Test/CheckTierPricingOfProductsTest.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml index 305c45290fa36..aa04570c1a908 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -34,9 +34,10 @@ <requiredEntity createDataKey="category"/> </createData> <createData entity="Simple_US_Customer" stepKey="customer"/> + <!--Login as admin--> + <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> - <!--Login as admin--> - <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> + <!--Create website, Sore adn Store View--> <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="AdminCreateWebsite"> <argument name="newWebsiteName" value="secondWebsite"/> @@ -316,6 +317,7 @@ <actionGroup ref="DeleteCartPriceRuleByName" stepKey="cleanUpRule"> <argument name="ruleName" value="ship"/> </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> </after> </test> </tests> From 0169fba28b819628362e4690e64bf02c05d868bf Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 6 Sep 2018 18:37:27 +0300 Subject: [PATCH 27/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Test/Mftf/ActionGroup/AdminProductActionGroup.xml | 4 ++-- .../ActionGroup/SearchForProductOnBackendActionGroup.xml | 2 +- .../Test/Mftf/Test/CheckTierPricingOfProductsTest.xml | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 4b1b799205de6..f4ba3bb80ffa7 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -182,7 +182,7 @@ <waitForPageLoad stepKey="waitForPageOpened"/> <click selector="{{ProductInWebsitesSection.website(website)}}" stepKey="SelectWebsite"/> <click selector="{{AdminProductFormAdvancedPricingSection.save}}" stepKey="clickSaveProduct"/> - <waitForPageLoad stepKey="waitForPageOpened1"/> + <waitForPageLoad time='60' stepKey="waitForPageOpened1"/> </actionGroup> <actionGroup name="ProductSetAdvancedPricing"> @@ -205,7 +205,7 @@ <click selector="{{AdminProductFormAdvancedPricingSection.doneButton}}" stepKey="clickDoneButton"/> <waitForPageLoad stepKey="WaitForProductSave"/> <click selector="{{AdminProductFormAdvancedPricingSection.save}}" stepKey="clickSaveProduct1"/> - <waitForPageLoad stepKey="WaitForProductSave1"/> + <waitForPageLoad time="60" stepKey="WaitForProductSave1"/> <see userInput="You saved the product." stepKey="seeSaveConfirmation"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SearchForProductOnBackendActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SearchForProductOnBackendActionGroup.xml index ec97c231f9438..df32707afe85b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SearchForProductOnBackendActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SearchForProductOnBackendActionGroup.xml @@ -12,7 +12,7 @@ <argument name="product" defaultValue="product"/> </arguments> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> - <waitForPageLoad time="30" stepKey="waitForProductsPageToLoad"/> + <waitForPageLoad time="60" stepKey="waitForProductsPageToLoad"/> <click selector="{{AdminProductFiltersSection.filtersButton}}" stepKey="openFiltersSectionOnProductsPage"/> <conditionalClick selector="{{AdminProductFiltersSection.clearFiltersButton}}" dependentSelector="{{AdminProductFiltersSection.clearFiltersButton}}" visible="true" stepKey="cleanFiltersIfTheySet"/> <fillField userInput="{{product.sku}}" selector="{{AdminProductFiltersSection.skuInput}}" stepKey="fillSkuFieldOnFiltersSection"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml index aa04570c1a908..281bad4e49591 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml @@ -163,6 +163,7 @@ <click selector="{{OrdersGridSection.selectProduct($$product3.name$$)}}" stepKey="selectProduct3"/> <fillField selector="{{OrdersGridSection.setQuantity($$product3.name$$)}}" userInput="10" stepKey="AddProductQuantity3"/> <click stepKey="addProductsToOrder" selector="{{OrdersGridSection.addProductsToOrder}}"/> + <waitForLoadingMaskToDisappear stepKey="wait6"/> <!--Verify tier price values--> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice1"/> <assertEquals stepKey="verifyPrice1"> @@ -227,6 +228,7 @@ <click selector="{{OrdersGridSection.selectProduct($$product3.name$$)}}" stepKey="selectProduct7"/> <fillField selector="{{OrdersGridSection.setQuantity($$product3.name$$)}}" userInput="10" stepKey="AddProductQuantity7"/> <click stepKey="addProductsToOrder1" selector="{{OrdersGridSection.addProductsToOrder}}"/> + <waitForLoadingMaskToDisappear stepKey="wait7"/> <!--Verify tier price values--> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice7"/> <assertEquals stepKey="verifyPrice7"> @@ -249,9 +251,11 @@ <!--Add one more product and verify values--> <waitForPageLoad stepKey="waitForPgeLoaded3"/> <click selector="{{OrdersGridSection.addProducts}}" stepKey="clickToAddProduct2"/> + <waitForLoadingMaskToDisappear stepKey="wait8"/> <click selector="{{OrdersGridSection.selectProduct($$product4.name$$)}}" stepKey="selectProduct8"/> <fillField selector="{{OrdersGridSection.setQuantity($$product4.name$$)}}" userInput="10" stepKey="AddProductQuantity9"/> <click selector="{{OrdersGridSection.addProductsToOrder}}" stepKey="addProductsToOrder2"/> + <waitForLoadingMaskToDisappear stepKey="wait9"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product4.name$$)}}" stepKey="checkProductPrice10"/> <assertEquals stepKey="verifyPrice10"> <expectedResult type="string">{{testDataTierPrice.goldenPrice1}}</expectedResult> @@ -281,6 +285,7 @@ <selectOption selector="{{OrdersGridSection.removeItems($$product3.name$$)}}" userInput="Remove" stepKey="clickToRemove6"/> <waitForLoadingMaskToDisappear stepKey="wait4"/> <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate2"/> + <waitForLoadingMaskToDisappear stepKey="wait10"/> <!--TEST CASE #3--> <waitForPageLoad stepKey="WaitProductsDeleted1"/> @@ -289,9 +294,11 @@ <click selector="{{OrdersGridSection.selectProduct($$product1.name$$)}}" stepKey="selectProduct9"/> <fillField selector="{{OrdersGridSection.setQuantity($$product1.name$$)}}" userInput="10" stepKey="AddProductQuantity10"/> <click selector="{{OrdersGridSection.addProductsToOrder}}" stepKey="addProductsToOrder3"/> + <waitForLoadingMaskToDisappear stepKey="wait11"/> <fillField selector="{{OrdersGridSection.applyCoupon}}" userInput="ship" stepKey="AddCouponCode"/> <waitForLoadingMaskToDisappear stepKey="wait5"/> <click selector="{{OrdersGridSection.update}}" stepKey="ClickToUpdate3"/> + <waitForLoadingMaskToDisappear stepKey="wait12"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product1.name$$)}}" stepKey="checkProductPrice14"/> <grabTextFrom selector="{{OrdersGridSection.productPrice($$product4.name$$)}}" stepKey="checkProductPrice15"/> <assertEquals stepKey="verifyPrice14"> From 06c69e361b283911fb2c2db4da04f81226749a9e Mon Sep 17 00:00:00 2001 From: vprohorov <vitaliy_prokharau@epam.com> Date: Thu, 19 Jul 2018 19:48:51 +0300 Subject: [PATCH 28/57] MAGETWO-91624: Braintree saved cards use billing address the same as shipping - Adding Braintree vault to checkout layout - Adding billing address form to vault payment method template - Adding automated test --- .../StorefrontFillCartDataActionGroup.xml | 29 +++++ .../Test/Mftf/Data/BraintreeData.xml | 49 ++++++++ .../Mftf/Metadata/braintree_config-meta.xml | 18 +++ .../BraintreeConfigurationPaymentSection.xml | 23 ++++ .../BraintreeCreditCardOnCheckoutTest.xml | 107 ++++++++++++++++++ .../frontend/layout/checkout_index_index.xml | 3 + .../Section/CheckoutOrderSummarySection.xml | 4 + .../Mftf/Section/CheckoutPaymentSection.xml | 3 + .../frontend/web/template/payment/form.html | 5 + 9 files changed, 241 insertions(+) create mode 100644 app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml create mode 100644 app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml create mode 100644 app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml new file mode 100644 index 0000000000000..b25ef8b809d69 --- /dev/null +++ b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontFillCartDataActionGroup"> + <arguments> + <argument name="cartData" defaultValue="PaymentAndShippingInfo"/> + </arguments> + <switchToIFrame selector="{{BraintreeConfigurationPaymentSection.cartFrame}}" stepKey="switchToIframe"/> + <fillField selector="{{BraintreeConfigurationPaymentSection.cartCode}}" userInput="{{cartData.cardNumber}}" stepKey="setCartCode"/> + <switchToIFrame stepKey="switchBack"/> + <switchToIFrame selector="{{BraintreeConfigurationPaymentSection.monthFrame}}" stepKey="switchToIframe1"/> + <fillField selector="{{BraintreeConfigurationPaymentSection.month}}" userInput="{{cartData.month}}" stepKey="setMonth"/> + <switchToIFrame stepKey="switchBack1"/> + <switchToIFrame selector="{{BraintreeConfigurationPaymentSection.yearFrame}}" stepKey="switchToIframe2"/> + <fillField selector="{{BraintreeConfigurationPaymentSection.year}}" userInput="{{cartData.year}}" stepKey="setYear"/> + <switchToIFrame stepKey="switchBack2"/> + <switchToIFrame selector="{{BraintreeConfigurationPaymentSection.codeFrame}}" stepKey="switchToIframe3"/> + <fillField selector="{{BraintreeConfigurationPaymentSection.verificationNumber}}" userInput="{{cartData.cvv}}" stepKey="setVerificationNumber"/> + <switchToIFrame stepKey="SwitchBackToWindow"/> + + </actionGroup> + +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml b/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml index 8e55362a6cba4..8f2588a6effa5 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml @@ -35,6 +35,33 @@ <data key="value">somePrivateKey</data> </entity> + <entity name="BraintreeConfig" type="braintree_config_state"> + <requiredEntity type="title">BraintreeTitle</requiredEntity> + <requiredEntity type="payment_action">PaymentAction</requiredEntity> + <requiredEntity type="environment">Environment</requiredEntity> + <requiredEntity type="merchant_id">MerchantId</requiredEntity> + <requiredEntity type="public_key">PublicKey</requiredEntity> + <requiredEntity type="private_key">PrivateKey</requiredEntity> + </entity> + <entity name="BraintreeTitle" type="title"> + <data key="value">Credit Card (Braintree)</data> + </entity> + <entity name="PaymentAction" type="payment_action"> + <data key="value">authorize</data> + </entity> + <entity name="Environment" type="environment"> + <data key="value">sandbox</data> + </entity> + <entity name="MerchantId" type="merchant_id"> + <data key="value">d4pdjhxgjfrsmzbf</data> + </entity> + <entity name="PublicKey" type="public_key"> + <data key="value">m7q4wmh43xrgyrst</data> + </entity> + <entity name="PrivateKey" type="private_key"> + <data key="value">67de364080b1b4e2492d7a3de413a572</data> + </entity> + <!-- default configuration used to restore Magento config --> <entity name="DefaultBraintreeConfig" type="braintree_config_state"> <requiredEntity type="title">DefaultTitle</requiredEntity> @@ -63,6 +90,28 @@ <data key="value"/> </entity> + <entity name="CustomBraintreeConfigurationData" type="custom_braintree_config_state"> + <requiredEntity type="braintree_cc_vault_active">BraintreeValuteActive</requiredEntity> + <requiredEntity type="active">EnableSolution</requiredEntity> + </entity> + <entity name="BraintreeValuteActive" type="braintree_cc_vault_active"> + <data key="value">1</data> + </entity> + <entity name="EnableSolution" type="active"> + <data key="value">1</data> + </entity> + + <entity name="RollBackCustomBraintreeConfigurationData" type="custom_braintree_config_state"> + <requiredEntity type="braintree_cc_vault_active">DefaultBraintreeValuteActive</requiredEntity> + <requiredEntity type="active">DefaultEnableSolution</requiredEntity> + </entity> + <entity name="DefaultBraintreeValuteActive" type="braintree_cc_vault_active"> + <data key="value">0</data> + </entity> + <entity name="DefaultEnableSolution" type="active"> + <data key="value">0</data> + </entity> + <entity name="testData" type="data"> <data key="websiteName" unique="suffix">Website</data> <data key="websiteCode" unique="suffix">new_website</data> diff --git a/app/code/Magento/Braintree/Test/Mftf/Metadata/braintree_config-meta.xml b/app/code/Magento/Braintree/Test/Mftf/Metadata/braintree_config-meta.xml index 83018852bfeb5..5e3b870d65c67 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Metadata/braintree_config-meta.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Metadata/braintree_config-meta.xml @@ -42,4 +42,22 @@ </object> </object> </operation> + <operation name="CustomBraintreeConfigState" dataType="custom_braintree_config_state" type="create" auth="adminFormKey" url="/admin/system_config/save/section/payment/" method="POST"> + <object key="groups" dataType="custom_braintree_config_state"> + <object key="braintree_section" dataType="custom_braintree_config_state"> + <object key="groups" dataType="custom_braintree_config_state"> + <object key="braintree" dataType="custom_braintree_config_state"> + <object key="fields" dataType="custom_braintree_config_state"> + <object key="braintree_cc_vault_active" dataType="braintree_cc_vault_active"> + <field key="value">integer</field> + </object> + <object key="active" dataType="active"> + <field key="value">string</field> + </object> + </object> + </object> + </object> + </object> + </object> + </operation> </operations> diff --git a/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml b/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml new file mode 100644 index 0000000000000..57510d4bab686 --- /dev/null +++ b/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="BraintreeConfigurationPaymentSection"> + <element name="creditCart" type="radio" selector="#braintree"/> + <element name="paymentMethod" type="radio" selector="//div[@class='payment-group']//input[contains(@id, 'braintree_cc_vault_')]"/> + <element name="cartFrame" type="iframe" selector="braintree-hosted-field-number"/> + <element name="monthFrame" type="iframe" selector="braintree-hosted-field-expirationMonth"/> + <element name="yearFrame" type="iframe" selector="braintree-hosted-field-expirationYear"/> + <element name="codeFrame" type="iframe" selector="braintree-hosted-field-cvv"/> + <element name="cartCode" type="input" selector="#credit-card-number"/> + <element name="month" type="input" selector="#expiration-month"/> + <element name="year" type="input" selector="#expiration-year"/> + <element name="verificationNumber" type="input" selector="#cvv"/> + </section> +</sections> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml new file mode 100644 index 0000000000000..88242e333226e --- /dev/null +++ b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="BraintreeCreditCardOnCheckoutTest"> + <annotations> + <features value="Braintree"/> + <stories value="MAGETWO-91624 - Braintree saved cards use billing address the same as shipping"/> + <title value="Use saved for Braintree credit card on checkout with selecting billing address"/> + <description value="Use saved for Braintree credit card on checkout with selecting billing address"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-93767"/> + <group value="braintree"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="category"/> + <createData entity="SimpleProduct" stepKey="product"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="customer"/> + <createData entity="BraintreeConfig" stepKey="BraintreeConfigurationData"/> + <createData entity="CustomBraintreeConfigurationData" stepKey="CustomBraintreeConfigurationData"/> + </before> + + <after> + <deleteData createDataKey="product" stepKey="deleteProduct1"/> + <deleteData createDataKey="customer" stepKey="deleteCustomer"/> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <createData entity="DefaultBraintreeConfig" stepKey="DefaultBraintreeConfig"/> + <createData entity="RollBackCustomBraintreeConfigurationData" stepKey="RollBackCustomBraintreeConfigurationData"/> + </after> + <!--Go to storefront--> + <amOnPage url="" stepKey="DoToStorefront"/> + <!--Create account--> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUserFromStorefrontActionGroup"> + <argument name="Customer" value="Simple_US_Customer"/> + </actionGroup> + + <!--Add product to cart--> + <amOnPage url="$$product.sku$$.html" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <!--Proceed to checkout--> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="GoToCheckoutFromMinicartActionGroup"/> + + <actionGroup ref="LoggedInCheckoutFillNewBillingAddressActionGroup" stepKey="LoggedInCheckoutFillNewBillingAddressActionGroup"> + <argument name="Address" value="US_Address_CA"/> + </actionGroup> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" time="30" stepKey="waitForPaymentSectionLoaded"/> + <!--Fill cart data--> + <click selector="{{BraintreeConfigurationPaymentSection.creditCart}}" stepKey="SelectBraintreePaymentMethod"/> + <waitForPageLoad stepKey="waitForPageLoad3"/> + <actionGroup ref="StorefrontFillCartDataActionGroup" stepKey="StorefrontFillCartDataActionGroup"/> + <waitForPageLoad stepKey="waitForPageLoad4"/> + <!--Place order--> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="PlaceOrder"/> + <waitForPageLoad stepKey="waitForPageLoad5"/> + + <!--Add product to cart again--> + <amOnPage url="$$product.sku$$.html" stepKey="goToProductPage1"/> + <waitForPageLoad stepKey="waitForPageLoad6"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart1"/> + <waitForPageLoad stepKey="waitForPageLoad7"/> + <!--Proceed to checkout--> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="GoToCheckoutFromMinicartActionGroup1"/> + <click selector="{{CheckoutPaymentSection.addressAction('New Address')}}" stepKey="clickOnNewAddress"/> + <waitForPageLoad stepKey="waitForPageLoad8"/> + <actionGroup ref="LoggedInCheckoutFillNewBillingAddressActionGroup" stepKey="LoggedInCheckoutFillNewBillingAddressActionGroup1"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + <click selector="{{CheckoutPaymentSection.addressAction('Save Address')}}" stepKey="SaveAddress"/> + <waitForPageLoad stepKey="waitForPageLoad9"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext1"/> + <waitForPageLoad stepKey="waitForPageLoad10"/> + <click selector="{{BraintreeConfigurationPaymentSection.paymentMethod}}" stepKey="SelectBraintreePaymentMethod1"/> + <waitForPageLoad stepKey="waitForPageLoad11"/> + <click selector="{{CheckoutPaymentSection.shippingAndBillingAddressSame}}" stepKey="UncheckCheckBox"/> + + <click selector="{{CheckoutShippingSection.updateAddress}}" stepKey="clickToUpdate"/> + <waitForPageLoad stepKey="waitForPageLoad12"/> + <!--Place order--> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="PlaceOrder1"/> + <waitForPageLoad stepKey="waitForPageLoad13"/> + + <click selector="{{CheckoutOrderSummarySection.orderNumber}}" stepKey="ClickOnOrderNumber"/> + <waitForPageLoad stepKey="waitForPageLoad14"/> + <!--Check billing and shipping addresses also additional Address info--> + <click selector="{{CheckoutPaymentSection.addressBook}}" stepKey="goToAddressBook"/> + <grabTextFrom selector="{{CheckoutOrderSummarySection.shippingAddress}}" stepKey="shippingAddr"/> + <grabTextFrom selector="{{CheckoutOrderSummarySection.billingAddress}}" stepKey="billingAddr"/> + <grabTextFrom selector="{{CheckoutOrderSummarySection.additionalAddress}}" stepKey="additionalAddress"/> + <see userInput="Shipping Address" stepKey="seeShippingAddress"/> + <see userInput="Billing Address" stepKey="seeBillingAddress"/> + <assertEquals stepKey="assertValuesAreEqual" actual="$billingAddr" expected="$shippingAddr"/> + <assertNotEquals stepKey="assertValuesAreNotEqual" actual="$billingAddr" expected="$additionalAddress"/> + </test> +</tests> diff --git a/app/code/Magento/Braintree/view/frontend/layout/checkout_index_index.xml b/app/code/Magento/Braintree/view/frontend/layout/checkout_index_index.xml index ab294f8e797b7..c4152e1c3ebf9 100644 --- a/app/code/Magento/Braintree/view/frontend/layout/checkout_index_index.xml +++ b/app/code/Magento/Braintree/view/frontend/layout/checkout_index_index.xml @@ -35,6 +35,9 @@ <item name="braintree_paypal" xsi:type="array"> <item name="isBillingAddressRequired" xsi:type="boolean">false</item> </item> + <item name="braintree_cc_vault" xsi:type="array"> + <item name="isBillingAddressRequired" xsi:type="boolean">true</item> + </item> </item> </item> </item> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutOrderSummarySection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutOrderSummarySection.xml index 3074f390306b1..6e00329901757 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutOrderSummarySection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutOrderSummarySection.xml @@ -13,5 +13,9 @@ <element name="productItemName" type="text" selector=".product-item-name"/> <element name="productItemQty" type="text" selector=".value"/> <element name="productItemPrice" type="text" selector=".price"/> + <element name="orderNumber" type="text" selector="//div[@class='checkout-success']//a"/> + <element name="shippingAddress" type="textarea" selector="//*[@class='box box-address-shipping']//address"/> + <element name="billingAddress" type="textarea" selector="//*[@class='box box-address-billing']//address"/> + <element name="additionalAddress" type="text" selector=".block.block-addresses-list"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 259f672ae8163..7dda1110fd145 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -47,5 +47,8 @@ <element name="taxPercentage" type="text" selector=".totals-tax-details .mark"/> <element name="orderSummaryTotalIncluding" type="text" selector="//tr[@class='grand totals incl']//span[@class='price']" /> <element name="orderSummaryTotalExcluding" type="text" selector="//tr[@class='grand totals excl']//span[@class='price']" /> + <element name="shippingAndBillingAddressSame" type="input" selector="#billing-address-same-as-shipping-braintree_cc_vault"/> + <element name="addressAction" type="button" selector="//span[text()='{{action}}']" parameterized="true"/> + <element name="addressBook" type="button" selector="//a[text()='Address Book']"/> </section> </sections> diff --git a/app/code/Magento/Vault/view/frontend/web/template/payment/form.html b/app/code/Magento/Vault/view/frontend/web/template/payment/form.html index 0ef330cd3014e..1118f79feeba5 100644 --- a/app/code/Magento/Vault/view/frontend/web/template/payment/form.html +++ b/app/code/Magento/Vault/view/frontend/web/template/payment/form.html @@ -32,6 +32,11 @@ <div class="payment-method-content"> <each args="getRegion('messages')" render=""></each> + <div class="payment-method-billing-address"> + <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) --> + <!-- ko template: getTemplate() --><!-- /ko --> + <!--/ko--> + </div> <div class="checkout-agreements-block"> <!-- ko foreach: $parent.getRegion('before-place-order') --> <!-- ko template: getTemplate() --><!-- /ko --> From 38176e75c34b97de9e42961901505987b154e21b Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan <lusine_hakobyan@epam.com> Date: Wed, 5 Sep 2018 18:41:51 +0400 Subject: [PATCH 29/57] MAGETWO-94407: [2.3.0] Cart Price Rule for configurable products - Add automated test --- .../AdminEditProductAttributesSection.xml | 3 +- .../Section/StorefrontMiniCartSection.xml | 4 +- .../AdminCartPriceRulesFormSection.xml | 7 +- ...inCreateCartPriceRuleForCouponCodeTest.xml | 2 +- ...artPriceRuleForConfigurableProductTest.xml | 148 ++++++++++++++++++ 5 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminEditProductAttributesSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminEditProductAttributesSection.xml index 703e9e7ec70ac..7c71cffaef96a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminEditProductAttributesSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminEditProductAttributesSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminEditProductAttributesSection"> <element name="AttributeName" type="text" selector="#name"/> <element name="ChangeAttributeNameToggle" type="checkbox" selector="#toggle_name"/> @@ -18,5 +18,6 @@ <element name="AttributeDescription" type="text" selector="#description"/> <element name="ChangeAttributeDescriptionToggle" type="checkbox" selector="#toggle_description"/> <element name="Save" type="button" selector="button[title=Save]" timeout="30"/> + <element name="defaultLabel" type="text" selector="//td[contains(text(), '{{attributeName}}')]/following-sibling::td[contains(@class, 'col-frontend_label')]" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml index 2c556f25f2064..df63e437ee4d8 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="StorefrontMinicartSection"> <element name="productCount" type="text" selector="//header//div[contains(@class, 'minicart-wrapper')]//a[contains(@class, 'showcart')]//span[@class='counter-number']"/> <element name="productLinkByName" type="button" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details']//a[contains(text(), '{{var1}}')]" parameterized="true"/> @@ -25,5 +25,7 @@ <element name="miniCartSubtotalField" type="text" selector=".block-minicart .amount span.price"/> <element name="itemQuantity" type="input" selector="//a[text()='{{productName}}']/../..//input[contains(@class,'cart-item-qty')]" parameterized="true"/> <element name="itemQuantityUpdate" type="button" selector="//a[text()='{{productName}}']/../..//span[text()='Update']" parameterized="true"/> + <element name="itemDiscount" type="text" selector="//tr[@class='totals']//td[@class='amount']/span"/> + <element name="subtotal" type="text" selector="//tr[@class='totals sub']//td[@class='amount']/span"/> </section> </sections> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml index f31ff1a456898..fdea14fe1b6c7 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml @@ -6,7 +6,7 @@ */ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminCartPriceRulesFormSection"> <element name="save" type="button" selector="#save" timeout="30"/> <element name="saveAndContinue" type="button" selector="#save_and_continue" timeout="30"/> @@ -25,6 +25,11 @@ <!-- Actions sub-form --> <element name="actionsHeader" type="button" selector="div[data-index='actions']" timeout="30"/> <element name="apply" type="select" selector="select[name='simple_action']"/> + <element name="conditions" type="button" selector=".rule-param.rule-param-new-child > a"/> + <element name="childAttribute" type="select" selector="//select[contains(@name, 'new_child')]"/> + <element name="condition" type="text" selector="//span[@class='rule-param']/a[text()='{{arg}}']" parameterized="true"/> + <element name="operator" type="select" selector="//select[contains(@name, '[operator]')]"/> + <element name="option" type="select" selector="//ul[@class='rule-param-children']//select[contains(@name, '[value]')]"/> <element name="applyDiscountToShipping" type="checkbox" selector="input[name='apply_to_shipping']"/> <element name="applyDiscountToShippingLabel" type="checkbox" selector="input[name='apply_to_shipping']+label"/> <element name="discountAmount" type="input" selector="input[name='discount_amount']"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml index a33a4b819b530..e6fe1fa2043a8 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml @@ -30,7 +30,7 @@ <argument name="ruleName" value="{{_defaultCoupon.code}}"/> </actionGroup> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="logout"/> </after> <!-- Create a cart price rule based on a coupon code --> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml new file mode 100644 index 0000000000000..b2e9dcf27c1cf --- /dev/null +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="CartPriceRuleForConfigurableProductTest"> + <annotations> + <features value="SalesRule"/> + <stories value="MAGETWO-94407 - Cart Price Rule for configurable products"/> + <title value="Checking Cart Price Rule for configurable products"/> + <description value="Checking Cart Price Rule for configurable products"/> + <severity value="BLOCKER"/> + <testCaseId value="MAGETWO-94471"/> + <group value="SalesRule"/> + </annotations> + + <before> + <!-- Create the category --> + <createData entity="ApiCategory" stepKey="createCategory"/> + <!-- Create the configurable product and add it to the category --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Create an attribute with two options to be used in the first child product --> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Add the attribute we just created to default attribute set --> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + + <!-- Get the option of the attribute we created --> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <!-- Create a simple product and give it the attribute with option --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Create the configurable product --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Add simple product to the configurable product --> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + + <after> + <actionGroup ref="DeleteCartPriceRuleByName" stepKey="DeleteCartPriceRuleByName"> + <argument name="ruleName" value="{{SimpleSalesRule.name}}"/> + </actionGroup> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + <deleteData createDataKey="createCategory" stepKey="deleteApiCategory"/> + <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + </after> + + <!-- Create the rule --> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForRulesPage"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{SimpleSalesRule.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" userInput="Main Website" stepKey="selectWebsites"/> + <actionGroup ref="selectNotLoggedInCustomerGroup" stepKey="selectNotLoggedInCustomerGroup"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.coupon}}" userInput="Specific Coupon" stepKey="selectCouponType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.couponCode}}" userInput="ABCD" stepKey="fillCouponCOde"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="50" stepKey="fillDiscountAmount"/> + <scrollTo selector="{{AdminCartPriceRulesFormSection.conditions}}" stepKey="ScrollToApplyRuleForConditions"/> + <click selector="{{AdminCartPriceRulesFormSection.conditions}}" stepKey="ApplyRuleForConditions"/> + <waitForPageLoad stepKey="waitForDropDownOpened"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.childAttribute}}" userInput="$$createConfigProductAttribute.attribute[frontend_labels][0][label]$$" stepKey="selectAttribute"/> + <waitForPageLoad stepKey="waitForOperatorOpened"/> + <click selector="{{AdminCartPriceRulesFormSection.condition('is')}}" stepKey="clickToChooseCondition"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.operator}}" userInput="is not" stepKey="selectOperator"/> + <waitForPageLoad stepKey="waitForOperatorOpened1"/> + <click selector="{{AdminCartPriceRulesFormSection.condition('...')}}" stepKey="clickToChooseOption"/> + <waitForPageLoad stepKey="waitForConditionOpened2"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.option}}" userInput="option1" stepKey="selectOption"/> + <waitForPageLoad stepKey="waitForPageLoaded"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + + <!-- Add the first product to the cart --> + <amOnPage url="$$createConfigChildProduct1.sku$$.html" stepKey="goToProductPage1"/> + <waitForPageLoad stepKey="waitForProductPageLoad1"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart1"/> + <waitForPageLoad stepKey="waitForAddToCart1"/> + <!-- Add the second product to the cart --> + <amOnPage url="$$createConfigChildProduct2.sku$$.html" stepKey="goToProductPage2"/> + <waitForPageLoad stepKey="waitForProductPageLoad2"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart2"/> + <waitForPageLoad stepKey="waitForAddToCart2"/> + + <!--View and edit cart--> + <actionGroup ref="clickViewAndEditCartFromMiniCart" stepKey="clickViewAndEditCartFromMiniCart"/> + <click selector="{{DiscountSection.DiscountTab}}" stepKey="scrollToDiscountTab" /> + <fillField selector="{{DiscountSection.CouponInput}}" userInput="ABCD" stepKey="fillCouponCode" /> + <click selector="{{DiscountSection.ApplyCodeBtn}}" stepKey="applyCode"/> + <waitForPageLoad stepKey="waitForPageLoad3"/> + <see userInput="You used coupon code" stepKey="assertText"/> + <!--Verify values--> + <grabTextFrom selector="{{StorefrontMinicartSection.itemDiscount}}" stepKey="getDiscount"/> + <grabTextFrom selector="{{StorefrontMinicartSection.subtotal}}" stepKey="getSubtotal"/> + <assertEquals stepKey="checkDescount"> + <expectedResult type="string">-$117.00</expectedResult> + <actualResult type="variable">$getDiscount</actualResult> + </assertEquals> + <assertEquals stepKey="checkSubtotal"> + <expectedResult type="string">$357.00</expectedResult> + <actualResult type="variable">$getSubtotal</actualResult> + </assertEquals> + </test> +</tests> From 4ae59e03fc287827522eaa0e926be907e393f0d2 Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Mon, 10 Sep 2018 13:15:16 +0300 Subject: [PATCH 30/57] MAGETWO-94406: [2.3.0] "Directory Data" and "Cart" sections are loaded twice after user logged in - Updated customer data reload --- app/code/Magento/Customer/view/frontend/web/js/customer-data.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index 1d69602bc6e30..cfa06c6e12003 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -331,6 +331,7 @@ define([ */ reload: function (sectionNames, updateSectionId) { return dataProvider.getFromServer(sectionNames, updateSectionId).done(function (sections) { + $(document).trigger('customer-data-reload', [sectionNames]); buffer.update(sections); }); }, From 41eb7b541d6f6e331d61c75245be5d8f72914f82 Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan <lusine_hakobyan@epam.com> Date: Tue, 11 Sep 2018 10:40:19 +0400 Subject: [PATCH 31/57] MAGETWO-91624: Braintree saved cards use billing address the same as shipping - Update automated test according to review --- .../Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml | 2 +- .../Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml index b25ef8b809d69..bc6d6c2b46dc9 100644 --- a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml +++ b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontFillCartDataActionGroup.xml @@ -6,7 +6,7 @@ */ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <actionGroup name="StorefrontFillCartDataActionGroup"> <arguments> <argument name="cartData" defaultValue="PaymentAndShippingInfo"/> diff --git a/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml b/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml index 57510d4bab686..d8e1b837a1d1b 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Section/BraintreeConfigurationPaymentSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <section name="BraintreeConfigurationPaymentSection"> <element name="creditCart" type="radio" selector="#braintree"/> <element name="paymentMethod" type="radio" selector="//div[@class='payment-group']//input[contains(@id, 'braintree_cc_vault_')]"/> From a2828fbea02c9a7048a9efea6208c9bb1d5f5fa1 Mon Sep 17 00:00:00 2001 From: vprohorov <prohorov.vital@gmail.com> Date: Tue, 11 Sep 2018 13:33:34 +0300 Subject: [PATCH 32/57] MAGETWO-91624: Braintree saved cards use billing address the same as shipping - Changing form template --- .../Vault/view/frontend/web/template/payment/form.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Vault/view/frontend/web/template/payment/form.html b/app/code/Magento/Vault/view/frontend/web/template/payment/form.html index 1118f79feeba5..b5593626fb15c 100644 --- a/app/code/Magento/Vault/view/frontend/web/template/payment/form.html +++ b/app/code/Magento/Vault/view/frontend/web/template/payment/form.html @@ -33,9 +33,9 @@ <div class="payment-method-content"> <each args="getRegion('messages')" render=""></each> <div class="payment-method-billing-address"> - <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) --> - <!-- ko template: getTemplate() --><!-- /ko --> - <!--/ko--> + <each args="data: $parent.getRegion(getBillingAddressFormName()), as: '$item'"> + <render args="$item.getTemplate()"/> + </each> </div> <div class="checkout-agreements-block"> <!-- ko foreach: $parent.getRegion('before-place-order') --> From 40e4f0d3d9d6d8036181939731ce4d834358b321 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 11 Sep 2018 15:15:15 +0300 Subject: [PATCH 33/57] MAGETWO-91540: REST API extension_attributes for configurable products is empty when using search criteria on products - Fix conflicts --- app/code/Magento/Catalog/Model/ProductRepository.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index b3342d950312d..b06c2ea1bb2cf 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -707,15 +707,9 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr */ private function addExtensionAttributes(Collection $collection) : Collection { - $ids = array_keys($collection->getItems()); - if (empty($ids)) { - return $collection; - } - foreach ($collection->getItems() as $item) { $this->readExtensions->execute($item); } - return $collection; } From 0d6e11b9cab2877ed18debaa4e130fe50e081c7e Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 11 Sep 2018 18:14:34 +0300 Subject: [PATCH 34/57] MAGETWO-91540: REST API extension_attributes for configurable products is empty when using search criteria on products - Fix performance conflicts --- app/code/Magento/Catalog/Model/ProductRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index b06c2ea1bb2cf..51a3f24b1f7bf 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -689,7 +689,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr $this->getCacheKey( [ false, - $product->hasData(\Magento\Catalog\Model\Product::STORE_ID) ? $product->getStoreId() : null + $product->getStoreId() ] ), $product From d96ad6898027d72a5e53e56d751252a788f83f53 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Tue, 11 Sep 2018 18:29:22 +0300 Subject: [PATCH 35/57] MAGETWO-91540: REST API extension_attributes for configurable products is empty when using search criteria on products - Fix performance test --- setup/performance-toolkit/benchmark.jmx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 1cab68878bc20..7e9ed5377f154 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -1365,7 +1365,7 @@ adminCategoryIdsList.add(vars.get("category_id"));</stringProp> <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extract product ids" enabled="true"> <stringProp name="RegexExtractor.useHeaders">false</stringProp> <stringProp name="RegexExtractor.refname">configurable_product_ids</stringProp> - <stringProp name="RegexExtractor.regex">\"id\":(\d+),</stringProp> + <stringProp name="RegexExtractor.regex">\"id\":(\d+),\"sku\"</stringProp> <stringProp name="RegexExtractor.template">$1$</stringProp> <stringProp name="RegexExtractor.default"/> <stringProp name="RegexExtractor.match_number">-1</stringProp> @@ -1575,7 +1575,7 @@ productList.add(productMap);</stringProp> <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extract product ids" enabled="true"> <stringProp name="RegexExtractor.useHeaders">false</stringProp> <stringProp name="RegexExtractor.refname">configurable_product_for_edit_ids</stringProp> - <stringProp name="RegexExtractor.regex">\"id\":(\d+),</stringProp> + <stringProp name="RegexExtractor.regex">\"id\":(\d+),\"sku\"</stringProp> <stringProp name="RegexExtractor.template">$1$</stringProp> <stringProp name="RegexExtractor.default"/> <stringProp name="RegexExtractor.match_number">-1</stringProp> @@ -1798,7 +1798,7 @@ editProductList.add(editProductMap);</stringProp> <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extract product ids" enabled="true"> <stringProp name="RegexExtractor.useHeaders">false</stringProp> <stringProp name="RegexExtractor.refname">simple_product_for_edit_ids</stringProp> - <stringProp name="RegexExtractor.regex">\"id\":(\d+),</stringProp> + <stringProp name="RegexExtractor.regex">\"id\":(\d+),\"sku\"</stringProp> <stringProp name="RegexExtractor.template">$1$</stringProp> <stringProp name="RegexExtractor.default"/> <stringProp name="RegexExtractor.match_number">-1</stringProp> @@ -2014,7 +2014,7 @@ editProductList.add(editProductMap);</stringProp> <RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="Regular Expression Extractor: Extract product ids" enabled="true"> <stringProp name="RegexExtractor.useHeaders">false</stringProp> <stringProp name="RegexExtractor.refname">simple_product_ids</stringProp> - <stringProp name="RegexExtractor.regex">\"id\":(\d+),</stringProp> + <stringProp name="RegexExtractor.regex">\"id\":(\d+),\"sku\"</stringProp> <stringProp name="RegexExtractor.template">$1$</stringProp> <stringProp name="RegexExtractor.default"/> <stringProp name="RegexExtractor.match_number">-1</stringProp> From 4126d27002c22a2a9dad3bc4d36003e783adee57 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 12 Sep 2018 11:43:05 +0300 Subject: [PATCH 36/57] MAGETWO-91540: REST API extension_attributes for configurable products is empty when using search criteria on products - Fix unit tests --- .../Test/Unit/Model/ProductRepositoryTest.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index 7d3162acead64..c729a0c58e1ec 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -28,7 +28,6 @@ use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\DB\Adapter\ConnectionException; -use Magento\Framework\EntityManager\Operation\Read\ReadExtensions; use Magento\Framework\Filesystem; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; @@ -180,11 +179,6 @@ class ProductRepositoryTest extends \PHPUnit\Framework\TestCase */ private $cacheLimit = 2; - /** - * @var ReadExtensions|\PHPUnit_Framework_MockObject_MockObject - */ - private $readExtensionsMock; - /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -298,8 +292,6 @@ function ($value) { } ) ); - $this->readExtensionsMock = $this->getMockBuilder(ReadExtensions::class) - ->disableOriginalConstructor()->getMock(); $this->model = $this->objectManager->getObject( ProductRepository::class, @@ -323,8 +315,7 @@ function ($value) { 'mediaGalleryProcessor' => $this->mediaGalleryProcessor, 'collectionProcessor' => $this->collectionProcessor, 'serializer' => $this->serializerMock, - 'cacheLimit' => $this->cacheLimit, - 'readExtensions' => $this->readExtensionsMock, + 'cacheLimit' => $this->cacheLimit ] ); } @@ -777,8 +768,6 @@ public function testGetList() $collectionMock->expects($this->once())->method('load'); $collectionMock->expects($this->once())->method('addCategoryIds'); $collectionMock->expects($this->atLeastOnce())->method('getItems')->willReturn([$this->product]); - $this->readExtensionsMock->expects($this->once())->method('execute')->with($this->product); - $collectionMock->expects($this->atLeastOnce())->method('getItems')->willReturn([$this->product]); $collectionMock->expects($this->once())->method('getSize')->willReturn(128); $searchResultsMock = $this->createMock(\Magento\Catalog\Api\Data\ProductSearchResultsInterface::class); $searchResultsMock->expects($this->once())->method('setSearchCriteria')->with($searchCriteriaMock); From 40d5668984614fbbb89051300126f45d100a3b78 Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan <lusine_hakobyan@epam.com> Date: Wed, 12 Sep 2018 13:21:29 +0400 Subject: [PATCH 37/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Update automated test --- .../Test/Mftf/Section/AdminCustomerAccountInformationSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml index 26776e19ac387..2b9491b643a47 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountInformationSection.xml @@ -15,6 +15,7 @@ <element name="lastName" type="input" selector="input[name='customer[lastname]']"/> <element name="email" type="input" selector="input[name='customer[email]']"/> <element name="group" type="select" selector="[name='customer[group_id]']"/> + <element name="groupValue" type="button" selector="//span[text()='{{groupValue}}']" parameterized="true"/> <element name="associateToWebsite" type="select" selector="//select[@name='customer[website_id]']"/> <element name="saveCustomer" type="button" selector="//button[@title='Save Customer']"/> <element name="storeView" type="select" selector="//select[@name='customer[sendemail_store_id]']"/> From 236829c36958c8fe745c80f4f74015614e74ad62 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Wed, 12 Sep 2018 12:23:01 +0300 Subject: [PATCH 38/57] MAGETWO-94407: [2.3.0] Cart Price Rule for configurable products - Add suggest to composer --- app/code/Magento/ConfigurableProduct/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index b03a8a65702be..e795ea7cd3618 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -22,6 +22,7 @@ "magento/module-msrp": "*", "magento/module-webapi": "*", "magento/module-sales": "*", + "magento/module-sales-rule": "*", "magento/module-product-video": "*", "magento/module-configurable-sample-data": "*", "magento/module-product-links-sample-data": "*" From fbc22d23ee12231e18aa9f2c0efcd21a64768b4f Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 12 Sep 2018 12:27:08 +0300 Subject: [PATCH 39/57] MAGETWO-94407: Cart Price Rule for configurable products - Fix unit tests --- .../SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php index 51c7b9ede5aa2..8ca6b20db3b5a 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php @@ -298,8 +298,8 @@ public function testQuoteLocaleFormatPrice($isValid, $conditionValue, $operator ->method('getProduct') ->willReturn($product); - $this->model->setAttribute('quote_item_price') - ->setOperator($operator); + $this->model->setAttribute('quote_item_price'); + $this->model->setData('operator', $operator); $this->assertEquals($isValid, $this->model->setValue($conditionValue)->validate($item)); } From 5f2dcd21f0073246b0b1fc67505d5684c2219355 Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Wed, 12 Sep 2018 14:10:47 +0300 Subject: [PATCH 40/57] MAGETWO-87974: Can't hide product images via hide_from_product_page attribute during import - Fixed an issue with 'Undefined index' notice after product import; --- app/code/Magento/CatalogImportExport/Model/Import/Product.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 657cc85cfa924..b4e9bcafe43f9 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1726,7 +1726,9 @@ protected function _saveProducts() : Store::DEFAULT_STORE_ID; $imageHiddenStates = $this->getImagesHiddenStates($rowData); foreach (array_keys($imageHiddenStates) as $image) { - if (array_key_exists($image, $existingImages[$rowSku])) { + if (array_key_exists($rowSku, $existingImages) + && array_key_exists($image, $existingImages[$rowSku]) + ) { $rowImages[self::COL_MEDIA_IMAGE][] = $image; $uploadedImages[$image] = $image; } From 1946914689ce5a29e84d725a4ba0a860ba41d513 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Wed, 12 Sep 2018 14:46:37 +0300 Subject: [PATCH 41/57] MAGETWO-94407: [2.3.0] Cart Price Rule for configurable products - Fix static tests --- .../Model/Rule/Condition/Product.php | 5 +- .../Model/Rule/Condition/Product/Combine.php | 57 +++++++++++++------ 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php index 4fdc240ba6b65..f9885fc54379d 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php @@ -66,9 +66,8 @@ public function loadAttributeOptions() $attributes = []; foreach ($productAttributes as $attribute) { /* @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ - if (!$attribute->isAllowedForRuleCondition() || !$attribute->getDataUsingMethod( - $this->_isUsedForRuleProperty - ) + if (!$attribute->isAllowedForRuleCondition() + || !$attribute->getDataUsingMethod($this->_isUsedForRuleProperty) ) { continue; } diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php index 8180fb0d18798..0d7a2537ebcd0 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php @@ -100,22 +100,7 @@ protected function _isValid($entity) foreach ($this->getConditions() as $cond) { if ($entity instanceof \Magento\Framework\Model\AbstractModel) { - $attributeScope = $cond->getAttributeScope(); - if ($attributeScope === 'parent') { - $validateEntities = [$entity]; - } elseif ($attributeScope === 'children') { - $validateEntities = $entity->getChildren() ?: [$entity]; - } else { - $validateEntities = $entity->getChildren() ?: []; - $validateEntities[] = $entity; - } - $validated = !$true; - foreach ($validateEntities as $validateEntity) { - $validated = $cond->validate($validateEntity); - if ($validated === $true) { - break; - } - } + $validated = $this->validateEntity($cond, $entity); } else { $validated = $cond->validateByEntityId($entity); } @@ -127,4 +112,44 @@ protected function _isValid($entity) } return $all ? true : false; } + + /** + * @param object $cond + * @param \Magento\Framework\Model\AbstractModel $entity + * @return bool + */ + private function validateEntity($cond, \Magento\Framework\Model\AbstractModel $entity) + { + $true = (bool)$this->getValue(); + $validated = !$true; + foreach ($this->retrieveValidateEntities($cond->getAttributeScope(), $entity) as $validateEntity) { + $validated = $cond->validate($validateEntity); + if ($validated === $true) { + break; + } + } + + return $validated; + } + + /** + * Retrieve entities for validation by attribute scope + * + * @param $attributeScope + * @param \Magento\Framework\Model\AbstractModel $entity + * @return \Magento\Framework\Model\AbstractModel[] + */ + private function retrieveValidateEntities($attributeScope, \Magento\Framework\Model\AbstractModel $entity) + { + if ($attributeScope === 'parent') { + $validateEntities = [$entity]; + } elseif ($attributeScope === 'children') { + $validateEntities = $entity->getChildren() ?: [$entity]; + } else { + $validateEntities = $entity->getChildren() ?: []; + $validateEntities[] = $entity; + } + + return $validateEntities; + } } From 59688116714c41791a7e34c97668489ad6809c6d Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Wed, 12 Sep 2018 15:56:40 +0300 Subject: [PATCH 42/57] MAGETWO-87974: Can't hide product images via hide_from_product_page attribute during import - Fixed an issue with incorrect image savind in non default store; --- app/code/Magento/CatalogImportExport/Model/Import/Product.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index b4e9bcafe43f9..ffe7dc0304e1f 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1732,6 +1732,10 @@ protected function _saveProducts() $rowImages[self::COL_MEDIA_IMAGE][] = $image; $uploadedImages[$image] = $image; } + + if (empty($rowImages)) { + $rowImages[self::COL_MEDIA_IMAGE][] = $image; + } } $rowData[self::COL_MEDIA_IMAGE] = []; From c7a1adfb1c6d57cbaf65f67280be8950439429ef Mon Sep 17 00:00:00 2001 From: Alexey Yakimovich <yakimovich@almagy.com> Date: Wed, 12 Sep 2018 17:43:02 +0300 Subject: [PATCH 43/57] MAGETWO-87974: Can't hide product images via hide_from_product_page attribute during import - Removed show_on_product_page field form export/import; --- .../CatalogImportExport/Model/Export/Product.php | 12 ------------ .../CatalogImportExport/Model/Import/Product.php | 4 +--- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 62ef8c994de0b..22390ede1a4f1 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -734,7 +734,6 @@ protected function setHeaderColumns($customOptionsData, $stockItemRows) 'additional_images', 'additional_image_labels', 'hide_from_product_page', - 'show_on_product_page', 'custom_options' ] ); @@ -1199,7 +1198,6 @@ private function appendMultirowData(&$dataRow, $multiRawData) $additionalImages = []; $additionalImageLabels = []; $additionalImageIsDisabled = []; - $additionalImageIsEnabled = []; foreach ($multiRawData['mediaGalery'][$productLinkId] as $mediaItem) { if ((int)$mediaItem['_media_store_id'] === Store::DEFAULT_STORE_ID) { $additionalImages[] = $mediaItem['_media_image']; @@ -1207,8 +1205,6 @@ private function appendMultirowData(&$dataRow, $multiRawData) if ($mediaItem['_media_is_disabled'] == true) { $additionalImageIsDisabled[] = $mediaItem['_media_image']; - } else { - $additionalImageIsEnabled[] = $mediaItem['_media_image']; } } } @@ -1218,8 +1214,6 @@ private function appendMultirowData(&$dataRow, $multiRawData) implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageLabels); $dataRow['hide_from_product_page'] = implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageIsDisabled); - $dataRow['show_on_product_page'] = - implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageIsEnabled); $multiRawData['mediaGalery'][$productLinkId] = []; } foreach ($this->_linkTypeProvider->getLinkTypes() as $linkTypeName => $linkId) { @@ -1253,8 +1247,6 @@ private function appendMultirowData(&$dataRow, $multiRawData) if ((int)$mediaItem['_media_store_id'] === $storeId) { if ($mediaItem['_media_is_disabled'] == true) { $additionalImageIsDisabled[] = $mediaItem['_media_image']; - } else { - $additionalImageIsEnabled[] = $mediaItem['_media_image']; } } } @@ -1263,10 +1255,6 @@ private function appendMultirowData(&$dataRow, $multiRawData) $dataRow['hide_from_product_page'] = implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageIsDisabled); } - if ($additionalImageIsEnabled) { - $dataRow['show_on_product_page'] = - implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalImageIsEnabled); - } } if (!empty($this->collectedMultiselectsData[$storeId][$productId])) { diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index ffe7dc0304e1f..8cbf0f8d6be9c 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -312,7 +312,6 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity self::COL_MEDIA_IMAGE => 'additional_images', '_media_image_label' => 'additional_image_labels', '_media_is_disabled' => 'hide_from_product_page', - '_media_is_enabled' => 'show_on_product_page', Product::COL_STORE => 'store_view_code', Product::COL_ATTR_SET => 'attribute_set_code', Product::COL_TYPE => 'product_type', @@ -1945,8 +1944,7 @@ private function getImagesHiddenStates($rowData) { $statesArray = []; $mappingArray = [ - '_media_is_disabled' => '1', - '_media_is_enabled' => '0' + '_media_is_disabled' => '1' ]; foreach ($mappingArray as $key => $value) { From b3ca6a1583f8ca2b4eecb83a8d2dbb92c735109f Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Wed, 12 Sep 2018 18:45:37 +0300 Subject: [PATCH 44/57] MAGETWO-87974: Can't hide product images via hide_from_product_page attribute during import - Removed show_on_product_page field form export/import; --- app/code/Magento/CatalogImportExport/Model/Export/Product.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 22390ede1a4f1..23aa8d65ddb0d 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -1241,7 +1241,6 @@ private function appendMultirowData(&$dataRow, $multiRawData) $dataRow = $this->rowCustomizer->addData($dataRow, $productId); } else { $additionalImageIsDisabled = []; - $additionalImageIsEnabled = []; if (!empty($multiRawData['mediaGalery'][$productLinkId])) { foreach ($multiRawData['mediaGalery'][$productLinkId] as $mediaItem) { if ((int)$mediaItem['_media_store_id'] === $storeId) { From e85882651918d9a97f6cfebe2a640d30913b630e Mon Sep 17 00:00:00 2001 From: Lusine Hakobyan <lusine_hakobyan@epam.com> Date: Wed, 12 Sep 2018 22:40:25 +0400 Subject: [PATCH 45/57] MAGETWO-91624: Braintree saved cards use billing address the same as shipping - Add signout action --- .../Test/BraintreeCreditCardOnCheckoutTest.xml | 1 + .../Test/Mftf/ActionGroup/CheckoutActionGroup.xml | 7 +++++++ .../Mftf/Section/StoreFrontSignOutSection.xml | 15 +++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontSignOutSection.xml diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml index 88242e333226e..7f6d862ada085 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml @@ -35,6 +35,7 @@ <deleteData createDataKey="category" stepKey="deleteCategory"/> <createData entity="DefaultBraintreeConfig" stepKey="DefaultBraintreeConfig"/> <createData entity="RollBackCustomBraintreeConfigurationData" stepKey="RollBackCustomBraintreeConfigurationData"/> + <actionGroup ref="StorefrontSignOutActionGroup" stepKey="StorefrontSignOutActionGroup"/> </after> <!--Go to storefront--> <amOnPage url="" stepKey="DoToStorefront"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index ebb1e81620fac..b658f7e4af578 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -145,4 +145,11 @@ <see selector="{{CheckoutSuccessMainSection.success}}" userInput="{{emailYouMessage}}" stepKey="seeEmailYou"/> </actionGroup> + <actionGroup name="StorefrontSignOutActionGroup"> + <click selector="{{StoreFrontSignOutSection.customerAccount}}" stepKey="clickCustomerButton"/> + <click selector="{{StoreFrontSignOutSection.signOut}}" stepKey="clickToSignOut"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <see userInput="You are signed out" stepKey="signOut"/> + </actionGroup> + </actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontSignOutSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontSignOutSection.xml new file mode 100644 index 0000000000000..29c1c9c01be70 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StoreFrontSignOutSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StoreFrontSignOutSection"> + <element name="customerAccount" type="button" selector=".customer-name"/> + <element name="signOut" type="button" selector="div.customer-menu li.authorization-link"/> + </section> +</sections> \ No newline at end of file From c98e1d9cbaeb7e326ec6ba722f966d349fd0b06e Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Wed, 12 Sep 2018 17:43:50 -0500 Subject: [PATCH 46/57] MQE-1244: Bump MFTF version in Magento --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index dda9790675739..e2a646275d98b 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "~2.13.0", "lusitanian/oauth": "~0.8.10", - "magento/magento2-functional-testing-framework": "2.3.5", + "magento/magento2-functional-testing-framework": "2.3.6", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 86826f3b2d5af..2550f70f0be81 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ecd17c9b3713554b75fa656e0aecd96c", + "content-hash": "18982aa4d36bcfd22cf073dfb578efdb", "packages": [ { "name": "braintree/braintree_php", @@ -6351,16 +6351,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.5", + "version": "2.3.6", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "bb1518aab82464e25ff97874da939d13ba4b6fac" + "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/bb1518aab82464e25ff97874da939d13ba4b6fac", - "reference": "bb1518aab82464e25ff97874da939d13ba4b6fac", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/57021e12ded213a0031c4d4f6293e06ce6f144ce", + "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce", "shasum": "" }, "require": { @@ -6418,7 +6418,7 @@ "magento", "testing" ], - "time": "2018-08-21T16:57:34+00:00" + "time": "2018-09-05T15:17:20+00:00" }, { "name": "moontoast/math", From e33476ff035d6e39ebd8b320a7d591533c61fe81 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 13 Sep 2018 12:49:48 +0300 Subject: [PATCH 47/57] MAGETWO-91697: [Magento Cloud] "Tier Pricing" of Products changes to "Price" (without discount) after Updated Items and Quantities - Fix static test --- .../ResourceModel/Selection/Collection.php | 3 ++ .../ResourceModel/Product/Collection.php | 34 ++++++++----------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php index 69f13a775561b..d1ea6847d90ef 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php @@ -261,7 +261,10 @@ public function addPriceFilter($product, $searchMin, $useRegularPrice = false) } /** + * Get Catalog Rule Processor. + * * @return \Magento\CatalogRule\Model\ResourceModel\Product\CollectionProcessor + * * @deprecated 100.2.0 */ private function getCatalogRuleProcessor() diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 6b3ab1638b8b6..b5f5b6b0deb55 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -455,8 +455,7 @@ public function getFlatState() } /** - * Retrieve is flat enabled flag - * Return always false if magento run admin + * Retrieve is flat enabled. Return always false if magento run admin. * * @return bool */ @@ -487,8 +486,7 @@ protected function _construct() } /** - * Standard resource collection initialization - * Needed for child classes + * Standard resource collection initialization. Needed for child classes. * * @param string $model * @param string $entityModel @@ -527,8 +525,7 @@ protected function _prepareStaticFields() } /** - * Retrieve collection empty item - * Redeclared for specifying id field name without getting resource model inside model + * Get collection empty item. Redeclared for specifying id field name without getting resource model inside model. * * @return \Magento\Framework\DataObject */ @@ -614,8 +611,7 @@ public function _loadAttributes($printQuery = false, $logQuery = false) } /** - * Add attribute to entities in collection - * If $attribute=='*' select all attributes + * Add attribute to entities in collection. If $attribute=='*' select all attributes. * * @param array|string|integer|\Magento\Framework\App\Config\Element $attribute * @param bool|string $joinType @@ -651,8 +647,7 @@ public function addAttributeToSelect($attribute, $joinType = false) } /** - * Processing collection items after loading - * Adding url rewrites, minimal prices, final prices, tax percents + * Processing collection items after loading. Adding url rewrites, minimal prices, final prices, tax percents. * * @return $this */ @@ -755,8 +750,7 @@ public function addIdFilter($productId, $exclude = false) } /** - * Adding product website names to result collection - * Add for each product websites information + * Adding product website names to result collection. Add for each product websites information. * * @return $this */ @@ -767,7 +761,7 @@ public function addWebsiteNamesToResult() } /** - * {@inheritdoc} + * @inheritdoc */ public function load($printQuery = false, $logQuery = false) { @@ -824,8 +818,7 @@ protected function doAddWebsiteNamesToResult() } /** - * Add store availability filter. Include availability product - * for store website + * Add store availability filter. Include availability product for store website. * * @param null|string|bool|int|Store $store * @return $this @@ -1113,7 +1106,7 @@ public function getSelectCountSql() /** * Get SQL for get record count * - * @param null $select + * @param \Magento\Framework\DB\Select $select * @param bool $resetLeftJoins * @return \Magento\Framework\DB\Select */ @@ -1355,8 +1348,7 @@ public function joinUrlRewrite() } /** - * Add URL rewrites data to product - * If collection loadded - run processing else set flag + * Add URL rewrites data to product. If collection loadded - run processing else set flag. * * @param int|string $categoryId * @return $this @@ -1579,7 +1571,8 @@ public function addAttributeToFilter($attribute, $condition = null, $joinType = } /** - * {@inheritdoc} + * @inheritdoc + * * @since 101.0.0 */ protected function getEntityPkName(\Magento\Eav\Model\Entity\AbstractEntity $entity) @@ -2317,7 +2310,10 @@ private function getGalleryReadHandler() } /** + * Retrieve Media gallery resource. + * * @deprecated 101.0.1 + * * @return \Magento\Catalog\Model\ResourceModel\Product\Gallery */ private function getMediaGalleryResource() From de44fd9cfaaa761e8974081cd8e33eccc9ec1b8a Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 13 Sep 2018 13:47:06 +0300 Subject: [PATCH 48/57] MAGETWO-87974: Can't hide product images via hide_from_product_page attribute during import - Fix static test --- .../Model/Import/Product.php | 38 +++++++++++++++++-- .../Import/Product/MediaGalleryProcessor.php | 8 ++-- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 8cbf0f8d6be9c..7d132b9082380 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -898,8 +898,8 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData, $ } /** - * * Multiple value separator getter. + * * @return string */ public function getMultipleValueSeparator() @@ -949,6 +949,8 @@ public function getMediaGalleryAttributeId() } /** + * Get product by type name. + * * @param string $name * @return Product\Type\AbstractType */ @@ -1189,8 +1191,10 @@ protected function _initErrorTemplates() } /** - * Set valid attribute set and product type to rows with all scopes - * to ensure that existing products doesn't changed. + * Set valid attribute set and product type to rows. + * + * Set valid attribute set and product type to rows with all + * scopes to ensure that existing products doesn't changed. * * @param array $rowData * @return array @@ -1220,6 +1224,7 @@ protected function _prepareRowForDb(array $rowData) /** * Gather and save information about product links. + * * Must be called after ALL products saving done. * * @return $this @@ -1468,6 +1473,7 @@ public function saveProductEntity(array $entityRowsIn, array $entityRowsUp) /** * Return additional data, needed to select. + * * @return array */ private function getOldSkuFieldsForSelect() @@ -1477,6 +1483,7 @@ private function getOldSkuFieldsForSelect() /** * Adds newly created products to _oldSku + * * @param array $newProducts * @return void */ @@ -1514,6 +1521,7 @@ private function getNewSkuFieldsForSelect() /** * Init media gallery resources + * * @return void * @since 100.0.4 * @deprecated @@ -1544,6 +1552,8 @@ protected function getExistingImages($bunch) } /** + * Retrieve image from row. + * * @param array $rowData * @return array */ @@ -1937,6 +1947,7 @@ protected function _saveProducts() /** * Prepare array with image states (visible or hidden from product page) + * * @param array $rowData * @return array */ @@ -1961,6 +1972,8 @@ private function getImagesHiddenStates($rowData) } /** + * Process row categories. + * * @param array $rowData * @return array */ @@ -1988,6 +2001,8 @@ protected function processRowCategories($rowData) } /** + * Get product websites. + * * @param string $productSku * @return array */ @@ -1997,6 +2012,8 @@ public function getProductWebsites($productSku) } /** + * Retrieve product categories. + * * @param string $productSku * @return array */ @@ -2006,6 +2023,8 @@ public function getProductCategories($productSku) } /** + * Get store id by code. + * * @param string $storeCode * @return array|int|null|string */ @@ -2097,6 +2116,8 @@ protected function _getUploader() } /** + * Retrieve uploader. + * * @return Uploader * @throws \Magento\Framework\Exception\LocalizedException */ @@ -2107,6 +2128,7 @@ public function getUploader() /** * Uploading files into the "catalog/product" media folder. + * * Return a new file name if the same file is already exists. * * @param string $fileName @@ -2301,7 +2323,7 @@ public function getEntityTypeCode() * Returns array of new products data with SKU as key. All SKU keys are in lowercase for avoiding creation of * new products with the same SKU in different letter cases. * - * @var string $sku + * @param string $sku * @return array */ public function getNewSku($sku = null) @@ -2494,6 +2516,8 @@ public function validateRow(array $rowData, $rowNum) } /** + * Check if need to validate url key. + * * @param array $rowData * @return bool */ @@ -2805,8 +2829,11 @@ protected function getProductUrlSuffix($storeId = null) } /** + * Get url key. + * * @param array $rowData * @return string + * * @since 100.0.3 */ protected function getUrlKey($rowData) @@ -2823,7 +2850,10 @@ protected function getUrlKey($rowData) } /** + * Retrieve resource. + * * @return Proxy\Product\ResourceModel + * * @since 100.0.3 */ protected function getResource() diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php index 4e74aba3f926c..d43dc11a68fcf 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/MediaGalleryProcessor.php @@ -103,7 +103,7 @@ public function __construct( /** * Save product media gallery. * - * @param $mediaGalleryData + * @param array $mediaGalleryData * @return void */ public function saveMediaGallery(array $mediaGalleryData) @@ -159,7 +159,7 @@ public function updateMediaGalleryLabels(array $labels) /** * Update 'disabled' field for media gallery entity * - * @param array $labels + * @param array $images * @return void */ public function updateMediaGalleryVisibility(array $images) @@ -287,7 +287,7 @@ private function initMediaGalleryResources() /** * Save media gallery data per store. * - * @param $storeId + * @param int $storeId * @param array $mediaGalleryData * @param array $newMediaValues * @param array $valueToProductId @@ -363,6 +363,8 @@ private function getProductEntityLinkField() } /** + * Get resource. + * * @return \Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceModel */ private function getResource() From 1f8bf28b04d08efc2a3c8fc9b24dc9dc6bc93d28 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 13 Sep 2018 13:53:53 +0300 Subject: [PATCH 49/57] MAGETWO-91594: Unable to finish import when one product divided between import "bunches" - Fix static test --- .../CatalogImportExport/Model/Import/Product/Option.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php index dcfd817c553e7..c7eb722050303 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php @@ -1122,6 +1122,8 @@ protected function _getMultiRowFormat($rowData) } /** + * Process option row. + * * @param string $name * @param array $optionRow * @return array @@ -1203,6 +1205,7 @@ private function addFileOptions($result, $optionRow) /** * Import data rows. + * * Additional store view data (option titles) will be sought in store view specified import file rows * * @return boolean @@ -1309,6 +1312,8 @@ protected function _importData() } /** + * Check options titles. + * * If products were split up between bunches, * this function will add needed option for option titles * @@ -1364,6 +1369,8 @@ private function setLastOptionTitle(array &$titles) : void } /** + * Remove existing options. + * * Remove all existing options if import behaviour is APPEND * in other case remove options for products with empty "custom_options" row only. * @@ -1617,6 +1624,8 @@ private function getExistingOptionTypeId($optionId, $storeId, $optionTypeTitle) } /** + * Rarse required data. + * * Parse required data from current row and store to class internal variables some data * for underlying dependent rows * From 28d72fa2a8d94dadbcbee6c41f1cb40e2c06318e Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 13 Sep 2018 14:08:45 +0300 Subject: [PATCH 50/57] MAGETWO-94407: [2.3.0] Cart Price Rule for configurable products - Fix static test --- app/code/Magento/SalesRule/Model/Rule/Condition/Product.php | 4 +++- .../SalesRule/Model/Rule/Condition/Product/Combine.php | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php index f9885fc54379d..b0bba8e8f72d6 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php @@ -118,7 +118,7 @@ private function getAttributeScopeElement() /** * Set attribute value * - * @param $value + * @param string $value */ public function setAttribute($value) { @@ -213,6 +213,8 @@ public function getValueElementChooserUrl() } /** + * Get formatted price. + * * @param string $value * @return float|null */ diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php index 0d7a2537ebcd0..1649dea80ef5b 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php @@ -8,6 +8,7 @@ use Magento\Catalog\Model\ResourceModel\Product\Collection; /** + * Combine conditions for product. * @api * @since 100.0.2 */ @@ -114,6 +115,8 @@ protected function _isValid($entity) } /** + * Validate entity. + * * @param object $cond * @param \Magento\Framework\Model\AbstractModel $entity * @return bool @@ -135,7 +138,7 @@ private function validateEntity($cond, \Magento\Framework\Model\AbstractModel $e /** * Retrieve entities for validation by attribute scope * - * @param $attributeScope + * @param string $attributeScope * @param \Magento\Framework\Model\AbstractModel $entity * @return \Magento\Framework\Model\AbstractModel[] */ From be6bf03a011c09e74b60cad8129eda5f2897cf8d Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 13 Sep 2018 15:33:10 +0300 Subject: [PATCH 51/57] MAGETWO-87974: Can't hide product images via hide_from_product_page attribute during import - Fix static test --- app/code/Magento/CatalogImportExport/Model/Import/Product.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 7d132b9082380..e57c4fc801fa4 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -2013,7 +2013,7 @@ public function getProductWebsites($productSku) /** * Retrieve product categories. - * + * * @param string $productSku * @return array */ @@ -2024,7 +2024,7 @@ public function getProductCategories($productSku) /** * Get store id by code. - * + * * @param string $storeCode * @return array|int|null|string */ From b2c55f721d5adc4fb45ea8ca26033182ce5253e6 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 13 Sep 2018 15:44:42 +0300 Subject: [PATCH 52/57] MAGETWO-91540: REST API extension_attributes for configurable products is empty when using search criteria on products - Fix static test --- .../Magento/Catalog/Model/ProductRepository.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 51a3f24b1f7bf..d124bf5e42639 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -30,6 +30,7 @@ use Magento\Framework\Exception\ValidatorException; /** + * Product Repository. * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) */ @@ -241,7 +242,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function get($sku, $editMode = false, $storeId = null, $forceReload = false) { @@ -271,7 +272,7 @@ public function get($sku, $editMode = false, $storeId = null, $forceReload = fal } /** - * {@inheritdoc} + * @inheritdoc */ public function getById($productId, $editMode = false, $storeId = null, $forceReload = false) { @@ -361,6 +362,8 @@ protected function initializeProductData(array $productData, $createNew) } /** + * Assign product to websites. + * * @param \Magento\Catalog\Model\Product $product * @return void */ @@ -376,6 +379,8 @@ private function assignProductToWebsites(\Magento\Catalog\Model\Product $product } /** + * Process new gallery media entry. + * * @param ProductInterface $product * @param array $newEntry * @return $this @@ -628,7 +633,7 @@ public function save(ProductInterface $product, $saveOptions = false) } /** - * {@inheritdoc} + * @inheritdoc */ public function delete(ProductInterface $product) { @@ -652,7 +657,7 @@ public function delete(ProductInterface $product) } /** - * {@inheritdoc} + * @inheritdoc */ public function deleteById($sku) { @@ -661,7 +666,7 @@ public function deleteById($sku) } /** - * {@inheritdoc} + * @inheritdoc */ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria) { @@ -784,6 +789,8 @@ private function determineImageRoles(ProductInterface $product, array $images) : } /** + * Retrieve media gallery processor. + * * @return Product\Gallery\Processor */ private function getMediaGalleryProcessor() From 35092e098a61ec9adb8d1e585ed382b8f06fa3bd Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Thu, 13 Sep 2018 09:08:07 -0500 Subject: [PATCH 53/57] MQE-1112: Bump MFTF version in Magento - Flaky test stabilization --- .../Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml | 4 ++-- .../Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml index 6c535e3004e69..112b065dec9a4 100644 --- a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml +++ b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml @@ -30,7 +30,7 @@ <selectOption stepKey="selectDisplayZeroTaxCart" selector="{{AdminConfigureTaxSection.dropdownDisplayZeroTaxCart}}" userInput="Yes"/> <!-- change the options for orders, invoices, credit memos display to show tax --> - <conditionalClick stepKey="clickOrdersInvoicesCreditSales" selector="{{AdminConfigureTaxSection.ordersInvoicesCreditSales}}" dependentSelector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalSales}}" visible="false"/> + <conditionalClick stepKey="clickOrdersInvoicesCreditSales" selector="{{AdminConfigureTaxSection.ordersInvoicesCreditSales}}" dependentSelector="{{AdminConfigureTaxSection.taxSalesDisplay}}" visible="false"/> <uncheckOption stepKey="clickTaxTotalSales" selector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalSales}}"/> <selectOption stepKey="selectTaxTotalSales" selector="{{AdminConfigureTaxSection.dropdownIncludeTaxTotalSales}}" userInput="Yes"/> <uncheckOption stepKey="clickDisplayTaxSummarySales" selector="{{AdminConfigureTaxSection.systemValueDisplayTaxSummarySales}}"/> @@ -66,7 +66,7 @@ <selectOption stepKey="selectDisplayZeroTaxCart" selector="{{AdminConfigureTaxSection.dropdownDisplayZeroTaxCart}}" userInput="Yes"/> <!-- change the options for orders, invoices, credit memos display to not show tax --> - <conditionalClick stepKey="clickOrdersInvoicesCreditSales" selector="{{AdminConfigureTaxSection.ordersInvoicesCreditSales}}" dependentSelector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalSales}}" visible="false"/> + <conditionalClick stepKey="clickOrdersInvoicesCreditSales" selector="{{AdminConfigureTaxSection.ordersInvoicesCreditSales}}" dependentSelector="{{AdminConfigureTaxSection.taxSalesDisplay}}" visible="false"/> <checkOption stepKey="clickTaxTotalSales" selector="{{AdminConfigureTaxSection.systemValueIncludeTaxTotalSales}}"/> <selectOption stepKey="selectTaxTotalSales" selector="{{AdminConfigureTaxSection.dropdownIncludeTaxTotalSales}}" userInput="Yes"/> <checkOption stepKey="clickDisplayTaxSummarySales" selector="{{AdminConfigureTaxSection.systemValueDisplayTaxSummarySales}}"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml index 896d719a436ca..8e52800516dae 100644 --- a/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml +++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminConfigureTaxSection.xml @@ -35,6 +35,7 @@ <element name="taxDisplayProductPricesDisabled" type="select" selector="#tax_display_type[disabled='disabled']"/> <element name="taxDisplayProductPricesInherit" type="checkbox" selector="#tax_display_type_inherit"/> + <element name="taxSalesDisplay" type="block" selector=".config.admin__collapsible-block#tax_sales_display" timeout="30"/> <element name="shoppingCartDisplay" type="block" selector="#tax_cart_display-head" timeout="30"/> <element name="systemValueIncludeTaxTotalCart" type="checkbox" selector="#row_tax_cart_display_grandtotal input[type='checkbox']"/> <element name="dropdownIncludeTaxTotalCart" type="checkbox" selector="#row_tax_cart_display_grandtotal select"/> From 802532af5dc2ace029d6d70c8879e84cd22fe738 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 13 Sep 2018 18:49:16 +0300 Subject: [PATCH 54/57] MAGETWO-87974: Can't hide product images via hide_from_product_page attribute during import - Fix static test --- .../Magento/CatalogImportExport/Model/Import/Product.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index e57c4fc801fa4..9877727a5affb 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -949,7 +949,7 @@ public function getMediaGalleryAttributeId() } /** - * Get product by type name. + * Retrieve product type by name. * * @param string $name * @return Product\Type\AbstractType @@ -1972,7 +1972,7 @@ private function getImagesHiddenStates($rowData) } /** - * Process row categories. + * Resolve valid category ids from provided row data. * * @param array $rowData * @return array @@ -2829,7 +2829,7 @@ protected function getProductUrlSuffix($storeId = null) } /** - * Get url key. + * Retrieve url key from provided row data. * * @param array $rowData * @return string From 836681b8a1343c18b5e247e6a93318455ee60250 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Thu, 13 Sep 2018 19:03:51 +0300 Subject: [PATCH 55/57] MAGETWO-91760: Custom address attributes displays with wrong value on checkout - Fix CR comments - Fix static tests --- .../Checkout/Model/DefaultConfigProvider.php | 83 +++- .../Block/AbstractResetCheckoutConfig.php | 106 ----- .../ResetCheckoutConfigOnCartShipping.php | 32 -- .../Block/ResetCheckoutConfigOnOnePage.php | 31 -- .../ResetCheckoutConfigOnOnePageTest.php | 418 ------------------ app/code/Magento/Checkout/etc/di.xml | 6 - .../web/template/billing-address/details.html | 53 ++- .../address-renderer/default.html | 64 ++- .../address-renderer/default.html | 53 ++- 9 files changed, 167 insertions(+), 679 deletions(-) delete mode 100644 app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php delete mode 100644 app/code/Magento/Checkout/Plugin/Block/Cart/ResetCheckoutConfigOnCartShipping.php delete mode 100644 app/code/Magento/Checkout/Plugin/Block/ResetCheckoutConfigOnOnePage.php delete mode 100644 app/code/Magento/Checkout/Test/Unit/Plugin/Block/ResetCheckoutConfigOnOnePageTest.php diff --git a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php index 16f13511001e9..ea6cdd2e51b4a 100644 --- a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php +++ b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php @@ -13,6 +13,7 @@ use Magento\Customer\Model\Context as CustomerContext; use Magento\Customer\Model\Session as CustomerSession; use Magento\Customer\Model\Url as CustomerUrlManager; +use Magento\Eav\Api\AttributeOptionManagementInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Http\Context as HttpContext; use Magento\Framework\App\ObjectManager; @@ -26,11 +27,18 @@ use Magento\Store\Model\ScopeInterface; /** + * Default Config Provider + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) */ class DefaultConfigProvider implements ConfigProviderInterface { + /** + * @var AttributeOptionManagementInterface + */ + private $attributeOptionManager; + /** * @var CheckoutHelper */ @@ -194,6 +202,7 @@ class DefaultConfigProvider implements ConfigProviderInterface * @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement * @param UrlInterface $urlBuilder * @param AddressMetadataInterface $addressMetadata + * @param AttributeOptionManagementInterface $attributeOptionManager * @codeCoverageIgnore * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -224,7 +233,8 @@ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement, UrlInterface $urlBuilder, - AddressMetadataInterface $addressMetadata = null + AddressMetadataInterface $addressMetadata = null, + AttributeOptionManagementInterface $attributeOptionManager = null ) { $this->checkoutHelper = $checkoutHelper; $this->checkoutSession = $checkoutSession; @@ -253,10 +263,15 @@ public function __construct( $this->paymentMethodManagement = $paymentMethodManagement; $this->urlBuilder = $urlBuilder; $this->addressMetadata = $addressMetadata ?: ObjectManager::getInstance()->get(AddressMetadataInterface::class); + $this->attributeOptionManager = $attributeOptionManager ?? + ObjectManager::getInstance()->get(AttributeOptionManagementInterface::class); } /** - * {@inheritdoc} + * Return configuration array + * + * @return array|mixed + * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function getConfig() { @@ -359,7 +374,7 @@ private function filterNotVisibleAttributes(array $attributes) } } - return $attributes; + return $this->setLabelsToAttributes($attributes); } /** @@ -581,6 +596,7 @@ protected function getStaticBaseUrl() /** * Return quote totals data + * * @return array */ private function getTotalsData() @@ -612,6 +628,7 @@ private function getTotalsData() /** * Returns active carriers codes + * * @return array */ private function getActiveCarriers() @@ -625,6 +642,7 @@ private function getActiveCarriers() /** * Returns origin country code + * * @return string */ private function getOriginCountryCode() @@ -638,7 +656,9 @@ private function getOriginCountryCode() /** * Returns array of payment methods - * @return array + * + * @return array $paymentMethods + * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function getPaymentMethods() { @@ -654,4 +674,59 @@ private function getPaymentMethods() } return $paymentMethods; } + + /** + * Set Labels to custom Attributes + * + * @param array $customAttributes + * @return array $customAttributes + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + private function setLabelsToAttributes(array $customAttributes) : array + { + if (!empty($customAttributes)) { + foreach ($customAttributes as $customAttributeCode => $customAttribute) { + $attributeOptionLabels = $this->getAttributeLabels($customAttribute, $customAttributeCode); + if (!empty($attributeOptionLabels)) { + $customAttributes[$customAttributeCode]['label'] = implode(', ', $attributeOptionLabels); + } + } + } + + return $customAttributes; + } + + /** + * Get Labels by CustomAttribute and CustomAttributeCode + * + * @param array $customAttribute + * @param string|integer $customAttributeCode + * @return array $attributeOptionLabels + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\StateException + */ + private function getAttributeLabels(array $customAttribute, string $customAttributeCode) : array + { + $attributeOptionLabels = []; + + if (!empty($customAttribute['value'])) { + $customAttributeValues = explode(',', $customAttribute['value']); + $attributeOptions = $this->attributeOptionManager->getItems( + \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, + $customAttributeCode + ); + + if (!empty($attributeOptions)) { + foreach ($attributeOptions as $attributeOption) { + $attributeOptionValue = $attributeOption->getValue(); + if (in_array($attributeOptionValue, $customAttributeValues)) { + $attributeOptionLabels[] = $attributeOption->getLabel() ?? $attributeOptionValue; + } + } + } + } + + return $attributeOptionLabels; + } } diff --git a/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php b/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php deleted file mode 100644 index 69d4e2601e23b..0000000000000 --- a/app/code/Magento/Checkout/Plugin/Block/AbstractResetCheckoutConfig.php +++ /dev/null @@ -1,106 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Checkout\Plugin\Block; - -use Magento\Checkout\Block\Cart\Shipping; -use Magento\Checkout\Block\Onepage; - -/** - * Class AbstractResetCheckoutConfig - * Needed for reformat Customer Data address with custom attributes as options add labels for correct view on UI - */ -class AbstractResetCheckoutConfig -{ - /** - * @var \Magento\Eav\Api\AttributeOptionManagementInterface - */ - private $attributeOptionManager; - - /* - * @var \Magento\Framework\Json\Helper\Data - */ - private $serializer; - - /** - * @param \Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManager - * @param \Magento\Framework\Serialize\SerializerInterface - */ - public function __construct( - \Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManager, - \Magento\Framework\Serialize\SerializerInterface $serializer - ) - { - $this->attributeOptionManager = $attributeOptionManager; - $this->serializer = $serializer; - } - - /** - * After Get Checkout Config - * - * @param Onepage|Shipping $subject - * @param mixed $result - * @return string - * @throws \Magento\Framework\Exception\InputException - * @throws \Magento\Framework\Exception\StateException - */ - protected function getSerializedCheckoutConfig($subject, $result) - { - $resultArray = $data = $this->serializer->unserialize($result); - $customerAddresses = isset($resultArray['customerData']['addresses']) - ? $resultArray['customerData']['addresses'] : []; - $hasAtLeastOneOptionAttribute = false; - - if (is_array($customerAddresses) && !empty($customerAddresses)) { - foreach ($customerAddresses as $customerAddressIndex => $customerAddress) { - if (!empty($customerAddress['custom_attributes'])) { - foreach ($customerAddress['custom_attributes'] as $customAttributeCode => $customAttribute) { - $attributeOptionLabels = $this->getAttributeLabels($customAttribute, $customAttributeCode); - - if (!empty($attributeOptionLabels)) { - $hasAtLeastOneOptionAttribute = true; - $resultArray['customerData']['addresses'][$customerAddressIndex]['custom_attributes'] - [$customAttributeCode]['label'] = implode(', ', $attributeOptionLabels); - } - } - } - } - } - - return $hasAtLeastOneOptionAttribute ? $this->serializer->serialize($resultArray) : $result; - } - - /** - * Get Labels by CustomAttribute and CustomAttributeCode - * - * @param $customAttribute - * @param $customAttributeCode - * @return array - * @throws \Magento\Framework\Exception\InputException - * @throws \Magento\Framework\Exception\StateException - */ - private function getAttributeLabels($customAttribute, $customAttributeCode) - { - $attributeOptionLabels = []; - $customAttributeValues = explode(',', $customAttribute['value']); - $attributeOptions = $this->attributeOptionManager->getItems( - \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, - $customAttributeCode - ); - - if (!empty($attributeOptions)) { - foreach ($attributeOptions as $attributeOption) { - $attributeOptionValue = $attributeOption->getValue(); - if (in_array($attributeOptionValue, $customAttributeValues)) { - $attributeOptionLabels[] = $attributeOption->getLabel() ?? $attributeOptionValue; - } - } - } - - return $attributeOptionLabels; - } -} diff --git a/app/code/Magento/Checkout/Plugin/Block/Cart/ResetCheckoutConfigOnCartShipping.php b/app/code/Magento/Checkout/Plugin/Block/Cart/ResetCheckoutConfigOnCartShipping.php deleted file mode 100644 index fed3f0abbfbee..0000000000000 --- a/app/code/Magento/Checkout/Plugin/Block/Cart/ResetCheckoutConfigOnCartShipping.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Checkout\Plugin\Block\Cart; - -use Magento\Checkout\Block\Cart\Shipping; -use Magento\Checkout\Plugin\Block\AbstractResetCheckoutConfig; - -/** - * Class ResetCheckoutConfigOnCartShipping - * Needed for reformat Customer Data address with custom attributes as options add labels for correct view on ShippingUI - */ -class ResetCheckoutConfigOnCartShipping extends AbstractResetCheckoutConfig -{ - /** - * After Get Checkout Config - * - * @param Shipping $subject - * @param mixed $result - * @return string - * @throws \Magento\Framework\Exception\InputException - * @throws \Magento\Framework\Exception\StateException - */ - public function afterGetSerializedCheckoutConfig(Shipping $subject, $result) - { - return $this->getSerializedCheckoutConfig($subject, $result); - } -} diff --git a/app/code/Magento/Checkout/Plugin/Block/ResetCheckoutConfigOnOnePage.php b/app/code/Magento/Checkout/Plugin/Block/ResetCheckoutConfigOnOnePage.php deleted file mode 100644 index 3d53b28ab61c2..0000000000000 --- a/app/code/Magento/Checkout/Plugin/Block/ResetCheckoutConfigOnOnePage.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Checkout\Plugin\Block; - -use Magento\Checkout\Block\Onepage; - -/** - * Class ResetCheckoutConfigOnOnePage - * Needed for reformat Customer Data address with custom attributes as options add labels for correct view on UI OnePage - */ -class ResetCheckoutConfigOnOnePage extends AbstractResetCheckoutConfig -{ - /** - * After Get Checkout Config - * - * @param Onepage $subject - * @param mixed $result - * @return string - * @throws \Magento\Framework\Exception\InputException - * @throws \Magento\Framework\Exception\StateException - */ - public function afterGetSerializedCheckoutConfig(Onepage $subject, $result) - { - return $this->getSerializedCheckoutConfig($subject, $result); - } -} diff --git a/app/code/Magento/Checkout/Test/Unit/Plugin/Block/ResetCheckoutConfigOnOnePageTest.php b/app/code/Magento/Checkout/Test/Unit/Plugin/Block/ResetCheckoutConfigOnOnePageTest.php deleted file mode 100644 index 656fa628b042b..0000000000000 --- a/app/code/Magento/Checkout/Test/Unit/Plugin/Block/ResetCheckoutConfigOnOnePageTest.php +++ /dev/null @@ -1,418 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Checkout\Test\Unit\Plugin\Block; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; - -class ResetCheckoutConfigOnOnePageTest extends \PHPUnit\Framework\TestCase -{ - - /** - * @var \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage - */ - private $resetCheckoutConfigOnOnePage; - - /** - * @var \Magento\Eav\Api\AttributeOptionManagementInterface - */ - private $attributeOptionManagerMock; - - /** - * @var \Magento\Framework\Serialize\SerializerInterface - */ - private $serializerMock; - - /** - * @var \Magento\Checkout\Block\Onepage - */ - private $onePageMock; - - /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager - */ - private $objectManagerHelper; - - protected function setUp() - { - - $this->attributeOptionManagerMock = $this->createMock( - \Magento\Eav\Api\AttributeOptionManagementInterface::class - ); - - $this->serializerMock = $this->createMock( - \Magento\Framework\Serialize\SerializerInterface::class - ); - - $this->onePageMock = $this->createMock(\Magento\Checkout\Block\Onepage::class); - - $this->objectManagerHelper = new ObjectManagerHelper($this); - - $this->resetCheckoutConfigOnOnePage = $this->objectManagerHelper->getObject( - \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::class, - [ - 'attributeOptionManager' => $this->attributeOptionManagerMock, - 'serializer' => $this->serializerMock - ] - ); - } - - /** - * Test for reformat serialized checkout config with empty Result for Onepage - * - * @covers \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::afterGetSerializedCheckoutConfig() - * @return void - */ - public function testAfterGetSerializedCheckoutConfigWithEmptyResults() - { - $result = $this->resetCheckoutConfigOnOnePage->afterGetSerializedCheckoutConfig( - $this->onePageMock, json_encode([]) - ); - - $this->assertEquals( - $result, - '[]' - ); - } - - /** - * Test for reformat serialized checkout config with only options custom attributes in custom address for Onepage - * - * @covers \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::afterGetSerializedCheckoutConfig() - * @return void - */ - public function testAfterGetSerializedCheckoutConfigWithOnlyOptionsCustomAttributesInCustomAddressResults() - { - $textAttributeCode = 'text'; - $textAttributeValue = 'some text'; - $dropAttributeCode = 'dropnew'; - $dropAttributeValue1 = 15; - $dropAttributeLabel1 = 'drop 1'; - $dropAttributeValue2 = 16; - $dropAttributeLabel2 = 'drop 2'; - $multiDropAttributeValue1 = 17; - $multiDropAttributeLabel1 = 'multidrop 1'; - $multiDropAttributeValue2 = 18; - $multiDropAttributeLabel2 = 'multidrop 2'; - $multiDropAttributeCode = 'multidrop'; - $mockCheckoutConfig = [ - 'customerData' => [ - 'addresses' => [ - [ - 'custom_attributes' => [ - $dropAttributeCode => [ - 'attribute_code' => $dropAttributeCode, - 'value' => "$dropAttributeValue1", - ], - $textAttributeCode => [ - 'attribute_code' => $textAttributeCode, - 'value' => $textAttributeValue, - ], - $multiDropAttributeCode => [ - 'attribute_code' => $multiDropAttributeCode, - 'value' => "$multiDropAttributeValue1,$multiDropAttributeValue2", - ] - ] - ] - ] - ] - ]; - - $expectedCheckoutConfig = [ - 'customerData' => [ - 'addresses' => [ - [ - 'custom_attributes' => [ - $dropAttributeCode => [ - 'attribute_code' => $dropAttributeCode, - 'value' => $dropAttributeValue1, - 'label' => $dropAttributeLabel1 - ], - $textAttributeCode => [ - 'attribute_code' => $textAttributeCode, - 'value' => $textAttributeValue, - ], - $multiDropAttributeCode => [ - 'attribute_code' => $multiDropAttributeCode, - 'value' => "$multiDropAttributeValue1,$multiDropAttributeValue2", - 'label' => "$multiDropAttributeLabel1, $multiDropAttributeLabel2" - ] - ] - ] - ] - ] - ]; - - $attributeOptionDropNew1 = $this->getMockBuilder( - \Magento\Eav\Api\Data\AttributeOptionInterface::class - ) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $attributeOptionDropNew2 = $this->getMockBuilder( - \Magento\Eav\Api\Data\AttributeOptionInterface::class - ) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $attributeOptionMultidropDropNew1 = $this->getMockBuilder( - \Magento\Eav\Api\Data\AttributeOptionInterface::class - ) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $attributeOptionMultidropDropNew2 = $this->getMockBuilder( - \Magento\Eav\Api\Data\AttributeOptionInterface::class - ) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $this->serializerMock->expects($this->once()) - ->method('unserialize') - ->with( - json_encode($mockCheckoutConfig) - ) - ->willReturn($mockCheckoutConfig); - - $this->serializerMock->expects($this->once()) - ->method('serialize') - ->with( - $expectedCheckoutConfig - ) - ->willReturn(json_encode($expectedCheckoutConfig)); - - $attributeOptionDropNew1->expects($this->once()) - ->method('getValue') - ->will($this->returnValue($dropAttributeValue1)); - $attributeOptionDropNew1->expects($this->once()) - ->method('getLabel') - ->will($this->returnValue($dropAttributeLabel1)); - - $attributeOptionDropNew2->expects($this->once()) - ->method('getValue') - ->will($this->returnValue($dropAttributeValue2)); - - $attributeOptionMultidropDropNew1->expects($this->once()) - ->method('getValue') - ->will($this->returnValue($multiDropAttributeValue1)); - $attributeOptionMultidropDropNew1->expects($this->once()) - ->method('getLabel') - ->will($this->returnValue($multiDropAttributeLabel1)); - - $attributeOptionMultidropDropNew2->expects($this->once()) - ->method('getValue') - ->will($this->returnValue($multiDropAttributeValue2)); - - $attributeOptionMultidropDropNew2->expects($this->once()) - ->method('getLabel') - ->will($this->returnValue($multiDropAttributeLabel2)); - - $this->attributeOptionManagerMock->expects($this->at(0)) - ->method('getItems') - ->with( - \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, - $dropAttributeCode - ) - ->will($this->returnValue([$attributeOptionDropNew1, $attributeOptionDropNew2])); - - $this->attributeOptionManagerMock->expects($this->at(1)) - ->method('getItems') - ->with( - \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, - $textAttributeCode - ) - ->will($this->returnValue(null)); - - $this->attributeOptionManagerMock->expects($this->at(2)) - ->method('getItems') - ->with( - \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, - $multiDropAttributeCode - ) - ->will($this->returnValue([$attributeOptionMultidropDropNew1, $attributeOptionMultidropDropNew2])); - - $this->resetCheckoutConfigOnOnePage = $this->objectManagerHelper->getObject( - \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::class, - [ - 'attributeOptionManager' => $this->attributeOptionManagerMock, - 'serializer' => $this->serializerMock - ] - ); - - $result = $this->resetCheckoutConfigOnOnePage->afterGetSerializedCheckoutConfig( - $this->onePageMock, json_encode($mockCheckoutConfig) - ); - - $this->assertEquals( - $result, - json_encode($expectedCheckoutConfig) - ); - } - - /** - * Test for reformat serialized checkout config with options - * and other custom attributes in custom address for Onepage - * - * @covers \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::afterGetSerializedCheckoutConfig() - * @return void - */ - public function testAfterGetSerializedCheckoutConfigWithOptionsAndOtherCustomAttributesInCustomAddressResults() - { - $dropAttributeCode = 'dropnew'; - $dropAttributeValue1 = 15; - $dropAttributeLabel1 = 'drop 1'; - $dropAttributeValue2 = 16; - $dropAttributeLabel2 = 'drop 2'; - $multiDropAttributeValue1 = 17; - $multiDropAttributeLabel1 = 'multidrop 1'; - $multiDropAttributeValue2 = 18; - $multiDropAttributeLabel2 = 'multidrop 2'; - $multiDropAttributeCode = 'multidrop'; - $mockCheckoutConfig = [ - 'customerData' => [ - 'addresses' => [ - [ - 'custom_attributes' => [ - $dropAttributeCode => [ - 'attribute_code' => $dropAttributeCode, - 'value' => "$dropAttributeValue1", - ], - $multiDropAttributeCode => [ - 'attribute_code' => $multiDropAttributeCode, - 'value' => "$multiDropAttributeValue1,$multiDropAttributeValue2", - ] - ] - ] - ] - ] - ]; - - $expectedCheckoutConfig = [ - 'customerData' => [ - 'addresses' => [ - [ - 'custom_attributes' => [ - $dropAttributeCode => [ - 'attribute_code' => $dropAttributeCode, - 'value' => $dropAttributeValue1, - 'label' => $dropAttributeLabel1 - ], - $multiDropAttributeCode => [ - 'attribute_code' => $multiDropAttributeCode, - 'value' => "$multiDropAttributeValue1,$multiDropAttributeValue2", - 'label' => "$multiDropAttributeLabel1, $multiDropAttributeLabel2" - ] - ] - ] - ] - ] - ]; - - $attributeOptionDropNew1 = $this->getMockBuilder( - \Magento\Eav\Api\Data\AttributeOptionInterface::class - ) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $attributeOptionDropNew2 = $this->getMockBuilder( - \Magento\Eav\Api\Data\AttributeOptionInterface::class - ) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $attributeOptionMultidropDropNew1 = $this->getMockBuilder( - \Magento\Eav\Api\Data\AttributeOptionInterface::class - ) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $attributeOptionMultidropDropNew2 = $this->getMockBuilder( - \Magento\Eav\Api\Data\AttributeOptionInterface::class - ) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $this->serializerMock->expects($this->once()) - ->method('unserialize') - ->with( - json_encode($mockCheckoutConfig) - ) - ->willReturn($mockCheckoutConfig); - - $this->serializerMock->expects($this->once()) - ->method('serialize') - ->with( - $expectedCheckoutConfig - ) - ->willReturn(json_encode($expectedCheckoutConfig)); - - $attributeOptionDropNew1->expects($this->once()) - ->method('getValue') - ->will($this->returnValue($dropAttributeValue1)); - $attributeOptionDropNew1->expects($this->once()) - ->method('getLabel') - ->will($this->returnValue($dropAttributeLabel1)); - - $attributeOptionDropNew2->expects($this->once()) - ->method('getValue') - ->will($this->returnValue($dropAttributeValue2)); - - $attributeOptionMultidropDropNew1->expects($this->once()) - ->method('getValue') - ->will($this->returnValue($multiDropAttributeValue1)); - $attributeOptionMultidropDropNew1->expects($this->once()) - ->method('getLabel') - ->will($this->returnValue($multiDropAttributeLabel1)); - - $attributeOptionMultidropDropNew2->expects($this->once()) - ->method('getValue') - ->will($this->returnValue($multiDropAttributeValue2)); - $attributeOptionMultidropDropNew2->expects($this->once()) - ->method('getLabel') - ->will($this->returnValue($multiDropAttributeLabel2)); - - $this->attributeOptionManagerMock->expects($this->at(0)) - ->method('getItems') - ->with( - \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, - $dropAttributeCode - ) - ->will($this->returnValue([$attributeOptionDropNew1, $attributeOptionDropNew2])); - - $this->attributeOptionManagerMock->expects($this->at(1)) - ->method('getItems') - ->with( - \Magento\Customer\Model\Indexer\Address\AttributeProvider::ENTITY, - $multiDropAttributeCode - ) - ->will($this->returnValue([$attributeOptionMultidropDropNew1, $attributeOptionMultidropDropNew2])); - - $this->resetCheckoutConfigOnOnePage = $this->objectManagerHelper->getObject( - \Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage::class, - [ - 'attributeOptionManager' => $this->attributeOptionManagerMock, - 'serializer' => $this->serializerMock - ] - ); - - $result = $this->resetCheckoutConfigOnOnePage->afterGetSerializedCheckoutConfig( - $this->onePageMock, json_encode($mockCheckoutConfig) - ); - - $this->assertEquals( - $result, - json_encode($expectedCheckoutConfig) - ); - } -} diff --git a/app/code/Magento/Checkout/etc/di.xml b/app/code/Magento/Checkout/etc/di.xml index 267f144e7483d..71dfd12bb4779 100644 --- a/app/code/Magento/Checkout/etc/di.xml +++ b/app/code/Magento/Checkout/etc/di.xml @@ -52,10 +52,4 @@ <type name="Magento\Quote\Model\Quote"> <plugin name="clear_addresses_after_product_delete" type="Magento\Checkout\Plugin\Model\Quote\ResetQuoteAddresses"/> </type> - <type name="Magento\Checkout\Block\Onepage"> - <plugin name="deserialize_config_and_add_label_to_custom_options" type="Magento\Checkout\Plugin\Block\ResetCheckoutConfigOnOnePage"/> - </type> - <type name="Magento\Checkout\Block\Cart\Shipping"> - <plugin name="deserialize_config_and_add_label_to_custom_options_shipping" type="Magento\Checkout\Plugin\Block\Cart\ResetCheckoutConfigOnCartShipping"/> - </type> </config> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html index fd994a4e8a955..01f4868e95c1c 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html @@ -4,28 +4,37 @@ * See COPYING.txt for license details. */ --> -<div class="billing-address-details" data-bind="if: isAddressDetailsVisible() && currentBillingAddress()"> - <!-- ko text: currentBillingAddress().prefix --><!-- /ko --> <!-- ko text: currentBillingAddress().firstname --><!-- /ko --> <!-- ko text: currentBillingAddress().middlename --><!-- /ko --> - <!-- ko text: currentBillingAddress().lastname --><!-- /ko --> <!-- ko text: currentBillingAddress().suffix --><!-- /ko --><br/> - <!-- ko text: _.values(currentBillingAddress().street).join(", ") --><!-- /ko --><br/> - <!-- ko text: currentBillingAddress().city --><!-- /ko -->, <span data-bind="html: currentBillingAddress().region"></span> <!-- ko text: currentBillingAddress().postcode --><!-- /ko --><br/> - <!-- ko text: getCountryName(currentBillingAddress().countryId) --><!-- /ko --><br/> - <!-- ko if: (currentBillingAddress().telephone) --> - <a data-bind="text: currentBillingAddress().telephone, attr: {'href': 'tel:' + currentBillingAddress().telephone}"></a> - <!-- /ko --><br/> - <!-- ko foreach: { data: currentBillingAddress().customAttributes, as: 'element' } --> - <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } --> - <!-- ko if: (typeof element[attribute] === "object") --> - <!-- ko text: element[attribute].value --><!-- /ko --> - <!-- /ko --> - <!-- ko if: (typeof element[attribute] === "string") --> - <!-- ko text: element[attribute] --><!-- /ko --> - <!-- /ko --><br/> - <!-- /ko --> - <!-- /ko --> - <button type="button" +<div if="isAddressDetailsVisible() && currentBillingAddress()" class="billing-address-details"> + <text args="currentBillingAddress().prefix"/> <text args="currentBillingAddress().firstname"/> <text args="currentBillingAddress().middlename"/> + <text args="currentBillingAddress().lastname"/> <text args="currentBillingAddress().suffix"/><br/> + <text args="_.values(currentBillingAddress().street).join(', ')"/><br/> + <text args="currentBillingAddress().city "/>, <span html="currentBillingAddress().region"></span> <text args="currentBillingAddress().postcode"/><br/> + <text args="getCountryName(currentBillingAddress().countryId)"/><br/> + <a if="currentBillingAddress().telephone" attr="'href': 'tel:' + currentBillingAddress().telephone" text="currentBillingAddress().telephone"></a><br/> + + <each args="data: currentBillingAddress().customAttributes, as: 'element'"> + <each args="data: Object.keys(element), as: 'attribute'"> + <if args="typeof element[attribute] === 'object'"> + <if args="element[attribute].label"> + <text args="element[attribute].label"/> + </if> + <ifnot args="element[attribute].label"> + <if args="element[attribute].value"> + <text args="element[attribute].value"/> + </if> + </ifnot> + <if args="typeof element[attribute] === 'string'"> + <text args="element[attribute]"/> + </if> + </if><br/> + </each> + </each> + + <button visible="!isAddressSameAsShipping()" + type="button" class="action action-edit-address" - data-bind="visible: !isAddressSameAsShipping(), click: editAddress"> - <span data-bind="i18n: 'Edit'"></span> + click="editAddress"> + <span translate="'Edit'"></span> </button> </div> + diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index 467aca8fd0558..c610afec4bf9d 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -4,40 +4,38 @@ * See COPYING.txt for license details. */ --> -<div class="shipping-address-item" data-bind="css: isSelected() ? 'selected-item' : 'not-selected-item'"> - <!-- ko text: address().prefix --><!-- /ko --> <!-- ko text: address().firstname --><!-- /ko --> <!-- ko text: address().middlename --><!-- /ko --> - <!-- ko text: address().lastname --><!-- /ko --> <!-- ko text: address().suffix --><!-- /ko --><br/> - <!-- ko text: _.values(address().street).join(", ") --><!-- /ko --><br/> - <!-- ko text: address().city --><!-- /ko -->, <span data-bind="html: address().region"></span> <!-- ko text: address().postcode --><!-- /ko --><br/> - <!-- ko text: getCountryName(address().countryId) --><!-- /ko --><br/> - <!-- ko if: (address().telephone) --> - <a data-bind="text: address().telephone, attr: {'href': 'tel:' + address().telephone}"></a> - <!-- /ko --><br/> - <!-- ko foreach: { data: address().customAttributes, as: 'element' } --> - <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } --> - <!-- ko if: (typeof element[attribute] === "object") --> - <!-- ko if: (element[attribute].label) --> - <!-- ko text: element[attribute].label --><!-- /ko --> - <!-- /ko --> - <!-- ko ifnot: (element[attribute].label) --> - <!-- ko if: (element[attribute].value) --> - <!-- ko text: element[attribute].value --><!-- /ko --> - <!-- /ko --> - <!-- /ko --> - <!-- /ko --> - <!-- ko if: (typeof element[attribute] === "string") --> - <!-- ko text: element[attribute] --><!-- /ko --> - <!-- /ko --><br/> - <!-- /ko --> - <!-- /ko --> - <!-- ko if: (address().isEditable()) --> - <button type="button" +<div class="shipping-address-item" css="'selected-item' : isSelected() , 'not-selected-item':!isSelected()"> + <text args="address().prefix"/> <text args="address().firstname"/> <text args="address().middlename"/> + <text args="address().lastname"/> <text args="address().suffix"/><br/> + <text args="_.values(address().street).join(', ')"/><br/> + <text args="address().city "/>, <span html="address().region"></span> <text args="address().postcode"/><br/> + <text args="getCountryName(address().countryId)"/><br/> + <a if="address().telephone" attr="'href': 'tel:' + address().telephone" text="address().telephone"></a><br/> + + <each args="data: address().customAttributes, as: 'element'"> + <each args="data: Object.keys(element), as: 'attribute'"> + <if args="typeof element[attribute] === 'object'"> + <if args="element[attribute].label"> + <text args="element[attribute].label"/> + </if> + <ifnot args="element[attribute].label"> + <if args="element[attribute].value"> + <text args="element[attribute].value"/> + </if> + </ifnot> + <if args="typeof element[attribute] === 'string'"> + <text args="element[attribute]"/> + </if> + </if><br/> + </each> + </each> + + <button visible="address().isEditable()" type="button" class="action edit-address-link" - data-bind="click: editAddress, visible: address().isEditable()"> - <span data-bind="i18n: 'Edit'"></span> + click="editAddress"> + <span translate="'Edit'"></span> </button> - <!-- /ko --> - <button type="button" data-bind="click: selectAddress" class="action action-select-shipping-item"> - <span data-bind="i18n: 'Ship Here'"></span> + <button type="button" click="selectAddress" class="action action-select-shipping-item"> + <span translate="'Ship Here'"></span> </button> </div> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index 58a8ca66cafe1..f03ec8dc8f3de 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -4,30 +4,29 @@ * See COPYING.txt for license details. */ --> -<!-- ko if: (visible()) --> - <!-- ko text: address().prefix --><!-- /ko --> <!-- ko text: address().firstname --><!-- /ko --> <!-- ko text: address().middlename --><!-- /ko --> - <!-- ko text: address().lastname --><!-- /ko --> <!-- ko text: address().suffix --><!-- /ko --><br/> - <!-- ko text: _.values(address().street).join(", ") --><!-- /ko --><br/> - <!-- ko text: address().city --><!-- /ko -->, <span data-bind="html: address().region"></span> <!-- ko text: address().postcode --><!-- /ko --><br/> - <!-- ko text: getCountryName(address().countryId) --><!-- /ko --><br/> - <!-- ko if: (address().telephone) --> - <a data-bind="text: address().telephone, attr: {'href': 'tel:' + address().telephone}"></a> - <!-- /ko --><br/> - <!-- ko foreach: { data: address().customAttributes, as: 'element' } --> - <!-- ko foreach: { data: Object.keys(element), as: 'attribute' } --> - <!-- ko if: (typeof element[attribute] === "object") --> - <!-- ko if: (element[attribute].label) --> - <!-- ko text: element[attribute].label --><!-- /ko --> - <!-- /ko --> - <!-- ko ifnot: (element[attribute].label) --> - <!-- ko if: (element[attribute].value) --> - <!-- ko text: element[attribute].value --><!-- /ko --> - <!-- /ko --> - <!-- /ko --> - <!-- /ko --> - <!-- ko if: (typeof element[attribute] === "string") --> - <!-- ko text: element[attribute] --><!-- /ko --> - <!-- /ko --><br/> - <!-- /ko --> - <!-- /ko --> -<!-- /ko --> +<if args="visible()"> + <text args="address().prefix"/> <text args="address().firstname"/> <text args="address().middlename"/> + <text args="address().lastname"/> <text args="address().suffix"/><br/> + <text args="_.values(address().street).join(', ')"/><br/> + <text args="address().city "/>, <span html="address().region"></span> <text args="address().postcode"/><br/> + <text args="getCountryName(address().countryId)"/><br/> + <a if="address().telephone" attr="'href': 'tel:' + address().telephone" text="address().telephone"></a><br/> + + <each args="data: address().customAttributes, as: 'element'"> + <each args="data: Object.keys(element), as: 'attribute'"> + <if args="typeof element[attribute] === 'object'"> + <if args="element[attribute].label"> + <text args="element[attribute].label"/> + </if> + <ifnot args="element[attribute].label"> + <if args="element[attribute].value"> + <text args="element[attribute].value"/> + </if> + </ifnot> + <if args="typeof element[attribute] === 'string'"> + <text args="element[attribute]"/> + </if> + </if><br/> + </each> + </each> +</if> From c49c8a1232dde2c8a9cf4126355fe0aacbe4b283 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 13 Sep 2018 19:22:40 +0300 Subject: [PATCH 56/57] MAGETWO-94407: [2.3.0] Cart Price Rule for configurable products - Fix static test --- app/code/Magento/SalesRule/Model/Rule/Condition/Product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php index b0bba8e8f72d6..9bda4793e8681 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php @@ -213,7 +213,7 @@ public function getValueElementChooserUrl() } /** - * Get formatted price. + * Get locale-based formatted price. * * @param string $value * @return float|null From 92e5fdd8dcf88d1c026064c333d34a956d55cdf4 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Thu, 13 Sep 2018 22:08:07 +0300 Subject: [PATCH 57/57] MAGETWO-91760: Custom address attributes displays with wrong value on checkout - Fix template --- .../view/frontend/web/template/billing-address/details.html | 6 +++--- .../template/shipping-address/address-renderer/default.html | 6 +++--- .../shipping-information/address-renderer/default.html | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html index 01f4868e95c1c..cc1d960bbe44b 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html @@ -23,9 +23,9 @@ <text args="element[attribute].value"/> </if> </ifnot> - <if args="typeof element[attribute] === 'string'"> - <text args="element[attribute]"/> - </if> + </if> + <if args="typeof element[attribute] === 'string'"> + <text args="element[attribute]"/> </if><br/> </each> </each> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index c610afec4bf9d..05ced7a978f82 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -23,9 +23,9 @@ <text args="element[attribute].value"/> </if> </ifnot> - <if args="typeof element[attribute] === 'string'"> - <text args="element[attribute]"/> - </if> + </if> + <if args="typeof element[attribute] === 'string'"> + <text args="element[attribute]"/> </if><br/> </each> </each> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index f03ec8dc8f3de..97286a28552d2 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -23,9 +23,9 @@ <text args="element[attribute].value"/> </if> </ifnot> - <if args="typeof element[attribute] === 'string'"> - <text args="element[attribute]"/> - </if> + </if> + <if args="typeof element[attribute] === 'string'"> + <text args="element[attribute]"/> </if><br/> </each> </each>