diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php b/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php index b763774f917308529f724af8b7758887fe0fd5ba..e37fe022342ed5c194914133b9392ef559ff083a 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php +++ b/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php @@ -76,6 +76,7 @@ class AdvancedPricing extends \Magento\CatalogImportExport\Model\Export\Product ImportAdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => '', ImportAdvancedPricing::COL_TIER_PRICE_QTY => '', ImportAdvancedPricing::COL_TIER_PRICE => '', + ImportAdvancedPricing::COL_TIER_PRICE_TYPE => '' ]; /** @@ -279,6 +280,8 @@ class AdvancedPricing extends \Magento\CatalogImportExport\Model\Export\Product } /** + * Correct export data. + * * @param array $exportData * @return array * @SuppressWarnings(PHPMD.UnusedLocalVariable) @@ -302,6 +305,12 @@ class AdvancedPricing extends \Magento\CatalogImportExport\Model\Export\Product : null ); unset($exportRow[ImportAdvancedPricing::VALUE_ALL_GROUPS]); + } elseif ($keyTemplate === ImportAdvancedPricing::COL_TIER_PRICE) { + $exportRow[$keyTemplate] = $row[ImportAdvancedPricing::COL_TIER_PRICE_PERCENTAGE_VALUE] + ? $row[ImportAdvancedPricing::COL_TIER_PRICE_PERCENTAGE_VALUE] + : $row[ImportAdvancedPricing::COL_TIER_PRICE]; + $exportRow[ImportAdvancedPricing::COL_TIER_PRICE_TYPE] + = $this->tierPriceTypeValue($row[ImportAdvancedPricing::COL_TIER_PRICE_PERCENTAGE_VALUE]); } else { $exportRow[$keyTemplate] = $row[$keyTemplate]; } @@ -311,11 +320,25 @@ class AdvancedPricing extends \Magento\CatalogImportExport\Model\Export\Product $customExportData[$key] = $exportRow; unset($exportRow); } + return $customExportData; } /** - * Get Tier and Group Pricing + * Check type for tier price. + * + * @param string $tierPricePercentage + * @return string + */ + private function tierPriceTypeValue($tierPricePercentage) + { + return $tierPricePercentage + ? ImportAdvancedPricing::TIER_PRICE_TYPE_PERCENT + : ImportAdvancedPricing::TIER_PRICE_TYPE_FIXED; + } + + /** + * Get tier prices. * * @param array $listSku * @param string $table @@ -336,6 +359,7 @@ class AdvancedPricing extends \Magento\CatalogImportExport\Model\Export\Product ImportAdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => 'ap.customer_group_id', ImportAdvancedPricing::COL_TIER_PRICE_QTY => 'ap.qty', ImportAdvancedPricing::COL_TIER_PRICE => 'ap.value', + ImportAdvancedPricing::COL_TIER_PRICE_PERCENTAGE_VALUE => 'ap.percentage_value', ]; if (isset($exportFilter) && !empty($exportFilter)) { $price = $exportFilter['tier_price']; @@ -371,6 +395,9 @@ class AdvancedPricing extends \Magento\CatalogImportExport\Model\Export\Product if (isset($price[1]) && !empty($price[1])) { $select->where('ap.value <= ?', $price[1]); } + if (isset($price[0]) && !empty($price[0]) || isset($price[1]) && !empty($price[1])) { + $select->orWhere('ap.percentage_value IS NOT NULL'); + } if (isset($updatedAtFrom) && !empty($updatedAtFrom)) { $select->where('cpe.updated_at >= ?', $updatedAtFrom); } diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php index 53c4605a819132df0791df60edb325ed5cf5837c..e2275f767ee7ba74ff42528cc6fdb1aa94882c36 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php +++ b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php @@ -33,6 +33,14 @@ class AdvancedPricing extends \Magento\ImportExport\Model\Import\Entity\Abstract const COL_TIER_PRICE = 'tier_price'; + const COL_TIER_PRICE_PERCENTAGE_VALUE = 'percentage_value'; + + const COL_TIER_PRICE_TYPE = 'tier_price_value_type'; + + const TIER_PRICE_TYPE_FIXED = 'Fixed'; + + const TIER_PRICE_TYPE_PERCENT = 'Discount'; + const TABLE_TIER_PRICE = 'catalog_product_entity_tier_price'; const DEFAULT_ALL_GROUPS_GROUPED_PRICE_VALUE = '0'; @@ -46,7 +54,7 @@ class AdvancedPricing extends \Magento\ImportExport\Model\Import\Entity\Abstract const VALIDATOR_TEAR_PRICE = 'validator_tear_price'; /** - * Validation failure message template definitions + * Validation failure message template definitions. * * @var array */ @@ -57,6 +65,8 @@ class AdvancedPricing extends \Magento\ImportExport\Model\Import\Entity\Abstract ValidatorInterface::ERROR_INVALID_TIER_PRICE_QTY => 'Tier Price data price or quantity value is invalid', ValidatorInterface::ERROR_INVALID_TIER_PRICE_SITE => 'Tier Price data website is invalid', ValidatorInterface::ERROR_INVALID_TIER_PRICE_GROUP => 'Tier Price customer group is invalid', + ValidatorInterface::ERROR_INVALID_TIER_PRICE_TYPE => 'Value for \'tier_price_value_type\' ' . + 'attribute contains incorrect value, acceptable values are Fixed, Discount', ValidatorInterface::ERROR_TIER_DATA_INCOMPLETE => 'Tier Price data is incomplete', ValidatorInterface::ERROR_INVALID_ATTRIBUTE_DECIMAL => 'Value for \'%s\' attribute contains incorrect value, acceptable values are in decimal format', @@ -70,7 +80,7 @@ class AdvancedPricing extends \Magento\ImportExport\Model\Import\Entity\Abstract protected $needColumnCheck = true; /** - * Valid column names + * Valid column names. * * @array */ @@ -80,6 +90,7 @@ class AdvancedPricing extends \Magento\ImportExport\Model\Import\Entity\Abstract self::COL_TIER_PRICE_CUSTOMER_GROUP, self::COL_TIER_PRICE_QTY, self::COL_TIER_PRICE, + self::COL_TIER_PRICE_TYPE ]; /** @@ -379,7 +390,10 @@ class AdvancedPricing extends \Magento\ImportExport\Model\Import\Entity\Abstract $rowData[self::COL_TIER_PRICE_CUSTOMER_GROUP] ), 'qty' => $rowData[self::COL_TIER_PRICE_QTY], - 'value' => $rowData[self::COL_TIER_PRICE], + 'value' => $rowData[self::COL_TIER_PRICE_TYPE] === self::TIER_PRICE_TYPE_FIXED + ? $rowData[self::COL_TIER_PRICE] : 0, + 'percentage_value' => $rowData[self::COL_TIER_PRICE_TYPE] === self::TIER_PRICE_TYPE_PERCENT + ? $rowData[self::COL_TIER_PRICE] : null, 'website_id' => $this->getWebsiteId($rowData[self::COL_TIER_PRICE_WEBSITE]) ]; } @@ -429,7 +443,7 @@ class AdvancedPricing extends \Magento\ImportExport\Model\Import\Entity\Abstract } } if ($priceIn) { - $this->_connection->insertOnDuplicate($tableName, $priceIn, ['value']); + $this->_connection->insertOnDuplicate($tableName, $priceIn, ['value', 'percentage_value']); } } return $this; diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPrice.php b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPrice.php index 5bc9bebf420768184c08ea3f2861e5cfcaaf2e21..53ee3013c625beabb7a6f42229a32a9eb7b02eee 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPrice.php +++ b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPrice.php @@ -22,7 +22,8 @@ class TierPrice extends \Magento\CatalogImportExport\Model\Import\Product\Valida AdvancedPricing::COL_TIER_PRICE_WEBSITE, AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP, AdvancedPricing::COL_TIER_PRICE_QTY, - AdvancedPricing::COL_TIER_PRICE + AdvancedPricing::COL_TIER_PRICE, + AdvancedPricing::COL_TIER_PRICE_TYPE ]; /** @@ -101,6 +102,7 @@ class TierPrice extends \Magento\CatalogImportExport\Model\Import\Product\Valida || !isset($value[AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP]) || !isset($value[AdvancedPricing::COL_TIER_PRICE_QTY]) || !isset($value[AdvancedPricing::COL_TIER_PRICE]) + || !isset($value[AdvancedPricing::COL_TIER_PRICE_TYPE]) || $this->hasEmptyColumns($value) ) { $this->_addMessages([self::ERROR_TIER_DATA_INCOMPLETE]); diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPriceType.php b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPriceType.php new file mode 100644 index 0000000000000000000000000000000000000000..29982459e0211991427aafa5eddecf88011b899d --- /dev/null +++ b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPriceType.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator; + +use Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing; +use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface; + +/** + * Class TierPriceType validates tier price type. + */ +class TierPriceType extends \Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator +{ + /** + * {@inheritdoc} + */ + public function init($context) + { + return parent::init($context); + } + + /** + * Validate tier price type. + * + * @param array $value + * @return bool + */ + public function isValid($value) + { + $isValid = true; + + if (isset($value[AdvancedPricing::COL_TIER_PRICE_TYPE]) + && !empty($value[AdvancedPricing::COL_TIER_PRICE_TYPE]) + && !in_array( + $value[AdvancedPricing::COL_TIER_PRICE_TYPE], + [AdvancedPricing::TIER_PRICE_TYPE_FIXED, AdvancedPricing::TIER_PRICE_TYPE_PERCENT] + ) + ) { + $this->_addMessages([RowValidatorInterface::ERROR_INVALID_TIER_PRICE_TYPE]); + $isValid = false; + } + + return $isValid; + } +} diff --git a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/TierPriceTypeTest.php b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/TierPriceTypeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6abdd2232fb44233882e140f61f8020aef145289 --- /dev/null +++ b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/TierPriceTypeTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdvancedPricingImportExport\Test\Unit\Model\Import\AdvancedPricing\Validator; + +use \Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing as AdvancedPricing; + +/** + * Class TierPriceTypeTest. + */ +class TierPriceTypeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var AdvancedPricing\Validator\TierPriceType + */ + private $tierPriceType; + + /** + * Set up. + * + * @return void + */ + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->tierPriceType = $objectManager->getObject( + AdvancedPricing\Validator\TierPriceType::class, + [] + ); + } + + /** + * Test for isValid() method. + * + * @dataProvider isValidDataProvider + * @param array $value + * @param bool $expectedResult + */ + public function testIsValid(array $value, $expectedResult) + { + $result = $this->tierPriceType->isValid($value); + $this->assertEquals($expectedResult, $result); + } + + /** + * Data Provider for testIsValid(). + * + * @return array + */ + public function isValidDataProvider() + { + return [ + [ + [AdvancedPricing::COL_TIER_PRICE_TYPE => AdvancedPricing::TIER_PRICE_TYPE_FIXED], + true + ], + [ + [AdvancedPricing::COL_TIER_PRICE_TYPE => AdvancedPricing::TIER_PRICE_TYPE_PERCENT], + true + ], + [ + [], + true + ], + [ + [AdvancedPricing::COL_TIER_PRICE_TYPE => null], + true + ], + [ + [AdvancedPricing::COL_TIER_PRICE_TYPE => 'wrong type'], + false + ] + ]; + } +} diff --git a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricingTest.php b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricingTest.php index a289e9970b4999ee82bde14fdb452ef0d78236df..1c80f5789c38108ae9f94030871602f5628086e1 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricingTest.php +++ b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricingTest.php @@ -418,33 +418,123 @@ class AdvancedPricingTest extends \Magento\ImportExport\Test\Unit\Model\Import\A $groupWebsiteId, $expectedTierPrices ) { - $this->advancedPricing + $skuProduct = 'product1'; + $sku = $data[0][AdvancedPricing::COL_SKU]; + $advancedPricing = $this->getAdvancedPricingMock( + [ + 'retrieveOldSkus', + 'validateRow', + 'addRowError', + 'getCustomerGroupId', + 'getWebSiteId', + 'deleteProductTierPrices', + 'getBehavior', + 'saveAndReplaceAdvancedPrices', + 'processCountExistingPrices', + 'processCountNewPrices' + ] + ); + $advancedPricing ->expects($this->any()) ->method('getBehavior') ->willReturn(\Magento\ImportExport\Model\Import::BEHAVIOR_APPEND); $this->dataSourceModel->expects($this->at(0))->method('getNextBunch')->willReturn($data); - $this->advancedPricing->expects($this->any())->method('validateRow')->willReturn(true); + $advancedPricing->expects($this->any())->method('validateRow')->willReturn(true); - $this->advancedPricing->expects($this->any())->method('getCustomerGroupId')->willReturnMap( + $advancedPricing->expects($this->any())->method('getCustomerGroupId')->willReturnMap( [ [$data[0][AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP], $tierCustomerGroupId], ] ); - $this->advancedPricing->expects($this->any())->method('getWebSiteId')->willReturnMap( + $advancedPricing->expects($this->any())->method('getWebSiteId')->willReturnMap( [ [$data[0][AdvancedPricing::COL_TIER_PRICE_WEBSITE], $tierWebsiteId], ] ); - $this->advancedPricing->expects($this->any())->method('saveProductPrices')->will($this->returnSelf()); + $oldSkus = [$sku => $skuProduct]; + $expectedTierPrices[$sku][0][self::LINK_FIELD] = $skuProduct; + $advancedPricing->expects($this->once())->method('retrieveOldSkus')->willReturn($oldSkus); + $this->connection->expects($this->once()) + ->method('insertOnDuplicate') + ->with(self::TABLE_NAME, $expectedTierPrices[$sku], ['value', 'percentage_value']); - $this->advancedPricing->expects($this->any())->method('processCountExistingPrices')->willReturnSelf(); - $this->advancedPricing->expects($this->any())->method('processCountNewPrices')->willReturnSelf(); + $advancedPricing->expects($this->any())->method('processCountExistingPrices')->willReturnSelf(); + $advancedPricing->expects($this->any())->method('processCountNewPrices')->willReturnSelf(); - $result = $this->invokeMethod($this->advancedPricing, 'saveAndReplaceAdvancedPrices'); + $result = $this->invokeMethod($advancedPricing, 'saveAndReplaceAdvancedPrices'); - $this->assertEquals($this->advancedPricing, $result); + $this->assertEquals($advancedPricing, $result); + } + + /** + * Test method saveAndReplaceAdvancedPrices with append import behaviour. + */ + public function testSaveAndReplaceAdvancedPricesAppendBehaviourDataAndCallsWithoutTierPrice() + { + $data = [ + 0 => [ + AdvancedPricing::COL_SKU => 'sku value', + AdvancedPricing::COL_TIER_PRICE_WEBSITE => null, + AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => 'tier price customer group value - not all groups', + AdvancedPricing::COL_TIER_PRICE_QTY => 'tier price qty value', + AdvancedPricing::COL_TIER_PRICE => 'tier price value', + AdvancedPricing::COL_TIER_PRICE_TYPE => AdvancedPricing::TIER_PRICE_TYPE_FIXED + ], + ]; + $tierCustomerGroupId = 'tier customer group id value'; + $tierWebsiteId = 'tier website id value'; + $expectedTierPrices = []; + + $skuProduct = 'product1'; + $sku = $data[0][AdvancedPricing::COL_SKU]; + $advancedPricing = $this->getAdvancedPricingMock( + [ + 'retrieveOldSkus', + 'validateRow', + 'addRowError', + 'getCustomerGroupId', + 'getWebSiteId', + 'deleteProductTierPrices', + 'getBehavior', + 'saveAndReplaceAdvancedPrices', + 'processCountExistingPrices', + 'processCountNewPrices' + ] + ); + $advancedPricing + ->expects($this->any()) + ->method('getBehavior') + ->willReturn(\Magento\ImportExport\Model\Import::BEHAVIOR_APPEND); + $this->dataSourceModel->expects($this->at(0))->method('getNextBunch')->willReturn($data); + $advancedPricing->expects($this->any())->method('validateRow')->willReturn(true); + + $advancedPricing->expects($this->any())->method('getCustomerGroupId')->willReturnMap( + [ + [$data[0][AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP], $tierCustomerGroupId], + ] + ); + + $advancedPricing->expects($this->any())->method('getWebSiteId')->willReturnMap( + [ + [$data[0][AdvancedPricing::COL_TIER_PRICE_WEBSITE], $tierWebsiteId], + ] + ); + + $oldSkus = [$sku => $skuProduct]; + $expectedTierPrices[$sku][0][self::LINK_FIELD] = $skuProduct; + $advancedPricing->expects($this->never())->method('retrieveOldSkus')->willReturn($oldSkus); + $this->connection->expects($this->never()) + ->method('insertOnDuplicate') + ->with(self::TABLE_NAME, $expectedTierPrices[$sku], ['value', 'percentage_value']); + + $advancedPricing->expects($this->any())->method('processCountExistingPrices')->willReturnSelf(); + $advancedPricing->expects($this->any())->method('processCountNewPrices')->willReturnSelf(); + + $result = $this->invokeMethod($advancedPricing, 'saveAndReplaceAdvancedPrices'); + + $this->assertEquals($advancedPricing, $result); } /** @@ -575,6 +665,7 @@ class AdvancedPricingTest extends \Magento\ImportExport\Test\Unit\Model\Import\A AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => 'tier price customer group value - not all groups ', AdvancedPricing::COL_TIER_PRICE_QTY => 'tier price qty value', AdvancedPricing::COL_TIER_PRICE => 'tier price value', + AdvancedPricing::COL_TIER_PRICE_TYPE => AdvancedPricing::TIER_PRICE_TYPE_FIXED ], ], '$tierCustomerGroupId' => 'tier customer group id value', @@ -585,25 +676,25 @@ class AdvancedPricingTest extends \Magento\ImportExport\Test\Unit\Model\Import\A 'sku value' => [ [ 'all_groups' => false, - //$rowData[self::COL_TIER_PRICE_CUSTOMER_GROUP] == self::VALUE_ALL_GROUPS 'customer_group_id' => 'tier customer group id value', - //$tierCustomerGroupId 'qty' => 'tier price qty value', 'value' => 'tier price value', 'website_id' => 'tier website id value', + 'percentage_value' => null ], ], ], ], - [// tier customer group is equal to all group + [ '$data' => [ 0 => [ AdvancedPricing::COL_SKU => 'sku value', //tier AdvancedPricing::COL_TIER_PRICE_WEBSITE => 'tier price website value', - AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => AdvancedPricing::VALUE_ALL_GROUPS, + AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => 'tier price customer group value - not all groups ', AdvancedPricing::COL_TIER_PRICE_QTY => 'tier price qty value', AdvancedPricing::COL_TIER_PRICE => 'tier price value', + AdvancedPricing::COL_TIER_PRICE_TYPE => AdvancedPricing::TIER_PRICE_TYPE_PERCENT ], ], '$tierCustomerGroupId' => 'tier customer group id value', @@ -613,33 +704,44 @@ class AdvancedPricingTest extends \Magento\ImportExport\Test\Unit\Model\Import\A '$expectedTierPrices' => [ 'sku value' => [ [ - 'all_groups' => true, - //$rowData[self::COL_TIER_PRICE_CUSTOMER_GROUP] == self::VALUE_ALL_GROUPS + 'all_groups' => false, 'customer_group_id' => 'tier customer group id value', - //$tierCustomerGroupId 'qty' => 'tier price qty value', - 'value' => 'tier price value', + 'value' => 0, + 'percentage_value' => 'tier price value', 'website_id' => 'tier website id value', ], ], ], ], - [ + [// tier customer group is equal to all group '$data' => [ 0 => [ AdvancedPricing::COL_SKU => 'sku value', //tier - AdvancedPricing::COL_TIER_PRICE_WEBSITE => null, - AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => 'tier price customer group value - not all groups', + AdvancedPricing::COL_TIER_PRICE_WEBSITE => 'tier price website value', + AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => AdvancedPricing::VALUE_ALL_GROUPS, AdvancedPricing::COL_TIER_PRICE_QTY => 'tier price qty value', AdvancedPricing::COL_TIER_PRICE => 'tier price value', + AdvancedPricing::COL_TIER_PRICE_TYPE => AdvancedPricing::TIER_PRICE_TYPE_FIXED ], ], '$tierCustomerGroupId' => 'tier customer group id value', '$groupCustomerGroupId' => 'group customer group id value', '$tierWebsiteId' => 'tier website id value', '$groupWebsiteId' => 'group website id value', - '$expectedTierPrices' => [], + '$expectedTierPrices' => [ + 'sku value' => [ + [ + 'all_groups' => true, + 'customer_group_id' => 'tier customer group id value', + 'qty' => 'tier price qty value', + 'value' => 'tier price value', + 'website_id' => 'tier website id value', + 'percentage_value' => null + ], + ], + ], ], [ '$data' => [ @@ -650,6 +752,7 @@ class AdvancedPricingTest extends \Magento\ImportExport\Test\Unit\Model\Import\A AdvancedPricing::COL_TIER_PRICE_CUSTOMER_GROUP => 'tier price customer group value - not all groups', AdvancedPricing::COL_TIER_PRICE_QTY => 'tier price qty value', AdvancedPricing::COL_TIER_PRICE => 'tier price value', + AdvancedPricing::COL_TIER_PRICE_TYPE => AdvancedPricing::TIER_PRICE_TYPE_FIXED ], ], '$tierCustomerGroupId' => 'tier customer group id value', @@ -660,12 +763,11 @@ class AdvancedPricingTest extends \Magento\ImportExport\Test\Unit\Model\Import\A 'sku value' => [ [ 'all_groups' => false, - //$rowData[self::COL_TIER_PRICE_CUSTOMER_GROUP] == self::VALUE_ALL_GROUPS 'customer_group_id' => 'tier customer group id value', - //$tierCustomerGroupId 'qty' => 'tier price qty value', 'value' => 'tier price value', 'website_id' => 'tier website id value', + 'percentage_value' => null ], ] ], @@ -746,7 +848,7 @@ class AdvancedPricingTest extends \Magento\ImportExport\Test\Unit\Model\Import\A $this->connection->expects($this->exactly($callNum)) ->method('insertOnDuplicate') - ->with(self::TABLE_NAME, $priceIn, ['value']); + ->with(self::TABLE_NAME, $priceIn, ['value', 'percentage_value']); $this->invokeMethod($this->advancedPricing, 'saveProductPrices', [$priceData, 'table']); } diff --git a/app/code/Magento/AdvancedPricingImportExport/etc/di.xml b/app/code/Magento/AdvancedPricingImportExport/etc/di.xml index c3444069c14c0f3f226bad8cf61ef0d5fc092c17..711d4b8b399f5a8709a1fa0760b16c1aad60106f 100644 --- a/app/code/Magento/AdvancedPricingImportExport/etc/di.xml +++ b/app/code/Magento/AdvancedPricingImportExport/etc/di.xml @@ -14,6 +14,7 @@ <argument name="validators" xsi:type="array"> <item name="tierPrice" xsi:type="object">Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\TierPrice</item> <item name="website" xsi:type="object">Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\Website</item> + <item name="tierPriceType" xsi:type="object">Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator\TierPriceType</item> </argument> </arguments> </type> diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/TierPriceTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/TierPriceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9dccb8eef452ad50e58e04aef1f7273a3fb524a4 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/TierPriceTest.php @@ -0,0 +1,141 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier; + +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\TierPrice; + +/** + * Class TierPriceTest. + */ +class TierPriceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ProductPriceOptionsInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $productPriceOptions; + + /** + * @var ArrayManager|\PHPUnit_Framework_MockObject_MockObject + */ + private $arrayManager; + + /** + * @var TierPrice + */ + private $tierPrice; + + /** + * Set Up. + * @return void + */ + protected function setUp() + { + $this->productPriceOptions = $this->getMock(ProductPriceOptionsInterface::class); + $this->arrayManager = $this->getMock(ArrayManager::class, [], [], '', false); + + $this->tierPrice = (new ObjectManager($this))->getObject(TierPrice::class, [ + 'productPriceOptions' => $this->productPriceOptions, + 'arrayManager' => $this->arrayManager, + ]); + } + + /** + * Test modifyData. + */ + public function testModifyData() + { + $data = [1, 2]; + $this->assertEquals($data, $this->tierPrice->modifyData($data)); + } + + /** + * Test modifyMeta. + */ + public function testModifyMeta() + { + $meta = [1, 2]; + $tierPricePath = 'tier_price'; + $priceWrapperPath = 'tier_price/some-wrapper'; + $pricePath = $priceWrapperPath . '/price'; + $priceMeta = [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'visible' => true, + 'validation' => ['validate-number' => true], + ], + ], + ], + ]; + + $this->productPriceOptions->expects($this->once())->method('toOptionArray')->willReturn([ + [ + 'value' => ProductPriceOptionsInterface::VALUE_FIXED, + 'label' => 'label1', + ], + ]); + + $this->productPriceOptions->expects($this->once())->method('toOptionArray')->willReturn([ + [ + 'value' => ProductPriceOptionsInterface::VALUE_FIXED, + 'label' => 'label1', + ], + ]); + + $this->arrayManager + ->expects($this->exactly(2)) + ->method('findPath') + ->willReturnMap([ + [ + ProductAttributeInterface::CODE_TIER_PRICE, + $meta, + null, + 'children', + ArrayManager::DEFAULT_PATH_DELIMITER, + $tierPricePath + ], + [ + ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE, + $meta, + $tierPricePath, + null, + ArrayManager::DEFAULT_PATH_DELIMITER, + $pricePath + ], + ]); + $this->arrayManager + ->expects($this->once()) + ->method('get') + ->with($pricePath, $meta) + ->willReturn($priceMeta); + $this->arrayManager + ->expects($this->once()) + ->method('remove') + ->with($pricePath, $meta) + ->willReturn($meta); + $this->arrayManager + ->expects($this->once()) + ->method('slicePath') + ->with($pricePath, 0, -1) + ->willReturn($priceWrapperPath); + $this->arrayManager + ->expects($this->once()) + ->method('merge') + ->with($priceWrapperPath, $meta, $this->isType('array')) + ->willReturnArgument(2); + + $modifiedMeta = $this->tierPrice->modifyMeta($meta); + $children = $modifiedMeta['price_value']['children']; + + $this->assertNotEmpty($children[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_VALUE_TYPE]); + $this->assertNotEmpty($children[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PERCENTAGE_VALUE]); + $this->assertEquals($priceMeta, $children[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE]); + } +} diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php new file mode 100644 index 0000000000000000000000000000000000000000..ac511edcf2e5338eba6b83c60cf38a749406cf89 --- /dev/null +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -0,0 +1,171 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier; + +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\Ui\Component\Container; +use Magento\Ui\Component\Form\Element\DataType\Price; +use Magento\Ui\Component\Form\Element\Input; +use Magento\Ui\Component\Form\Element\Select; +use Magento\Ui\Component\Form\Field; + +/** + * Tier prices modifier adds price type option to tier prices. + */ +class TierPrice extends AbstractModifier +{ + /** + * @var ProductPriceOptionsInterface + */ + private $productPriceOptions; + + /** + * @var ArrayManager + */ + private $arrayManager; + + /** + * @param ProductPriceOptionsInterface $productPriceOptions + * @param ArrayManager $arrayManager + */ + public function __construct( + ProductPriceOptionsInterface $productPriceOptions, + ArrayManager $arrayManager + ) { + $this->productPriceOptions = $productPriceOptions; + $this->arrayManager = $arrayManager; + } + + /** + * {@inheritdoc} + */ + public function modifyData(array $data) + { + return $data; + } + + /** + * {@inheritdoc} + */ + public function modifyMeta(array $meta) + { + $tierPricePath = $this->arrayManager->findPath( + ProductAttributeInterface::CODE_TIER_PRICE, + $meta, + null, + 'children' + ); + if ($tierPricePath) { + $pricePath = $this->arrayManager->findPath( + ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE, + $meta, + $tierPricePath + ); + + if ($pricePath) { + $priceMeta = $this->arrayManager->get($pricePath, $meta); + $updatedStructure = $this->getUpdatedTierPriceStructure($priceMeta); + $meta = $this->arrayManager->remove($pricePath, $meta); + $meta = $this->arrayManager->merge( + $this->arrayManager->slicePath($pricePath, 0, -1), + $meta, + $updatedStructure + ); + } + } + return $meta; + } + + /** + * Get updated tier price structure. + * + * @param array $priceMeta + * @return array + */ + private function getUpdatedTierPriceStructure(array $priceMeta) + { + $priceTypeOptions = $this->productPriceOptions->toOptionArray(); + $firstOption = $priceTypeOptions ? current($priceTypeOptions) : null; + + $priceMeta['arguments']['data']['config']['visible'] = $firstOption + && $firstOption['value'] == ProductPriceOptionsInterface::VALUE_FIXED; + $priceMeta['arguments']['data']['config']['validation'] = [ + 'validate-number' => true, + ]; + return [ + 'price_value' => [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'componentType' => Container::NAME, + 'formElement' => Container::NAME, + 'dataType' => Price::NAME, + 'component' => 'Magento_Ui/js/form/components/group', + 'label' => __('Price'), + 'enableLabel' => true, + 'dataScope' => '', + 'sortOrder' => isset($priceMeta['arguments']['data']['config']['sortOrder']) + ? $priceMeta['arguments']['data']['config']['sortOrder'] : 40, + ], + ], + ], + 'children' => [ + ProductAttributeInterface::CODE_TIER_PRICE_FIELD_VALUE_TYPE => [ + 'arguments' => [ + 'data' => [ + 'options' => $priceTypeOptions, + 'config' => [ + 'componentType' => Field::NAME, + 'formElement' => Select::NAME, + 'dataType' => 'text', + 'component' => 'Magento_Catalog/js/tier-price/value-type-select', + 'prices' => [ + ProductPriceOptionsInterface::VALUE_FIXED => '${ $.parentName }.' + . ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE, + ProductPriceOptionsInterface::VALUE_PERCENT => '${ $.parentName }.' + . ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PERCENTAGE_VALUE, + ], + ], + ], + ], + ], + ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE => $priceMeta, + ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PERCENTAGE_VALUE => [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'componentType' => Field::NAME, + 'formElement' => Input::NAME, + 'dataType' => Price::NAME, + 'addbefore' => '%', + 'validation' => [ + 'validate-number' => true, + 'less-than-equals-to' => 100 + ], + 'visible' => $firstOption + && $firstOption['value'] == ProductPriceOptionsInterface::VALUE_PERCENT, + ], + ], + ], + ], + 'price_calc' => [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'componentType' => Container::NAME, + 'component' => 'Magento_Catalog/js/tier-price/percentage-processor', + 'visible' => false + ], + ], + ] + ] + ], + ], + ]; + } +} diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml index 584a2e51514db53a0250615a55d67455ca1a0f57..5fc5ec8d44fd0a88f8a5d542d5518fa60ad77629 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/di.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml @@ -142,6 +142,10 @@ <item name="class" xsi:type="string">Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Attributes</item> <item name="sortOrder" xsi:type="number">120</item> </item> + <item name="advanced-pricing-tier-price-type" xsi:type="array"> + <item name="class" xsi:type="string">Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\TierPrice</item> + <item name="sortOrder" xsi:type="number">150</item> + </item> </argument> </arguments> </virtualType> diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/percentage-processor.js b/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/percentage-processor.js new file mode 100644 index 0000000000000000000000000000000000000000..afc0bab3f7fa4baa4dfbb76dc261b0e97672d80e --- /dev/null +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/percentage-processor.js @@ -0,0 +1,73 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'uiElement', + 'underscore', + 'Magento_Ui/js/lib/view/utils/async', + 'Magento_Catalog/js/utils/percentage-price-calculator' +], function (Element, _, $, percentagePriceCalculator) { + 'use strict'; + + return Element.extend({ + defaults: { + priceElem: '${ $.parentName }.price', + selector: 'input', + imports: { + priceValue: '${ $.priceElem }:priceValue' + }, + exports: { + calculatedVal: '${ $.priceElem }:value' + } + }, + + /** + * {@inheritdoc} + */ + initialize: function () { + this._super(); + + _.bindAll(this, 'initPriceListener', 'onInput'); + + $.async({ + component: this.priceElem, + selector: this.selector + }, this.initPriceListener); + + return this; + }, + + /** + * {@inheritdoc} + */ + initObservable: function () { + return this._super() + .observe(['visible']); + }, + + /** + * Handles keyup event on price input. + * + * {@param} HTMLElement elem + */ + initPriceListener: function (elem) { + $(elem).on('keyup.priceCalc', this.onInput); + }, + + /** + * Delegates calculation of the price input value to percentagePriceCalculator. + * + * {@param} object event + */ + onInput: function (event) { + var value = event.currentTarget.value; + + if (value.slice(-1) === '%') { + value = percentagePriceCalculator(this.priceValue, value); + this.set('calculatedVal', value); + } + } + }); +}); diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/value-type-select.js b/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/value-type-select.js new file mode 100644 index 0000000000000000000000000000000000000000..216a767d393d57e6596c4d9d75cb7aef0e4a86f7 --- /dev/null +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/value-type-select.js @@ -0,0 +1,118 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'Magento_Ui/js/form/element/select', + 'uiRegistry', + 'underscore' +], function (Select, uiRegistry, _) { + 'use strict'; + + return Select.extend({ + defaults: { + prices: {} + }, + + /** + * {@inheritdoc} + */ + initialize: function () { + this._super() + .prepareForm(); + }, + + /** + * {@inheritdoc} + */ + setInitialValue: function () { + this.initialValue = this.getInitialValue(); + + if (this.value.peek() !== this.initialValue) { + this.value(this.initialValue); + } + + this.isUseDefault(this.disabled()); + + return this; + }, + + /** + * {@inheritdoc} + */ + prepareForm: function () { + var elements = this.getElementsByPrices(), + prices = this.prices, + currencyType = _.keys(prices)[0], + select = this; + + uiRegistry.get(elements, function () { + _.each(arguments, function (currentValue) { + if (parseFloat(currentValue.value()) > 0) { + _.each(prices, function (priceValue, priceKey) { + if (priceValue === currentValue.name) { + currencyType = priceKey; + } + }); + } + }); + select.value(currencyType); + select.on('value', select.onUpdate.bind(select)); + select.onUpdate(); + }); + }, + + /** + * @returns {Array} + */ + getElementsByPrices: function () { + var elements = []; + + _.each(this.prices, function (currentValue) { + elements.push(currentValue); + }); + + return elements; + }, + + /** + * Callback that fires when 'value' property is updated + */ + onUpdate: function () { + var value = this.value(), + prices = this.prices, + select = this, + parentDataScopeArr = this.dataScope.split('.'), + parentDataScope, + elements = this.getElementsByPrices(); + + parentDataScopeArr.pop(); + parentDataScope = parentDataScopeArr.join('.'); + + uiRegistry.get(elements, function () { + var sourceData = select.source.get(parentDataScope); + + _.each(arguments, function (currentElement) { + var index; + + _.each(prices, function (priceValue, priceKey) { + if (priceValue === currentElement.name) { + index = priceKey; + } + }); + + if (value === index) { + currentElement.visible(true); + sourceData[currentElement.index] = currentElement.value(); + } else { + currentElement.value(''); + currentElement.visible(false); + delete sourceData[currentElement.index]; + } + }); + select.source.set(parentDataScope, sourceData); + }); + } + }); +}); diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/utils/percentage-price-calculator.js b/app/code/Magento/Catalog/view/adminhtml/web/js/utils/percentage-price-calculator.js new file mode 100644 index 0000000000000000000000000000000000000000..b7c18d5332f56347d269dc623ff05c2bff936959 --- /dev/null +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/utils/percentage-price-calculator.js @@ -0,0 +1,45 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define(['Magento_Ui/js/lib/validation/utils'], function (utils) { + 'use strict'; + + /** + * Calculates the price input value when entered percentage value. + * + * @param {String} price + * @param {String} input + * + * @returns {String} + */ + return function (price, input) { + var result, + lastInputSymbol = input.slice(-1), + inputPercent = input.slice(0, -1), + parsedPercent = utils.parseNumber(inputPercent), + parsedPrice = utils.parseNumber(price); + + if (lastInputSymbol !== '%') { + result = input; + } else if ( + input === '%' || + isNaN(parsedPrice) || + parsedPercent != inputPercent || /* eslint eqeqeq:0 */ + isNaN(parsedPercent) || + input === '' + ) { + result = ''; + } else if (parsedPercent > 100) { + result = '0.00'; + } else if (lastInputSymbol === '%') { + result = parsedPrice - parsedPrice * (inputPercent / 100); + result = result.toFixed(2); + } else { + result = input; + } + + return result; + }; +}); diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php index 45cd01bc8252d71711389ae3a837cffb2a846ac0..3f9e157c5710a63c1bb3a47d0462953e96ac48c1 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/RowValidatorInterface.php @@ -45,6 +45,8 @@ interface RowValidatorInterface extends \Magento\Framework\Validator\ValidatorIn const ERROR_INVALID_TIER_PRICE_GROUP = 'tierPriceGroupInvalid'; + const ERROR_INVALID_TIER_PRICE_TYPE = 'tierPriceTypeInvalid'; + const ERROR_TIER_DATA_INCOMPLETE = 'tierPriceDataIsIncomplete'; const ERROR_SKU_NOT_FOUND_FOR_DELETE = 'skuNotFoundToDelete'; diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php index 2f054b5a9c4d10c93dd83193493ae35cd4f00a48..6d3f8b763026cd0514b6c87b4dc898717bc75ee0 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Export/Filter.php @@ -6,6 +6,7 @@ namespace Magento\ImportExport\Block\Adminhtml\Export; use Magento\Eav\Model\Entity\Attribute; +use Magento\Catalog\Api\Data\ProductAttributeInterface; /** * Export filter block @@ -185,25 +186,39 @@ class Filter extends \Magento\Backend\Block\Widget\Grid\Extended $toValue = $this->escapeHtml(next($value)); } - return '<strong class="admin__control-support-text">' . __( - 'From' - ) . - ':</strong> ' . - '<input type="text" name="' . - $name . - '[]" class="admin__control-text input-text input-text-range"' . - ' value="' . - $fromValue . - '"/> ' . - '<strong class="admin__control-support-text">' . - __( - 'To' - ) . - ':</strong> <input type="text" name="' . - $name . - '[]" class="admin__control-text input-text input-text-range" value="' . - $toValue . - '" />'; + return '<strong class="admin__control-support-text">' . + $this->getFromAttributePrefix($attribute) . + ':</strong> ' . + '<input type="text" name="' . + $name . + '[]" class="admin__control-text input-text input-text-range"' . + ' value="' . + $fromValue . + '"/> ' . + '<strong class="admin__control-support-text">' . + __( + 'To' + ) . + ':</strong> <input type="text" name="' . + $name . + '[]" class="admin__control-text input-text input-text-range" value="' . + $toValue . + '" />'; + } + + /** + * Get 'From' prefix to attribute. + * + * @param Attribute $attribute + * @return \Magento\Framework\Phrase + */ + protected function getFromAttributePrefix(Attribute $attribute) + { + $attributePrefix = $attribute->getAttributeCode() === ProductAttributeInterface::CODE_TIER_PRICE + ? __('Fixed Price: From') + : __('From'); + + return $attributePrefix; } /** diff --git a/app/code/Magento/ImportExport/Files/Sample/advanced_pricing.csv b/app/code/Magento/ImportExport/Files/Sample/advanced_pricing.csv index 82db6382bd8d5fda511e50a6da9fa4876fa35f1a..e4c203bed3be9ae6f935e7cb1f6cfbeb086d8816 100644 --- a/app/code/Magento/ImportExport/Files/Sample/advanced_pricing.csv +++ b/app/code/Magento/ImportExport/Files/Sample/advanced_pricing.csv @@ -1,5 +1,5 @@ -sku,tier_price_website,tier_price_customer_group,tier_price_qty,tier_price -sku123,base,General,2,10 -sku124,All Websites [USD],ALL GROUPS,3,15 -sku123,,,, -sku124,,,, +sku,tier_price_website,tier_price_customer_group,tier_price_qty,tier_price,tier_price_value_type +sku123,base,General,2,10,Fixed +sku124,All Websites [USD],ALL GROUPS,3,15,Discount +sku123,,,,, +sku124,,,,, diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json index 5e403d2180652a6f3565bf03b573abf75310f19f..d5e3b41f47fd93387b0ce70e1764105fa7341027 100644 --- a/app/code/Magento/ImportExport/composer.json +++ b/app/code/Magento/ImportExport/composer.json @@ -3,6 +3,7 @@ "description": "N/A", "require": { "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", + "magento/module-catalog": "101.1.*", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml index dff1a9fd71d865dd52fd6cdd0e05d3e3d000db94..411833f03335645e4395cd8bb5695121cc4c2dad 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml @@ -90,6 +90,10 @@ <input>input</input> <selector>input[name='url_key']</selector> </url_key> + <use_default_url_key> + <input>checkbox</input> + <selector>input[name='use_default[url_key]']</selector> + </use_default_url_key> <meta_title> <input>input</input> <selector>input[name='meta_title']</selector> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/PageActions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/PageActions.php index 27e15044df11d91765251d1de783243cf6b55adf..808da58c7dd4995a20f88ef2059df2ecc9eb574f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/PageActions.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/PageActions.php @@ -7,12 +7,18 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Category\Edit; use Magento\Backend\Test\Block\FormPageActions; +use Magento\Mtf\Client\Locator; /** * Category page actions. */ class PageActions extends FormPageActions { + /** + * Top page element to implement a scrolling in case of floating blocks overlay. + */ + const TOP_ELEMENT_TO_SCROLL = '.page-title'; + /** * Locator for "OK" button in warning block * @@ -20,6 +26,20 @@ class PageActions extends FormPageActions */ protected $warningBlock = '.ui-widget-content .ui-dialog-buttonset button:first-child'; + /** + * Change Store View selector. + * + * @var string + */ + protected $storeChangeButton = '#store-change-button'; + + /** + * Selector for confirm. + * + * @var string + */ + protected $confirmModal = '.confirm._show[data-role=modal]'; + /** * Click on "Save" button * @@ -33,4 +53,23 @@ class PageActions extends FormPageActions $warningBlock->click(); } } + + /** + * Select Store View. + * + * @param string $name + * @return void + */ + public function selectStoreView($name) + { + $this->browser->find(self::TOP_ELEMENT_TO_SCROLL)->click(); + $this->_rootElement->find($this->storeChangeButton)->click(); + $this->waitForElementVisible($name, Locator::SELECTOR_LINK_TEXT); + $this->_rootElement->find($name, Locator::SELECTOR_LINK_TEXT)->click(); + $element = $this->browser->find($this->confirmModal); + /** @var \Magento\Ui\Test\Block\Adminhtml\Modal $modal */ + $modal = $this->blockFactory->create(\Magento\Ui\Test\Block\Adminhtml\Modal::class, ['element' => $element]); + $modal->acceptAlert(); + $this->waitForElementVisible($this->storeChangeButton); + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php index 15a624c4b734f828264ebfee75801d80d08c5f05..447e1319898084dfecbcb50e3f801ae04ae9f156 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php @@ -60,6 +60,13 @@ class Tree extends Block */ protected $header = 'header'; + /** + * Xpath locator for category in tree. + * + * @var string + */ + protected $categoryInTree = '//*[@class="x-tree-node-ct"]/li/div/a/span[contains(text(), "%s")]/..'; + /** * Get backend abstract block. * @@ -153,6 +160,26 @@ class Tree extends Block ->isElementVisible($categoryPath); } + /** + * Assign child category to the parent. + * + * @param string $parentCategoryName + * @param string $childCategoryName + * + * @return void + */ + public function assignCategory($parentCategoryName, $childCategoryName) + { + $this->_rootElement->find(sprintf($this->categoryInTree, $childCategoryName), Locator::SELECTOR_XPATH)->click(); + $this->getTemplateBlock()->waitLoader(); + $targetElement = $this->_rootElement->find( + sprintf($this->categoryInTree, $parentCategoryName), + Locator::SELECTOR_XPATH + ); + $this->_rootElement->find(sprintf($this->categoryInTree, $childCategoryName), Locator::SELECTOR_XPATH) + ->dragAndDrop($targetElement); + } + /** * Expand all categories tree. * diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/AdvancedPricing/OptionTier.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/AdvancedPricing/OptionTier.xml index ca10de4ebf8c127fdb310073437261cab7d7a435..9df266994f4fad767a0c13478bdc2e8cbb002c99 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/AdvancedPricing/OptionTier.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/AdvancedPricing/OptionTier.xml @@ -10,6 +10,13 @@ <price> <selector>[name$="[price]"]</selector> </price> + <value_type> + <selector>[name$="[value_type]"]</selector> + <input>select</input> + </value_type> + <percentage_value> + <selector>[name$="[percentage_value]"]</selector> + </percentage_value> <website> <selector>[name$="[website_id]"]</selector> <input>select</input> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php index b6e95f5393e1455796b190642414d0e53345b59c..08d38f45c4ff99a4eae99a1be3c3972bdba7f790 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php @@ -14,9 +14,12 @@ use Magento\Mtf\Client\Element\SimpleElement; use Magento\Mtf\Client\Locator; use Magento\Mtf\Fixture\FixtureInterface; use Magento\Ui\Test\Block\Adminhtml\DataGrid; +use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\ProductDetails\NewCategoryIds; /** * Product form on backend product page. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ProductForm extends FormSections { @@ -48,6 +51,13 @@ class ProductForm extends FormSections */ protected $attributeBlock = '[data-index="%s"]'; + /** + * NewCategoryIds block selector. + * + * @var string + */ + protected $newCategoryModalForm = '.product_form_product_form_create_category_modal'; + /** * Magento form loader. * @@ -70,8 +80,6 @@ class ProductForm extends FormSections * @param FixtureInterface|null $category * @return $this * @throws \Exception - * - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function fill(FixtureInterface $product, SimpleElement $element = null, FixtureInterface $category = null) { @@ -88,9 +96,14 @@ class ProductForm extends FormSections $this->callRender($typeId, 'fill', $renderArguments); } else { $sections = $this->getFixtureFieldsByContainers($product); - + $category = $product->hasData('category_ids') + ? $product->getDataFieldConfig('category_ids')['source']->getCategories()[0] : $category; if ($category) { - $sections['product-details']['category_ids']['value'] = $category->getName(); + if ((int)$category->getId()) { + $sections['product-details']['category_ids']['value'] = $category->getName(); + } else { + $this->getNewCategoryModalForm()->addNewCategory($category); + } } $this->fillContainers($sections, $element); } @@ -193,6 +206,19 @@ class ProductForm extends FormSections ); } + /** + * Get New Category Modal Form. + * + * @return NewCategoryIds + */ + public function getNewCategoryModalForm() + { + return $this->blockFactory->create( + \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\ProductDetails\NewCategoryIds::class, + ['element' => $this->browser->find($this->newCategoryModalForm)] + ); + } + /** * Get attribute element. * diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/TopToolbar.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/TopToolbar.php index 3d5e550560e857b8530037637b4f97f7763874e2..f7529f1fcb61e262856bdf8856c0cbaf14ce57d2 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/TopToolbar.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/TopToolbar.php @@ -36,12 +36,11 @@ class TopToolbar extends Block /** * Get all available method of sorting product * - * @return array|string + * @return array */ public function getSortType() { $content = $this->_rootElement->find($this->sorter)->getText(); - preg_match_all('/\w+\s?\w+/', $content, $matches); - return $matches[0]; + return explode("\n", $content); } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceInCart.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceInCart.php new file mode 100644 index 0000000000000000000000000000000000000000..1bc689d8e1b1e3009bbf2f3fc563b3aa51ccc3c7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceInCart.php @@ -0,0 +1,129 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Test\Constraint; + +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Checkout\Test\Page\CheckoutCart; +use Magento\Mtf\Client\BrowserInterface; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Mtf\Fixture\FixtureInterface; + +/** + * This assert adds product to cart and checks price. + */ +class AssertProductTierPriceInCart extends AbstractConstraint +{ + /** + * Price on form. + * + * @var string + */ + private $formPrice; + + /** + * Fixture actual price. + * + * @var string + */ + private $fixtureActualPrice; + + /** + * Fixture price. + * + * @var string + */ + private $fixturePrice; + + /** + * Assertion that the product is correctly displayed in cart. + * + * @param CatalogProductView $catalogProductView + * @param FixtureInterface $product + * @param BrowserInterface $browser + * @param CheckoutCart $checkoutCart + * @return void + */ + public function processAssert( + CatalogProductView $catalogProductView, + FixtureInterface $product, + BrowserInterface $browser, + CheckoutCart $checkoutCart + ) { + $checkoutCart->open(); + $checkoutCart->getCartBlock()->clearShoppingCart(); + // Add product to cart + $browser->open($_ENV['app_frontend_url'] . $product->getUrlKey() . '.html'); + $requiredQty = $product->getDataFieldConfig('tier_price')['source']->getData()[0]['price_qty']; + $catalogProductView->getViewBlock()->setQtyAndClickAddToCart($requiredQty); + $catalogProductView->getMessagesBlock()->waitSuccessMessage(); + + // Check price + $this->countPrices($product, $checkoutCart); + \PHPUnit_Framework_Assert::assertEquals( + $this->fixtureActualPrice, + $this->formPrice, + 'Product price in shopping cart is not correct.' + ); + } + + /** + * Count prices. + * + * @param FixtureInterface $product + * @param CheckoutCart $checkoutCart + * @return void + */ + private function countPrices(FixtureInterface $product, CheckoutCart $checkoutCart) + { + /** @var CatalogProductSimple $product */ + $this->fixturePrice = $product->getPrice(); + $this->prepareFormPrice($product, $checkoutCart); + $this->countCheckoutCartItemPrice($product); + } + + /** + * Prepare form price. + * + * @param FixtureInterface $product + * @param CheckoutCart $checkoutCart + * @return void + */ + private function prepareFormPrice(FixtureInterface $product, CheckoutCart $checkoutCart) + { + $checkoutCart->open(); + $cartItem = $checkoutCart->getCartBlock()->getCartItem($product); + $this->formPrice = $cartItem->getPrice(); + } + + /** + * Count cart item price. + * + * @param FixtureInterface $product + * @return void + */ + private function countCheckoutCartItemPrice(FixtureInterface $product) + { + $tierPrice = $product->getDataFieldConfig('tier_price')['source']->getData()[0]; + + if ($tierPrice['value_type'] === "Percent") { + $this->fixtureActualPrice = $this->fixturePrice * (1 - $tierPrice['percentage_value'] / 100); + } else { + $this->fixtureActualPrice = $tierPrice['price']; + } + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Product is correctly displayed in cart.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml index b9ba495535e82eb970f8ff02ebaa7097aab999b0..ed6f9568c2441aa1bba72eb3992cb6b6f89066f7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Category.xml @@ -41,6 +41,7 @@ <field name="use_config_price_range" is_required="0" group="display_setting" /> <field name="layered_navigation_price_step" is_required="0" group="display_setting" /> <field name="url_key" group="seo" /> + <field name="use_default_url_key" group="seo" /> <field name="meta_title" is_required="" group="seo" /> <field name="meta_keywords" is_required="" group="seo" /> <field name="meta_description" is_required="" group="seo" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml index e1cbc1a1d8ba2dba7f3be971b3f1b456f6e7d02a..997d0ab1d7f11c64ce33ea386870055ea2e77798 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml @@ -98,6 +98,87 @@ <field name="url_key" xsi:type="string">simple-product-%isolation%</field> </dataset> + <dataset name="product_1_dollar"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">product_1_dollar %isolation%</field> + <field name="sku" xsi:type="string">sku_product_1_dollar_%isolation%</field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1000</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">1</item> + </field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="url_key" xsi:type="string">product-1-dollar-%isolation%</field> + </dataset> + + <dataset name="product_5_dollar"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">product_5_dollar %isolation%</field> + <field name="sku" xsi:type="string">sku_product_5_dollar_%isolation%</field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1000</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">5</item> + </field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="url_key" xsi:type="string">product-5-dollar-%isolation%</field> + </dataset> + + <dataset name="product_9_99_dollar"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">product_9_99_dollar %isolation%</field> + <field name="sku" xsi:type="string">sku_product_9_99_dollar_%isolation%</field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1000</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">9.99</item> + </field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="url_key" xsi:type="string">product-9-99-dollar-%isolation%</field> + </dataset> + <dataset name="product_10_dollar"> <field name="attribute_set_id" xsi:type="array"> <item name="dataset" xsi:type="string">default</item> @@ -128,6 +209,33 @@ </field> </dataset> + <dataset name="product_15_dollar"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">product_15_dollar %isolation%</field> + <field name="sku" xsi:type="string">sku_product_15_dollar_%isolation%</field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1000</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">15</item> + </field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="url_key" xsi:type="string">product-15-dollar-%isolation%</field> + </dataset> + <dataset name="product_20_dollar"> <field name="attribute_set_id" xsi:type="array"> <item name="dataset" xsi:type="string">default</item> @@ -155,6 +263,33 @@ <field name="url_key" xsi:type="string">product-20-dollar-%isolation%</field> </dataset> + <dataset name="product_21_dollar"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">product_21_dollar %isolation%</field> + <field name="sku" xsi:type="string">sku_product_21_dollar_%isolation%</field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1000</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">21</item> + </field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="url_key" xsi:type="string">product-21-dollar-%isolation%</field> + </dataset> + <dataset name="product_with_url_key"> <field name="name" xsi:type="string">Simple Product %isolation%</field> <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field> @@ -1263,5 +1398,101 @@ </field> </dataset> + <dataset name="with_default_custom_option"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">Simple Product %isolation%</field> + <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">56.78</item> + </field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="url_key" xsi:type="string">simple-product-%isolation%</field> + <field name="category_ids" xsi:type="array"> + <item name="dataset" xsi:type="string">default_subcategory</item> + </field> + <field name="custom_options" xsi:type="array"> + <item name="dataset" xsi:type="string">percent_and_fixed_radio_options</item> + </field> + <field name="checkout_data" xsi:type="array"> + <item name="dataset" xsi:type="string">simple_order_qty_1_price_56</item> + </field> + </dataset> + + <dataset name="with_fixed_custom_option"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">Simple Product %isolation%</field> + <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">56.78</item> + </field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="url_key" xsi:type="string">simple-product-%isolation%</field> + <field name="category_ids" xsi:type="array"> + <item name="dataset" xsi:type="string">default_subcategory</item> + </field> + <field name="custom_options" xsi:type="array"> + <item name="dataset" xsi:type="string">percent_and_fixed_radio_options</item> + </field> + <field name="checkout_data" xsi:type="array"> + <item name="dataset" xsi:type="string">with_fixed_custom_option</item> + </field> + </dataset> + + <dataset name="with_percent_custom_option"> + <field name="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="name" xsi:type="string">Simple Product %isolation%</field> + <field name="sku" xsi:type="string">sku_simple_product_%isolation%</field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">56.78</item> + </field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">1</field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="qty" xsi:type="string">1</item> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </item> + </field> + <field name="url_key" xsi:type="string">simple-product-%isolation%</field> + <field name="category_ids" xsi:type="array"> + <item name="dataset" xsi:type="string">default_subcategory</item> + </field> + <field name="custom_options" xsi:type="array"> + <item name="dataset" xsi:type="string">percent_and_fixed_radio_options</item> + </field> + <field name="checkout_data" xsi:type="array"> + <item name="dataset" xsi:type="string">with_percent_custom_option</item> + </field> + </dataset> + </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple/CheckoutData.xml index 53ec00f56b1e87662966c8298fa4104a6f804b0e..180da27ca2a099ab36c00473ac35572c45a31ffd 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple/CheckoutData.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple/CheckoutData.xml @@ -101,6 +101,14 @@ </field> </dataset> + <dataset name="simple_order_qty_2"> + <field name="qty" xsi:type="string">2</field> + <field name="cartItem" xsi:type="array"> + <item name="price" xsi:type="string">560</item> + <item name="subtotal" xsi:type="string">560</item> + </field> + </dataset> + <dataset name="simple_two_products"> <field name="qty" xsi:type="string">2</field> <field name="cartItem" xsi:type="array"> @@ -148,5 +156,47 @@ <dataset name="simple_order_qty_3"> <field name="qty" xsi:type="string">3</field> </dataset> + + <dataset name="simple_order_qty_1_price_56"> + <field name="qty" xsi:type="string">1</field> + <field name="cartItem" xsi:type="array"> + <item name="price" xsi:type="string">49.40</item> + <item name="subtotal" xsi:type="string">49.40</item> + </field> + </dataset> + + <dataset name="with_fixed_custom_option"> + <field name="options" xsi:type="array"> + <item name="custom_options" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">attribute_key_0</item> + <item name="value" xsi:type="string">option_key_0</item> + </item> + </item> + </field> + <field name="qty" xsi:type="string">1</field> + <field name="cartItem" xsi:type="array"> + <item name="price" xsi:type="string">61.74</item> + <item name="qty" xsi:type="string">1</item> + <item name="subtotal" xsi:type="string">61.74</item> + </field> + </dataset> + + <dataset name="with_percent_custom_option"> + <field name="options" xsi:type="array"> + <item name="custom_options" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">attribute_key_0</item> + <item name="value" xsi:type="string">option_key_1</item> + </item> + </item> + </field> + <field name="qty" xsi:type="string">1</field> + <field name="cartItem" xsi:type="array"> + <item name="price" xsi:type="string">53.85</item> + <item name="qty" xsi:type="string">1</item> + <item name="subtotal" xsi:type="string">53.85</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/CustomOptions.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/CustomOptions.xml index 3252f0178e24195e724b45a17021d0528990070a..ae9c2238c9e008ac8086d365a1b1547d3309762b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/CustomOptions.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/CustomOptions.xml @@ -358,5 +358,29 @@ </item> </field> </dataset> + + <dataset name="percent_and_fixed_radio_options"> + <field name="0" xsi:type="array"> + <item name="title" xsi:type="string">custom menu</item> + <item name="is_require" xsi:type="string">No</item> + <item name="type" xsi:type="string">Select/Radio Buttons</item> + <item name="options" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">12.34 bucks</item> + <item name="price" xsi:type="string">12.34</item> + <item name="price_type" xsi:type="string">Fixed</item> + <item name="sku" xsi:type="string">sku_radio_buttons_row_1</item> + <item name="sort_order" xsi:type="string">0</item> + </item> + <item name="1" xsi:type="array"> + <item name="title" xsi:type="string">9 Percent</item> + <item name="price" xsi:type="string">9</item> + <item name="price_type" xsi:type="string">Percent</item> + <item name="sku" xsi:type="string">sku_radio_buttons_row_2</item> + <item name="sort_order" xsi:type="string">0</item> + </item> + </item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml index 412818cbe40e71634eb1e635d8dc8e1630913b49..2f517f4d6cf3cc03020abc575d4e91cd7f7188da 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml @@ -77,5 +77,29 @@ </item> </field> </dataset> + + <dataset name="custom_with_fixed_discount"> + <field name="0" xsi:type="array"> + <item name="value_type" xsi:type="string">Fixed</item> + <item name="price" xsi:type="string">95</item> + <item name="website" xsi:type="string">All Websites [USD]</item> + <item name="price_qty" xsi:type="string">5</item> + <item name="customer_group" xsi:type="array"> + <item name="dataset" xsi:type="string">ALL_GROUPS</item> + </item> + </field> + </dataset> + + <dataset name="custom_with_percentage_discount"> + <field name="0" xsi:type="array"> + <item name="value_type" xsi:type="string">Percent</item> + <item name="percentage_value" xsi:type="string">3</item> + <item name="website" xsi:type="string">All Websites [USD]</item> + <item name="price_qty" xsi:type="string">10</item> + <item name="customer_group" xsi:type="array"> + <item name="dataset" xsi:type="string">ALL_GROUPS</item> + </item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml index fa81264dd2d4b061ef769f882408b104ba92793f..238fddba3de426f683e981c0a1b7b1b60c12fbeb 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml @@ -16,7 +16,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" /> </variation> <variation name="CreateCategoryEntityTestVariation2_RootCategory_AllFields"> - <data name="tag" xsi:type="string">to_maintain:yes</data> + <data name="issue" xsi:type="string">MAGETWO-60635: [CE][Categories] Design update dates are incorrect after save</data> <data name="description" xsi:type="string">Create root category with all fields</data> <data name="addCategory" xsi:type="string">addRootCategory</data> <data name="category/data/is_active" xsi:type="string">Yes</data> @@ -57,7 +57,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryPage" /> </variation> <variation name="CreateCategoryEntityTestVariation4_Subcategory_AllFields"> - <data name="tag" xsi:type="string">to_maintain:yes</data> + <data name="issue" xsi:type="string">MAGETWO-60635: [CE][Categories] Design update dates are incorrect after save</data> <data name="description" xsi:type="string">Create not anchor subcategory specifying all fields</data> <data name="addCategory" xsi:type="string">addSubcategory</data> <data name="category/data/parent_id/dataset" xsi:type="string">default_category</data> @@ -86,13 +86,14 @@ <data name="category/data/apply_design_to_products" xsi:type="string">Yes</data> <data name="category/data/schedule_update_from" xsi:type="string">01/10/2014</data> <data name="category/data/schedule_update_to" xsi:type="string">12/31/2024</data> + <data name="filterByPath" xsi:type="string">request_path</data> <constraint name="Magento\Catalog\Test\Constraint\AssertCategorySaveMessage" /> + <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteCategoryInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" /> <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryPage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" /> </variation> <variation name="CreateCategoryEntityTestVariation5_Anchor_MostOfFields"> - <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Create anchor subcategory with all fields</data> <data name="addCategory" xsi:type="string">addSubcategory</data> <data name="category/data/parent_id/dataset" xsi:type="string">default_category</data> @@ -153,7 +154,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" /> </variation> <variation name="CreateCategoryEntityTestVariation9_ThreeNesting"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> <data name="description" xsi:type="string">Create category with three nesting</data> <data name="addCategory" xsi:type="string">addSubcategory</data> <data name="category/data/parent_id/dataset" xsi:type="string">two_nested_categories</data> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml index 9f4a5e4bb71fea9293612125157757f7e3d965da..7979faa5e1f761844fa5d1bb8bebd00430e87623 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml @@ -317,6 +317,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPage" /> </variation> <variation name="CreateSimpleProductEntityTestVariation18"> + <data name="issue" xsi:type="string">MAGETWO-60470: [Import Custom options] An error occurs on attempt to save the product with imported options</data> <data name="description" xsi:type="string">Create product wit suite of custom options</data> <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data> <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data> @@ -509,6 +510,24 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCart" /> </variation> + <variation name="CreateSimpleProductEntityWithTierPriceTestVariation1" summary="Create Simple Product with fixed tier price."> + <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data> + <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data> + <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data> + <data name="product/data/price/value" xsi:type="string">100.00</data> + <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">555</data> + <data name="product/data/tier_price/dataset" xsi:type="string">custom_with_fixed_discount</data> + <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceInCart" /> + </variation> + <variation name="CreateSimpleProductEntityWithTierPriceTestVariation2" summary="Create Simple Product with percentage tier price."> + <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data> + <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data> + <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data> + <data name="product/data/price/value" xsi:type="string">200.00</data> + <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">555</data> + <data name="product/data/tier_price/dataset" xsi:type="string">custom_with_percentage_discount</data> + <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceInCart" /> + </variation> <variation name="CreateSimpleProductEntityWithImageTestVariation1" summary="Create product with image and try to save it again"> <data name="product/data/image/0/file" xsi:type="string">Magento/Catalog/Test/_files/test1.png</data> <data name="product/data/image/1/file" xsi:type="string">Magento/Catalog/Test/_files/test2.png</data> diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php index 4a4c6a25321c8363133aa0d6696cb29a35c946b5..68972e5bb766d458425ad6bf0796760325b931e8 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php @@ -11,6 +11,8 @@ use Magento\CatalogRule\Test\Fixture\CatalogRule; use Magento\Customer\Test\Fixture\Customer; use Magento\Mtf\Util\Command\Cli\Cron; use Magento\CatalogRule\Test\Page\Adminhtml\CatalogRuleEdit; +use Magento\Mtf\TestStep\TestStepFactory; +use Magento\Mtf\Fixture\FixtureInterface; /** * Preconditions: @@ -37,57 +39,66 @@ class ApplyCatalogPriceRulesTest extends AbstractCatalogRuleEntityTest * Apply catalog price rules. * * @param array $catalogRules - * @param CatalogProductSimple $product * @param CatalogRuleEdit $catalogRuleEdit + * @param TestStepFactory $stepFactory * @param Cron $cron * @param bool $isCronEnabled * @param Customer $customer - * @return array + * @param array $products + * @return FixtureInterface[] */ public function test( array $catalogRules, - CatalogProductSimple $product, CatalogRuleEdit $catalogRuleEdit, + TestStepFactory $stepFactory, Cron $cron, $isCronEnabled = false, - Customer $customer = null + Customer $customer = null, + array $products = null ) { - $product->persist(); - - foreach ($catalogRules as $catalogPriceRule) { - $catalogPriceRule = $this->createCatalogPriceRule($catalogPriceRule, $product, $customer); + if ($customer !== null) { + $customer->persist(); + } - if ($isCronEnabled) { - $cron->run(); - $cron->run(); - } else { - $catalogRuleEdit->open(['id' => $catalogPriceRule->getId()]); - $this->catalogRuleNew->getFormPageActions()->saveAndApply(); + $products = $stepFactory->create( + \Magento\Catalog\Test\TestStep\CreateProductsStep::class, + ['products' => $products] + )->run()['products']; + + foreach ($catalogRules as $catalogRule) { + foreach ($products as $product) { + $catalogPriceRule = $this->createCatalogPriceRule($catalogRule, $product, $customer); + if ($isCronEnabled) { + $cron->run(); + $cron->run(); + } else { + $catalogRuleEdit->open(['id' => $catalogPriceRule->getId()]); + $this->catalogRuleNew->getFormPageActions()->saveAndApply(); + } } } - - return ['products' => [$product]]; + return ['products' => $products]; } /** * Prepare condition for catalog price rule. * - * @param CatalogProductSimple $productSimple + * @param FixtureInterface $product * @param array $catalogPriceRule * @return array */ - private function prepareCondition(CatalogProductSimple $productSimple, array $catalogPriceRule) + private function prepareCondition(FixtureInterface $product, array $catalogPriceRule) { $result = []; $conditionEntity = explode('|', trim($catalogPriceRule['data']['rule'], '[]'))[0]; switch ($conditionEntity) { case 'Category': - $result['%category_id%'] = $productSimple->getDataFieldConfig('category_ids')['source']->getIds()[0]; + $result['%category_id%'] = $product->getDataFieldConfig('category_ids')['source']->getIds()[0]; break; case 'Attribute': /** @var \Magento\Catalog\Test\Fixture\CatalogProductAttribute[] $attrs */ - $attributes = $productSimple->getDataFieldConfig('attribute_set_id')['source'] + $attributes = $product->getDataFieldConfig('attribute_set_id')['source'] ->getAttributeSet()->getDataFieldConfig('assigned_attributes')['source']->getAttributes(); $result['%attribute_id%'] = $attributes[0]->getAttributeCode(); @@ -110,7 +121,6 @@ class ApplyCatalogPriceRulesTest extends AbstractCatalogRuleEntityTest */ private function applyCustomerGroup(array $catalogPriceRule, Customer $customer) { - $customer->persist(); /** @var \Magento\Customer\Test\Fixture\CustomerGroup $customerGroup */ $customerGroup = $customer->getDataFieldConfig('group_id')['source']->getCustomerGroup(); $catalogPriceRule['data']['customer_group_ids']['option_0'] = $customerGroup->getCustomerGroupId(); @@ -121,20 +131,19 @@ class ApplyCatalogPriceRulesTest extends AbstractCatalogRuleEntityTest /** * Create catalog price rule. * - * @param CatalogProductSimple $product * @param array $catalogPriceRule + * @param FixtureInterface $product * @param Customer $customer * @return CatalogRule */ private function createCatalogPriceRule( array $catalogPriceRule, - CatalogProductSimple $product, + FixtureInterface $product, Customer $customer = null ) { if (isset($catalogPriceRule['data']['rule'])) { $catalogPriceRule = $this->prepareCondition($product, $catalogPriceRule); } - if ($customer !== null) { $catalogPriceRule = $this->applyCustomerGroup($catalogPriceRule, $customer); } diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml index c732ae1f2b877b1ad95a53083a5ea82c5f27460f..00b02c61bd61cb07587fd2df00ef035d85c09b95 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.xml @@ -11,7 +11,7 @@ <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> <data name="catalogRules/0/dataset" xsi:type="string">catalog_price_rule_priority_0</data> <data name="catalogRules/1/dataset" xsi:type="string">catalog_price_rule_priority_2</data> - <data name="product/dataset" xsi:type="string">simple_for_salesrule_2</data> + <data name="products/0" xsi:type="string">catalogProductSimple::simple_for_salesrule_2</data> <data name="cartPrice/sub_total" xsi:type="string">15</data> <data name="cartPrice/grand_total" xsi:type="string">20</data> <data name="productPrice/0/discount_amount" xsi:type="string">35</data> @@ -26,7 +26,7 @@ <data name="catalogRules/0/dataset" xsi:type="string">catalog_price_rule_priority_0</data> <data name="catalogRules/1/dataset" xsi:type="string">catalog_price_rule_priority_1_stop_further_rules</data> <data name="catalogRules/2/dataset" xsi:type="string">catalog_price_rule_priority_2</data> - <data name="product/dataset" xsi:type="string">simple_for_salesrule_2</data> + <data name="products/0" xsi:type="string">catalogProductSimple::simple_for_salesrule_2</data> <data name="cartPrice/sub_total" xsi:type="string">20</data> <data name="cartPrice/grand_total" xsi:type="string">25</data> <data name="productPrice/0/discount_amount" xsi:type="string">30</data> @@ -40,7 +40,7 @@ <variation name="ApplyCatalogRules_WithExpireDate" summary="Apply Catalog Price rule with Expire Date and Catalog Price Rule with Start Date"> <data name="catalogRules/0/dataset" xsi:type="string">active_catalog_price_rule_with_conditions</data> <data name="catalogRules/1/dataset" xsi:type="string">active_catalog_rule</data> - <data name="product/dataset" xsi:type="string">simple_for_salesrule_2</data> + <data name="products/0" xsi:type="string">catalogProductSimple::simple_for_salesrule_2</data> <data name="cartPrice/sub_total" xsi:type="string">45</data> <data name="cartPrice/grand_total" xsi:type="string">50</data> <data name="productPrice/0/discount_amount" xsi:type="string">5</data> @@ -53,7 +53,7 @@ </variation> <variation name="ApplyCatalogRule_ForGuestUsers_ByProductAttribute_AdjustPriceToValue" summary="Apply Catalog Price Rule with Product Attribute in Condition" ticketId="MAGETWO-30095"> <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> - <data name="product/dataset" xsi:type="string">product_with_custom_color_attribute</data> + <data name="products/0" xsi:type="string">catalogProductSimple::product_with_custom_color_attribute</data> <data name="catalogRules/0/data/name" xsi:type="string">Catalog Price Rule %isolation%</data> <data name="catalogRules/0/data/is_active" xsi:type="string">Active</data> <data name="catalogRules/0/data/website_ids/option_0" xsi:type="string">Main Website</data> @@ -72,7 +72,7 @@ <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleAppliedShoppingCart" /> </variation> <variation name="ApplyCatalogRule_ForGuestUsers_AdjustPriceToPercentage" summary="Apply Catalog Price Rule for Guest Users with Adjust Price to Percentage" ticketId="MAGETWO-23036"> - <data name="product/dataset" xsi:type="string">MAGETWO-23036</data> + <data name="products/0" xsi:type="string">catalogProductSimple::MAGETWO-23036</data> <data name="catalogRules/0/data/name" xsi:type="string">rule_name%isolation%</data> <data name="catalogRules/0/data/is_active" xsi:type="string">Active</data> <data name="catalogRules/0/data/website_ids/option_0" xsi:type="string">Main Website</data> @@ -93,7 +93,7 @@ <variation name="ApplyCatalogRule_ForNewCustomerGroup" summary="Apply Catalog Price Rules to Specific Customer Group" ticketId="MAGETWO-12908"> <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data> <data name="customer/dataset" xsi:type="string">customer_with_new_customer_group</data> - <data name="product/dataset" xsi:type="string">simple_10_dollar</data> + <data name="products/0" xsi:type="string">catalogProductSimple::simple_10_dollar</data> <data name="catalogRules/0/data/name" xsi:type="string">rule_name%isolation%</data> <data name="catalogRules/0/data/is_active" xsi:type="string">Active</data> <data name="catalogRules/0/data/website_ids/option_0" xsi:type="string">Main Website</data> @@ -113,5 +113,38 @@ <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleAppliedProductPage" /> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleAppliedShoppingCart" /> </variation> + <variation name="ApplyCatalogRuleForSimpleProductWithCustomOptions" summary="Apply Catalog Rule for Simple Product With Custom Options" ticketId="MAGETWO-23038"> + <data name="products/0" xsi:type="string">catalogProductSimple::with_default_custom_option</data> + <data name="products/1" xsi:type="string">catalogProductSimple::with_fixed_custom_option</data> + <data name="products/2" xsi:type="string">catalogProductSimple::with_percent_custom_option</data> + <data name="customer/dataset" xsi:type="string">customer_US</data> + <data name="catalogRules/0/data/name" xsi:type="string">CatalogPriceRule %isolation%</data> + <data name="catalogRules/0/data/is_active" xsi:type="string">Active</data> + <data name="catalogRules/0/data/website_ids/option_0" xsi:type="string">Main Website</data> + <data name="customer/data/group_id/dataset" xsi:type="string">default</data> + <data name="catalogRules/0/data/simple_action" xsi:type="string">Apply as percentage of original</data> + <data name="catalogRules/0/data/discount_amount" xsi:type="string">13</data> + <data name="catalogRules/0/data/stop_rules_processing" xsi:type="string">Yes</data> + <data name="cartPrice/sub_total" xsi:type="string">164.99</data> + <data name="cartPrice/grand_total" xsi:type="string">179.99</data> + <data name="productPrice/0/discount_amount" xsi:type="string">7.38</data> + <data name="productPrice/1/discount_amount" xsi:type="string">8.04</data> + <data name="productPrice/2/discount_amount" xsi:type="string">7.38</data> + <data name="productPrice/0/special" xsi:type="string">49.40</data> + <data name="productPrice/1/special" xsi:type="string">53.85</data> + <data name="productPrice/2/special" xsi:type="string">61.74</data> + <data name="productPrice/0/sub_total" xsi:type="string">49.40</data> + <data name="productPrice/1/sub_total" xsi:type="string">61.74</data> + <data name="productPrice/2/sub_total" xsi:type="string">53.85</data> + <data name="productPrice/0/regular" xsi:type="string">56.78</data> + <data name="productPrice/1/regular" xsi:type="string">61.98</data> + <data name="productPrice/2/regular" xsi:type="string">69.12</data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> + <data name="shippingAddress/dataset" xsi:type="string">UK_address</data> + <data name="payment/method" xsi:type="string">free</data> + <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleAppliedShoppingCart" /> + <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleAppliedOnepageCheckout" /> + </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php index 483d6fa28636ac9f875495d277691b8f2acc3778..a10d28f5e70e35a6e64abf63bf5f69df99823eb8 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Shipping.php @@ -86,16 +86,17 @@ class Shipping extends Form */ public function selectShippingMethod(array $shipping) { - $selector = sprintf($this->shippingMethod, $shipping['shipping_service'], $shipping['shipping_method']); - if (!$this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->isVisible()) { - $this->openEstimateShippingAndTax(); - } - - $element = $this->_rootElement->find($selector, Locator::SELECTOR_XPATH); - if (!$element->isDisabled()) { - $element->click(); - } else { - throw new \Exception("Unable to set value to field '$selector' as it's disabled."); + if (isset($shipping['shipping_service']) && isset($shipping['shipping_method'])) { + $selector = sprintf($this->shippingMethod, $shipping['shipping_service'], $shipping['shipping_method']); + if (!$this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->isVisible()) { + $this->openEstimateShippingAndTax(); + } + $element = $this->_rootElement->find($selector, Locator::SELECTOR_XPATH); + if (!$element->isDisabled()) { + $element->click(); + } else { + throw new \Exception("Unable to set value to field '$selector' as it's disabled."); + } } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar.php index cbda80aa712f00271370c55b1555a32472e95234..231589bfdab774a2c04ed2f5ebdc07a3bf91e786 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar.php @@ -36,6 +36,13 @@ class Sidebar extends Block */ protected $braintreePaypalCheckoutButton = './/button[contains(@id, "braintree-paypal-mini-cart")]'; + /** + * Locator value for "Proceed to Checkout" button. + * + * @var string + */ + private $proceedToCheckoutButton = '#top-cart-btn-checkout'; + /** * Minicart items quantity * @@ -116,6 +123,16 @@ class Sidebar extends Block ->click(); } + /** + * Click "Proceed to Checkout" button. + * + * @return void + */ + public function clickProceedToCheckoutButton() + { + $this->_rootElement->find($this->proceedToCheckoutButton)->click(); + } + /** * Wait counter qty visibility. * diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/CustomAddress.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/CustomAddress.php new file mode 100644 index 0000000000000000000000000000000000000000..6905aacd4018968eb0765735eb53c9b55feac2a4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/CustomAddress.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Checkout\Test\Block\Onepage; + +use Magento\Mtf\Block\Form; +use Magento\Mtf\Client\Locator; + +/** + * Form for custom billing address filling. + */ +class CustomAddress extends Form +{ + /** + * Update billing address button. + * + * @var string + */ + private $updateButtonSelector = '.action.action-update'; + + /** + * Select address dropdown. + * + * @var string + */ + private $select = "[name='billing_address_id']"; + + /** + * Click update on billing information block. + * + * @return void + */ + public function clickUpdate() + { + $this->_rootElement->find($this->updateButtonSelector)->click(); + } + + /** + * Set address value from dropdown. + * + * @param string $value + * @return void + */ + public function selectAddress($value) + { + $this->_rootElement->find($this->select, Locator::SELECTOR_CSS, 'select')->setValue($value); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method/Billing.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method/Billing.php index 167767e518a48bb4879c076d9de6c0fd95ece128..d93c24f2641b0f2f326b60e5478537b242a51b47 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method/Billing.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method/Billing.php @@ -36,6 +36,20 @@ class Billing extends Form */ protected $sameAsShippingCheckbox = '[name="billing-address-same-as-shipping"]'; + /** + * New address select selector. + * + * @var string + */ + private $newAddressSelect = '[name="billing_address_id"]'; + + /** + * New address option value. + * + * @var string + */ + private $newAddressOption = 'New Address'; + /** * Fill billing address. * @@ -44,6 +58,10 @@ class Billing extends Form */ public function fillBilling(Address $billingAddress) { + $select = $this->_rootElement->find($this->newAddressSelect, Locator::SELECTOR_CSS, 'select'); + if ($select && $select->isVisible()) { + $select->setValue($this->newAddressOption); + } $this->fill($billingAddress); $this->clickUpdate(); $this->waitForElementNotVisible($this->waitElement); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping.php index f2530c016b714bf5af16c2b6d0f0f6d690cc4af0..fe844bc08b0017b2aa1cabfe4a7882b3733c118a 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping.php @@ -36,6 +36,39 @@ class Shipping extends Form */ private $addressModalBlock = '//*[@id="opc-new-shipping-address"]/../..'; + /** + * @var string + */ + private $selectedAddress = '.shipping-address-item.selected-item'; + + /** + * New address button selector. + * + * @var string + */ + private $popupSelector = '.action-show-popup'; + + /** + * Locator for address select button. + * + * @var string + */ + private $addressSelectButton = '.action-select-shipping-item'; + + /** + * Locator for shipping address select block. + * + * @var string + */ + private $shippingAddressBlock = '.shipping-address-item'; + + /** + * Locator for shipping address select block. + * + * @var string + */ + private $selectedShippingAddressBlock = '.selected-item'; + /** * Click on "New Address" button. * @@ -69,4 +102,63 @@ class Shipping extends Form { return $this->_rootElement->getElements("div .field._required"); } + + /** + * @return array + */ + public function getSelectedAddress() + { + return $this->_rootElement->find($this->selectedAddress, Locator::SELECTOR_CSS)->getText(); + } + + /** + * Select address. + * + * @param string $address + * @return void + */ + public function selectAddress($address) + { + $addresses = $this->_rootElement->getElements($this->shippingAddressBlock); + foreach ($addresses as $addressBlock) { + if (strpos($addressBlock->getText(), $address) === 0 && !$this->isAddressSelected($address)) { + $addressBlock->find($this->addressSelectButton)->click(); + break; + } + } + } + + /** + * Check if address selected. + * + * @param string $address + * @return bool + */ + public function isAddressSelected($address) + { + $text = $this->_rootElement->find($this->shippingAddressBlock . $this->selectedShippingAddressBlock)->getText(); + + return $text == $address; + } + + /** + * Checks if new address button is visible. + * + * @return bool + */ + public function isPopupNewAddressButtonVisible() + { + $button = $this->_rootElement->find($this->popupSelector); + return $button->isVisible(); + } + + /** + * Clicks new address button. + * + * @return void + */ + public function clickPopupNewAddressButton() + { + $this->_rootElement->find($this->popupSelector)->click(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/Method.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/Method.php index d038ca0599d75a779a352622ac85213a183f8053..cce29d23f63b18fc2c469e3df964cb2dd81188e0 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/Method.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/Method.php @@ -10,12 +10,12 @@ use Magento\Mtf\Block\Block; use Magento\Mtf\Client\Locator; /** - * One page checkout status shipping method block + * One page checkout status shipping method block. */ class Method extends Block { /** - * Shipping method selector + * Shipping method selector. * * @var string */ diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/ShippingPopup.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/ShippingPopup.php new file mode 100644 index 0000000000000000000000000000000000000000..fa6a8fa2a28613094139eb6cb91126ab5e85763b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/ShippingPopup.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Checkout\Test\Block\Onepage; + +use Magento\Mtf\Block\Form; + +/** + * Checkout new shipping address popup block. + */ +class ShippingPopup extends Form +{ + /** + * Save address button selector. + * + * @var string + */ + private $saveAddressButton = '.action-save-address'; + + /** + * Click on save address button. + * + * @return void + */ + public function clickSaveAddressButton() + { + $this->browser->find($this->saveAddressButton)->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/ShippingPopup.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/ShippingPopup.xml new file mode 100644 index 0000000000000000000000000000000000000000..13403b792684512c9741bca74a78f7c84036eb48 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/ShippingPopup.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" ?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<mapping strict="0"> + <fields> + <firstname /> + <lastname /> + <company /> + <street> + <selector>input[name="street[0]"]</selector> + </street> + <city /> + <region_id> + <input>select</input> + </region_id> + <country_id> + <input>select</input> + </country_id> + <telephone /> + <postcode /> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCustomerIsRedirectedToCheckoutFromCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCustomerIsRedirectedToCheckoutFromCart.php new file mode 100644 index 0000000000000000000000000000000000000000..61fcf0f5adf8a3958050101ba053f104dc208fa3 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertCustomerIsRedirectedToCheckoutFromCart.php @@ -0,0 +1,115 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Checkout\Test\Constraint; + +use Magento\Sales\Test\Constraint\AssertOrderGrandTotal; +use Magento\Sales\Test\Page\Adminhtml\SalesOrderView; +use Magento\Sales\Test\Page\Adminhtml\OrderIndex; +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Checkout\Test\Page\CheckoutOnepage; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Mtf\TestStep\TestStepFactory; + +/** + * Assert first step on Checkout page is available. + * Assert that Order Grand Total is correct on order page in backend. + */ +class AssertCustomerIsRedirectedToCheckoutFromCart extends AbstractConstraint +{ + /** + * Factory for Test Steps. + * + * @var TestStepFactory + */ + private $stepFactory; + + /** + * Order Id. + * + * @var string + */ + private $orderId; + + /** + * Assert first step on Checkout page is available. + * Assert that Order Grand Total is correct on order page in backend. + * + * @param CmsIndex $cmsIndex + * @param CheckoutOnepage $checkoutOnepage + * @param TestStepFactory $stepFactory + * @param AssertOrderGrandTotal $assertOrderGrandTotal + * @param SalesOrderView $salesOrderView + * @param OrderIndex $orderIndex + * @param array $prices + * @param array $checkoutData + * @return void + */ + public function processAssert( + CmsIndex $cmsIndex, + CheckoutOnepage $checkoutOnepage, + TestStepFactory $stepFactory, + AssertOrderGrandTotal $assertOrderGrandTotal, + SalesOrderView $salesOrderView, + OrderIndex $orderIndex, + array $prices, + array $checkoutData = [] + ) { + $this->stepFactory = $stepFactory; + + $miniShoppingCart = $cmsIndex->getCartSidebarBlock(); + $miniShoppingCart->openMiniCart(); + $miniShoppingCart->clickProceedToCheckoutButton(); + + \PHPUnit_Framework_Assert::assertTrue( + !$checkoutOnepage->getMessagesBlock()->isVisible() + && $checkoutOnepage->getShippingMethodBlock()->isVisible(), + 'Checkout first step is not available.' + ); + + if (isset($checkoutData['shippingAddress'])) { + $this->getOrder($checkoutData); + } + + //Assert that Order Grand Total is correct on order page in backend. + $assertOrderGrandTotal->processAssert($salesOrderView, $orderIndex, $this->orderId, $prices); + } + + /** + * Get Order. + * + * @param array $checkoutData + * @return void + */ + protected function getOrder(array $checkoutData) + { + $this->stepFactory->create( + \Magento\Checkout\Test\TestStep\FillShippingAddressStep::class, + ['shippingAddress' => $checkoutData['shippingAddress']] + )->run(); + $this->objectManager->create( + \Magento\Checkout\Test\TestStep\FillShippingMethodStep::class, + ['shipping' => $checkoutData['shipping']] + )->run(); + $this->objectManager->create( + \Magento\Checkout\Test\TestStep\SelectPaymentMethodStep::class, + ['payment' => $checkoutData['payment']] + )->run(); + $this->orderId = $this->objectManager->create( + \Magento\Checkout\Test\TestStep\PlaceOrderStep::class + )->run()['orderId']; + } + + /** + * Returns string representation of successful assertion. + * + * @return string + */ + public function toString() + { + return 'Checkout first step is available.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductDataInMiniShoppingCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductDataInMiniShoppingCart.php index 2b10754d9b47b945bd5a87709e78b378a2a754df..3e78cfb076acb1c8d033bb3dfa0a6e44f3cfd02c 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductDataInMiniShoppingCart.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertProductDataInMiniShoppingCart.php @@ -14,12 +14,12 @@ use Magento\Mtf\Constraint\AbstractAssertForm; use Magento\Mtf\Fixture\FixtureInterface; /** - * Assert that product price and qty in mini shopping cart equal to expected price from data set. + * Assert that product price and qty in mini shopping cart are equal to expected price from data set. */ class AssertProductDataInMiniShoppingCart extends AbstractAssertForm { /** - * Assert that product price and qty in mini shopping cart are equal to expected price from data set. + * Assert that product price and qty in mini shopping cart equal to expected price from data set. * * @param CmsIndex $cmsIndex * @param Cart $cart diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutOnepage.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutOnepage.xml index f8dcf95b0c16d87d6f7a241d1f0980b86c5c08d5..0ab3bbb2c2cfcb01330fecd582bb235ed7805068 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutOnepage.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutOnepage.xml @@ -8,12 +8,16 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="CheckoutOnepage" mca="checkout" module="Magento_Checkout"> <block name="authenticationPopupBlock" class="Magento\Customer\Test\Block\Account\AuthenticationPopup" locator=".block-authentication" strategy="css selector" /> + <block name="authenticationWrapperBlock" class="Magento\Customer\Test\Block\Account\AuthenticationWrapper" locator="[data-block='authentication']" strategy="css selector" /> <block name="loginBlock" class="Magento\Checkout\Test\Block\Onepage\Login" locator="[data-role='email-with-possible-login']" strategy="css selector" /> + <block name="linksBlock" class="Magento\Theme\Test\Block\Links" locator=".header .links" strategy="css selector" /> <block name="shippingBlock" class="Magento\Checkout\Test\Block\Onepage\Shipping" locator="#checkout-step-shipping" strategy="css selector" /> + <block name="shippingAddressPopupBlock" class="Magento\Checkout\Test\Block\Onepage\ShippingPopup" locator="#opc-new-shipping-address" strategy="css selector" /> <block name="shippingMethodBlock" class="Magento\Checkout\Test\Block\Onepage\Shipping\Method" locator="#checkout-step-shipping_method" strategy="css selector" /> <block name="paymentBlock" class="Magento\Checkout\Test\Block\Onepage\Payment" locator="#checkout-step-payment" strategy="css selector" /> <block name="discountCodesBlock" class="Magento\Checkout\Test\Block\Onepage\Payment\DiscountCodes" locator=".discount-code" strategy="css selector" /> <block name="reviewBlock" class="Magento\Checkout\Test\Block\Onepage\Review" locator=".opc-block-summary" strategy="css selector" /> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".page.messages" strategy="css selector" /> + <block name="customAddressBlock" class="Magento\Checkout\Test\Block\Onepage\CustomAddress" locator=".checkout-billing-address" strategy="css selector" /> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/Repository/ConfigData.xml new file mode 100644 index 0000000000000000000000000000000000000000..f1d9108ec3fc4e960e462fe06d2b9e8866612f97 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Repository/ConfigData.xml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd"> + <repository class="Magento\Config\Test\Repository\ConfigData"> + <dataset name="disable_guest_checkout"> + <field name="checkout/options/guest_checkout" xsi:type="array"> + <item name="scope" xsi:type="string">checkout</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">No</item> + <item name="value" xsi:type="string">0</item> + </field> + </dataset> + <dataset name="disable_guest_checkout_rollback"> + <field name="checkout/options/guest_checkout" xsi:type="array"> + <item name="scope" xsi:type="string">checkout</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">Yes</item> + <item name="value" xsi:type="string">1</item> + </field> + </dataset> + <dataset name="disable_customer_redirect_after_logging"> + <field name="customer/startup/redirect_dashboard" xsi:type="array"> + <item name="scope" xsi:type="string">customer</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">No</item> + <item name="value" xsi:type="string">0</item> + </field> + </dataset> + <dataset name="disable_customer_redirect_after_logging_rollback"> + <field name="customer/startup/redirect_dashboard" xsi:type="array"> + <item name="scope" xsi:type="string">customer</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">Yes</item> + <item name="value" xsi:type="string">1</item> + </field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php index 58d0c23f2274fcdde30703aa8ca4920ec0aa208a..25922102e1269c95280697db6c3175c36d6253fc 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php @@ -33,7 +33,7 @@ use Magento\Mtf\TestCase\Scenario; * 14. Perform assertions. * * @group One_Page_Checkout - * @ZephyrId MAGETWO-27485, MAGETWO-12412, MAGETWO-12429 + * @ZephyrId MAGETWO-27485, MAGETWO-12412, MAGETWO-12429, MAGETWO-49917, MAGETWO-27485 * @ZephyrId MAGETWO-12444, MAGETWO-12848, MAGETWO-12849, MAGETWO-12850 */ class OnePageCheckoutTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml index 797255d4e374acf001132647eee1121168ec0b50..24f63035645f22ebbf051f2ab0cb8cbf48c59c93 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml @@ -7,6 +7,34 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Checkout\Test\TestCase\OnePageCheckoutTest" summary="OnePageCheckout within Offline Payment Methods" ticketId="MAGETWO-27485"> + <variation name="OnePageCheckoutUsingLoginPopup" summary="Customer is redirected to checkout on login if guest is disabled, flow for existed Customer" ticketId="MAGETWO-49916"> + <data name="products/0" xsi:type="string">catalogProductSimple::default</data> + <data name="customer/dataset" xsi:type="string">johndoe_with_addresses</data> + <data name="checkoutMethod" xsi:type="string">login</data> + <data name="prices" xsi:type="array"> + <item name="grandTotal" xsi:type="string">565.00</item> + </data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> + <data name="payment/method" xsi:type="string">checkmo</data> + <data name="configData" xsi:type="string">checkmo, disable_guest_checkout, disable_customer_redirect_after_logging</data> + <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + </variation> + <variation name="OnePageCheckoutUsingRegisterLink" summary="Customer is redirected to checkout on login if guest is disabled, flow with registration new Customer" ticketId="MAGETWO-49917"> + <data name="issue" xsi:type="string">MAGETWO-59816: Redirect works improperly in a browser incognito mode</data> + <data name="products/0" xsi:type="string">catalogProductSimple::default</data> + <data name="customer/dataset" xsi:type="string">register_customer</data> + <data name="checkoutMethod" xsi:type="string">register_before_checkout</data> + <data name="prices" xsi:type="array"> + <item name="grandTotal" xsi:type="string">565.00</item> + </data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> + <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data> + <data name="payment/method" xsi:type="string">checkmo</data> + <data name="configData" xsi:type="string">checkmo, disable_guest_checkout, disable_customer_redirect_after_logging, enable_https_frontend_only</data> + <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + </variation> <variation name="OnePageCheckoutTestVariation1" summary="Checkout as UK guest with virtual product and downloadable product using coupon for not logged in customers"> <data name="products/0" xsi:type="string">catalogProductVirtual::default</data> <data name="products/1" xsi:type="string">downloadableProduct::with_two_separately_links</data> @@ -168,12 +196,13 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> - <variation name="OnePageCheckoutTestVariation9" summary="One Page Checkout Products with Tier Prices"> + <variation name="OnePageCheckoutTestVariation9" summary="One Page Checkout Products with different shipping/billing address and Tier Prices" ticketId="MAGETWO-42604"> <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_order_qty_3</data> <data name="customer/dataset" xsi:type="string">default</data> - <data name="checkoutMethod" xsi:type="string">guest</data> - <data name="shippingAddress/dataset" xsi:type="string">UK_address</data> + <data name="checkoutMethod" xsi:type="string">login</data> + <data name="shippingAddress/dataset" xsi:type="string">UK_address_without_email</data> + <data name="billingAddress/dataset" xsi:type="string">UK_address_2_without_email</data> <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> <data name="shipping/shipping_method" xsi:type="string">Fixed</data> <data name="prices" xsi:type="array"> @@ -183,6 +212,7 @@ <data name="configData" xsi:type="string">banktransfer_specificcountry_gb</data> <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> + <constraint name="Magento\Customer\Test\Constraint\AssertCustomerDefaultAddressFrontendAddressBook" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation10" summary="One Page Checkout with all product types"> @@ -203,7 +233,88 @@ </data> <data name="payment/method" xsi:type="string">checkmo</data> <data name="configData" xsi:type="string">checkmo</data> + <constraint name="Magento\Customer\Test\Constraint\AssertCustomerDefaultAddressFrontendAddressBook" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> + </variation> + <variation name="OnePageCheckoutUsingSingInLink" summary="Login during checkout using 'Sign In' link" ticketId="MAGETWO-42547"> + <data name="products/0" xsi:type="string">catalogProductSimple::default</data> + <data name="customer/dataset" xsi:type="string">customer_UK_US_addresses</data> + <data name="checkoutMethod" xsi:type="string">sign_in</data> + <data name="shippingAddressCustomer" xsi:type="array"> + <item name="added" xsi:type="number">1</item> + </data> + <data name="billingAddressCustomer" xsi:type="array"> + <item name="added" xsi:type="number">1</item> + </data> + <data name="prices" xsi:type="array"> + <item name="grandTotal" xsi:type="string">565.00</item> + </data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> + <data name="payment/method" xsi:type="string">checkmo</data> + <data name="configData" xsi:type="string">checkmo</data> + <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> + </variation> + <variation name="OnePageCheckoutUsingNonDefaultAddress" summary="Checkout as Customer using non default address" ticketId="MAGETWO-42602"> + <data name="products/0" xsi:type="string">catalogProductSimple::default</data> + <data name="customer/dataset" xsi:type="string">customer_US_DE_UK</data> + <data name="checkoutMethod" xsi:type="string">login</data> + <data name="shippingAddressCustomer" xsi:type="array"> + <item name="added" xsi:type="number">1</item> + </data> + <data name="billingAddressCustomer" xsi:type="array"> + <item name="added" xsi:type="number">2</item> + </data> + <data name="prices" xsi:type="array"> + <item name="grandTotal" xsi:type="string">565.00</item> + </data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> + <data name="payment/method" xsi:type="string">checkmo</data> + <data name="configData" xsi:type="string">checkmo</data> + <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> + </variation> + <variation name="OnePageCheckoutUsingNewAddress" summary="Checkout as Customer using New address" ticketId="MAGETWO-42601"> + <data name="products/0" xsi:type="string">catalogProductSimple::default</data> + <data name="customer/dataset" xsi:type="string">johndoe_with_addresses</data> + <data name="checkoutMethod" xsi:type="string">sign_in</data> + <data name="prices" xsi:type="array"> + <item name="grandTotal" xsi:type="string">565.00</item> + </data> + <data name="shippingAddress/dataset" xsi:type="string">UK_address_without_email</data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> + <data name="billingCheckboxState" xsi:type="string">Yes</data> + <data name="billingAddress/dataset" xsi:type="string">US_address_1_without_email</data> + <data name="payment/method" xsi:type="string">checkmo</data> + <data name="configData" xsi:type="string">checkmo</data> + <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> + </variation> + <variation name="OnePageCheckoutTestVariation11" summary="Checkout as Customer using default address" ticketId="MAGETWO-42600, MAGETWO-42546"> + <data name="products/0" xsi:type="string">catalogProductSimple::default</data> + <data name="customer/dataset" xsi:type="string">customer_UK_US_addresses</data> + <data name="checkoutMethod" xsi:type="string">login</data> + <data name="shippingAddressCustomer" xsi:type="array"> + <item name="added" xsi:type="number">0</item> + </data> + <data name="billingAddressCustomer" xsi:type="array"> + <item name="added" xsi:type="number">0</item> + </data> + <data name="prices" xsi:type="array"> + <item name="grandTotal" xsi:type="string">565.00</item> + </data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> + <data name="payment/method" xsi:type="string">checkmo</data> + <data name="configData" xsi:type="string">checkmo_specificcountry_gb</data> + <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderAddresses" /> </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php index 62d773a6637bf8fdacedf62932d798dcd6d9e431..0bfe42f7fe78ced0ffb2282d69790ca42c4a1dec 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php @@ -11,6 +11,7 @@ use Magento\Cms\Test\Page\CmsIndex; use Magento\Mtf\Fixture\FixtureFactory; use Magento\Mtf\Fixture\FixtureInterface; use Magento\Mtf\TestCase\Injectable; +use Magento\Customer\Test\Fixture\Customer; /** * Preconditions: @@ -76,14 +77,28 @@ class UpdateProductFromMiniShoppingCartEntityTest extends Injectable /** * Update product from mini shopping cart. - * * @param array $originalProduct * @param array $checkoutData + * @param boolean $useMiniCartToEditQty + * @param array $shippingAddress + * @param array $shipping + * @param array $payment + * @param Customer $customer * @return array */ - public function test(array $originalProduct, array $checkoutData) - { + public function test( + array $originalProduct, + array $checkoutData, + $useMiniCartToEditQty = false, + $shippingAddress = null, + $shipping = null, + $payment = null, + Customer $customer = null + ) { // Preconditions: + if ($customer !== null) { + $customer->persist(); + } $product = $this->createProduct($originalProduct); $this->addToCart($product); @@ -93,16 +108,25 @@ class UpdateProductFromMiniShoppingCartEntityTest extends Injectable $newProduct = $this->createProduct([explode('::', $originalProduct[0])[0]], [$productData]); $miniShoppingCart = $this->cmsIndex->getCartSidebarBlock(); $miniShoppingCart->openMiniCart(); - $miniShoppingCart->getCartItem($newProduct)->clickEditItem(); - $this->catalogProductView->getViewBlock()->addToCart($newProduct); + if ($useMiniCartToEditQty) { + $miniShoppingCart->getCartItem($newProduct)->editQty($newProduct->getCheckoutData()); + } else { + $miniShoppingCart->getCartItem($newProduct)->clickEditItem(); + $this->catalogProductView->getViewBlock()->addToCart($newProduct); + } // Prepare data for asserts: $cart['data']['items'] = ['products' => [$newProduct]]; $deletedCart['data']['items'] = ['products' => [$product]]; return [ 'deletedCart' => $this->fixtureFactory->createByCode('cart', $deletedCart), - 'cart' => $this->fixtureFactory->createByCode('cart', $cart) + 'cart' => $this->fixtureFactory->createByCode('cart', $cart), + 'checkoutData' => [ + 'shippingAddress' => $shippingAddress, + 'shipping' => $shipping, + 'payment' => $payment + ] ]; } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml index 5f9b069ab85ca92d37ac8773ac3d1694e5d6ee81..cd500a935485cd0e08981d32a53b9280a7d2ad57 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml @@ -7,12 +7,22 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Checkout\Test\TestCase\UpdateProductFromMiniShoppingCartEntityTest" summary="Update Product from Mini Shopping Cart" ticketId="MAGETWO-29812"> - <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation1" summary="Update Simple"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> - <data name="originalProduct/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data> - <data name="checkoutData/dataset" xsi:type="string">simple_update_mini_shopping_cart</data> + <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation1" summary="Update Product Qty on Mini Shopping Cart" ticketId=" MAGETWO-35536"> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="originalProduct/0" xsi:type="string">catalogProductSimple::default</data> + <data name="checkoutData/dataset" xsi:type="string">simple_order_qty_2</data> + <data name="use_minicart_to_edit_qty" xsi:type="boolean">true</data> + <data name="prices" xsi:type="array"> + <item name="grandTotal" xsi:type="string">1130</item> + </data> + <data name="customer/dataset" xsi:type="string">customer_US</data> + <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> + <data name="shipping/shipping_method" xsi:type="string">Fixed</data> + <data name="shippingAddress/dataset" xsi:type="string">UK_address</data> + <data name="payment/method" xsi:type="string">free</data> <constraint name="Magento\Checkout\Test\Constraint\AssertProductDataInMiniShoppingCart" /> <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" /> + <constraint name="Magento\Checkout\Test\Constraint\AssertCustomerIsRedirectedToCheckoutFromCart" /> </variation> <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation2" summary="Update Configurable and verify previous product was updated to new one in shopping cart and mini shopping cart"> <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/FillBillingInformationStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/FillBillingInformationStep.php index a7d432fa38b2a6a3ef05f8b883887d093baae554..720965212ad38d6d249d7ef4f1634e2c43f5deb2 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/FillBillingInformationStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/FillBillingInformationStep.php @@ -10,6 +10,8 @@ use Magento\Checkout\Test\Page\CheckoutOnepage; use Magento\Customer\Test\Fixture\Address; use Magento\Mtf\TestStep\TestStepInterface; use Magento\Checkout\Test\Constraint\AssertBillingAddressSameAsShippingCheckbox; +use Magento\Customer\Test\Fixture\Customer; +use Magento\Mtf\ObjectManager; /** * Fill billing information. @@ -37,6 +39,13 @@ class FillBillingInformationStep implements TestStepInterface */ protected $shippingAddress; + /** + * Customer fixture. + * + * @var Customer + */ + protected $customer; + /** * "Same as Shipping" checkbox value assertion. * @@ -51,45 +60,85 @@ class FillBillingInformationStep implements TestStepInterface */ protected $billingCheckboxState; + /** + * Customer shipping address data for select. + * + * @var array + */ + private $billingAddressCustomer; + + /** + * Object manager instance. + * + * @var ObjectManager $objectManager + */ + protected $objectManager; + /** * @constructor * @param CheckoutOnepage $checkoutOnepage * @param AssertBillingAddressSameAsShippingCheckbox $assertBillingAddressCheckbox + * @param Customer $customer + * @param ObjectManager $objectManager * @param Address $billingAddress * @param Address $shippingAddress * @param string $billingCheckboxState + * @param array|null $billingAddressCustomer */ public function __construct( CheckoutOnepage $checkoutOnepage, AssertBillingAddressSameAsShippingCheckbox $assertBillingAddressCheckbox, + Customer $customer, + ObjectManager $objectManager, Address $billingAddress = null, Address $shippingAddress = null, - $billingCheckboxState = null + $billingCheckboxState = null, + $billingAddressCustomer = null ) { $this->checkoutOnepage = $checkoutOnepage; $this->billingAddress = $billingAddress; $this->shippingAddress = $shippingAddress; $this->assertBillingAddressCheckbox = $assertBillingAddressCheckbox; + $this->customer = $customer; + $this->objectManager = $objectManager; $this->billingCheckboxState = $billingCheckboxState; + $this->billingAddressCustomer = $billingAddressCustomer; } /** * Fill billing address. * - * @return void + * @return array */ public function run() { + $billingAddress = null; if ($this->billingCheckboxState) { $this->assertBillingAddressCheckbox->processAssert($this->checkoutOnepage, $this->billingCheckboxState); } - if ($this->billingAddress) { $selectedPaymentMethod = $this->checkoutOnepage->getPaymentBlock()->getSelectedPaymentMethodBlock(); if ($this->shippingAddress) { $selectedPaymentMethod->getBillingBlock()->unsetSameAsShippingCheckboxValue(); } $selectedPaymentMethod->getBillingBlock()->fillBilling($this->billingAddress); + $billingAddress = $this->billingAddress; + } + if (isset($this->billingAddressCustomer['added'])) { + $addressIndex = $this->billingAddressCustomer['added']; + $billingAddress = $this->customer->getDataFieldConfig('address')['source']->getAddresses()[$addressIndex]; + $address = $this->objectManager->create( + \Magento\Customer\Test\Block\Address\Renderer::class, + ['address' => $billingAddress, 'type' => 'html_for_select_element'] + )->render(); + $selectedPaymentMethod = $this->checkoutOnepage->getPaymentBlock()->getSelectedPaymentMethodBlock(); + $selectedPaymentMethod->getBillingBlock()->unsetSameAsShippingCheckboxValue(); + $this->checkoutOnepage->getCustomAddressBlock()->selectAddress($address); + $selectedPaymentMethod->getBillingBlock()->clickUpdate(); } + + return [ + 'billingAddress' => $billingAddress + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/FillShippingAddressStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/FillShippingAddressStep.php index 5150eb9964ba3e960e88694fcc781e7bc6d829e0..1c4e407fb8c24391da8ecf4498e1702adb0d254b 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/FillShippingAddressStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/FillShippingAddressStep.php @@ -8,7 +8,10 @@ namespace Magento\Checkout\Test\TestStep; use Magento\Checkout\Test\Page\CheckoutOnepage; use Magento\Customer\Test\Fixture\Address; +use Magento\Mtf\Fixture\FixtureFactory; use Magento\Mtf\TestStep\TestStepInterface; +use Magento\Customer\Test\Fixture\Customer; +use Magento\Mtf\ObjectManager; /** * Fill shipping address step. @@ -20,37 +23,109 @@ class FillShippingAddressStep implements TestStepInterface * * @var CheckoutOnepage */ - protected $checkoutOnepage; + private $checkoutOnepage; /** * Address fixture. * * @var Address */ - protected $shippingAddress; + private $shippingAddress; + + /** + * Customer fixture. + * + * @var Customer + */ + private $customer; + + /** + * Customer shipping address data for select. + * + * @var array + */ + private $shippingAddressCustomer; + + /** + * Object manager instance. + * + * @var ObjectManager + */ + private $objectManager; + + /** + * Fixture factory. + * + * @var FixtureFactory + */ + private $fixtureFactory; /** * @constructor * @param CheckoutOnepage $checkoutOnepage - * @param Address $shippingAddress + * @param Customer $customer + * @param ObjectManager $objectManager + * @param FixtureFactory $fixtureFactory + * @param Address|null $shippingAddress + * @param array|null $shippingAddressCustomer */ public function __construct( CheckoutOnepage $checkoutOnepage, - Address $shippingAddress = null + Customer $customer, + ObjectManager $objectManager, + FixtureFactory $fixtureFactory, + Address $shippingAddress = null, + $shippingAddressCustomer = null ) { $this->checkoutOnepage = $checkoutOnepage; + $this->customer = $customer; + $this->objectManager = $objectManager; + $this->fixtureFactory = $fixtureFactory; $this->shippingAddress = $shippingAddress; + $this->shippingAddressCustomer = $shippingAddressCustomer; } /** * Fill shipping address. * - * @return void + * @return array */ public function run() { + $shippingAddress = null; if ($this->shippingAddress) { - $this->checkoutOnepage->getShippingBlock()->fill($this->shippingAddress); + $shippingBlock = $this->checkoutOnepage->getShippingBlock(); + if ($shippingBlock->isPopupNewAddressButtonVisible()) { + $shippingBlock->clickPopupNewAddressButton(); + $this->checkoutOnepage->getShippingAddressPopupBlock() + ->fill($this->shippingAddress) + ->clickSaveAddressButton(); + } else { + $shippingBlock->fill($this->shippingAddress); + } + $shippingAddress = $this->shippingAddress; + } + if (isset($this->shippingAddressCustomer['new'])) { + $shippingAddress = $this->fixtureFactory->create( + 'address', + ['dataset' => $this->shippingAddressCustomer['new']] + ); + $this->checkoutOnepage->getShippingBlock()->clickPopupNewAddressButton(); + $this->checkoutOnepage->getShippingAddressPopupBlock()->fill($shippingAddress)->clickSaveAddressButton(); } + if (isset($this->shippingAddressCustomer['added'])) { + $addressIndex = $this->shippingAddressCustomer['added']; + $shippingAddress = $this->customer->getDataFieldConfig('address')['source']->getAddresses()[$addressIndex]; + $address = $this->objectManager->create( + \Magento\Customer\Test\Block\Address\Renderer::class, + ['address' => $shippingAddress, 'type' => 'html_without_company'] + )->render(); + $shippingBlock = $this->checkoutOnepage->getShippingBlock(); + $shippingBlock->selectAddress($address); + } + + return [ + 'shippingAddress' => $shippingAddress, + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php index eef5f2fbdd03a9b7325b01aa8b5d4293e566ffbb..cb32e5f0ddfe61d9e97e8ef211ce71bfa46ee71a 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php @@ -8,6 +8,7 @@ namespace Magento\Checkout\Test\TestStep; use Magento\Mtf\TestStep\TestStepInterface; use Magento\Customer\Test\Fixture\Customer; +use Magento\Customer\Test\Page\CustomerAccountCreate; use Magento\Checkout\Test\Page\CheckoutOnepage; use Magento\Customer\Test\TestStep\LogoutCustomerOnFrontendStep; @@ -51,6 +52,13 @@ class SelectCheckoutMethodStep implements TestStepInterface */ private $clickProceedToCheckoutStep; + /** + * Customer account create page instance. + * + * @var CustomerAccountCreate + */ + private $customerAccountCreatePage; + /** * Shipping carrier and method. * @@ -61,6 +69,7 @@ class SelectCheckoutMethodStep implements TestStepInterface /** * @constructor * @param CheckoutOnepage $checkoutOnepage + * @param CustomerAccountCreate $customerAccountCreatePage * @param Customer $customer * @param LogoutCustomerOnFrontendStep $logoutCustomerOnFrontend * @param ClickProceedToCheckoutStep $clickProceedToCheckoutStep @@ -69,6 +78,7 @@ class SelectCheckoutMethodStep implements TestStepInterface */ public function __construct( CheckoutOnepage $checkoutOnepage, + CustomerAccountCreate $customerAccountCreatePage, Customer $customer, LogoutCustomerOnFrontendStep $logoutCustomerOnFrontend, ClickProceedToCheckoutStep $clickProceedToCheckoutStep, @@ -76,6 +86,7 @@ class SelectCheckoutMethodStep implements TestStepInterface array $shipping = [] ) { $this->checkoutOnepage = $checkoutOnepage; + $this->customerAccountCreatePage = $customerAccountCreatePage; $this->customer = $customer; $this->logoutCustomerOnFrontend = $logoutCustomerOnFrontend; $this->clickProceedToCheckoutStep = $clickProceedToCheckoutStep; @@ -89,6 +100,17 @@ class SelectCheckoutMethodStep implements TestStepInterface * @return void */ public function run() + { + $this->processLogin(); + $this->processRegister(); + } + + /** + * Process login action. + * + * @return void + */ + private function processLogin() { if ($this->checkoutMethod === 'login') { if ($this->checkoutOnepage->getAuthenticationPopupBlock()->isVisible()) { @@ -101,17 +123,35 @@ class SelectCheckoutMethodStep implements TestStepInterface if (empty($this->shipping)) { $this->checkoutOnepage->getLoginBlock()->fillGuestFields($this->customer); } + } elseif ($this->checkoutMethod === 'sign_in') { + $this->checkoutOnepage->getAuthenticationWrapperBlock()->signInLinkClick(); + $this->checkoutOnepage->getAuthenticationWrapperBlock()->loginCustomer($this->customer); + } + } + + /** + * Process customer register action. + * + * @return void + */ + private function processRegister() + { + if ($this->checkoutMethod === 'register_before_checkout') { + $this->checkoutOnepage->getAuthenticationPopupBlock()->createAccount(); + $this->customerAccountCreatePage->getRegisterForm()->registerCustomer($this->customer); } } /** - * Logout customer on fronted. + * Logout customer on frontend. * * @return void */ public function cleanup() { - if ($this->checkoutMethod === 'login') { + if ($this->checkoutMethod === 'login' || + $this->checkoutMethod === 'sign_in' || + $this->checkoutMethod === 'register_before_checkout') { $this->logoutCustomerOnFrontend->run(); } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php index c4fcfd569490a6ac1f2ae68c2068d4f110f594bb..cc23998f60ac2ced653c294313cfa54eb98ef5a9 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php @@ -18,7 +18,7 @@ class AuthenticationPopup extends Form * * @var string */ - private $login = '[name="send"]'; + private $login = '.action.action-login.secondary'; /** * Selector for loading mask element. @@ -27,6 +27,23 @@ class AuthenticationPopup extends Form */ private $loadingMask = '.loading-mask'; + /** + * 'Create an Account' button. + * + * @var string + */ + protected $createAccountButton = '.action.action-register.primary'; + + /** + * Click 'Create an Account' button. + * + * @return void + */ + public function createAccount() + { + $this->_rootElement->find($this->createAccountButton)->click(); + } + /** * Login customer on authentication popup. * diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationWrapper.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationWrapper.php new file mode 100644 index 0000000000000000000000000000000000000000..56e7cf257f15c80b34144b78ae07e70405f77e3e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationWrapper.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Customer\Test\Block\Account; + +use Magento\Mtf\Block\Form; +use Magento\Customer\Test\Fixture\Customer; + +/** + * Authentication wrapper block. + */ +class AuthenticationWrapper extends AuthenticationPopup +{ + /** + * 'Sign In' link. + * + * @var string + */ + protected $signInLink = '[data-trigger="authentication"]'; + + /** + * Click on 'Sign In' link. + * + * @return void + */ + public function signInLinkClick() + { + $this->_rootElement->find($this->signInLink)->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationWrapper.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationWrapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..1bcb31c45dc391ed4d26457f74ed984812b3be57 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationWrapper.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" ?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<mapping strict="1"> + <fields> + <email> + <selector>[id='login-email']</selector> + </email> + <password> + <selector>[id='login-password']</selector> + </password> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Renderer.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Renderer.php index 832c376e6435708e0e7e2e632f79e20e769b21cb..fa654599932c3d0726313dc5666e1af2f2e20751 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Renderer.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Renderer.php @@ -53,6 +53,16 @@ class Renderer . "{{city}}, {{{$region}}}, {{postcode}}\n{{country_id}}\n{{depend}}T: {{telephone}}{{/depend}}" . "{{depend}}\nF: {{fax}}{{/depend}}{{depend}}\nVAT: {{vat_id}}{{/depend}}"; break; + case "html_without_company": + $outputPattern = "{{depend}}{{prefix}} {{/depend}}{{firstname}} {{depend}}{{middlename}} {{/depend}}" + . "{{lastname}}{{depend}} {{suffix}}{{/depend}}\n{{/depend}}{{street}}\n" + . "{{city}}, {{{$region}}} {{postcode}}\n{{country_id}}\n{{depend}}{{telephone}}{{/depend}}"; + break; + case "html_for_select_element": + $outputPattern = "{{depend}}{{prefix}} {{/depend}}{{firstname}} {{depend}}{{middlename}} {{/depend}}" + . "{{lastname}}{{depend}} {{suffix}}{{/depend}}, {{/depend}}{{street}}, " + . "{{city}}, {{{$region}}} {{postcode}}, {{country_id}}"; + break; case "oneline": default: $outputPattern = "{{depend}}{{prefix}} {{/depend}}{{firstname}} {{depend}}{{middlename}} {{/depend}}" diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerDefaultAddressFrontendAddressBook.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerDefaultAddressFrontendAddressBook.php index a95a0ba98e3bf7b751007fbb69ea841c77c6ceea..6ede7c49a070db88608296637595d986498e923b 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerDefaultAddressFrontendAddressBook.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerDefaultAddressFrontendAddressBook.php @@ -6,9 +6,10 @@ namespace Magento\Customer\Test\Constraint; +use Magento\Customer\Test\Block\Address\Renderer; use Magento\Customer\Test\Fixture\Address; -use Magento\Customer\Test\Page\CustomerAccountIndex; use Magento\Customer\Test\Page\CustomerAccountAddress; +use Magento\Customer\Test\Page\CustomerAccountIndex; use Magento\Mtf\Constraint\AbstractConstraint; /** @@ -20,25 +21,32 @@ class AssertCustomerDefaultAddressFrontendAddressBook extends AbstractConstraint * Asserts that Default Billing Address and Default Shipping Address equal to data from fixture. * * @param CustomerAccountIndex $customerAccountIndex - * @param CustomerAccountAddress $customerAccountAddress - * @param Address $address + * @param CustomerAccountAddress $customerAddress + * @param Address|null $shippingAddress + * @param Address|null $billingAddress * @return void */ public function processAssert( CustomerAccountIndex $customerAccountIndex, - CustomerAccountAddress $customerAccountAddress, - Address $address + CustomerAccountAddress $customerAddress, + Address $shippingAddress, + Address $billingAddress = null ) { + $customerAccountIndex->open(); $customerAccountIndex->getAccountMenuBlock()->openMenuItem('Address Book'); - $addressRenderer = $this->objectManager->create( - \Magento\Customer\Test\Block\Address\Renderer::class, - ['address' => $address, 'type' => 'html'] - ); - $addressToVerify = $addressRenderer->render(); + + $shippingAddressRendered = $this->createAddressRenderer($shippingAddress)->render(); + $validated = + $shippingAddressRendered == $customerAddress->getDefaultAddressBlock()->getDefaultShippingAddress(); + + if (null !== $billingAddress) { + $billingAddressRendered = $customerAddress->getDefaultAddressBlock()->getDefaultBillingAddress(); + $validated = + $validated && ($billingAddressRendered == $this->createAddressRenderer($billingAddress)->render()); + } \PHPUnit_Framework_Assert::assertTrue( - $addressToVerify == $customerAccountAddress->getDefaultAddressBlock()->getDefaultBillingAddress() - && $addressToVerify == $customerAccountAddress->getDefaultAddressBlock()->getDefaultShippingAddress(), + $validated, 'Customer default address on address book tab is not matching the fixture.' ); } @@ -52,4 +60,18 @@ class AssertCustomerDefaultAddressFrontendAddressBook extends AbstractConstraint { return 'Default billing and shipping address form is correct.'; } + + /** + * Instantiate Renderer object. + * + * @param Address $address + * @return Renderer + */ + private function createAddressRenderer(Address $address) + { + return $this->objectManager->create( + Renderer::class, + ['address' => $address, 'type' => 'html'] + ); + } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupChangedToDefaultOnCustomerForm.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupChangedToDefaultOnCustomerForm.php index 392a594c25c33db5fd89aee78a4c8bdce37df0fc..e489b6faf00526721ec894c74a0e3fe0de3ee0b5 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupChangedToDefaultOnCustomerForm.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupChangedToDefaultOnCustomerForm.php @@ -32,7 +32,7 @@ class AssertCustomerGroupChangedToDefaultOnCustomerForm extends AbstractConstrai CustomerIndexNew $customerIndexEdit ) { $customerIndexEdit->open(['id' => $customer->getId()]); - $customerFormData = $customerIndexNew->getCustomerForm()->getData(); + $customerFormData = $customerIndexNew->getCustomerForm()->getData($customer); \PHPUnit_Framework_Assert::assertTrue( $customerFormData['group_id'] == $defaultCustomerGroup->getCustomerGroupCode(), "Customer group not set to default after group was deleted." diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php index ddb20b29e063a734545787c6194e1a24a894d2e8..f880983074576396646ed0dc10be2ebb12c6b708 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Curl.php @@ -32,7 +32,8 @@ class Curl extends AbstractCurl implements CustomerInterface protected $mappingData = [ 'country_id' => [ 'United States' => 'US', - 'United Kingdom' => 'GB' + 'United Kingdom' => 'GB', + 'Germany' => 'DE' ], 'gender' => [ 'Male' => 1, diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Webapi.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Webapi.php index 8873e71610de0eafe4e7e7e2ff7afa8d25ce6eaf..aa63bfa50f052096d0468b5df6e8c12e7c1075af 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Webapi.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/Customer/Webapi.php @@ -33,7 +33,8 @@ class Webapi extends AbstractWebapi implements CustomerInterface ], 'country_id' => [ 'United States' => 'US', - 'United Kingdom' => 'GB' + 'United Kingdom' => 'GB', + 'Germany' => 'DE' ], 'region_id' => [ 'California' => 12, diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.xml index 70191dc828af7aecada34068c5d0e93cce4736ee..8baa7ce0d9310f7e2d7a17fab8c904530cf25629 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Address.xml @@ -189,6 +189,18 @@ <field name="telephone" xsi:type="string">555-55-555-55</field> </dataset> + <dataset name="UK_address_2_without_email"> + <field name="firstname" xsi:type="string">Billy</field> + <field name="lastname" xsi:type="string">Holiday</field> + <field name="company" xsi:type="string">Magento %isolation%</field> + <field name="city" xsi:type="string">Liverpool</field> + <field name="street" xsi:type="string">99 Henry St</field> + <field name="postcode" xsi:type="string">SE1 7RW</field> + <field name="country_id" xsi:type="string">United Kingdom</field> + <field name="region" xsi:type="string">Liverpool</field> + <field name="telephone" xsi:type="string">555-55-555-55</field> + </dataset> + <dataset name="UK_address_without_email"> <field name="firstname" xsi:type="string">Jane</field> <field name="lastname" xsi:type="string">Doe</field> @@ -219,13 +231,25 @@ <dataset name="DE_address"> <field name="firstname" xsi:type="string">Jan</field> <field name="lastname" xsi:type="string">Jansen</field> + <field name="email" xsi:type="string">JaneDoe_%isolation%@example.com</field> <field name="company" xsi:type="string">Magento %isolation%</field> <field name="city" xsi:type="string">Berlin</field> <field name="street" xsi:type="string">Augsburger Strabe 41</field> <field name="postcode" xsi:type="string">10789</field> <field name="country_id" xsi:type="string">Germany</field> - <field name="region_id" xsi:type="string">Berlin</field> + <field name="region" xsi:type="string">Berlin</field> <field name="telephone" xsi:type="string">333-33-333-33</field> </dataset> + + <dataset name="customer_UK_US_addresses"> + <field name="firstname" xsi:type="string">John</field> + <field name="lastname" xsi:type="string">Doe%isolation%</field> + <field name="email" xsi:type="string">John.Doe%isolation%@example.com</field> + <field name="password" xsi:type="string">123123^q</field> + <field name="password_confirmation" xsi:type="string">123123^q</field> + <field name="address" xsi:type="array"> + <item name="dataset" xsi:type="string">UK_address_default_billing, US_address_default_shipping</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Customer.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Customer.xml index 0892fac420357cc04c905252eac8cb58127865f9..3be7447c91dad863564835d08b459b6addfd86f5 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Customer.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/Customer.xml @@ -186,5 +186,30 @@ <item name="dataset" xsi:type="string">UK_address_with_VAT</item> </field> </dataset> + + <dataset name="customer_UK_US_addresses"> + <field name="firstname" xsi:type="string">John</field> + <field name="lastname" xsi:type="string">Doe%isolation%</field> + <field name="email" xsi:type="string">John.Doe%isolation%@example.com</field> + <field name="password" xsi:type="string">123123^q</field> + <field name="password_confirmation" xsi:type="string">123123^q</field> + <field name="address" xsi:type="array"> + <item name="dataset" xsi:type="string">UK_address_default_billing, US_address_default_shipping</item> + </field> + </dataset> + + <dataset name="customer_US_DE_UK"> + <field name="firstname" xsi:type="string">John</field> + <field name="lastname" xsi:type="string">Doe%isolation%</field> + <field name="group_id" xsi:type="array"> + <item name="dataset" xsi:type="string">General</item> + </field> + <field name="email" xsi:type="string">JohnDoe_%isolation%@example.com</field> + <field name="password" xsi:type="string">123123^q</field> + <field name="password_confirmation" xsi:type="string">123123^q</field> + <field name="address" xsi:type="array"> + <item name="dataset" xsi:type="string">US_address, DE_address, UK_address</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php index 34338371d45af849f54956588aee5a97c0f75ecd..b3d41a911af41d424ee6fcab048db42a8da8aa17 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php @@ -156,6 +156,10 @@ class UpdateCustomerFrontendEntityTest extends Injectable $this->customerAddressEdit->getEditForm()->fill($address); $this->customerAddressEdit->getEditForm()->saveAddress(); - return ['customer' => $this->prepareCustomer($customer, $initialCustomer)]; + return [ + 'customer' => $this->prepareCustomer($customer, $initialCustomer), + 'shippingAddress' => $address, + 'billingAddress' => $address + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/CreateCustomerStep.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/CreateCustomerStep.php index f3be4e8b89cfdc916426280bb63c806565226ad1..4beb9207f4f29883e035558e6ba0b1e256ea08ed 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/CreateCustomerStep.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/CreateCustomerStep.php @@ -46,7 +46,9 @@ class CreateCustomerStep implements TestStepInterface { $this->logoutCustomerOnFrontend = $logout; $this->customer = $customer; - if ($checkoutMethod === 'register' || $checkoutMethod === 'guest') { + if ($checkoutMethod === 'register' + || $checkoutMethod === 'guest' + || $checkoutMethod === 'register_before_checkout') { $this->persistCustomer = false; } } diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml index f6450b86c511adb44b615d7d97c6bc8495e5049e..08d4506b3c05461975797ec3ec31a11b63674304 100644 --- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Repository/ConfigData.xml @@ -29,6 +29,40 @@ <item name="value" xsi:type="string">10</item> </field> </dataset> + <dataset name="layered_navigation_automatic_equalize_price_range"> + <field name="catalog/layered_navigation/display_product_count" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Yes" xsi:type="string">1</item> + </field> + <field name="catalog/layered_navigation/price_range_calculation" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Automatic (equalize price ranges)" xsi:type="string">auto</item> + </field> + </dataset> + <dataset name="layered_navigation_automatic_equalize_product_counts"> + <field name="catalog/layered_navigation/display_product_count" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Yes" xsi:type="string">1</item> + </field> + <field name="catalog/layered_navigation/price_range_calculation" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Automatic (equalize product counts)" xsi:type="string">improved</item> + </field> + <field name="catalog/layered_navigation/one_price_interval" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" xsi:type="string">0</item> + </field> + <field name="catalog/layered_navigation/interval_division_limit" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" xsi:type="string">3</item> + </field> + </dataset> <dataset name="layered_navigation_manual_range_10_rollback"> <field name="catalog/layered_navigation/display_product_count" xsi:type="array"> <item name="scope" xsi:type="string">default</item> @@ -41,5 +75,29 @@ <item name="value" label="Automatic (equalize price ranges)" xsi:type="string">auto</item> </field> </dataset> + <dataset name="layered_navigation_automatic_equalize_price_range_rollback"> + <field name="catalog/layered_navigation/display_product_count" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Yes" xsi:type="string">1</item> + </field> + <field name="catalog/layered_navigation/price_range_calculation" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Automatic (equalize price ranges)" xsi:type="string">auto</item> + </field> + </dataset> + <dataset name="layered_navigation_automatic_equalize_product_counts_rollback"> + <field name="catalog/layered_navigation/display_product_count" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Yes" xsi:type="string">1</item> + </field> + <field name="catalog/layered_navigation/price_range_calculation" xsi:type="array"> + <item name="scope" xsi:type="string">default</item> + <item name="scope_id" xsi:type="number">0</item> + <item name="value" label="Automatic (equalize price ranges)" xsi:type="string">auto</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php index 543880aea127310181be8b7e7d5663495e8202ba..c42686f62591b21e29a5d28f1f42ba5fa1044260 100644 --- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Perform all assertions. * * @group Layered_Navigation - * @ZephyrId MAGETWO-12419 + * @ZephyrId MAGETWO-12419, MAGETWO-30617, MAGETWO-30700, MAGETWO-30702, MAGETWO-30703 */ class FilterProductListTest extends Injectable { diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml index 8a9388df40c9fc32ade9df9df40c650605244f27..0737dfd0d7ad6d58a5c736fa6ec6270eac2ad1b9 100644 --- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml @@ -10,6 +10,7 @@ <variation name="FilterProductListTestVariation1"> <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data> <data name="configData" xsi:type="string">layered_navigation_manual_range_10</data> + <data name="runReindex" xsi:type="string">Yes</data> <data name="category/dataset" xsi:type="string">default_anchor_subcategory</data> <data name="category/data/category_products/dataset" xsi:type="string">catalogProductSimple::product_20_dollar, configurableProduct::filterable_two_options_with_zero_price</data> <data name="layeredNavigation" xsi:type="array"> @@ -31,5 +32,66 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" /> <constraint name="Magento\LayeredNavigation\Test\Constraint\AssertFilterProductList" /> </variation> + <variation name="FilterProductListTestVariation2" ticketId="MAGETWO-30617, MAGETWO-30702"> + <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data> + <data name="configData" xsi:type="string">layered_navigation_automatic_equalize_price_range</data> + <data name="runReindex" xsi:type="string">Yes</data> + <data name="category/dataset" xsi:type="string">default_anchor_subcategory</data> + <data name="category/data/category_products/dataset" xsi:type="string"> + catalogProductSimple::product_1_dollar, catalogProductSimple::product_5_dollar, catalogProductSimple::product_9_99_dollar, catalogProductSimple::product_10_dollar, catalogProductSimple::product_15_dollar, catalogProductSimple::product_21_dollar + </data> + <data name="layeredNavigation" xsi:type="array"> + <item name="filters_0" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Price</item> + <item name="linkPattern" xsi:type="string">`^.+0\.00 - .+9\.99 3$`m</item> + <item name="products" xsi:type="string">product_0, product_1, product_2</item> + </item> + </item> + <item name="filters_1" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Price</item> + <item name="linkPattern" xsi:type="string">`^.+10\.00 - .+19\.99 2$`m</item> + <item name="products" xsi:type="string">product_3, product_4</item> + </item> + </item> + <item name="filters_2" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Price</item> + <item name="linkPattern" xsi:type="string">`^.+20\.00 and above 1$`m</item> + <item name="products" xsi:type="string">product_5</item> + </item> + </item> + </data> + <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" /> + <constraint name="Magento\LayeredNavigation\Test\Constraint\AssertFilterProductList" /> + </variation> + <variation name="FilterProductListTestVariation3" ticketId="MAGETWO-30700, MAGETWO-30703"> + <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data> + <data name="configData" xsi:type="string">layered_navigation_automatic_equalize_product_counts</data> + <data name="runReindex" xsi:type="string">Yes</data> + <data name="category/dataset" xsi:type="string">default_anchor_subcategory</data> + <data name="category/data/category_products/dataset" xsi:type="string"> + catalogProductSimple::product_1_dollar, catalogProductSimple::product_5_dollar, catalogProductSimple::product_9_99_dollar, catalogProductSimple::product_10_dollar, catalogProductSimple::product_15_dollar, catalogProductSimple::product_21_dollar + </data> + <data name="layeredNavigation" xsi:type="array"> + <item name="filters_0" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Price</item> + <item name="linkPattern" xsi:type="string">`^.+0\.00 - .+9\.99 3$`m</item> + <item name="products" xsi:type="string">product_0, product_1, product_2</item> + </item> + </item> + <item name="filters_1" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Price</item> + <item name="linkPattern" xsi:type="string">`^.+10\.00 and above 3$`m</item> + <item name="products" xsi:type="string">product_3, product_4, product_5</item> + </item> + </item> + </data> + <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" /> + <constraint name="Magento\LayeredNavigation\Test\Constraint\AssertFilterProductList" /> + </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Persistent/Test/Constraint/AssertCustomerIsRedirectedToCheckout.php b/dev/tests/functional/tests/app/Magento/Persistent/Test/Constraint/AssertCustomerIsRedirectedToCheckout.php new file mode 100644 index 0000000000000000000000000000000000000000..779740551527f48712ea40db23e74e3d5a7e4d60 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Persistent/Test/Constraint/AssertCustomerIsRedirectedToCheckout.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Persistent\Test\Constraint; + +use Magento\Checkout\Test\Page\CheckoutOnepage; +use Magento\Mtf\Constraint\AbstractConstraint; + +/** + * Assert first step on Checkout page is available. + */ +class AssertCustomerIsRedirectedToCheckout extends AbstractConstraint +{ + /** + * Assert first step on Checkout page is available. + * + * @param CheckoutOnepage $checkoutOnepage + * @return void + */ + public function processAssert(CheckoutOnepage $checkoutOnepage) + { + $checkoutOnepage->open(); + \PHPUnit_Framework_Assert::assertTrue( + !$checkoutOnepage->getMessagesBlock()->isVisible() + && $checkoutOnepage->getShippingMethodBlock()->isVisible(), + 'Checkout first step is not available.' + ); + } + + /** + * Returns string representation of successful assertion. + * + * @return string + */ + public function toString() + { + return 'Checkout first step is available.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Persistent/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Persistent/Test/Repository/ConfigData.xml new file mode 100644 index 0000000000000000000000000000000000000000..5494453986157df4f836cd3fca77f96fa421d520 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Persistent/Test/Repository/ConfigData.xml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd"> + <repository class="Magento\Config\Test\Repository\ConfigData"> + <dataset name="clearpersistence_on_signout"> + <field name="persistent/options/enabled" xsi:type="array"> + <item name="scope" xsi:type="string">persistent</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">Yes</item> + <item name="value" xsi:type="number">1</item> + </field> + <field name="persistent/options/logout_clear" xsi:type="array"> + <item name="scope" xsi:type="string">persistent</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">No</item> + <item name="value" xsi:type="number">0</item> + </field> + </dataset> + + <dataset name="clearpersistence_on_signout_rollback"> + <field name="persistent/options/enabled" xsi:type="array"> + <item name="scope" xsi:type="string">persistent</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">No</item> + <item name="value" xsi:type="number">0</item> + </field> + <field name="persistent/options/logout_clear" xsi:type="array"> + <item name="scope" xsi:type="string">persistent</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">Yes</item> + <item name="value" xsi:type="number">1</item> + </field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Persistent/Test/TestCase/CheckoutWithPersistentShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Persistent/Test/TestCase/CheckoutWithPersistentShoppingCartTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2211f9b12e2bf95764382b9d42f9e49578071dbf --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Persistent/Test/TestCase/CheckoutWithPersistentShoppingCartTest.php @@ -0,0 +1,181 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Persistent\Test\TestCase; + +use Magento\Customer\Test\Fixture\Customer; +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Customer\Test\Page\CustomerAccountCreate; +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Checkout\Test\Page\CheckoutCart; +use Magento\Mtf\Client\BrowserInterface; +use Magento\Customer\Test\TestStep\LogoutCustomerOnFrontendStep; +use Magento\Mtf\TestCase\Injectable; +use Magento\Mtf\TestStep\TestStepFactory; + +/** + * Preconditions: + * Apply configs: + * 1. Enable Persistent Shopping Cart. + * 2. Disable Clear Persistence on Sign Out. + * + * Steps: + * 1. Go to frontend. + * 2. Click Register link. + * 3. Fill registry form. + * 4. Click 'Create account' button. + * 5. Add simple product to shopping cart. + * 6. Sign out. + * + * @ZephyrId MAGETWO-45381 + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class CheckoutWithPersistentShoppingCartTest extends Injectable +{ + /** + * Config data. + * + * @string $configData + */ + private $configData; + + /** + * Customer registry page. + * + * @var CustomerAccountCreate + */ + private $customerAccountCreate; + + /** + * Cms page. + * + * @var CmsIndex $cmsIndex. + */ + private $cmsIndex; + + /** + * Frontend product view page. + * + * @var CatalogProductView + */ + private $catalogProductView; + + /** + * Interface Browser. + * + * @var BrowserInterface. + */ + private $browser; + + /** + * Page of checkout page. + * + * @var CheckoutCart + */ + private $checkoutCart; + + /** + * Customer log out step. + * + * @var LogoutCustomerOnFrontendStep + */ + private $logoutCustomerOnFrontendStep; + + /** + * Factory for Test Steps. + * + * @var TestStepFactory + */ + private $stepFactory; + + /** + * Inject data. + * + * @param CustomerAccountCreate $customerAccountCreate + * @param CmsIndex $cmsIndex + * @param LogoutCustomerOnFrontendStep $logoutCustomerOnFrontendStep + * @param CatalogProductView $catalogProductView + * @param BrowserInterface $browser + * @param CheckoutCart $checkoutCart + * @param TestStepFactory $stepFactory + * @return void + */ + public function __inject( + CustomerAccountCreate $customerAccountCreate, + CmsIndex $cmsIndex, + LogoutCustomerOnFrontendStep $logoutCustomerOnFrontendStep, + CatalogProductView $catalogProductView, + BrowserInterface $browser, + CheckoutCart $checkoutCart, + TestStepFactory $stepFactory + ) { + $this->customerAccountCreate = $customerAccountCreate; + $this->cmsIndex = $cmsIndex; + $this->logoutCustomerOnFrontendStep = $logoutCustomerOnFrontendStep; + $this->browser = $browser; + $this->catalogProductView = $catalogProductView; + $this->checkoutCart = $checkoutCart; + $this->stepFactory = $stepFactory; + } + + /** + * Prepare data. + * + * @param CatalogProductSimple $product + * @return array + */ + public function __prepare(CatalogProductSimple $product) + { + $product->persist(); + + return ['product' => $product]; + } + + /** + * Create Customer account on Storefront. + * + * @param string $configData + * @param CatalogProductSimple $product + * @param Customer $customer + * @return void + */ + public function test($configData, CatalogProductSimple $product, Customer $customer) + { + $this->configData = $configData; + $this->stepFactory->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $configData] + )->run(); + + // Steps + $this->cmsIndex->open(); + $this->cmsIndex->getLinksBlock()->openLink('Create an Account'); + $this->customerAccountCreate->getRegisterForm()->registerCustomer($customer); + + // Ensure that shopping cart is empty + $this->checkoutCart->open()->getCartBlock()->clearShoppingCart(); + + $this->browser->open($_ENV['app_frontend_url'] . $product->getUrlKey() . '.html'); + $this->catalogProductView->getViewBlock()->addToCart($product); + $this->catalogProductView->getMessagesBlock()->waitSuccessMessage(); + $this->logoutCustomerOnFrontendStep->run(); + } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->stepFactory->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData, 'rollback' => true] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Persistent/Test/TestCase/CheckoutWithPersistentShoppingCartTest.xml b/dev/tests/functional/tests/app/Magento/Persistent/Test/TestCase/CheckoutWithPersistentShoppingCartTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..db4e85d066610fa472dd41da6503217d235beb03 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Persistent/Test/TestCase/CheckoutWithPersistentShoppingCartTest.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\Persistent\Test\TestCase\CheckoutWithPersistentShoppingCartTest" summary="Checkout with Persistent Shopping Cart" ticketId="MAGETWO-45381"> + <variation name="RedirectCustomerToCheckoutTestVariation1" summary="Checkout with Persistent Shopping Cart"> + <data name="issue" xsi:type="string">MAGETWO-59976: Customer can't open Product on Storefront if Persistent Cart is enabled</data> + <data name="customer/dataset" xsi:type="string">register_customer</data> + <data name="configData" xsi:type="string">clearpersistence_on_signout</data> + <constraint name="Magento\Persistent\Test\Constraint\AssertCustomerIsRedirectedToCheckout" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/View/Addresses.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/View/Addresses.php new file mode 100644 index 0000000000000000000000000000000000000000..063f3f0d2a566bfc2443dc875324daec7f26c8a9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/View/Addresses.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Block\Adminhtml\Order\View; + +use Magento\Mtf\Block\Block; +use Magento\Mtf\Client\Locator; + +/** + * Block for information about addresses on order page. + */ +class Addresses extends Block +{ + /** + * Billing address. + * + * @var string + */ + private $billingAddress = '.order-billing-address address'; + + /** + * New address button selector. + * + * @var string + */ + private $newAddressButton = '.action-show-popup'; + + /** + * Shipping address. + * + * @var string + */ + private $shippingAddress = '.order-shipping-address address'; + + /** + * Get customer's billing address from the data inside block. + * + * @return string + */ + public function getCustomerBillingAddress() + { + return $this->_rootElement->find($this->billingAddress, Locator::SELECTOR_CSS)->getText(); + } + + /** + * Get customer's shipping address from the data inside block. + * + * @return string + */ + public function getCustomerShippingAddress() + { + return $this->_rootElement->find($this->shippingAddress, Locator::SELECTOR_CSS)->getText(); + } + + /** + * Checks if new address button is visible. + * + * @return bool + */ + public function isNewAddressButtonVisible() + { + $button = $this->_rootElement->find($this->newAddressButton); + return $button->isVisible(); + } + + /** + * Clicks new address button. + * + * @return void + */ + public function clickNewAddressButton() + { + $this->_rootElement->find($this->newAddressButton)->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderAddresses.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderAddresses.php new file mode 100644 index 0000000000000000000000000000000000000000..6964153ca3df6584b09e5942ec05434fbc5ae790 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderAddresses.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Constraint; + +use Magento\Sales\Test\Page\Adminhtml\SalesOrderView; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Customer\Test\Fixture\Address; + +/** + * Assert that Order Billing and Shipping addresses are correct on order page in backend. + */ +class AssertOrderAddresses extends AbstractConstraint +{ + /** + * Assert that Order Billing and Shipping addresses are correct on order page in backend. + * + * @param SalesOrderView $salesOrderView + * @param string $orderId + * @param Address $shippingAddress + * @param Address $billingAddress + * @return void + */ + public function processAssert( + SalesOrderView $salesOrderView, + $orderId, + Address $shippingAddress, + Address $billingAddress + ) { + + $selectedShippingAddress = $this->objectManager->create( + \Magento\Customer\Test\Block\Address\Renderer::class, + ['address' => $shippingAddress, 'type' => 'html'] + )->render(); + + $selectedBillingAddress = $this->objectManager->create( + \Magento\Customer\Test\Block\Address\Renderer::class, + ['address' => $billingAddress, 'type' => 'html'] + )->render(); + + $salesOrderView->open(['order_id' => $orderId]); + $orderBillingAddress = $salesOrderView->getAddressesBlock()->getCustomerBillingAddress(); + $orderShippingAddress = $salesOrderView->getAddressesBlock()->getCustomerShippingAddress(); + + \PHPUnit_Framework_Assert::assertTrue( + $selectedBillingAddress == $orderBillingAddress && $selectedShippingAddress == $orderShippingAddress, + 'Billing and shipping addresses from the address book and from the order page are not the same.' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Billing and shipping addresses from the address book and from the order page are the same.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/SalesOrderView.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/SalesOrderView.xml index 674b42732d2cd955db0e05b03ef79a8021492642..39c228e63f2c6ddbf53859694cc15e03ef03b05b 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/SalesOrderView.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/SalesOrderView.xml @@ -17,5 +17,6 @@ <block name="informationBlock" class="Magento\Sales\Test\Block\Adminhtml\Order\View\Info" locator=".order-account-information" strategy="css selector" /> <block name="orderInfoBlock" class="Magento\Sales\Test\Block\Adminhtml\Order\View\Tab\Info" locator="[data-ui-id='sales-order-tabs-tab-content-order-info']" strategy="css selector" /> <block name="orderInvoiceGrid" class="Magento\Sales\Test\Block\Adminhtml\Invoice\Grid" locator="//div[contains(@data-bind, 'sales_order_view_invoice_grid.sales_order_view_invoice_grid')]" strategy="xpath" /> + <block name="addressesBlock" class="Magento\Sales\Test\Block\Adminhtml\Order\View\Addresses" locator=".admin__page-section.order-addresses" strategy="css selector" /> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php index 284a09f42332fa456107017db9fb9bb5c78b3e65..218d10ad4bb1c6c6da47e04b7ac3da5963564c4a 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Scenario; * 12. Perform all assertions. * * @group Order_Management - * @ZephyrId MAGETWO-28696 + * @ZephyrId MAGETWO-28696, MAGETWO-17063 */ class CreateOrderBackendTest extends Scenario { diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml index bd592e9d71aaa1e9d74279af53c80ac3b319e376..2fb8f91d6d99794a426a91663f7a8ccef531a916 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.xml @@ -7,16 +7,16 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\CreateOrderBackendTest" summary="Create Order from Admin within Offline Payment Methods" ticketId="MAGETWO-28696"> - <variation name="CreateOrderBackendTestVariation1"> + <variation name="CreateOrderBackendTestVariation1" ticketId="MAGETWO-17063"> <data name="description" xsi:type="string">Create order with simple product for registered US customer using Fixed shipping method and Cash on Delivery payment method</data> - <data name="products/0" xsi:type="string">catalogProductSimple::default</data> + <data name="products/0" xsi:type="string">catalogProductSimple::with_one_custom_option</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="billingAddress/dataset" xsi:type="string">US_address_1_without_email</data> <data name="saveAddress" xsi:type="string">No</data> <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data> <data name="shipping/shipping_method" xsi:type="string">Fixed</data> <data name="prices" xsi:type="array"> - <item name="grandTotal" xsi:type="string">565.00</item> + <item name="grandTotal" xsi:type="string">425.00</item> </data> <data name="payment/method" xsi:type="string">cashondelivery</data> <data name="status" xsi:type="string">Pending</data> diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml index d0ad41011004a3fef531865ca1c6265f9406684e..141638e6b31b948665a46a08d8b5ea12cc0dfc74 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml @@ -399,5 +399,30 @@ <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleSuccessSaveMessage" /> <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleForm" /> </variation> + <variation name="CreateSalesRuleEntityTestVariation16" summary="Variation to check free shipping"> + <data name="salesRule/data/name" xsi:type="string">Cart Price Rule1 %isolation%</data> + <data name="salesRule/data/description" xsi:type="string">Cart Price Rule Description %isolation%</data> + <data name="salesRule/data/is_active" xsi:type="string">Yes</data> + <data name="salesRule/data/website_ids/0" xsi:type="string">Main Website</data> + <data name="salesRule/data/customer_group_ids/0" xsi:type="string">NOT LOGGED IN</data> + <data name="salesRule/data/coupon_type" xsi:type="string">No Coupon</data> + <data name="salesRule/data/simple_action" xsi:type="string">Percent of product price discount</data> + <data name="salesRule/data/conditions_serialized" xsi:type="string">[Subtotal|greater than|0]</data> + <data name="salesRule/data/discount_amount" xsi:type="string">50</data> + <data name="salesRule/data/apply_to_shipping" xsi:type="string">No</data> + <data name="salesRule/data/simple_free_shipping" xsi:type="string">For matching items only</data> + <data name="salesRule/data/store_labels/0" xsi:type="string">Sales Cart Rule labels</data> + <data name="cartPrice/sub_total" xsi:type="string">100.00</data> + <data name="cartPrice/grand_total" xsi:type="string">50.00</data> + <data name="cartPrice/discount" xsi:type="string">50.00</data> + <data name="address/data/country_id" xsi:type="string">United States</data> + <data name="address/data/region_id" xsi:type="string">California</data> + <data name="address/data/postcode" xsi:type="string">95814</data> + <data name="productForSalesRule1/dataset" xsi:type="string">simple_for_salesrule_1</data> + <data name="productQuantity/productForSalesRule1" xsi:type="string">1</data> + <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleSuccessSaveMessage" /> + <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleConditionIsApplied" /> + <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleFreeShippingIsApplied" /> + </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Topmenu.php b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Topmenu.php index cc2826c6d840e9d76304ff78015c5e1d49121145..8d11cfea1295ff3f1a874cd02fa606dbf44ec4db 100644 --- a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Topmenu.php +++ b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Topmenu.php @@ -63,6 +63,26 @@ class Topmenu extends Block $category[0]->click(); } + /** + * Hover on category from top menu by name. + * + * @param string $categoryName + * @return void + */ + public function hoverCategoryByName($categoryName) + { + $rootElement = $this->_rootElement; + $category = $this->waitLoadTopMenu($categoryName); + if ($category[1]) { + $rootElement->waitUntil( + function () use ($category) { + return $category[0]->isVisible() ? true : null; + } + ); + } + $category[0]->hover(); + } + /** * Check is visible category in top menu by name * diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php index e7033698568343a7c71e99e5150d77225f90f702..a57616d4d4d0be023c34d3631b6b7ea29a855a03 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php @@ -41,6 +41,13 @@ class Modal extends Block */ protected $inputFieldSelector = '[data-role="promptField"]'; + /** + * Locator value for accept warning button. + * + * @var string + */ + protected $acceptWarningSelector = '.action-primary'; + /** * Modal overlay selector. * @@ -48,6 +55,13 @@ class Modal extends Block */ protected $modalOverlay = '.modals-overlay'; + /** + * Selector for spinner element. + * + * @var string + */ + protected $loadingMask = '[data-role="loader"]'; + /** * Press OK on an alert, confirm, prompt a dialog. * @@ -59,6 +73,18 @@ class Modal extends Block $this->_rootElement->find($this->acceptButtonSelector)->click(); } + /** + * Press OK on a warning popup. + * + * @return void + */ + public function acceptWarning() + { + $this->waitModalAnimationFinished(); + $this->_rootElement->find($this->acceptWarningSelector)->click(); + $this->waitForElementNotVisible($this->loadingMask); + } + /** * Press Cancel on an alert, confirm, prompt a dialog. * diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertCategoryUrlWithCustomStoreView.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertCategoryUrlWithCustomStoreView.php new file mode 100644 index 0000000000000000000000000000000000000000..a33ace2ff35ba4c8e91d028b7940244885b67f65 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertCategoryUrlWithCustomStoreView.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\UrlRewrite\Test\Constraint; + +use Magento\Catalog\Test\Fixture\Category; +use Magento\Cms\Test\Page\CmsIndex; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Mtf\Client\BrowserInterface; +use Magento\Store\Test\Fixture\Store; + +/** + * Assert that Category URL key has been changed after changing Category parent. + */ +class AssertCategoryUrlWithCustomStoreView extends AbstractConstraint +{ + /** + * Assert that displayed category data on category page equals to passed from fixture. + * + * @param Store $storeView + * @param Category $childCategory + * @param Category $parentCategory + * @param Category $categoryUpdates + * @param CmsIndex $cmsIndex + * @param BrowserInterface $browser + */ + public function processAssert( + Store $storeView, + Category $childCategory, + Category $parentCategory, + Category $categoryUpdates, + CmsIndex $cmsIndex, + BrowserInterface $browser + ) { + $cmsIndex->open(); + $cmsIndex->getStoreSwitcherBlock()->selectStoreView($storeView->getName()); + $cmsIndex->getTopmenu()->hoverCategoryByName($parentCategory->getName()); + $cmsIndex->getTopmenu()->selectCategoryByName( + $childCategory->getName() + ); + $actualUrl = strtolower($parentCategory->getUrlKey() . '/' . $categoryUpdates->getUrlKey()); + $result = (bool)strpos($browser->getUrl(), $actualUrl); + + \PHPUnit_Framework_Assert::assertTrue( + $result, + "Category URL is not correct." + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Category URL is correct.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryInGrid.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryInGrid.php index b94e716ceac64e0038d50dcd22499fa51c779eeb..3630bd697b8593a966f4ed93b67794b80b6da185 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryInGrid.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryInGrid.php @@ -7,8 +7,8 @@ namespace Magento\UrlRewrite\Test\Constraint; use Magento\Catalog\Test\Fixture\Category; -use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex; use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\UrlRewrite\Test\Page\Adminhtml\UrlRewriteIndex; /** * Class AssertUrlRewriteCategoryInGrid @@ -17,16 +17,20 @@ use Magento\Mtf\Constraint\AbstractConstraint; class AssertUrlRewriteCategoryInGrid extends AbstractConstraint { /** - * Assert that url rewrite category in grid + * Assert that url rewrite category in grid. * * @param Category $category * @param UrlRewriteIndex $urlRewriteIndex + * @param string $filterByPath * @return void */ - public function processAssert(Category $category, UrlRewriteIndex $urlRewriteIndex) - { + public function processAssert( + Category $category, + UrlRewriteIndex $urlRewriteIndex, + $filterByPath = 'target_path' + ) { $urlRewriteIndex->open(); - $filter = ['target_path' => strtolower($category->getUrlKey())]; + $filter = [$filterByPath => strtolower($category->getUrlKey())]; \PHPUnit_Framework_Assert::assertTrue( $urlRewriteIndex->getUrlRedirectGrid()->isRowVisible($filter, true, false), 'URL Rewrite with request path "' . $category->getUrlKey() . '" is absent in grid.' @@ -34,7 +38,7 @@ class AssertUrlRewriteCategoryInGrid extends AbstractConstraint } /** - * URL rewrite category present in grid + * URL rewrite category present in grid. * * @return string */ diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php new file mode 100644 index 0000000000000000000000000000000000000000..659b29590622919363f3d98743208a4132ade678 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\UrlRewrite\Test\TestCase; + +use Magento\Catalog\Test\Page\Adminhtml\CatalogCategoryIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogCategoryEdit; +use Magento\Catalog\Test\Fixture\Category; +use Magento\Mtf\TestCase\Injectable; +use Magento\Store\Test\Fixture\Store; + +/** + * Test for Url rewrites in catalog categories after changing url key for store view and moving category. + * + * Preconditions: + * 1. Create additional Store View in Main Website Store. + * 2. Create sub-categories "first-test" and "second-test" in Default Category. + * 3. Add one or more any products to created sub-categories. + * 4. Reindex and clean caches. + * + * Steps: + * 1. Log in to backend. + * 2. Navigate to Products > Categories. + * 3. On the categories editing page change store view to created additional view. + * 4. Change URL key for category "first-test" from default to "first-test-2". Save. + * 5. Change store view to "All store views". + * 6. Move category "first-test" inside "second-test". + * 7. Perform all assertions. + * + * @ZephyrId MAGETWO-45385 + */ +class CategoryUrlRewriteTest extends Injectable +{ + /** + * CatalogCategoryIndex page. + * + * @var CatalogCategoryIndex + */ + private $catalogCategoryIndex; + + /** + * CatalogCategoryEdit page. + * + * @var CatalogCategoryEdit + */ + private $catalogCategoryEdit; + + /** + * Inject page end prepare default category. + * + * @param CatalogCategoryIndex $catalogCategoryIndex + * @param CatalogCategoryEdit $catalogCategoryEdit + * @return array + */ + public function __inject( + CatalogCategoryIndex $catalogCategoryIndex, + CatalogCategoryEdit $catalogCategoryEdit + ) { + $this->catalogCategoryIndex = $catalogCategoryIndex; + $this->catalogCategoryEdit = $catalogCategoryEdit; + } + + /** + * Runs test. + * + * @param Store $storeView + * @param Category $childCategory + * @param Category $parentCategory + * @param Category $categoryUpdates + * @return array + */ + public function test(Store $storeView, Category $childCategory, Category $parentCategory, Category $categoryUpdates) + { + // Preconditions: + $storeView->persist(); + $parentCategory->persist(); + $childCategory->persist(); + + // Steps: + $this->catalogCategoryIndex->open(); + $this->catalogCategoryIndex->getTreeCategories()->selectCategory($childCategory); + $this->catalogCategoryEdit->getFormPageActions()->selectStoreView($storeView->getName()); + $this->catalogCategoryEdit->getEditForm()->fill($categoryUpdates); + $this->catalogCategoryEdit->getFormPageActions()->save(); + $this->catalogCategoryIndex->getTreeCategories()->assignCategory( + $parentCategory->getName(), + $childCategory->getName() + ); + $this->catalogCategoryEdit->getModalBlock()->acceptWarning(); + + return [ + 'storeView' => $storeView, + 'childCategory' => $childCategory, + 'parentCategory' => $parentCategory + ]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..d39650944a203af72f92a30ff7918f4182b6cb37 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\UrlRewrite\Test\TestCase\CategoryUrlRewriteTest" summary="Check url rewrites in catalog categories after changing url key for store view and moving category." ticketId="MAGETWO-45385"> + <variation name="CategoryUrlRewriteTestVariation1"> + <data name="storeView/dataset" xsi:type="string">custom</data> + <data name="childCategory/dataset" xsi:type="string">default</data> + <data name="childCategory/data/category_products/dataset" xsi:type="string">catalogProductSimple::default</data> + <data name="parentCategory/dataset" xsi:type="string">default</data> + <data name="parentCategory/data/category_products/dataset" xsi:type="string">catalogProductSimple::default</data> + <data name="categoryUpdates/data/use_default_url_key" xsi:type="string">No</data> + <data name="categoryUpdates/data/url_key" xsi:type="string">UrlKey%isolation%</data> + <constraint name="Magento\UrlRewrite\Test\Constraint\AssertCategoryUrlWithCustomStoreView" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserPasswordChangedSuccessfully.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserPasswordChangedSuccessfully.php new file mode 100644 index 0000000000000000000000000000000000000000..fec96f699ea65babe062ffc25d4563304ab187ac --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserPasswordChangedSuccessfully.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\User\Test\Constraint; + +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\User\Test\Page\Adminhtml\UserIndex; + +/** + * Assert to check change password error appearance. + */ +class AssertUserPasswordChangedSuccessfully extends AbstractConstraint +{ + /** + * Fail message when provided password have been in use. + */ + const FAIL_MESSAGE = 'Sorry, but this password has already been used. Please create another.'; + + /** + * Asserts that failed message equals to expected message. + * + * @param UserIndex $userIndex + * @return void + */ + public function processAssert(UserIndex $userIndex) + { + $errorMessage = $userIndex->getMessagesBlock()->getErrorMessage(); + \PHPUnit_Framework_Assert::assertEquals( + self::FAIL_MESSAGE, + $errorMessage, + 'Password update failed with error: "' . self::FAIL_MESSAGE . '"' + ); + } + + /** + * Returns success message if there is fail message. + * + * @return string + */ + public function toString() + { + return 'Password validation completed successfully.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdatePasswordUserEntityPciRequirementsTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdatePasswordUserEntityPciRequirementsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..df95519e5ffe44c5dcc8b7d27adf2e3519eb4958 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdatePasswordUserEntityPciRequirementsTest.php @@ -0,0 +1,131 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\User\Test\TestCase; + +use Magento\Backend\Test\Page\AdminAuthLogin; +use Magento\Backend\Test\Page\Adminhtml\Dashboard; +use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Mtf\TestCase\Injectable; +use Magento\User\Test\Fixture\User; +use Magento\User\Test\Page\Adminhtml\UserEdit; + +/** + * Preconditions: + * 1. Admin user with assigned full access role is created. + * + * Steps: + * 1. Login to Magento admin module with valid credentials. + * 2. Navigate to System > All Users + * 3. Click on admin record to open > Account Information page. + * 4. Update password providing a new password. + * 5. Save user + * 6. Repeat Steps 4-5 4 times with different passwords. + * 7. Update password providing an original password for the user. + * + * @ZephyrId MAGETWO-48104 + */ +class UpdatePasswordUserEntityPciRequirementsTest extends Injectable +{ + /** + * User edit page on backend. + * + * @var UserEdit + */ + protected $userEdit; + + /** + * Dashboard page on backend. + * + * @var Dashboard + */ + protected $dashboard; + + /** + * Authorization page on backend. + * + * @var AdminAuthLogin + */ + protected $adminAuth; + + /** + * Fixture factory. + * + * @var FixtureFactory + */ + protected $fixtureFactory; + + /** + * Setup necessary data for test. + * + * @param UserEdit $userEdit + * @param Dashboard $dashboard + * @param AdminAuthLogin $adminAuth + * @param FixtureFactory $fixtureFactory + * @return void + */ + public function __inject( + UserEdit $userEdit, + Dashboard $dashboard, + AdminAuthLogin $adminAuth, + FixtureFactory $fixtureFactory + ) { + $this->userEdit = $userEdit; + $this->dashboard = $dashboard; + $this->adminAuth = $adminAuth; + $this->fixtureFactory = $fixtureFactory; + } + + /** + * Run Test. + * + * @param User $user + * @param array $passwords + * @return void + */ + public function test( + User $user, + array $passwords + ) { + // Preconditions + $user->persist(); + $initialPassword = $user->getPassword(); + $currentPassword = $user->getPassword(); + $passwords[] = $initialPassword; + + // Steps + $this->adminAuth->open(); + $this->adminAuth->getLoginBlock()->fill($user); + $this->adminAuth->getLoginBlock()->submit(); + + foreach ($passwords as $password) { + $data = [ + 'password' => $password, + 'password_confirmation' => $password, + 'current_password' => $currentPassword, + + ]; + $updatedUser = $this->fixtureFactory->createByCode('user', ['data' => $data]); + + $this->userEdit->open(['user_id' => $user->getUserId()]); + $this->userEdit->getUserForm()->fill($updatedUser); + $this->userEdit->getPageActions()->save(); + $currentPassword = $password; + } + } + + /** + * Logout Admin User from account. + * + * @return void + */ + public function tearDown() + { + if ($this->dashboard->getAdminPanelHeader()->isVisible()) { + $this->dashboard->getAdminPanelHeader()->logOut(); + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdatePasswordUserEntityPciRequirementsTest.xml b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdatePasswordUserEntityPciRequirementsTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..c2a24b0f102e22804b4e0e1b9c466176f8e32efa --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdatePasswordUserEntityPciRequirementsTest.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\User\Test\TestCase\UpdatePasswordUserEntityPciRequirementsTest" summary="PCI password requirements for admin users while changing a passworrd" ticketId="MAGETWO-48104"> + <variation name="UpdatePasswordUserEntityPciRequirementsTestVariation1"> + <data name="user/dataset" xsi:type="string">custom_admin_with_default_role</data> + <data name="passwords/0" xsi:type="string">123123^q0</data> + <data name="passwords/1" xsi:type="string">123123^q1</data> + <data name="passwords/2" xsi:type="string">123123^q2</data> + <data name="passwords/3" xsi:type="string">123123^q3</data> + <constraint name="Magento\User\Test\Constraint\AssertUserPasswordChangedSuccessfully" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricingTest.php b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricingTest.php index b8c72e9a3ebb19cdabc75933d56c0566e3f71bb8..4226ec190020cb4670c693ca681193b09ab30884 100644 --- a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricingTest.php +++ b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricingTest.php @@ -59,7 +59,9 @@ class AdvancedPricingTest extends \PHPUnit_Framework_TestCase $csvfile = uniqid('importexport_') . '.csv'; - $this->exportData($csvfile); + $exportContent = $this->exportData($csvfile); + $this->assertDiscountTypes($exportContent); + $this->importData($csvfile); while ($index > 0) { @@ -72,6 +74,24 @@ class AdvancedPricingTest extends \PHPUnit_Framework_TestCase } } + /** + * Assert for correct tier prices discount types. + * + * @param string $exportContent + * @return void + */ + private function assertDiscountTypes($exportContent) + { + $this->assertContains( + '2.0000,8.0000,Fixed', + $exportContent + ); + $this->assertContains( + '10.0000,50.00,Discount', + $exportContent + ); + } + /** * @magentoAppArea adminhtml * @magentoDbIsolation enabled diff --git a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricingTest.php b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricingTest.php index e5fd4cc0d9630080eb7c06f2558b02be889f8a57..bdbd06e2d626630c993ac72052d1119b5e323fbf 100644 --- a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricingTest.php +++ b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricingTest.php @@ -48,34 +48,52 @@ class AdvancedPricingTest extends \PHPUnit_Framework_TestCase [ 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, 'value' => '300.0000', - 'qty' => '10.0000' + 'qty' => '10.0000', + 'percentage_value' => null ], [ 'customer_group_id' => '1', 'value' => '11.0000', - 'qty' => '11.0000' + 'qty' => '11.0000', + 'percentage_value' => null ], [ 'customer_group_id' => '3', 'value' => '14.0000', - 'qty' => '14.0000' + 'qty' => '14.0000', + 'percentage_value' => null + ], + [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'value' => '160.5000', + 'qty' => '20.0000', + 'percentage_value' => '50.0000' ] ], 'AdvancedPricingSimple 2' => [ [ 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, 'value' => '1000000.0000', - 'qty' => '100.0000' + 'qty' => '100.0000', + 'percentage_value' => null ], [ 'customer_group_id' => '0', 'value' => '12.0000', - 'qty' => '12.0000' + 'qty' => '12.0000', + 'percentage_value' => null ], [ 'customer_group_id' => '2', 'value' => '13.0000', - 'qty' => '13.0000' + 'qty' => '13.0000', + 'percentage_value' => null + ], + [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'value' => '327.0000', + 'qty' => '200.0000', + 'percentage_value' => '50.0000' ] ] ]; @@ -121,18 +139,40 @@ class AdvancedPricingTest extends \PHPUnit_Framework_TestCase foreach ($productIdList as $sku => $productId) { $product->load($productId); $tierPriceCollection = $product->getTierPrices(); - $this->assertEquals(3, count($tierPriceCollection)); + $this->assertEquals(4, count($tierPriceCollection)); + $index = 0; /** @var \Magento\Catalog\Model\Product\TierPrice $tierPrice */ foreach ($tierPriceCollection as $tierPrice) { - $this->assertEquals(0, $tierPrice->getExtensionAttributes()->getPercentageValue()); + $this->checkPercentageDiscount($tierPrice, $sku, $index); $this->assertEquals(0, $tierPrice->getExtensionAttributes()->getWebsiteId()); $tierPriceData = $tierPrice->getData(); unset($tierPriceData['extension_attributes']); $this->assertContains($tierPriceData, $this->expectedTierPrice[$sku]); + $index ++; } } } + /** + * Check percentage discount type. + * + * @param \Magento\Catalog\Model\Product\TierPrice $tierPrice + * @param string $sku + * @param int $index + * @return void + */ + private function checkPercentageDiscount( + \Magento\Catalog\Model\Product\TierPrice $tierPrice, + $sku, + $index + ) { + $this->assertEquals( + $this->expectedTierPrice[$sku][$index]['percentage_value'], + $tierPrice->getExtensionAttributes()->getPercentageValue() + ); + $tierPrice->setData('percentage_value', $tierPrice->getExtensionAttributes()->getPercentageValue()); + } + /** * @magentoAppArea adminhtml * @magentoDbIsolation enabled @@ -241,14 +281,16 @@ class AdvancedPricingTest extends \PHPUnit_Framework_TestCase foreach ($productIdList as $sku => $productId) { $product->load($productId); $tierPriceCollection = $product->getTierPrices(); - $this->assertEquals(3, count($tierPriceCollection)); + $this->assertEquals(4, count($tierPriceCollection)); + $index = 0; /** @var \Magento\Catalog\Model\Product\TierPrice $tierPrice */ foreach ($tierPriceCollection as $tierPrice) { - $this->assertEquals(0, $tierPrice->getExtensionAttributes()->getPercentageValue()); + $this->checkPercentageDiscount($tierPrice, $sku, $index); $this->assertEquals(0, $tierPrice->getExtensionAttributes()->getWebsiteId()); $tierPriceData = $tierPrice->getData(); unset($tierPriceData['extension_attributes']); $this->assertContains($tierPriceData, $this->expectedTierPrice[$sku]); + $index ++; } } } diff --git a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/_files/import_advanced_pricing.csv b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/_files/import_advanced_pricing.csv index 37c0dff622f56e9bcbba0bfab9136b5aab0de4cd..0c25cb37bf220f3f453d67065bd9b46fcc7a768b 100644 --- a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/_files/import_advanced_pricing.csv +++ b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/_files/import_advanced_pricing.csv @@ -1,7 +1,9 @@ -sku,tier_price_website,tier_price_customer_group,tier_price_qty,tier_price -"AdvancedPricingSimple 1","All Websites [USD]","ALL GROUPS",10.0000,300.0000 -"AdvancedPricingSimple 2","All Websites [USD]","ALL GROUPS",100.0000,1000000.0000 -"AdvancedPricingSimple 1","All Websites [USD]",General,11.0000,11.0000 -"AdvancedPricingSimple 2","All Websites [USD]","NOT LOGGED IN",12.0000,12.0000 -"AdvancedPricingSimple 1","All Websites [USD]",Retailer,14.0000,14.0000 -"AdvancedPricingSimple 2","All Websites [USD]",Wholesale,13.0000,13.0000 +sku,tier_price_website,tier_price_customer_group,tier_price_qty,tier_price,tier_price_value_type +"AdvancedPricingSimple 1","All Websites [USD]","ALL GROUPS",10.0000,300.0000,Fixed +"AdvancedPricingSimple 2","All Websites [USD]","ALL GROUPS",100.0000,1000000.0000,Fixed +"AdvancedPricingSimple 1","All Websites [USD]",General,11.0000,11.0000,Fixed +"AdvancedPricingSimple 2","All Websites [USD]","NOT LOGGED IN",12.0000,12.0000,Fixed +"AdvancedPricingSimple 1","All Websites [USD]",Retailer,14.0000,14.0000,Fixed +"AdvancedPricingSimple 2","All Websites [USD]",Wholesale,13.0000,13.0000,Fixed +"AdvancedPricingSimple 1","All Websites [USD]","ALL GROUPS",20.0000,50,Discount +"AdvancedPricingSimple 2","All Websites [USD]","ALL GROUPS",200.0000,50,Discount diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/adminhtml/js/utils/percentage-price-calculator.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/adminhtml/js/utils/percentage-price-calculator.test.js new file mode 100644 index 0000000000000000000000000000000000000000..8785e41c2920c9e5f132ab3fda3270611f10838b --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Catalog/adminhtml/js/utils/percentage-price-calculator.test.js @@ -0,0 +1,67 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define(['Magento_Catalog/js/utils/percentage-price-calculator'], function (percentagePriceCalculator) { + 'use strict'; + + var basePrice = 100, + negativeBasePrice = -10, + decimalBasePrice = '100,1', + zeroBasePrice = 0; + + describe('Check valid calculation', function () { + it('5%', function () { + expect(percentagePriceCalculator(basePrice, '5%')).toBe('95.00'); + }); + it('0%', function () { + expect(percentagePriceCalculator(basePrice, '0%')).toBe('100.00'); + }); + it('100%', function () { + expect(percentagePriceCalculator(basePrice, '100%')).toBe('0.00'); + }); + it('110%', function () { + expect(percentagePriceCalculator(basePrice, '110%')).toBe('0.00'); + }); + it('5.5%', function () { + expect(percentagePriceCalculator(basePrice, '5.5%')).toBe('94.50'); + }); + it('.5%', function () { + expect(percentagePriceCalculator(basePrice, '.5%')).toBe('99.50'); + }); + it('-7%', function () { + expect(percentagePriceCalculator(basePrice, '-7%')).toBe('107.00'); + }); + }); + + describe('Check invalid input calculation', function () { + it('invalid with %', function () { + expect(percentagePriceCalculator(basePrice, '7p%')).toBe(''); + expect(percentagePriceCalculator(basePrice, '-%')).toBe(''); + }); + it('without %', function () { + expect(percentagePriceCalculator(basePrice, '7p')).toBe('7p'); + expect(percentagePriceCalculator(basePrice, '0')).toBe('0'); + expect(percentagePriceCalculator(basePrice, 'qwe')).toBe('qwe'); + }); + it('just %', function () { + expect(percentagePriceCalculator(basePrice, '%')).toBe(''); + }); + it('empty', function () { + expect(percentagePriceCalculator(basePrice, '')).toBe(''); + }); + }); + + describe('Other', function () { + it('negative base price', function () { + expect(percentagePriceCalculator(negativeBasePrice, '10%')).toBe('-9.00'); + }); + it('decimal base price', function () { + expect(percentagePriceCalculator(decimalBasePrice, '10%')).toBe('90.09'); + }); + it('zero base price', function () { + expect(percentagePriceCalculator(zeroBasePrice, '10%')).toBe('0.00'); + }); + }); +});