diff --git a/app/bootstrap.php b/app/bootstrap.php index ec60a1708dacc3d2238960e5b1c9e7c0da05cc92..c8e676cb69cffd5cf32de8f12f9f83987cc6619a 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -11,14 +11,14 @@ error_reporting(E_ALL); #ini_set('display_errors', 1); /* PHP version validation */ -if (!defined('PHP_VERSION_ID') || !(PHP_VERSION_ID >= 50600 && PHP_VERSION_ID < 50700 || PHP_VERSION_ID === 70002 || PHP_VERSION_ID === 70004 || PHP_VERSION_ID >= 70006)) { +if (!defined('PHP_VERSION_ID') || !(PHP_VERSION_ID >= 50605 && PHP_VERSION_ID < 50700 || PHP_VERSION_ID === 70002 || PHP_VERSION_ID === 70004 || PHP_VERSION_ID >= 70006)) { if (PHP_SAPI == 'cli') { - echo 'Magento supports PHP 5.6, 7.0.2, 7.0.4, and 7.0.6 or later. ' . + echo 'Magento supports PHP 5.6.5, 7.0.2, 7.0.4, and 7.0.6 or later. ' . 'Please read http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html'; } else { echo <<<HTML <div style="font:12px/1.35em arial, helvetica, sans-serif;"> - <p>Magento supports PHP 5.6, 7.0.2, 7.0.4, and 7.0.6 or later. Please read + <p>Magento supports PHP 5.6.5, 7.0.2, 7.0.4, and 7.0.6 or later. Please read <a target="_blank" href="http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html"> Magento System Requirements</a>. </div> @@ -35,6 +35,17 @@ $umaskFile = BP . '/magento_umask'; $mask = file_exists($umaskFile) ? octdec(file_get_contents($umaskFile)) : 002; umask($mask); +if (empty($_SERVER['ENABLE_IIS_REWRITES']) || ($_SERVER['ENABLE_IIS_REWRITES'] != 1)) { + /* + * Unset headers used by IIS URL rewrites. + */ + unset($_SERVER['HTTP_X_REWRITE_URL']); + unset($_SERVER['HTTP_X_ORIGINAL_URL']); + unset($_SERVER['IIS_WasUrlRewritten']); + unset($_SERVER['UNENCODED_URL']); + unset($_SERVER['ORIG_PATH_INFO']); +} + if (!empty($_SERVER['MAGE_PROFILER']) && isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'text/html') !== false diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json index 527268df36b41efe5078528138342a03fa33745d..09d8ce41bbb03607a2f8cd16831454c8565a5204 100644 --- a/app/code/Magento/AdminNotification/composer.json +++ b/app/code/Magento/AdminNotification/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-admin-notification", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-media-storage": "100.2.*", diff --git a/app/code/Magento/AdvancedPricingImportExport/composer.json b/app/code/Magento/AdvancedPricingImportExport/composer.json index 65ea7524dffff5bb778aaf5ec7658302072cfaf9..2fc465fa3c3dfd7a51abdd713f0c5c6dfd6843c6 100644 --- a/app/code/Magento/AdvancedPricingImportExport/composer.json +++ b/app/code/Magento/AdvancedPricingImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-advanced-pricing-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-catalog-inventory": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json index 0ca367d4854dfe5c35811d15aee4d718c0a4edb7..af88e8376dc756cb9e1f6180848df41e6fd8b5f3 100644 --- a/app/code/Magento/Authorization/composer.json +++ b/app/code/Magento/Authorization/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-authorization", "description": "Authorization module provides access to Magento ACL functionality.", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-backend": "100.2.*", "magento/framework": "100.2.*" }, diff --git a/app/code/Magento/Authorizenet/composer.json b/app/code/Magento/Authorizenet/composer.json index 0c9e9641b6076850310edd75a2a4ea5ed3ccd094..b93cb6688f56d826a8d981518612897aae6f1ac8 100644 --- a/app/code/Magento/Authorizenet/composer.json +++ b/app/code/Magento/Authorizenet/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-authorizenet", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-sales": "100.2.*", "magento/module-store": "100.2.*", "magento/module-quote": "100.2.*", diff --git a/app/code/Magento/Authorizenet/i18n/en_US.csv b/app/code/Magento/Authorizenet/i18n/en_US.csv index 7183c706dc0a2ed264e7e73d0e11743cbf450b40..45025304c4e4423d77f60e1e26af4f2da6a8a569 100644 --- a/app/code/Magento/Authorizenet/i18n/en_US.csv +++ b/app/code/Magento/Authorizenet/i18n/en_US.csv @@ -64,3 +64,4 @@ Debug,Debug "Minimum Order Total","Minimum Order Total" "Maximum Order Total","Maximum Order Total" "Sort Order","Sort Order" +"Sorry, but something went wrong. Please contact the seller.","Sorry, but something went wrong. Please contact the seller." diff --git a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js index cd05960c17633844fb1c57e92794066186a45965..86ec8e0c3922109170e19f4191fdbf7e27dc43d5 100644 --- a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js +++ b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js @@ -5,15 +5,16 @@ define( [ 'jquery', - 'Magento_Payment/js/view/payment/iframe' + 'Magento_Payment/js/view/payment/iframe', + 'mage/translate' ], - function ($, Component) { + function ($, Component, $t) { 'use strict'; return Component.extend({ defaults: { template: 'Magento_Authorizenet/payment/authorizenet-directpost', - timeoutMessage: 'Sorry, but something went wrong. Please contact the seller.' + timeoutMessage: $t('Sorry, but something went wrong. Please contact the seller.') }, placeOrderHandler: null, validateHandler: null, diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json index 7d428636a1f45e23d81879c99baaeef6744518fc..5cfe6955b46bb99f6dd8c76cd58e3ba9bb6f28ad 100644 --- a/app/code/Magento/Backend/composer.json +++ b/app/code/Magento/Backend/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-backend", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-directory": "100.2.*", "magento/module-developer": "100.2.*", diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json index 21ed6f1780a41348c5bb26556c14fcaa02c08770..ee05d6726db4c3bea7460893242d546a511fe0cc 100644 --- a/app/code/Magento/Backup/composer.json +++ b/app/code/Magento/Backup/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-backup", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-cron": "100.2.*", diff --git a/app/code/Magento/Braintree/composer.json b/app/code/Magento/Braintree/composer.json index 3b77e208837a4a4341baabbae615b7e35b266500..91cacf6add2b891dc4ad759cb6b1e9a6990cb397 100644 --- a/app/code/Magento/Braintree/composer.json +++ b/app/code/Magento/Braintree/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-braintree", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*", "magento/magento-composer-installer": "*", "magento/module-config": "100.2.*", diff --git a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js index 184260c39e954d1c5a1fd6d45b34f09fcab9daa7..075a1fdaf1fc118f42832fa438762715420a585a 100644 --- a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js +++ b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js @@ -98,7 +98,6 @@ define([ quote.totals.subscribe(function () { if (self.grandTotalAmount !== quote.totals()['base_grand_total']) { self.grandTotalAmount = quote.totals()['base_grand_total']; - self.reInitPayPal(); } }); diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index 50a3caaf68b3bd39ce1458e4883b4c1dd35c0525..538c80d9b1cf27af4ba14c911b0d0a6913c403c7 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -268,15 +268,12 @@ class BundlePanel extends AbstractModifier 'arguments' => [ 'data' => [ 'config' => [ - 'componentType' => 'dynamicRows', + 'componentType' => Container::NAME, + 'component' => 'Magento_Bundle/js/components/bundle-dynamic-rows', 'template' => 'ui/dynamic-rows/templates/collapsible', - 'label' => '', 'additionalClasses' => 'admin__field-wide', - 'collapsibleHeader' => true, - 'columnsHeader' => false, - 'deleteProperty' => false, - 'addButton' => false, 'dataScope' => 'data.bundle_options', + 'bundleSelectionsName' => 'product_bundle_container.bundle_selections' ], ], ], @@ -318,14 +315,11 @@ class BundlePanel extends AbstractModifier 'arguments' => [ 'data' => [ 'config' => [ - 'componentType' => DynamicRows::NAME, - 'label' => '', + 'componentType' => Container::NAME, + 'component' => 'Magento_Bundle/js/components/bundle-dynamic-rows-grid', 'sortOrder' => 50, 'additionalClasses' => 'admin__field-wide', - 'component' => 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid', 'template' => 'ui/dynamic-rows/templates/default', - 'columnsHeader' => false, - 'columnsHeaderAfterRender' => true, 'provider' => 'product_form.product_form_data_source', 'dataProvider' => '${ $.dataScope }' . '.bundle_button_proxy', 'identificationDRProperty' => 'product_id', @@ -343,8 +337,7 @@ class BundlePanel extends AbstractModifier 'selection_qty' => '', ], 'links' => ['insertData' => '${ $.provider }:${ $.dataProvider }'], - 'source' => 'product', - 'addButton' => false, + 'source' => 'product' ], ], ], @@ -561,7 +554,7 @@ class BundlePanel extends AbstractModifier 'componentType' => Container::NAME, 'isTemplate' => true, 'component' => 'Magento_Ui/js/dynamic-rows/record', - 'is_collection' => true, + 'is_collection' => true ], ], ], diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json index ab587044476db47c0a824cfdb130988f22591971..24756bdf950a7a42431e31cbc08090ca0141eb27 100644 --- a/app/code/Magento/Bundle/composer.json +++ b/app/code/Magento/Bundle/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-bundle", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-tax": "100.2.*", diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows-grid.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows-grid.js new file mode 100644 index 0000000000000000000000000000000000000000..e9a924e1cffe696688fed502bc715347c8afb8d2 --- /dev/null +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows-grid.js @@ -0,0 +1,59 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'underscore', + 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid' +], function (_, dynamicRowsGrid) { + 'use strict'; + + return dynamicRowsGrid.extend({ + defaults: { + label: '', + columnsHeader: false, + columnsHeaderAfterRender: true, + addButton: false + }, + + /** + * Initialize elements from grid + * + * @param {Array} data + * + * @returns {Object} Chainable. + */ + initElements: function (data) { + var newData = this.getNewData(data), + recordIndex; + + this.parsePagesData(data); + + if (newData.length) { + if (this.insertData().length) { + recordIndex = data.length - newData.length - 1; + + _.each(newData, function (newRecord) { + this.processingAddChild(newRecord, ++recordIndex, newRecord[this.identificationProperty]); + }, this); + } + } + + return this; + }, + + /** + * Mapping value from grid + * + * @param {Array} data + */ + mappingValue: function (data) { + if (_.isEmpty(data)) { + return; + } + + this._super(); + } + }); +}); diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows.js new file mode 100644 index 0000000000000000000000000000000000000000..b36d8003a399fb4af88d3e3cfab34559e2e80bea --- /dev/null +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-dynamic-rows.js @@ -0,0 +1,98 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'underscore', + 'mageUtils', + 'uiRegistry', + 'Magento_Ui/js/dynamic-rows/dynamic-rows' +], function (_, utils, registry, dynamicRows) { + 'use strict'; + + return dynamicRows.extend({ + defaults: { + label: '', + collapsibleHeader: true, + columnsHeader: false, + deleteProperty: false, + addButton: false + }, + + /** + * Set new data to dataSource, + * delete element + * + * @param {Array} data - record data + */ + _updateData: function (data) { + var elems = _.clone(this.elems()), + path, + dataArr, + optionBaseData; + + dataArr = this.recordData.splice(this.startIndex, this.recordData().length - this.startIndex); + dataArr.splice(0, this.pageSize); + elems = _.sortBy(this.elems(), function (elem) { + return ~~elem.index; + }); + + data.concat(dataArr).forEach(function (rec, idx) { + if (elems[idx]) { + elems[idx].recordId = rec[this.identificationProperty]; + } + + if (!rec.position) { + rec.position = this.maxPosition; + this.setMaxPosition(); + } + + path = this.dataScope + '.' + this.index + '.' + (this.startIndex + idx); + optionBaseData = _.pick(rec, function (value) { + return !_.isObject(value); + }); + this.source.set(path, optionBaseData); + this.source.set(path + '.bundle_button_proxy', []); + this.source.set(path + '.bundle_selections', []); + this.removeBundleItemsFromOption(idx); + _.each(rec['bundle_selections'], function (obj, index) { + this.source.set(path + '.bundle_button_proxy' + '.' + index, rec['bundle_button_proxy'][index]); + this.source.set(path + '.bundle_selections' + '.' + index, obj); + }, this); + }, this); + + this.elems(elems); + }, + + /** + * Removes nested dynamic-rows-grid rendered records from option + * + * @param {Number|String} index - element index + */ + removeBundleItemsFromOption: function (index) { + var bundleSelections = registry.get(this.name + '.' + index + '.' + this.bundleSelectionsName), + bundleSelectionsLength = (bundleSelections.elems() || []).length, + i; + + if (bundleSelectionsLength) { + for (i = 0; i < bundleSelectionsLength; i++) { + bundleSelections.elems()[0].destroy(); + } + } + }, + + /** + * {@inheritdoc} + */ + processingAddChild: function (ctx, index, prop) { + var recordIds = _.map(this.recordData(), function (rec) { + return parseInt(rec['record_id'], 10); + }), + maxRecordId = _.max(recordIds); + + prop = maxRecordId > -1 ? maxRecordId + 1 : prop; + this._super(ctx, index, prop); + } + }); +}); diff --git a/app/code/Magento/Bundle/view/base/web/js/price-bundle.js b/app/code/Magento/Bundle/view/base/web/js/price-bundle.js index 1a76acf17475670674c064c8384d628b87d924a7..607ac6e03a75a8beeb644c84a11400eee09012d9 100644 --- a/app/code/Magento/Bundle/view/base/web/js/price-bundle.js +++ b/app/code/Magento/Bundle/view/base/web/js/price-bundle.js @@ -295,6 +295,10 @@ define([ case 'hidden': optionHash = 'bundle-option-' + optionName + '##' + optionValue; optionQty = optionConfig[optionValue].qty || 0; + canQtyCustomize = optionConfig[optionValue].customQty === '1'; + qtyField = element.data('qtyField'); + qtyField.data('option', element); + toggleQtyField(qtyField, optionQty, optionId, optionValue, canQtyCustomize); tempChanges = utils.deepClone(optionConfig[optionValue].prices); tempChanges = applyTierPrice(tempChanges, optionQty, optionConfig); tempChanges = applyQty(tempChanges, optionQty); diff --git a/app/code/Magento/BundleImportExport/composer.json b/app/code/Magento/BundleImportExport/composer.json index 3d7900d98287c1eba32a5badd2d5b2fdc1857f25..2f5e3afdbff86ded9c88161ebea832c29b37f229 100644 --- a/app/code/Magento/BundleImportExport/composer.json +++ b/app/code/Magento/BundleImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-bundle-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-import-export": "100.2.*", "magento/module-catalog-import-export": "100.2.*", diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json index cafccadb41ad869ff87ee8eb154c747f569a4c79..c886e069b66e37d3b0c7a12af377a250cfc75192 100644 --- a/app/code/Magento/CacheInvalidate/composer.json +++ b/app/code/Magento/CacheInvalidate/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-cache-invalidate", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-page-cache": "100.2.*", "magento/framework": "100.2.*" }, diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json index 9d0ce3db92aa402a7c247fed21185953c4707342..45ecd32464e9cc3f647264420961d6848b0445e9 100644 --- a/app/code/Magento/Captcha/composer.json +++ b/app/code/Magento/Captcha/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-captcha", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-customer": "100.2.*", "magento/module-checkout": "100.2.*", diff --git a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php index d9702c5073fb653c132c89d761e9ddf14faa34c1..f1bb89d4424f7f4436abea0c137a0457a0ad13c8 100644 --- a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php +++ b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php @@ -124,7 +124,7 @@ class AbstractProduct extends \Magento\Framework\View\Element\Template */ public function getAddToCartUrl($product, $additional = []) { - if ($product->getTypeInstance()->hasRequiredOptions($product)) { + if (!$product->getTypeInstance()->isPossibleBuyFromList($product)) { if (!isset($additional['_escape'])) { $additional['_escape'] = true; } diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php index 4375092591d194962b108e2ba0351b1a03fa7e5c..40516e55e930c4021699dad26b43a4e83fe26a80 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php @@ -281,7 +281,7 @@ class FlatTableBuilder if (!empty($columnValueNames)) { $select->joinLeft( $temporaryValueTableName, - sprintf('e.%1$s = %2$s.%1$s', $linkField, $temporaryTableName), + sprintf('e.%1$s = %2$s.%1$s', $linkField, $temporaryValueTableName), $columnValueNames ); $allColumns = array_merge($allColumns, $columnValueNames); diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 9e9f18e0113717ad6853ea5d4512661a897e926c..c913c82de1acdecbf3328c37fe7529dfbab193ba 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -22,7 +22,6 @@ use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionFactory; * @method Product setHasError(bool $value) * @method \Magento\Catalog\Model\ResourceModel\Product getResource() * @method null|bool getHasError() - * @method Product setAssociatedProductIds(array $productIds) * @method array getAssociatedProductIds() * @method Product setNewVariationsAttributeSetId(int $value) * @method int getNewVariationsAttributeSetId() @@ -2614,4 +2613,16 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements } return $this->mediaGalleryProcessor; } + + /** + * Set the associated products + * + * @param array $productIds + * @return $this + */ + public function setAssociatedProductIds(array $productIds) + { + $this->getExtensionAttributes()->setConfigurableProductLinks($productIds); + return $this; + } } diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index 7d8b464db3b34cd116d2c8c7adae86113040e67f..34e1ad30ad434add33508bb63c7b8b1a78ddc9fb 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -498,8 +498,7 @@ class Image extends \Magento\Framework\Model\AbstractModel $path = [ $this->_catalogProductMediaConfig->getBaseMediaPath(), 'cache', - $this->_storeManager->getStore()->getId(), - $path[] = $this->getDestinationSubdir(), + $this->getDestinationSubdir(), ]; if (!empty($this->_width) || !empty($this->_height)) { $path[] = "{$this->_width}x{$this->_height}"; diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php index 6de6ea6c6c6bca8029aee2be5749d555690d48c8..11b8d03fc7ee5cc23dd627e65ad9651a5b243b7d 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php +++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php @@ -1092,4 +1092,15 @@ abstract class AbstractType { return []; } + + /** + * Check if product can be potentially buyed from the category page or some other list + * + * @param \Magento\Catalog\Model\Product $product + * @return bool + */ + public function isPossibleBuyFromList($product) + { + return !$this->hasRequiredOptions($product); + } } diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 4385c8add37aef25dc52a888d2ff839b49e734db..27796e1cda2a167848c2a3b8fb0d096f40c172d6 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -640,6 +640,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa $collection->load(); + $collection->addCategoryIds(); $searchResult = $this->searchResultsFactory->create(); $searchResult->setSearchCriteria($searchCriteria); $searchResult->setItems($collection->getItems()); diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php index d9612f18c9111df4634e18cb8b9abf523643f2e5..432bc696ef7cecd822b5168e7da70a9ed1cd4fc5 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php @@ -197,7 +197,7 @@ abstract class AbstractEav extends \Magento\Catalog\Model\ResourceModel\Product\ )->joinLeft( ['e' => $this->getTable('catalog_product_entity')], 'e.' . $linkField .' = l.parent_id', - ['e.entity_id as parent_id'] + [] )->join( ['cs' => $this->getTable('store')], '', @@ -205,9 +205,17 @@ abstract class AbstractEav extends \Magento\Catalog\Model\ResourceModel\Product\ )->join( ['i' => $idxTable], 'l.child_id = i.entity_id AND cs.store_id = i.store_id', - ['attribute_id', 'store_id', 'value'] + [] )->group( - ['parent_id', 'i.attribute_id', 'i.store_id', 'i.value'] + ['parent_id', 'i.attribute_id', 'i.store_id', 'i.value', 'l.child_id'] + )->columns( + [ + 'parent_id' => 'e.entity_id', + 'attribute_id' => 'i.attribute_id', + 'store_id' => 'i.store_id', + 'value' => 'i.value', + 'source_id' => 'l.child_id' + ] ); if ($parentIds !== null) { $select->where('e.entity_id IN(?)', $parentIds); @@ -222,7 +230,7 @@ abstract class AbstractEav extends \Magento\Catalog\Model\ResourceModel\Product\ 'select' => $select, 'entity_field' => new \Zend_Db_Expr('l.parent_id'), 'website_field' => new \Zend_Db_Expr('cs.website_id'), - 'store_field' => new \Zend_Db_Expr('cs.store_id') + 'store_field' => new \Zend_Db_Expr('cs.store_id'), ] ); diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Decimal.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Decimal.php index e8d9889e68d59384e74cfb3fc0491a2edb8f3edb..a45d4f13a1a9a811fffb6269bf94575675c60d80 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Decimal.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Decimal.php @@ -85,6 +85,7 @@ class Decimal extends AbstractEav 'pdd.attribute_id', 'cs.store_id', 'value' => $productValueExpression, + 'source_id' => 'cpe.entity_id', ] ); @@ -116,7 +117,7 @@ class Decimal extends AbstractEav 'select' => $select, 'entity_field' => new \Zend_Db_Expr('cpe.entity_id'), 'website_field' => new \Zend_Db_Expr('cs.website_id'), - 'store_field' => new \Zend_Db_Expr('cs.store_id') + 'store_field' => new \Zend_Db_Expr('cs.store_id'), ] ); diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index c4eda1c987192acb5dd7e5ce003fe8b9cff0bdc6..1d37c57aa8b251bc73edf6e4a06aed1789cdc476 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -178,6 +178,7 @@ class Source extends AbstractEav 'pid.attribute_id', 'pid.store_id', 'value' => $ifNullSql, + 'pid.entity_id', ] )->where( 'pid.attribute_id IN(?)', @@ -200,7 +201,7 @@ class Source extends AbstractEav 'select' => $select, 'entity_field' => new \Zend_Db_Expr('pid.entity_id'), 'website_field' => new \Zend_Db_Expr('pid.website_id'), - 'store_field' => new \Zend_Db_Expr('pid.store_id') + 'store_field' => new \Zend_Db_Expr('pid.store_id'), ] ); $query = $select->insertFromSelect($idxTable); @@ -221,11 +222,7 @@ class Source extends AbstractEav $connection = $this->getConnection(); // prepare multiselect attributes - if ($attributeId === null) { - $attrIds = $this->_getIndexableAttributes(true); - } else { - $attrIds = [$attributeId]; - } + $attrIds = $attributeId === null ? $this->_getIndexableAttributes(true) : [$attributeId]; if (!$attrIds) { return $this; @@ -247,20 +244,20 @@ class Source extends AbstractEav $productValueExpression = $connection->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value'); $select = $connection->select()->from( ['pvd' => $this->getTable('catalog_product_entity_varchar')], - [$productIdField, 'attribute_id'] + [] )->join( ['cs' => $this->getTable('store')], '', - ['store_id'] + [] )->joinLeft( ['pvs' => $this->getTable('catalog_product_entity_varchar')], "pvs.{$productIdField} = pvd.{$productIdField} AND pvs.attribute_id = pvd.attribute_id" . ' AND pvs.store_id=cs.store_id', - ['value' => $productValueExpression] + [] )->joinLeft( ['cpe' => $this->getTable('catalog_product_entity')], "cpe.{$productIdField} = pvd.{$productIdField}", - ['entity_id'] + [] )->where( 'pvd.store_id=?', $connection->getIfNullSql('pvs.store_id', \Magento\Store\Model\Store::DEFAULT_STORE_ID) @@ -272,6 +269,14 @@ class Source extends AbstractEav $attrIds )->where( 'cpe.entity_id IS NOT NULL' + )->columns( + [ + 'entity_id' => 'cpe.entity_id', + 'attribute_id' => 'attribute_id', + 'store_id' => 'cs.store_id', + 'value' => $productValueExpression, + 'source_id' => 'cpe.entity_id', + ] ); $statusCond = $connection->quoteInto('=?', ProductStatus::STATUS_ENABLED); @@ -289,30 +294,11 @@ class Source extends AbstractEav 'select' => $select, 'entity_field' => new \Zend_Db_Expr('cpe.entity_id'), 'website_field' => new \Zend_Db_Expr('cs.website_id'), - 'store_field' => new \Zend_Db_Expr('cs.store_id') + 'store_field' => new \Zend_Db_Expr('cs.store_id'), ] ); - $i = 0; - $data = []; - $query = $select->query(); - while ($row = $query->fetch()) { - $values = explode(',', $row['value']); - foreach ($values as $valueId) { - if (isset($options[$row['attribute_id']][$valueId])) { - $data[] = [$row['entity_id'], $row['attribute_id'], $row['store_id'], $valueId]; - $i++; - if ($i % 10000 == 0) { - $this->_saveIndexData($data); - $data = []; - } - } - } - } - - $this->_saveIndexData($data); - unset($options); - unset($data); + $this->saveDataFromSelect($select, $options); return $this; } @@ -331,7 +317,7 @@ class Source extends AbstractEav $connection = $this->getConnection(); $connection->insertArray( $this->getIdxTable(), - ['entity_id', 'attribute_id', 'store_id', 'value'], + ['entity_id', 'attribute_id', 'store_id', 'value', 'source_id'], $data ); return $this; @@ -348,4 +334,31 @@ class Source extends AbstractEav { return $this->tableStrategy->getTableName('catalog_product_index_eav'); } + + /** + * @param \Magento\Framework\DB\Select $select + * @param array $options + * @return void + */ + private function saveDataFromSelect(\Magento\Framework\DB\Select $select, array $options) + { + $i = 0; + $data = []; + $query = $select->query(); + while ($row = $query->fetch()) { + $values = explode(',', $row['value']); + foreach ($values as $valueId) { + if (isset($options[$row['attribute_id']][$valueId])) { + $data[] = [$row['entity_id'], $row['attribute_id'], $row['store_id'], $valueId, $row['source_id']]; + $i++; + if ($i % 10000 == 0) { + $this->_saveIndexData($data); + $data = []; + } + } + } + } + + $this->_saveIndexData($data); + } } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php index 289445ae2daf07c4132f6d69372c84fcfb36a066..2b979ff79fe5c498215b6b144e71897b9ca2c913 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php @@ -368,7 +368,7 @@ class DefaultPrice extends AbstractIndexer implements PriceInterface 'select' => $select, 'entity_field' => new \Zend_Db_Expr('e.entity_id'), 'website_field' => new \Zend_Db_Expr('cw.website_id'), - 'store_field' => new \Zend_Db_Expr('cs.store_id') + 'store_field' => new \Zend_Db_Expr('cs.store_id'), ] ); diff --git a/app/code/Magento/Catalog/Setup/InstallSchema.php b/app/code/Magento/Catalog/Setup/InstallSchema.php index 171e96efe9b0a1e714e1331fc2ed95a175cd58fb..a2ba6aa283f6516021f0baffaafd6e6470c060f0 100644 --- a/app/code/Magento/Catalog/Setup/InstallSchema.php +++ b/app/code/Magento/Catalog/Setup/InstallSchema.php @@ -18,6 +18,7 @@ class InstallSchema implements InstallSchemaInterface /** * {@inheritdoc} * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @throws \Zend_Db_Exception */ public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { @@ -2429,7 +2430,6 @@ class InstallSchema implements InstallSchemaInterface 'option_id', $installer->getTable('catalog_product_option'), 'option_id', - \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE, \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE ) ->setComment( diff --git a/app/code/Magento/Catalog/Setup/UpgradeSchema.php b/app/code/Magento/Catalog/Setup/UpgradeSchema.php index cbcce1d427bb6c91fa000bff0b4a069ab02d034f..7fc2ef7d219ba917aa59c9887749a9024bda49ce 100755 --- a/app/code/Magento/Catalog/Setup/UpgradeSchema.php +++ b/app/code/Magento/Catalog/Setup/UpgradeSchema.php @@ -61,9 +61,56 @@ class UpgradeSchema implements UpgradeSchemaInterface } } + if (version_compare($context->getVersion(), '2.1.2', '<')) { + $this->addSourceEntityIdToProductEavIndex($setup); + } + $setup->endSetup(); } + /** + * Add the column 'source_id' to the Product EAV index tables. + * It allows to identify which entity was used to create value in the index. + * It is useful to identify original entity in a composite products. + * + * @param SchemaSetupInterface $setup + * @return void + */ + private function addSourceEntityIdToProductEavIndex(SchemaSetupInterface $setup) + { + $tables = [ + 'catalog_product_index_eav', + 'catalog_product_index_eav_idx', + 'catalog_product_index_eav_tmp', + 'catalog_product_index_eav_decimal', + 'catalog_product_index_eav_decimal_idx', + 'catalog_product_index_eav_decimal_tmp', + ]; + $connection = $setup->getConnection(); + foreach ($tables as $tableName) { + $tableName = $setup->getTable($tableName); + $connection->addColumn( + $tableName, + 'source_id', + [ + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, + 'unsigned' => true, + 'nullable' => false, + 'default' => 0, + 'comment' => 'Original entity Id for attribute value', + ] + ); + $connection->dropIndex($tableName, $connection->getPrimaryKeyName($tableName)); + $primaryKeyFields = ['entity_id', 'attribute_id', 'store_id', 'value', 'source_id']; + $setup->getConnection()->addIndex( + $tableName, + $connection->getIndexName($tableName, $primaryKeyFields), + $primaryKeyFields, + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_PRIMARY + ); + } + } + /** * @param SchemaSetupInterface $setup * @return void diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php index f420f140b35820e3cbcebf986ed305217523aab2..39e3263722a7c3f84fce9f6ce3e5b8ee2f2899d6 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php @@ -154,9 +154,9 @@ class ListProductTest extends \PHPUnit_Framework_TestCase ]; $this->typeInstanceMock->expects($this->once()) - ->method('hasRequiredOptions') + ->method('isPossibleBuyFromList') ->with($this->equalTo($this->productMock)) - ->will($this->returnValue(false)); + ->will($this->returnValue(true)); $this->cartHelperMock->expects($this->any()) ->method('getAddUrl') ->with($this->equalTo($this->productMock), $this->equalTo([])) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php index 7e5a8305467e8e979a9ccc79d39d7ffdb70bb339..d90261f068f5023d8987bab6d64585032385c8ee 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php @@ -107,44 +107,42 @@ class FlatTableBuilderTest extends \PHPUnit_Framework_TestCase public function testBuild() { - list($storeId, $changedIds, $valueFieldSuffix, $tableDropSuffix, $fillTmpTables) = [1, [], '', '', true]; + $storeId = 1; + $changedIds = []; + $valueFieldSuffix = '_value'; + $tableDropSuffix = ''; + $fillTmpTables = true; $tableName = 'catalog_product_entity'; $attributeTable = 'catalog_product_entity_int'; $temporaryTableName = 'catalog_product_entity_int_tmp_indexer'; - $temporaryValueTableName = 'catalog_product_entity_int_tmp_indexer'; + $temporaryValueTableName = 'catalog_product_entity_int_tmp_indexer_value'; $linkField = 'entity_id'; $statusId = 22; + $eavCustomField = 'space_weight'; + $eavCustomValueField = $eavCustomField . $valueFieldSuffix; $this->flatIndexerMock->expects($this->once())->method('getAttributes')->willReturn([]); $this->flatIndexerMock->expects($this->exactly(3))->method('getFlatColumns') - ->willReturnOnConsecutiveCalls( - [], - [$linkField => []], - [$linkField => []] - ); + ->willReturnOnConsecutiveCalls([], [$eavCustomValueField => []], [$eavCustomValueField => []]); $this->flatIndexerMock->expects($this->once())->method('getFlatIndexes')->willReturn([]); $statusAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class) ->disableOriginalConstructor() ->getMock(); + $eavCustomAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class) + ->disableOriginalConstructor() + ->getMock(); $this->flatIndexerMock->expects($this->once())->method('getTablesStructure') ->willReturn( [ - 'catalog_product_entity' => [ - $linkField => $statusAttributeMock - ], + 'catalog_product_entity' => [$linkField => $statusAttributeMock], 'catalog_product_entity_int' => [ - $linkField => $statusAttributeMock + $linkField => $statusAttributeMock, + $eavCustomField => $eavCustomAttributeMock ] ] ); $this->flatIndexerMock->expects($this->atLeastOnce())->method('getTable') - ->withConsecutive( - [$tableName], - ['catalog_product_website'] - ) - ->willReturnOnConsecutiveCalls( - $tableName, - 'catalog_product_website' - ); + ->withConsecutive([$tableName], ['catalog_product_website']) + ->willReturnOnConsecutiveCalls($tableName, 'catalog_product_website'); $this->flatIndexerMock->expects($this->once())->method('getAttribute') ->with('status') ->willReturn($statusAttributeMock); @@ -155,6 +153,9 @@ class FlatTableBuilderTest extends \PHPUnit_Framework_TestCase $statusAttributeMock->expects($this->atLeastOnce())->method('getBackend')->willReturn( $backendMock ); + $eavCustomAttributeMock->expects($this->atLeastOnce())->method('getBackend')->willReturn( + $backendMock + ); $statusAttributeMock->expects($this->atLeastOnce())->method('getId')->willReturn($statusId); $tableMock = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Table::class) ->disableOriginalConstructor() @@ -185,12 +186,12 @@ class FlatTableBuilderTest extends \PHPUnit_Framework_TestCase [ $temporaryTableName, "e.{$linkField} = {$temporaryTableName}.{$linkField}", - [$linkField] + [$linkField, $eavCustomField] ], [ $temporaryValueTableName, - "e.{$linkField} = " . $temporaryValueTableName . ".{$linkField}", - [$linkField] + "e.{$linkField} = {$temporaryValueTableName}.{$linkField}", + [$eavCustomValueField] ] )->willReturnSelf(); $this->metadataPoolMock->expects($this->atLeastOnce())->method('getMetadata')->with(ProductInterface::class) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php index a032ffa33b37561117fac3f6e603cb77dd34152d..44f7f87cc2c62afc2c09d262bbd2721683fcfea3 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php @@ -180,7 +180,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase $this->image->setBaseFile('/somefile.png'); $this->assertEquals('catalog/product/somefile.png', $this->image->getBaseFile()); $this->assertEquals( - 'catalog/product/cache/1//beff4985b56e3afdbeabfc89641a4582/somefile.png', + 'catalog/product/cache//beff4985b56e3afdbeabfc89641a4582/somefile.png', $this->image->getNewFile() ); } @@ -302,7 +302,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase $this->testSetGetBaseFile(); $url = $this->image->getUrl(); $this->assertEquals( - 'http://magento.com/media/catalog/product/cache/1//beff4985b56e3afdbeabfc89641a4582/somefile.png', + 'http://magento.com/media/catalog/product/cache//beff4985b56e3afdbeabfc89641a4582/somefile.png', $url ); } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index e91bb469eb112d4de70cba92bff5b93ca069ca58..8c08d0c63bc5e93c7ab690f6441eaa02281b3255 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -715,6 +715,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase ->method('process') ->with($searchCriteriaMock, $collectionMock); $collectionMock->expects($this->once())->method('load'); + $collectionMock->expects($this->once())->method('addCategoryIds'); $collectionMock->expects($this->once())->method('getItems')->willReturn([$itemsMock]); $collectionMock->expects($this->once())->method('getSize')->willReturn(128); $searchResultsMock = $this->getMock( diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ImagesTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ImagesTest.php index 2172e184a9a2ed400d80eb89314855c69fb2c7c1..7a55bd31e3deef64ddeaf5b452cc1b7eb389517c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ImagesTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ImagesTest.php @@ -24,7 +24,9 @@ class ImagesTest extends AbstractModifierTest public function testModifyData() { - $this->assertSame($this->getSampleData(), $this->getModel()->modifyData($this->getSampleData())); + $this->productMock->expects($this->once())->method('getId')->willReturn(2051); + $actualResult = $this->getModel()->modifyData($this->getSampleData()); + $this->assertSame("", $actualResult[2051]['product']['media_gallery']['images'][0]['label']); } public function testModifyMeta() @@ -40,4 +42,24 @@ class ImagesTest extends AbstractModifierTest $this->assertSame([], $this->getModel()->modifyMeta($meta)); } + + /** + * {@inheritdoc} + */ + protected function getSampleData() + { + return [ + 2051 => [ + 'product' => [ + 'media_gallery' => [ + 'images' => [ + [ + 'label' => null + ] + ] + ] + ] + ] + ]; + } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php index 0fbba264f7e93383f07434a7fe2ebf4586d54516..886c7a070adf93b68ec54f45813ba80911029e44 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php @@ -315,17 +315,6 @@ class General extends AbstractModifier $importsConfig = [ 'mask' => $this->locator->getStore()->getConfig('catalog/fields_masks/' . $listener), 'component' => 'Magento_Catalog/js/components/import-handler', - 'imports' => [ - 'handleNameChanges' => '${$.provider}:data.product.name', - 'handleDescriptionChanges' => '${$.provider}:data.product.description', - 'handleSkuChanges' => '${$.provider}:data.product.sku', - 'handleColorChanges' => '${$.provider}:data.product.color', - 'handleCountryChanges' => '${$.provider}:data.product.country_of_manufacture', - 'handleGenderChanges' => '${$.provider}:data.product.gender', - 'handleMaterialChanges' => '${$.provider}:data.product.material', - 'handleShortDescriptionChanges' => '${$.provider}:data.product.short_description', - 'handleSizeChanges' => '${$.provider}:data.product.size' - ], 'allowImport' => !$this->locator->getProduct()->getId(), ]; diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Images.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Images.php index 810a06df4a42f76392ee54525eb5bf6ffc5f489f..a8536cacc79668797ac961e1082c7b8c0f020e76 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Images.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Images.php @@ -51,6 +51,21 @@ class Images extends AbstractModifier */ public function modifyData(array $data) { + /** @var \Magento\Catalog\Api\Data\ProductInterface $product */ + $product = $this->locator->getProduct(); + $modelId = $product->getId(); + if ( + isset($data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery']) + && !empty($data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery']) + && !empty($data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery']['images']) + ) { + foreach ($data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery']['images'] as $index => $image) { + if (!isset($image['label'])) { + $data[$modelId][self::DATA_SOURCE_DEFAULT]['media_gallery']['images'][$index]['label'] = ""; + } + } + }; + return $data; } } diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json index 64157f6bc8af74e82975668e43a62ef583227908..8c77dd77f98b74a53ee1124a16c473d843d21d60 100644 --- a/app/code/Magento/Catalog/composer.json +++ b/app/code/Magento/Catalog/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-eav": "100.2.*", "magento/module-cms": "101.1.*", diff --git a/app/code/Magento/Catalog/etc/module.xml b/app/code/Magento/Catalog/etc/module.xml index c629bf6a180ccc0ec42e51a67352f6eaa673dd86..0c9e6bb356fe14101d467a04aa91b23fb6873f09 100644 --- a/app/code/Magento/Catalog/etc/module.xml +++ b/app/code/Magento/Catalog/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_Catalog" setup_version="2.1.1"> + <module name="Magento_Catalog" setup_version="2.1.2"> <sequence> <module name="Magento_Eav"/> <module name="Magento_Cms"/> diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js index e67bde152475f62769d6eaff73548893f98ed7d0..a0aec918ccda24f1ae05486bc5d9ec59522f0ca7 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js @@ -4,148 +4,78 @@ */ define([ + 'Magento_Ui/js/form/element/abstract', 'underscore', - 'Magento_Ui/js/form/element/textarea' -], function (_, Textarea) { + 'uiRegistry' +], function (Abstract, _, registry) { 'use strict'; - return Textarea.extend({ + return Abstract.extend({ defaults: { allowImport: true, autoImportIfEmpty: false, - values: { - 'name': '', - 'description': '', - 'sku': '', - 'color': '', - 'country_of_manufacture': '', - 'gender': '', - 'material': '', - 'short_description': '', - 'size': '' - }, - valueUpdate: 'input', - mask: '' + values: {}, + mask: '', + queryTemplate: 'ns = ${ $.ns }, index = ' }, - /** - * Handle name value changes, if it's allowed - * - * @param {String} newValue - */ - handleNameChanges: function (newValue) { - this.values.name = newValue; - this.updateValue(); - }, - - /** - * Handle description value changes, if it's allowed - * - * @param {String} newValue - */ - handleDescriptionChanges: function (newValue) { - this.values.description = newValue; - this.updateValue(); - }, + /** @inheritdoc */ + initialize: function () { + this._super(); - /** - * Handle sku value changes, if it's allowed - * - * @param {String} newValue - */ - handleSkuChanges: function (newValue) { - if (this.code !== 'sku') { - this.values.sku = newValue; - this.updateValue(); + if (this.allowImport) { + this.setHandlers(); } }, /** - * Handle color value changes, if it's allowed - * - * @param {String} newValue - */ - handleColorChanges: function (newValue) { - this.values.color = newValue; - this.updateValue(); - }, - - /** - * Handle country value changes, if it's allowed - * - * @param {String} newValue + * Split mask placeholder and attach events to placeholder fields. */ - handleCountryChanges: function (newValue) { - this.values.country = newValue; - this.updateValue(); - }, + setHandlers: function () { + var str = this.mask || '', + placeholders; - /** - * Handle gender value changes, if it's allowed - * - * @param {String} newValue - */ - handleGenderChanges: function (newValue) { - this.values.gender = newValue; - this.updateValue(); - }, + placeholders = str.match(/{{(.*?)}}/g); // Get placeholders - /** - * Handle material value changes, if it's allowed - * - * @param {String} newValue - */ - handleMaterialChanges: function (newValue) { - this.values.material = newValue; - this.updateValue(); - }, + _.each(placeholders, function (placeholder) { + placeholder = placeholder.replace(/[{{}}]/g, ''); // Remove curly braces - /** - * Handle short description value changes, if it's allowed - * - * @param {String} newValue - */ - handleShortDescriptionChanges: function (newValue) { - this.values['short_description'] = newValue; - this.updateValue(); + registry.get(this.queryTemplate + placeholder, function (component) { + this.values[placeholder] = component.getPreview(); + component.on('value', this.updateValue.bind(this, placeholder, component)); + component.valueUpdate = 'keyup'; + }.bind(this)); + }, this); }, /** - * Handle size value changes, if it's allowed + * Update field with mask value, if it's allowed. * - * @param {String} newValue + * @param {Object} placeholder + * @param {Object} component */ - handleSizeChanges: function (newValue) { - this.values.size = newValue; - this.updateValue(); - }, + updateValue: function (placeholder, component) { + var string = this.mask || '', + nonEmptyValueFlag = false; - /** - * Update field value, if it's allowed - */ - updateValue: function () { - var str = this.mask || '', - nonEmptyValueFlag = false, - tmpElement; + if (placeholder) { + this.values[placeholder] = component.getPreview() || ''; + } if (!this.allowImport) { return; } - if (str) { - _.each(this.values, function (propertyValue, propertyName) { - str = str.replace('{{' + propertyName + '}}', propertyValue); - nonEmptyValueFlag = nonEmptyValueFlag || !!propertyValue; - }); - } - - // strip tags - tmpElement = document.createElement('div'); - tmpElement.innerHTML = str; - str = tmpElement.textContent || tmpElement.innerText || ''; + _.each(this.values, function (propertyValue, propertyName) { + string = string.replace('{{' + propertyName + '}}', propertyValue); + nonEmptyValueFlag = nonEmptyValueFlag || !!propertyValue; + }); if (nonEmptyValueFlag) { - this.value(str); + string = string.replace(/(<([^>]+)>)/ig, ''); // Remove html tags + this.value(string); + } else { + this.value(''); } }, @@ -169,13 +99,20 @@ define([ * and disallow/allow import value */ userChanges: function () { + + /** + * As userChanges is called before updateValue, + * we forced to get value from component by reference + */ + var actualValue = arguments[1].currentTarget.value; + this._super(); - if (this.value() === '') { + if (actualValue === '') { this.allowImport = true; if (this.autoImportIfEmpty) { - this.updateValue(); + this.updateValue(null, null); } } else { this.allowImport = false; diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml index 4c8ae8eaae9524fe75f74ba5f0dd45ef045c2954..298cdcc29e953a74625a3834edab6b9a5eb47631 100644 --- a/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml +++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_category_view.xml @@ -28,53 +28,6 @@ </block> <block class="Magento\Catalog\Block\Product\ProductList\Toolbar" name="product_list_toolbar" template="Magento_Catalog::product/list/toolbar.phtml"> <block class="Magento\Theme\Block\Html\Pager" name="product_list_toolbar_pager"/> - <!-- The following code shows how to set your own pager increments --> - <!-- - <action method="setDefaultListPerPage"> - <argument name="limit" xsi:type="string">4</argument> - </action> - <action method="setDefaultGridPerPage"> - <argument name="limit" xsi:type="string">3</argument> - </action> - <action method="addPagerLimit"> - <argument name="mode" xsi:type="string">list</argument> - <argument name="limit" xsi:type="string">2</argument> - </action> - <action method="addPagerLimit"> - <argument name="mode" xsi:type="string">list</argument> - <argument name="limit" xsi:type="string">4</argument> - </action> - <action method="addPagerLimit"> - <argument name="mode" xsi:type="string">list</argument> - <argument name="limit" xsi:type="string">6</argument> - </action> - <action method="addPagerLimit"> - <argument name="mode" xsi:type="string">list</argument> - <argument name="limit" xsi:type="string">8</argument> - </action> - <action method="addPagerLimit" translate="label"> - <argument name="mode" xsi:type="string">list</argument> - <argument name="limit" xsi:type="string">all</argument> - <argument name="label" xsi:type="string">All</argument> - </action> - <action method="addPagerLimit"> - <argument name="mode" xsi:type="string">grid</argument> - <argument name="limit" xsi:type="string">3</argument> - </action> - <action method="addPagerLimit"> - <argument name="mode" xsi:type="string">grid</argument> - <argument name="limit" xsi:type="string">6</argument> - </action> - <action method="addPagerLimit"> - <argument name="mode" xsi:type="string">grid</argument> - <argument name="limit" xsi:type="string">9</argument> - </action> - <action method="addPagerLimit" translate="label"> - <argument name="mode" xsi:type="string">grid</argument> - <argument name="limit" xsi:type="string">all</argument> - <argument name="label" xsi:type="string">All</argument> - </action> - --> </block> <action method="setToolbarBlockName"> <argument name="name" xsi:type="string">product_list_toolbar</argument> diff --git a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js index 45c9f73e051c788c55f24d2f95f1e286c7d6bd02..7db4f5d745626c0da12d9a4032bc5466c57f282b 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js @@ -84,6 +84,17 @@ define([ } if (res.backUrl) { + var eventData = { + 'form': form, + 'redirectParameters': [] + } + // trigger global event, so other modules will be able add parameters to redirect url + $('body').trigger('catalogCategoryAddToCartRedirect', eventData); + if (eventData.redirectParameters.length > 0) { + var parameters = res.backUrl.split('#'); + parameters.push(eventData.redirectParameters.join('&')); + res.backUrl = parameters.join('#'); + } window.location = res.backUrl; return; } diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index afb2e86b6248a79523405c78acd1cf27953b90c2..54208dcdba534139c96e8fd975e0757f9ecb11e1 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -2304,7 +2304,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity $sku = $rowData[self::COL_SKU]; - if (isset($this->_oldSku[$sku])) { + if (isset($this->_oldSku[$sku]) && Import::BEHAVIOR_REPLACE !== $this->getBehavior()) { // can we get all necessary data from existent DB product? // check for supported type of existing product if (isset($this->_productTypeModels[$this->_oldSku[$sku]['type_id']])) { @@ -2356,7 +2356,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity $rowAttributesValid = $productTypeValidator->isRowValid( $rowData, $rowNum, - !isset($this->_oldSku[$sku]) + !(isset($this->_oldSku[$sku]) && Import::BEHAVIOR_REPLACE !== $this->getBehavior()) ); if (!$rowAttributesValid && self::SCOPE_DEFAULT == $rowScope) { // mark SCOPE_DEFAULT row as invalid for future child rows if product not in DB already diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index 7dbd7f4bc5e656ff09712549886e97a95fa3f4f1..8ed5f43692df51482038e1d1f7d4b91f05fd8c23 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-catalog-url-rewrite": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/CatalogInventory/Setup/UpgradeData.php b/app/code/Magento/CatalogInventory/Setup/UpgradeData.php index db3408c01b77f9fc620ee0862f2f71f2eec232c5..1741ffce9cdfa1bc0374666a704386241e935f67 100644 --- a/app/code/Magento/CatalogInventory/Setup/UpgradeData.php +++ b/app/code/Magento/CatalogInventory/Setup/UpgradeData.php @@ -54,7 +54,7 @@ class UpgradeData implements UpgradeDataInterface public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) { $setup->startSetup(); - if (version_compare($context->getVersion(), '2.0.2') < 0) { + if (version_compare($context->getVersion(), '2.2.0') < 0) { $this->upgradeCatalogInventoryStockItem($setup); } $setup->endSetup(); diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index 254d8d2db4bf9db35b338507cdd744d1aaf0e152..684f616ecd6fcfca7088c257afec000fba6a4b1d 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog-inventory", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/code/Magento/CatalogInventory/etc/events.xml b/app/code/Magento/CatalogInventory/etc/events.xml index a1476c2c3f8b161568a042725d6b04c37aeb1be9..d9db59b7a17663b48b2ba2df7677d4147cba11b5 100644 --- a/app/code/Magento/CatalogInventory/etc/events.xml +++ b/app/code/Magento/CatalogInventory/etc/events.xml @@ -33,9 +33,6 @@ <event name="sales_order_item_cancel"> <observer name="inventory" instance="Magento\CatalogInventory\Observer\CancelOrderItemObserver"/> </event> - <event name="sales_order_creditmemo_save_after"> - <observer name="inventory" instance="Magento\CatalogInventory\Observer\RefundOrderInventoryObserver"/> - </event> <event name="catalog_product_save_after"> <observer name="inventory" instance="Magento\CatalogInventory\Observer\SaveInventoryDataObserver"/> </event> diff --git a/app/code/Magento/CatalogInventory/etc/module.xml b/app/code/Magento/CatalogInventory/etc/module.xml index 711d18bead9c9ece376e74f3b13aced3419b7806..7aff70e2258312c49a6a6cde35bb87c5cb0e8400 100644 --- a/app/code/Magento/CatalogInventory/etc/module.xml +++ b/app/code/Magento/CatalogInventory/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_CatalogInventory" setup_version="2.0.2"> + <module name="Magento_CatalogInventory" setup_version="2.2.0"> <sequence> <module name="Magento_Catalog"/> </sequence> diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json index 71eb5b49db1fc68eadb064968796cfdaf1081d60..004ab82a028d3aba288b71a234dead24d63a4755 100644 --- a/app/code/Magento/CatalogRule/composer.json +++ b/app/code/Magento/CatalogRule/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog-rule", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-rule": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/code/Magento/CatalogRuleConfigurable/composer.json b/app/code/Magento/CatalogRuleConfigurable/composer.json index cc51269e2d9720e380612cf56c712ff2459bbe35..b930380f7bb025ea409be398c013c12773cb2f20 100644 --- a/app/code/Magento/CatalogRuleConfigurable/composer.json +++ b/app/code/Magento/CatalogRuleConfigurable/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog-rule-configurable", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-configurable-product": "100.2.*", "magento/framework": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php index 9b75e6e6e0c325819d09f543cc445ae61eb7fb84..ddf86951068acc3c95017e54e489faf92e4b28cc 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php @@ -6,6 +6,7 @@ namespace Magento\CatalogSearch\Model\Adapter\Mysql\Aggregation; use Magento\Catalog\Model\Product; +use Magento\CatalogInventory\Model\Stock; use Magento\Customer\Model\Session; use Magento\Eav\Model\Config; use Magento\Framework\App\ResourceConnection; @@ -79,7 +80,13 @@ class DataProvider implements DataProviderInterface $select = $this->getSelect(); - if ($attribute->getAttributeCode() == 'price') { + $select->joinInner( + ['entities' => $entityIdsTable->getName()], + 'main_table.entity_id = entities.entity_id', + [] + ); + + if ($attribute->getAttributeCode() === 'price') { /** @var \Magento\Store\Model\Store $store */ $store = $this->scopeResolver->getScope($currentScope); if (!$store instanceof \Magento\Store\Model\Store) { @@ -94,19 +101,24 @@ class DataProvider implements DataProviderInterface $currentScopeId = $this->scopeResolver->getScope($currentScope) ->getId(); $table = $this->resource->getTableName( - 'catalog_product_index_eav' . ($attribute->getBackendType() == 'decimal' ? '_decimal' : '') + 'catalog_product_index_eav' . ($attribute->getBackendType() === 'decimal' ? '_decimal' : '') ); - $select->from(['main_table' => $table], ['value']) + $subSelect = $select; + $subSelect->from(['main_table' => $table], ['main_table.value']) + ->joinLeft( + ['stock_index' => $this->resource->getTableName('cataloginventory_stock_status')], + 'main_table.source_id = stock_index.product_id', + [] + ) ->where('main_table.attribute_id = ?', $attribute->getAttributeId()) - ->where('main_table.store_id = ? ', $currentScopeId); + ->where('main_table.store_id = ? ', $currentScopeId) + ->where('stock_index.stock_status = ?', Stock::STOCK_IN_STOCK) + ->group(['main_table.entity_id', 'main_table.value']); + $parentSelect = $this->getSelect(); + $parentSelect->from(['main_table' => $subSelect], ['main_table.value']); + $select = $parentSelect; } - $select->joinInner( - ['entities' => $entityIdsTable->getName()], - 'main_table.entity_id = entities.entity_id', - [] - ); - return $select; } diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php new file mode 100644 index 0000000000000000000000000000000000000000..7099ce2502b19e21de48ae570e2dc063be6162d1 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/AliasResolver.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Adapter\Mysql\Filter; + + +use Magento\CatalogSearch\Model\Search\RequestGenerator; + +/** + * Purpose of class is to resolve table alias for Search Request filter + */ +class AliasResolver +{ + /** + * The suffix for stock status filter that may be added to the query beside the filter query + * Used when showing of Out of Stock products is disabled. + */ + const STOCK_FILTER_SUFFIX = '_stock'; + + /** + * @param \Magento\Framework\Search\Request\FilterInterface $filter + * @return string alias of the filter in database + */ + public function getAlias(\Magento\Framework\Search\Request\FilterInterface $filter) + { + $alias = null; + $field = $filter->getField(); + switch ($field) { + case 'price': + $alias = 'price_index'; + break; + case 'category_ids': + $alias = 'category_ids_index'; + break; + default: + $alias = $field . RequestGenerator::FILTER_SUFFIX; + break; + } + return $alias; + } +} diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php index 05205f04f8b99cd903f345f8c1f7dc04384e7aee..fb579c1dce29c7da26b35288ff61040363f4f510 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php @@ -8,8 +8,11 @@ namespace Magento\CatalogSearch\Model\Adapter\Mysql\Filter; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\CatalogInventory\Model\Stock; use Magento\CatalogSearch\Model\Search\TableMapper; use Magento\Eav\Model\Config; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ResourceConnection; use Magento\Framework\App\ScopeResolverInterface; use Magento\Framework\DB\Adapter\AdapterInterface; @@ -17,6 +20,7 @@ use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\Search\Adapter\Mysql\ConditionManager; use Magento\Framework\Search\Adapter\Mysql\Filter\PreprocessorInterface; use Magento\Framework\Search\Request\FilterInterface; +use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\Store; /** @@ -60,9 +64,14 @@ class Preprocessor implements PreprocessorInterface private $metadataPool; /** - * @var TableMapper + * @var ScopeConfigInterface */ - private $tableMapper; + private $scopeConfig; + + /** + * @var AliasResolver + */ + private $aliasResolver; /** * @param ConditionManager $conditionManager @@ -71,6 +80,9 @@ class Preprocessor implements PreprocessorInterface * @param ResourceConnection $resource * @param TableMapper $tableMapper * @param string $attributePrefix + * @param ScopeConfigInterface $scopeConfig + * @param AliasResolver $aliasResolver + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( ConditionManager $conditionManager, @@ -78,7 +90,9 @@ class Preprocessor implements PreprocessorInterface Config $config, ResourceConnection $resource, TableMapper $tableMapper, - $attributePrefix + $attributePrefix, + ScopeConfigInterface $scopeConfig = null, + AliasResolver $aliasResolver = null ) { $this->conditionManager = $conditionManager; $this->scopeResolver = $scopeResolver; @@ -86,7 +100,16 @@ class Preprocessor implements PreprocessorInterface $this->resource = $resource; $this->connection = $resource->getConnection(); $this->attributePrefix = $attributePrefix; - $this->tableMapper = $tableMapper; + + if (null === $scopeConfig) { + $scopeConfig = ObjectManager::getInstance()->get(ScopeConfigInterface::class); + } + if (null === $aliasResolver) { + $aliasResolver = ObjectManager::getInstance()->get(AliasResolver::class); + } + + $this->scopeConfig = $scopeConfig; + $this->aliasResolver = $aliasResolver; } /** @@ -117,7 +140,7 @@ class Preprocessor implements PreprocessorInterface } elseif ($filter->getField() === 'category_ids') { return 'category_ids_index.category_id = ' . (int) $filter->getValue(); } elseif ($attribute->isStatic()) { - $alias = $this->tableMapper->getMappingAlias($filter); + $alias = $this->aliasResolver->getAlias($filter); $resultQuery = str_replace( $this->connection->quoteIdentifier($attribute->getAttributeCode()), $this->connection->quoteIdentifier($alias . '.' . $attribute->getAttributeCode()), @@ -208,7 +231,7 @@ class Preprocessor implements PreprocessorInterface */ private function processTermSelect(FilterInterface $filter, $isNegation) { - $alias = $this->tableMapper->getMappingAlias($filter); + $alias = $this->aliasResolver->getAlias($filter); if (is_array($filter->getValue())) { $value = sprintf( '%s IN (%s)', @@ -224,9 +247,31 @@ class Preprocessor implements PreprocessorInterface $value ); + if ($this->isAddStockFilter()) { + $resultQuery = sprintf( + '%1$s AND %2$s%3$s.stock_status = %4$s', + $resultQuery, + $alias, + AliasResolver::STOCK_FILTER_SUFFIX, + Stock::STOCK_IN_STOCK + ); + } + return $resultQuery; } + /** + * @return bool + */ + private function isAddStockFilter() + { + $isShowOutOfStock = $this->scopeConfig->isSetFlag( + 'cataloginventory/options/show_out_of_stock', + ScopeInterface::SCOPE_STORE + ); + return false === $isShowOutOfStock; + } + /** * Get product metadata pool * diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php new file mode 100644 index 0000000000000000000000000000000000000000..8626b2ea15b077fc42380afaba82b245e7387937 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/ExclusionStrategy.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\FilterMapper; + +use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver; + +/** + * Strategy which processes exclusions from general rules + */ +class ExclusionStrategy implements FilterStrategyInterface +{ + /** + * @var \Magento\Framework\App\ResourceConnection + */ + private $resourceConnection; + + /** + * @var AliasResolver + */ + private $aliasResolver; + + /** + * @var \Magento\Store\Model\StoreManagerInterface + */ + private $storeManager; + + /** + * @param \Magento\Framework\App\ResourceConnection $resourceConnection + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param AliasResolver $aliasResolver + */ + public function __construct( + \Magento\Framework\App\ResourceConnection $resourceConnection, + \Magento\Store\Model\StoreManagerInterface $storeManager, + AliasResolver $aliasResolver + ) { + $this->resourceConnection = $resourceConnection; + $this->storeManager = $storeManager; + $this->aliasResolver = $aliasResolver; + } + + /** + * {@inheritDoc} + */ + public function apply( + \Magento\Framework\Search\Request\FilterInterface $filter, + \Magento\Framework\DB\Select $select + ) { + $isApplied = false; + $field = $filter->getField(); + if ('price' === $field) { + $alias = $this->aliasResolver->getAlias($filter); + $tableName = $this->resourceConnection->getTableName('catalog_product_index_price'); + $select->joinInner( + [ + $alias => $tableName + ], + $this->resourceConnection->getConnection()->quoteInto( + 'search_index.entity_id = price_index.entity_id AND price_index.website_id = ?', + $this->storeManager->getWebsite()->getId() + ), + [] + ); + $isApplied = true; + } elseif ('category_ids' === $field) { + $alias = $this->aliasResolver->getAlias($filter); + $tableName = $this->resourceConnection->getTableName('catalog_category_product_index'); + $select->joinInner( + [ + $alias => $tableName + ], + 'search_index.entity_id = category_ids_index.product_id', + [] + ); + $isApplied = true; + } + return $isApplied; + } +} diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php new file mode 100644 index 0000000000000000000000000000000000000000..d244e3d5f754893fb671a3b6c81565eb5c920ff7 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterContext.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\FilterMapper; + + +use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver; +use Magento\Eav\Model\Config as EavConfig; +use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; + +/** + * FilterContext represents a Context of the Strategy pattern + * Its responsibility is to choose appropriate strategy to apply passed filter to the Select + */ +class FilterContext implements FilterStrategyInterface +{ + /** + * @var ExclusionStrategy + */ + private $exclusionStrategy; + + /** + * @var EavConfig + */ + private $eavConfig; + + /** + * @var TermDropdownStrategy + */ + private $termDropdownStrategy; + + /** + * @var StaticAttributeStrategy + */ + private $staticAttributeStrategy; + + /** + * @var AliasResolver + */ + private $aliasResolver; + + /** + * @param EavConfig $eavConfig + * @param AliasResolver $aliasResolver + * @param ExclusionStrategy $exclusionStrategy + * @param TermDropdownStrategy $termDropdownStrategy + * @param StaticAttributeStrategy $staticAttributeStrategy + */ + public function __construct( + EavConfig $eavConfig, + AliasResolver $aliasResolver, + ExclusionStrategy $exclusionStrategy, + TermDropdownStrategy $termDropdownStrategy, + StaticAttributeStrategy $staticAttributeStrategy + ) { + $this->eavConfig = $eavConfig; + $this->aliasResolver = $aliasResolver; + $this->exclusionStrategy = $exclusionStrategy; + $this->termDropdownStrategy = $termDropdownStrategy; + $this->staticAttributeStrategy = $staticAttributeStrategy; + } + + /** + * {@inheritDoc} + */ + public function apply( + \Magento\Framework\Search\Request\FilterInterface $filter, + \Magento\Framework\DB\Select $select + ) { + $isApplied = $this->exclusionStrategy->apply($filter, $select); + + if (!$isApplied) { + $attribute = $this->getAttributeByCode($filter->getField()); + if ($attribute) { + if ($filter->getType() === \Magento\Framework\Search\Request\FilterInterface::TYPE_TERM + && in_array($attribute->getFrontendInput(), ['select', 'multiselect'], true) + ) { + $isApplied = $this->termDropdownStrategy->apply($filter, $select); + } elseif ($attribute->getBackendType() === AbstractAttribute::TYPE_STATIC) { + $isApplied = $this->staticAttributeStrategy->apply($filter, $select); + } + } + } + + return $isApplied; + } + + /** + * @param string $field + * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function getAttributeByCode($field) + { + return $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $field); + } +} diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..cf17f7d5132efbf8246af0de674d7c789551aa3e --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterStrategyInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\FilterMapper; + +/** + * FilterStrategyInterface provides the interface to work with strategies + */ +interface FilterStrategyInterface +{ + /** + * @param \Magento\Framework\Search\Request\FilterInterface $filter + * @param \Magento\Framework\DB\Select $select + * @return bool is filter was applied + */ + public function apply( + \Magento\Framework\Search\Request\FilterInterface $filter, + \Magento\Framework\DB\Select $select + ); +} diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php new file mode 100644 index 0000000000000000000000000000000000000000..eb9d61b5a7f4c352d23096050a5acd292dc80d54 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StaticAttributeStrategy.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\FilterMapper; + +use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver; +use Magento\Eav\Model\Config as EavConfig; + +/** + * This strategy handles static attributes + */ +class StaticAttributeStrategy implements FilterStrategyInterface +{ + /** + * @var \Magento\Framework\App\ResourceConnection + */ + private $resourceConnection; + + /** + * @var AliasResolver + */ + private $aliasResolver; + + /** + * @var EavConfig + */ + private $eavConfig; + + /** + * @param \Magento\Framework\App\ResourceConnection $resourceConnection + * @param EavConfig $eavConfig + * @param AliasResolver $aliasResolver + */ + public function __construct( + \Magento\Framework\App\ResourceConnection $resourceConnection, + EavConfig $eavConfig, + AliasResolver $aliasResolver + ) { + $this->resourceConnection = $resourceConnection; + $this->eavConfig = $eavConfig; + $this->aliasResolver = $aliasResolver; + } + + /** + * {@inheritDoc} + */ + public function apply( + \Magento\Framework\Search\Request\FilterInterface $filter, + \Magento\Framework\DB\Select $select + ) { + $attribute = $this->getAttributeByCode($filter->getField()); + $alias = $this->aliasResolver->getAlias($filter); + $select->joinInner( + [$alias => $attribute->getBackendTable()], + 'search_index.entity_id = ' + . $this->resourceConnection->getConnection()->quoteIdentifier("$alias.entity_id"), + [] + ); + return true; + } + + /** + * @param string $field + * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function getAttributeByCode($field) + { + return $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $field); + } +} diff --git a/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php new file mode 100644 index 0000000000000000000000000000000000000000..76828fe28f4348c8b90c9f1bf695906242c77222 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Search/FilterMapper/TermDropdownStrategy.php @@ -0,0 +1,127 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Model\Search\FilterMapper; + +use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver; +use Magento\Eav\Model\Config as EavConfig; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ResourceConnection; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; + +/** + * This strategy handles attributes which comply with two criteria: + * - The filter for dropdown or multi-select attribute + * - The filter is Term filter + * + */ +class TermDropdownStrategy implements FilterStrategyInterface +{ + /** + * @var AliasResolver + */ + private $aliasResolver; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var EavConfig + */ + private $eavConfig; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * @param StoreManagerInterface $storeManager + * @param ResourceConnection $resourceConnection + * @param EavConfig $eavConfig + * @param ScopeConfigInterface $scopeConfig + * @param AliasResolver $aliasResolver + */ + public function __construct( + StoreManagerInterface $storeManager, + ResourceConnection $resourceConnection, + EavConfig $eavConfig, + ScopeConfigInterface $scopeConfig, + AliasResolver $aliasResolver + ) { + $this->storeManager = $storeManager; + $this->resourceConnection = $resourceConnection; + $this->eavConfig = $eavConfig; + $this->scopeConfig = $scopeConfig; + $this->aliasResolver = $aliasResolver; + } + + /** + * {@inheritDoc} + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function apply( + \Magento\Framework\Search\Request\FilterInterface $filter, + \Magento\Framework\DB\Select $select + ) { + $alias = $this->aliasResolver->getAlias($filter); + $attribute = $this->getAttributeByCode($filter->getField()); + $joinCondition = sprintf( + 'search_index.entity_id = %1$s.entity_id AND %1$s.attribute_id = %2$d AND %1$s.store_id = %3$d', + $alias, + $attribute->getId(), + $this->storeManager->getWebsite()->getId() + ); + $select->joinLeft( + [$alias => $this->resourceConnection->getTableName('catalog_product_index_eav')], + $joinCondition, + [] + ); + if ($this->isAddStockFilter()) { + $stockAlias = $alias . AliasResolver::STOCK_FILTER_SUFFIX; + $select->joinLeft( + [ + $stockAlias => $this->resourceConnection->getTableName('cataloginventory_stock_status'), + ], + sprintf('%2$s.product_id = %1$s.source_id', $alias, $stockAlias), + [] + ); + } + + return true; + } + + /** + * @param string $field + * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute + * @throws \Magento\Framework\Exception\LocalizedException + */ + private function getAttributeByCode($field) + { + return $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $field); + } + + /** + * @return bool + */ + private function isAddStockFilter() + { + $isShowOutOfStock = $this->scopeConfig->isSetFlag( + 'cataloginventory/options/show_out_of_stock', + ScopeInterface::SCOPE_STORE + ); + + return false === $isShowOutOfStock; + } +} diff --git a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php index 1d30bb4a14d23a94d79a2faa5bc20823df220d8d..0e96e4de700259c9dc48c8f876983e2642316a86 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php @@ -99,6 +99,7 @@ class IndexBuilder implements IndexBuilderInterface * * @param RequestInterface $request * @return Select + * @throws \LogicException */ public function build(RequestInterface $request) { @@ -132,7 +133,7 @@ class IndexBuilder implements IndexBuilderInterface ), [] ); - $select->where('stock_index.stock_status = ?', Stock::DEFAULT_STOCK_ID); + $select->where('stock_index.stock_status = ?', Stock::STOCK_IN_STOCK); } return $select; diff --git a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php index ca7298e1beaac560ee66427f2b9d57db7ce21508..ac726192856a5fa555eae6757cd83b16930565ee 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php @@ -6,10 +6,11 @@ namespace Magento\CatalogSearch\Model\Search; -use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; +use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver; +use Magento\CatalogSearch\Model\Search\FilterMapper\FilterStrategyInterface; use Magento\Eav\Model\Config as EavConfig; -use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ResourceConnection as AppResource; use Magento\Framework\DB\Select; @@ -21,12 +22,15 @@ use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface; use Magento\Store\Model\StoreManagerInterface; /** + * Responsibility of the TableMapper is to collect all filters from the search query + * and pass them one by one for processing in the FilterContext, + * which will apply them to the Select * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TableMapper { /** - * @var Resource + * @var AppResource */ private $resource; @@ -40,22 +44,59 @@ class TableMapper */ private $eavConfig; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * @var FilterStrategyInterface + */ + private $filterStrategy; + + /** + * @var AliasResolver + */ + private $aliasResolver; + /** * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @param AppResource $resource * @param StoreManagerInterface $storeManager * @param CollectionFactory $attributeCollectionFactory * @param EavConfig $eavConfig + * @param ScopeConfigInterface $scopeConfig + * @param FilterStrategyInterface $filterStrategy + * @param AliasResolver $aliasResolver */ public function __construct( AppResource $resource, StoreManagerInterface $storeManager, CollectionFactory $attributeCollectionFactory, - EavConfig $eavConfig = null + EavConfig $eavConfig = null, + ScopeConfigInterface $scopeConfig = null, + FilterStrategyInterface $filterStrategy = null, + AliasResolver $aliasResolver = null ) { $this->resource = $resource; $this->storeManager = $storeManager; - $this->eavConfig = $eavConfig !== null ? $eavConfig : ObjectManager::getInstance()->get(EavConfig::class); + + if (null === $eavConfig) { + $eavConfig = ObjectManager::getInstance()->get(EavConfig::class); + } + if (null === $scopeConfig) { + $scopeConfig = ObjectManager::getInstance()->get(ScopeConfigInterface::class); + } + if (null === $filterStrategy) { + $filterStrategy = ObjectManager::getInstance()->get(FilterStrategyInterface::class); + } + if (null === $aliasResolver) { + $aliasResolver = ObjectManager::getInstance()->get(AliasResolver::class); + } + $this->eavConfig = $eavConfig; + $this->scopeConfig = $scopeConfig; + $this->filterStrategy = $filterStrategy; + $this->aliasResolver = $aliasResolver; } /** @@ -66,111 +107,53 @@ class TableMapper */ public function addTables(Select $select, RequestInterface $request) { - $mappedTables = []; - $filters = $this->getFilters($request->getQuery()); + $appliedFilters = []; + $filters = $this->getFiltersFromQuery($request->getQuery()); foreach ($filters as $filter) { - list($alias, $table, $mapOn, $mappedFields, $joinType) = $this->getMappingData($filter); - if (!array_key_exists($alias, $mappedTables)) { - switch ($joinType) { - case \Magento\Framework\DB\Select::INNER_JOIN: - $select->joinInner( - [$alias => $table], - $mapOn, - $mappedFields - ); - break; - case \Magento\Framework\DB\Select::LEFT_JOIN: - $select->joinLeft( - [$alias => $table], - $mapOn, - $mappedFields - ); - break; - default: - throw new \LogicException(__('Unsupported join type: %1', $joinType)); + $alias = $this->aliasResolver->getAlias($filter); + if (!array_key_exists($alias, $appliedFilters)) { + $isApplied = $this->filterStrategy->apply($filter, $select); + if ($isApplied) { + $appliedFilters[$alias] = true; } - $mappedTables[$alias] = $table; } } return $select; } /** + * This method is deprecated. + * Please use \Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver::getAlias() instead. + * + * @deprecated + * @see AliasResolver::getAlias() + * * @param FilterInterface $filter * @return string */ public function getMappingAlias(FilterInterface $filter) { - list($alias) = $this->getMappingData($filter); - return $alias; - } - - /** - * Returns mapping data for field in format: [ - * 'table_alias', - * 'table', - * 'join_condition', - * ['fields'], - * 'joinType' - * ] - * @param FilterInterface $filter - * @return array - */ - private function getMappingData(FilterInterface $filter) - { - $alias = null; - $table = null; - $mapOn = null; - $mappedFields = null; - $field = $filter->getField(); - $joinType = \Magento\Framework\DB\Select::INNER_JOIN; - $fieldToTableMap = $this->getFieldToTableMap($field); - if ($fieldToTableMap) { - list($alias, $table, $mapOn, $mappedFields) = $fieldToTableMap; - $table = $this->resource->getTableName($table); - } elseif ($attribute = $this->getAttributeByCode($field)) { - if ($filter->getType() === FilterInterface::TYPE_TERM - && in_array($attribute->getFrontendInput(), ['select', 'multiselect'], true) - ) { - $joinType = \Magento\Framework\DB\Select::LEFT_JOIN; - $table = $this->resource->getTableName('catalog_product_index_eav'); - $alias = $field . RequestGenerator::FILTER_SUFFIX; - $mapOn = sprintf( - 'search_index.entity_id = %1$s.entity_id AND %1$s.attribute_id = %2$d AND %1$s.store_id = %3$d', - $alias, - $attribute->getId(), - $this->getStoreId() - ); - $mappedFields = []; - } elseif ($attribute->getBackendType() === AbstractAttribute::TYPE_STATIC) { - $table = $attribute->getBackendTable(); - $alias = $field . RequestGenerator::FILTER_SUFFIX; - $mapOn = 'search_index.entity_id = ' . $alias . '.entity_id'; - $mappedFields = null; - } - } - - return [$alias, $table, $mapOn, $mappedFields, $joinType]; + return $this->aliasResolver->getAlias($filter); } /** * @param RequestQueryInterface $query * @return FilterInterface[] */ - private function getFilters($query) + private function getFiltersFromQuery(RequestQueryInterface $query) { $filters = []; switch ($query->getType()) { case RequestQueryInterface::TYPE_BOOL: /** @var \Magento\Framework\Search\Request\Query\BoolExpression $query */ foreach ($query->getMust() as $subQuery) { - $filters = array_merge($filters, $this->getFilters($subQuery)); + $filters = array_merge($filters, $this->getFiltersFromQuery($subQuery)); } foreach ($query->getShould() as $subQuery) { - $filters = array_merge($filters, $this->getFilters($subQuery)); + $filters = array_merge($filters, $this->getFiltersFromQuery($subQuery)); } foreach ($query->getMustNot() as $subQuery) { - $filters = array_merge($filters, $this->getFilters($subQuery)); + $filters = array_merge($filters, $this->getFiltersFromQuery($subQuery)); } break; case RequestQueryInterface::TYPE_FILTER: @@ -219,57 +202,4 @@ class TableMapper } return $filters; } - - /** - * @return int - */ - private function getWebsiteId() - { - return $this->storeManager->getWebsite()->getId(); - } - - /** - * @return int - */ - private function getStoreId() - { - return $this->storeManager->getStore()->getId(); - } - - /** - * @param string $field - * @return array|null - */ - private function getFieldToTableMap($field) - { - $fieldToTableMap = [ - 'price' => [ - 'price_index', - 'catalog_product_index_price', - $this->resource->getConnection()->quoteInto( - 'search_index.entity_id = price_index.entity_id AND price_index.website_id = ?', - $this->getWebsiteId() - ), - [] - ], - 'category_ids' => [ - 'category_ids_index', - 'catalog_category_product_index', - 'search_index.entity_id = category_ids_index.product_id', - [] - ] - ]; - return array_key_exists($field, $fieldToTableMap) ? $fieldToTableMap[$field] : null; - } - - /** - * @param string $field - * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute - * @throws \Magento\Framework\Exception\LocalizedException - */ - private function getAttributeByCode($field) - { - $attribute = $this->eavConfig->getAttribute(Product::ENTITY, $field); - return $attribute; - } } diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ab01d2553a3edcebde8a564a8ca8b8bb8cf2c7dd --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/AliasResolverTest.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Test\Unit\Model\Adapter\Mysql\Filter; + +use Magento\CatalogSearch\Model\Search\RequestGenerator; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class AliasResolverTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver + */ + private $aliasResolver; + + /** + * @inheritDoc + */ + protected function setUp() + { + $objectManagerHelper = new ObjectManagerHelper($this); + $this->aliasResolver = $objectManagerHelper->getObject( + \Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver::class, + [] + ); + } + + /** + * @param string $field + * @param string $expectedAlias + * @dataProvider aliasDataProvider + */ + public function testGetFilterAlias($field, $expectedAlias) + { + $filter = $this->getMockBuilder(\Magento\Framework\Search\Request\Filter\Term::class) + ->setMethods(['getField']) + ->disableOriginalConstructor() + ->getMock(); + $filter->expects($this->once()) + ->method('getField') + ->willReturn($field); + $this->assertSame($expectedAlias, $this->aliasResolver->getAlias($filter)); + } + + /** + * @return array + */ + public function aliasDataProvider() + { + return [ + 'general' => [ + 'field' => 'general', + 'alias' => 'general' . RequestGenerator::FILTER_SUFFIX, + ], + 'price' => [ + 'field' => 'price', + 'alias' => 'price_index', + ], + 'category_ids' => [ + 'field' => 'category_ids', + 'alias' => 'category_ids_index', + ], + ]; + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php index 0949bf6469be92611fbefa4c45962d8255570892..2cd6935586bd816bcc8c1e444b242c3b3f7a1472 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Adapter/Mysql/Filter/PreprocessorTest.php @@ -6,6 +6,7 @@ namespace Magento\CatalogSearch\Test\Unit\Model\Adapter\Mysql\Filter; +use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver; use Magento\Framework\DB\Select; use Magento\Framework\EntityManager\EntityMetadata; use Magento\Framework\Search\Request\FilterInterface; @@ -18,9 +19,9 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject; class PreprocessorTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\CatalogSearch\Model\Search\TableMapper|\PHPUnit_Framework_MockObject_MockObject + * @var AliasResolver|\PHPUnit_Framework_MockObject_MockObject */ - private $tableMapper; + private $aliasResolver; /** * @var \Magento\Framework\DB\Adapter\AdapterInterface|MockObject @@ -141,7 +142,7 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase ) ); - $this->tableMapper = $this->getMockBuilder(\Magento\CatalogSearch\Model\Search\TableMapper::class) + $this->aliasResolver = $this->getMockBuilder(AliasResolver::class) ->disableOriginalConstructor() ->getMock(); $this->metadataPoolMock = $this->getMockBuilder(\Magento\Framework\EntityManager\MetadataPool::class) @@ -164,7 +165,7 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase 'resource' => $resource, 'attributePrefix' => 'attr_', 'metadataPool' => $this->metadataPoolMock, - 'tableMapper' => $this->tableMapper, + 'aliasResolver' => $this->aliasResolver, ] ); } @@ -234,7 +235,7 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase $this->attribute->method('getAttributeCode') ->willReturn('static_attribute'); - $this->tableMapper->expects($this->once())->method('getMappingAlias') + $this->aliasResolver->expects($this->once())->method('getAlias') ->willReturn('attr_table_alias'); $this->filter->expects($this->exactly(3)) ->method('getField') @@ -272,7 +273,7 @@ class PreprocessorTest extends \PHPUnit_Framework_TestCase ->method('getFrontendInput') ->willReturn($frontendInput); - $this->tableMapper->expects($this->once())->method('getMappingAlias') + $this->aliasResolver->expects($this->once())->method('getAlias') ->willReturn('termAttrAlias'); $this->filter->expects($this->exactly(3)) diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9f133b763889bafb4843f7f9f868a3995a842eed --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/FilterMapper/FilterContextTest.php @@ -0,0 +1,236 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogSearch\Test\Unit\Model\Search\FilterMapper; + +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver; +use Magento\CatalogSearch\Model\Search\FilterMapper\ExclusionStrategy; +use Magento\CatalogSearch\Model\Search\FilterMapper\FilterContext; +use Magento\CatalogSearch\Model\Search\FilterMapper\StaticAttributeStrategy; +use Magento\CatalogSearch\Model\Search\FilterMapper\TermDropdownStrategy; +use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Framework\Search\Request\FilterInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +class FilterContextTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FilterContext|\PHPUnit_Framework_MockObject_MockObject + */ + private $filterContext; + + /** + * @var AliasResolver|\PHPUnit_Framework_MockObject_MockObject + */ + private $aliasResolver; + + /** + * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $eavConfig; + + /** + * @var ExclusionStrategy|\PHPUnit_Framework_MockObject_MockObject + */ + private $exclusionStrategy; + + /** + * @var TermDropdownStrategy|\PHPUnit_Framework_MockObject_MockObject + */ + private $termDropdownStrategy; + + /** + * @var StaticAttributeStrategy|\PHPUnit_Framework_MockObject_MockObject + */ + private $staticAttributeStrategy; + + /** + * @var \Magento\Framework\DB\Select + */ + private $select; + + /** + * @inheritDoc + */ + protected function setUp() + { + $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) + ->disableOriginalConstructor() + ->setMethods(['getAttribute']) + ->getMock(); + $this->aliasResolver = $this->getMockBuilder( + AliasResolver::class + ) + ->disableOriginalConstructor() + ->setMethods(['getAlias']) + ->getMock(); + $this->exclusionStrategy = $this->getMockBuilder(ExclusionStrategy::class) + ->disableOriginalConstructor() + ->setMethods(['apply']) + ->getMock(); + $this->termDropdownStrategy = $this->getMockBuilder(TermDropdownStrategy::class) + ->disableOriginalConstructor() + ->setMethods(['apply']) + ->getMock(); + $this->staticAttributeStrategy = $this->getMockBuilder(StaticAttributeStrategy::class) + ->disableOriginalConstructor() + ->setMethods(['apply']) + ->getMock(); + $this->select = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + $objectManager = new ObjectManager($this); + $this->filterContext = $objectManager->getObject( + FilterContext::class, + [ + 'eavConfig' => $this->eavConfig, + 'aliasResolver' => $this->aliasResolver, + 'exclusionStrategy' => $this->exclusionStrategy, + 'termDropdownStrategy' => $this->termDropdownStrategy, + 'staticAttributeStrategy' => $this->staticAttributeStrategy, + ] + ); + } + + public function testApplyOnExclusionFilter() + { + $filter = $this->createFilterMock(); + $this->exclusionStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(true); + $this->eavConfig->expects($this->never())->method('getAttribute'); + $this->assertTrue($this->filterContext->apply($filter, $this->select)); + } + + public function testApplyFilterWithoutAttribute() + { + $filter = $this->createFilterMock('some_field'); + $this->exclusionStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(false); + $this->eavConfig->expects($this->once()) + ->method('getAttribute') + ->with(\Magento\Catalog\Model\Product::ENTITY, 'some_field') + ->willReturn(null); + $this->assertFalse($this->filterContext->apply($filter, $this->select)); + } + + public function testApplyOnTermFilterBySelect() + { + $filter = $this->createFilterMock('select_field', FilterInterface::TYPE_TERM); + $attribute = $this->createAttributeMock('select'); + $this->eavConfig->expects($this->once()) + ->method('getAttribute') + ->with(\Magento\Catalog\Model\Product::ENTITY, 'select_field') + ->willReturn($attribute); + $this->exclusionStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(false); + $this->termDropdownStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(true); + $this->assertTrue($this->filterContext->apply($filter, $this->select)); + } + + public function testApplyOnTermFilterByMultiSelect() + { + $filter = $this->createFilterMock('multiselect_field', FilterInterface::TYPE_TERM); + $attribute = $this->createAttributeMock('multiselect'); + $this->eavConfig->expects($this->once()) + ->method('getAttribute') + ->with(\Magento\Catalog\Model\Product::ENTITY, 'multiselect_field') + ->willReturn($attribute); + $this->exclusionStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(false); + $this->termDropdownStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(true); + $this->assertTrue($this->filterContext->apply($filter, $this->select)); + } + + public function testApplyOnTermFilterByStaticAttribute() + { + $filter = $this->createFilterMock('multiselect_field', FilterInterface::TYPE_TERM); + $attribute = $this->createAttributeMock('text', AbstractAttribute::TYPE_STATIC); + $this->eavConfig->expects($this->once()) + ->method('getAttribute') + ->with(\Magento\Catalog\Model\Product::ENTITY, 'multiselect_field') + ->willReturn($attribute); + $this->exclusionStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(false); + $this->staticAttributeStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(true); + $this->assertTrue($this->filterContext->apply($filter, $this->select)); + } + + public function testApplyOnTermFilterByUnknownAttributeType() + { + $filter = $this->createFilterMock('multiselect_field', FilterInterface::TYPE_TERM); + $attribute = $this->createAttributeMock('text', 'text'); + $this->eavConfig->expects($this->once()) + ->method('getAttribute') + ->with(\Magento\Catalog\Model\Product::ENTITY, 'multiselect_field') + ->willReturn($attribute); + $this->exclusionStrategy->expects($this->once()) + ->method('apply') + ->with($filter, $this->select) + ->willReturn(false); + $this->assertFalse($this->filterContext->apply($filter, $this->select)); + } + + /** + * @param string $field + * @param string $type + * @return FilterInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private function createFilterMock($field = null, $type = null) + { + $filter = $this->getMockBuilder(FilterInterface::class) + ->setMethods(['getField', 'getType']) + ->getMockForAbstractClass(); + $filter->expects($this->any()) + ->method('getField') + ->willReturn($field); + $filter->expects($this->any()) + ->method('getType') + ->willReturn($type); + + return $filter; + } + + /** + * @param string|null $frontendInput + * @param string|null $backendType + * @return Attribute|\PHPUnit_Framework_MockObject_MockObject + */ + private function createAttributeMock($frontendInput = null, $backendType = null) + { + $attribute = $this->getMockBuilder(Attribute::class) + ->disableOriginalConstructor() + ->setMethods(['getFrontendInput', 'getBackendType']) + ->getMock(); + $attribute->expects($this->any()) + ->method('getFrontendInput') + ->willReturn($frontendInput); + $attribute->expects($this->any()) + ->method('getBackendType') + ->willReturn($backendType); + return $attribute; + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php index dd9a556146ab3e40e4e1182f44c959c8260d9c8d..dad4ad8095f5af27fa3ce7cd48b1803c706d80a6 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php @@ -6,6 +6,9 @@ namespace Magento\CatalogSearch\Test\Unit\Model\Search; +use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection; +use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; +use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver; use Magento\Framework\Search\Request\FilterInterface; use Magento\Framework\Search\Request\QueryInterface; use \Magento\Framework\TestFramework\Unit\Helper\ObjectManager; @@ -16,8 +19,10 @@ use \Magento\Framework\TestFramework\Unit\Helper\ObjectManager; */ class TableMapperTest extends \PHPUnit_Framework_TestCase { - const WEBSITE_ID = 4512; - const STORE_ID = 2514; + /** + * @var AliasResolver|\PHPUnit_Framework_MockObject_MockObject + */ + private $aliasResolver; /** * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject @@ -25,7 +30,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase private $eavConfig; /** - * @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection|\PHPUnit_Framework_MockObject_MockObject + * @var Collection|\PHPUnit_Framework_MockObject_MockObject */ private $attributeCollection; @@ -59,11 +64,6 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase */ private $resource; - /** - * @var \Magento\Store\Api\Data\StoreInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $store; - /** * @var \Magento\CatalogSearch\Model\Search\TableMapper */ @@ -76,65 +76,49 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase $this->connection = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class) ->disableOriginalConstructor() ->getMock(); - $this->connection->expects($this->any()) - ->method('quoteInto') - ->willReturnCallback( - function ($query, $expression) { - return str_replace('?', $expression, $query); - } - ); + $this->connection->expects($this->never())->method('quoteInto'); $this->resource = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class) ->disableOriginalConstructor() ->getMock(); - $this->resource->method('getTableName') - ->willReturnCallback( - function ($table) { - return 'prefix_' . $table; - } - ); - $this->resource->expects($this->any()) - ->method('getConnection') - ->willReturn($this->connection); + $this->resource->expects($this->never())->method('getTableName'); + $this->resource->expects($this->never())->method('getConnection'); $this->website = $this->getMockBuilder(\Magento\Store\Api\Data\WebsiteInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->website->expects($this->any()) - ->method('getId') - ->willReturn(self::WEBSITE_ID); - $this->store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $this->store->expects($this->any()) - ->method('getId') - ->willReturn(self::STORE_ID); + $this->website->expects($this->never())->method('getId'); + $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) ->disableOriginalConstructor() ->getMock(); - $this->storeManager->expects($this->any()) - ->method('getWebsite') - ->willReturn($this->website); - $this->storeManager->expects($this->any()) - ->method('getStore') - ->willReturn($this->store); - $this->attributeCollection = $this->getMockBuilder( - \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection::class - ) + $this->storeManager->expects($this->never())->method('getWebsite'); + $this->storeManager->expects($this->never())->method('getStore'); + + $this->attributeCollection = $this->getMockBuilder(Collection::class) ->disableOriginalConstructor() ->getMock(); - $attributeCollectionFactory = $this->getMockBuilder( - \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory::class - ) + $attributeCollectionFactory = $this->getMockBuilder(CollectionFactory::class) ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); $attributeCollectionFactory->expects($this->never()) ->method('create'); + $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) ->setMethods(['getAttribute']) ->disableOriginalConstructor() ->getMock(); + + $this->aliasResolver = $this->getMockBuilder(AliasResolver::class) + ->disableOriginalConstructor() + ->getMock(); + $this->aliasResolver->expects($this->any()) + ->method('getAlias') + ->willReturnCallback(function (FilterInterface $filter) { + return $filter->getField() . '_alias'; + }); + $this->target = $objectManager->getObject( \Magento\CatalogSearch\Model\Search\TableMapper::class, [ @@ -142,6 +126,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase 'storeManager' => $this->storeManager, 'attributeCollectionFactory' => $attributeCollectionFactory, 'eavConfig' => $this->eavConfig, + 'aliasResolver' => $this->aliasResolver, ] ); @@ -160,14 +145,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->once()) ->method('getQuery') ->willReturn($query); - $this->select->expects($this->once()) - ->method('joinInner') - ->with( - ['price_index' => 'prefix_catalog_product_index_price'], - 'search_index.entity_id = price_index.entity_id AND price_index.website_id = ' . self::WEBSITE_ID, - [] - ) - ->willReturnSelf(); + $select = $this->target->addTables($this->select, $this->request); $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select'); } @@ -176,18 +154,10 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase { $priceFilter = $this->createRangeFilter('static'); $query = $this->createFilterQuery($priceFilter); - $this->createAttributeMock('static', 'static', 'backend_table', 0, 'select'); $this->request->expects($this->once()) ->method('getQuery') ->willReturn($query); - $this->select->expects($this->once()) - ->method('joinInner') - ->with( - ['static_filter' => 'backend_table'], - 'search_index.entity_id = static_filter.entity_id', - null - ) - ->willReturnSelf(); + $select = $this->target->addTables($this->select, $this->request); $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select'); } @@ -199,46 +169,25 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->once()) ->method('getQuery') ->willReturn($query); - $this->select->expects($this->once()) - ->method('joinInner') - ->with( - ['category_ids_index' => 'prefix_catalog_category_product_index'], - 'search_index.entity_id = category_ids_index.product_id', - [] - ) - ->willReturnSelf(); + $select = $this->target->addTables($this->select, $this->request); $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select'); } public function testAddTermFilter() { - $this->createAttributeMock('color', null, null, 132, 'select', 0); $categoryIdsFilter = $this->createTermFilter('color'); $query = $this->createFilterQuery($categoryIdsFilter); $this->request->expects($this->once()) ->method('getQuery') ->willReturn($query); - $this->select->expects($this->once()) - ->method('joinLeft') - ->with( - ['color_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = color_filter.entity_id' - . ' AND color_filter.attribute_id = 132' - . ' AND color_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); + $select = $this->target->addTables($this->select, $this->request); $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select'); } public function testAddBoolQueryWithTermFiltersInside() { - $this->createAttributeMock('must1', null, null, 101, 'select', 0); - $this->createAttributeMock('should1', null, null, 102, 'select', 1); - $this->createAttributeMock('mustNot1', null, null, 103, 'select', 2); - $query = $this->createBoolQuery( [ $this->createFilterQuery($this->createTermFilter('must1')), @@ -253,45 +202,13 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->once()) ->method('getQuery') ->willReturn($query); - $this->select->expects($this->at(0)) - ->method('joinLeft') - ->with( - ['must1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = must1_filter.entity_id' - . ' AND must1_filter.attribute_id = 101' - . ' AND must1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(1)) - ->method('joinLeft') - ->with( - ['should1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = should1_filter.entity_id' - . ' AND should1_filter.attribute_id = 102' - . ' AND should1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(2)) - ->method('joinLeft') - ->with( - ['mustNot1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = mustNot1_filter.entity_id' - . ' AND mustNot1_filter.attribute_id = 103' - . ' AND mustNot1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); + $select = $this->target->addTables($this->select, $this->request); $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select'); } public function testAddBoolQueryWithTermAndPriceFiltersInside() { - $this->createAttributeMock('must1', null, null, 101, 'select', 0); - $this->createAttributeMock('should1', null, null, 102, 'select', 1); - $this->createAttributeMock('mustNot1', null, null, 103, 'select', 2); $query = $this->createBoolQuery( [ $this->createFilterQuery($this->createTermFilter('must1')), @@ -307,53 +224,13 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->once()) ->method('getQuery') ->willReturn($query); - $this->select->expects($this->at(0)) - ->method('joinLeft') - ->with( - ['must1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = must1_filter.entity_id' - . ' AND must1_filter.attribute_id = 101' - . ' AND must1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(1)) - ->method('joinInner') - ->with( - ['price_index' => 'prefix_catalog_product_index_price'], - 'search_index.entity_id = price_index.entity_id AND price_index.website_id = ' . self::WEBSITE_ID, - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(2)) - ->method('joinLeft') - ->with( - ['should1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = should1_filter.entity_id' - . ' AND should1_filter.attribute_id = 102' - . ' AND should1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(3)) - ->method('joinLeft') - ->with( - ['mustNot1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = mustNot1_filter.entity_id' - . ' AND mustNot1_filter.attribute_id = 103' - . ' AND mustNot1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); + $select = $this->target->addTables($this->select, $this->request); $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select'); } public function testAddBoolFilterWithTermFiltersInside() { - $this->createAttributeMock('must1', null, null, 101, 'select', 0); - $this->createAttributeMock('should1', null, null, 102, 'select', 1); - $this->createAttributeMock('mustNot1', null, null, 103, 'select', 2); $query = $this->createFilterQuery( $this->createBoolFilter( [ @@ -370,45 +247,13 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->once()) ->method('getQuery') ->willReturn($query); - $this->select->expects($this->at(0)) - ->method('joinLeft') - ->with( - ['must1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = must1_filter.entity_id' - . ' AND must1_filter.attribute_id = 101' - . ' AND must1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(1)) - ->method('joinLeft') - ->with( - ['should1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = should1_filter.entity_id' - . ' AND should1_filter.attribute_id = 102' - . ' AND should1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(2)) - ->method('joinLeft') - ->with( - ['mustNot1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = mustNot1_filter.entity_id' - . ' AND mustNot1_filter.attribute_id = 103' - . ' AND mustNot1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); + $select = $this->target->addTables($this->select, $this->request); $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select'); } public function testAddBoolFilterWithBoolFiltersInside() { - $this->createAttributeMock('must1', null, null, 101, 'select', 0); - $this->createAttributeMock('should1', null, null, 102, 'select', 1); - $this->createAttributeMock('mustNot1', null, null, 103, 'select', 2); $query = $this->createFilterQuery( $this->createBoolFilter( [ @@ -425,36 +270,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->once()) ->method('getQuery') ->willReturn($query); - $this->select->expects($this->at(0)) - ->method('joinLeft') - ->with( - ['must1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = must1_filter.entity_id' - . ' AND must1_filter.attribute_id = 101' - . ' AND must1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(1)) - ->method('joinLeft') - ->with( - ['should1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = should1_filter.entity_id' - . ' AND should1_filter.attribute_id = 102' - . ' AND should1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); - $this->select->expects($this->at(2)) - ->method('joinLeft') - ->with( - ['mustNot1_filter' => 'prefix_catalog_product_index_eav'], - 'search_index.entity_id = mustNot1_filter.entity_id' - . ' AND mustNot1_filter.attribute_id = 103' - . ' AND mustNot1_filter.store_id = 2514', - [] - ) - ->willReturnSelf(); + $select = $this->target->addTables($this->select, $this->request); $this->assertEquals($this->select, $select, 'Returned results isn\'t equal to passed select'); } @@ -472,6 +288,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->willReturn(QueryInterface::TYPE_FILTER); $query->method('getReference') ->willReturn($filter); + return $query; } @@ -495,6 +312,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->willReturn($should); $query->method('getMustNot') ->willReturn($mustNot); + return $query; } @@ -518,6 +336,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->willReturn($should); $query->method('getMustNot') ->willReturn($mustNot); + return $query; } @@ -532,6 +351,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase FilterInterface::TYPE_RANGE, $field ); + return $filter; } @@ -546,6 +366,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase FilterInterface::TYPE_TERM, $field ); + return $filter; } @@ -564,40 +385,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->willReturn($type); $filter->method('getField') ->willReturn($field); - return $filter; - } - /** - * @param string $code - * @param string $backendType - * @param string $backendTable - * @param int $attributeId - * @param string $frontendInput - * @param int $positionInCollection - */ - private function createAttributeMock( - $code, - $backendType = null, - $backendTable = null, - $attributeId = 120, - $frontendInput = 'select', - $positionInCollection = 0 - ) { - $attribute = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) - ->setMethods(['getBackendType', 'getBackendTable', 'getId', 'getFrontendInput']) - ->disableOriginalConstructor() - ->getMock(); - $attribute->method('getId') - ->willReturn($attributeId); - $attribute->method('getBackendType') - ->willReturn($backendType); - $attribute->method('getBackendTable') - ->willReturn($backendTable); - $attribute->method('getFrontendInput') - ->willReturn($frontendInput); - $this->eavConfig->expects($this->at($positionInCollection)) - ->method('getAttribute') - ->with(\Magento\Catalog\Model\Product::ENTITY, $code) - ->willReturn($attribute); + return $filter; } } diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index 49756420bd2308cd1f8326f474395b6209c7450c..313cc99881a318799c15488fa742151e26db18ec 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog-search", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-search": "100.2.*", diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml index f62b4e47767a25230c5c2ad8372f99acc6bda2eb..7e9451f9b83e7ada30455509b8fd686a0c251705 100644 --- a/app/code/Magento/CatalogSearch/etc/di.xml +++ b/app/code/Magento/CatalogSearch/etc/di.xml @@ -11,6 +11,7 @@ <preference for="Magento\Framework\Search\Adapter\Mysql\Filter\PreprocessorInterface" type="Magento\CatalogSearch\Model\Adapter\Mysql\Filter\Preprocessor" /> <preference for="Magento\Framework\Search\Dynamic\DataProviderInterface" type="Magento\CatalogSearch\Model\Adapter\Mysql\Dynamic\DataProvider" /> <preference for="Magento\Framework\Search\Adapter\OptionsInterface" type="Magento\CatalogSearch\Model\Adapter\Options" /> + <preference for="Magento\CatalogSearch\Model\Search\FilterMapper\FilterStrategyInterface" type="Magento\CatalogSearch\Model\Search\FilterMapper\FilterContext"/> <type name="Magento\CatalogSearch\Model\Indexer\IndexerHandlerFactory"> <arguments> <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument> diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index 8fd54cbc8ee8319f625cd6320954a0c821bf9a52..a5f66cd09dda49086434a4dc73b073fe7f0ee9c3 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog-url-rewrite", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-backend": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-catalog-import-export": "100.2.*", diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json index 330f46176286c70822a32762dccfed157a2ce358..198e54db32d888dfc32eafd33f5c6b3ca45da870 100644 --- a/app/code/Magento/CatalogWidget/composer.json +++ b/app/code/Magento/CatalogWidget/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-catalog-widget", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-widget": "100.2.*", "magento/module-backend": "100.2.*", diff --git a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml index 080714bd228de24f0aa69cae014cb554ef814c53..212846aaa01d7efd067eb14a546b8dcb3467fc1f 100644 --- a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml +++ b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml @@ -15,7 +15,6 @@ $mode = 'grid'; $image = 'new_products_content_widget_grid'; - $title = $block->getTitle() ? __($block->getTitle()) : ''; $items = $block->getProductCollection()->getItems(); $showWishlist = true; @@ -25,9 +24,9 @@ $description = false; ?> <div class="block widget block-products-list <?php /* @noEscape */ echo $mode; ?>"> - <?php if ($title): ?> + <?php if ($block->getTitle()): ?> <div class="block-title"> - <strong><?php echo $block->escapeHtml($title); ?></strong> + <strong><?php echo $block->escapeHtml(__($block->getTitle())); ?></strong> </div> <?php endif ?> <div class="block-content"> @@ -64,27 +63,23 @@ <div class="actions-primary"> <?php if ($_item->isSaleable()): ?> <?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?> - <button class="action tocart primary" - data-mage-init='{"redirectUrl":{"url":"<?php echo $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}' - type="button" title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>"> - <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> + <button class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?php echo $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}' type="button" title="<?php echo $block->escapeHtmlAttr(__('Add to Cart')) ?>"> + <span><?php echo $block->escapeHtml(__('Add to Cart')) ?></span> </button> <?php else: ?> <?php $postDataHelper = $this->helper('Magento\Framework\Data\Helper\PostHelper'); $postData = $postDataHelper->getPostData($block->getAddToCartUrl($_item), ['product' => $_item->getEntityId()]) ?> - <button class="action tocart primary" - data-post='<?php /* @noEscape */ echo $postData; ?>' - type="button" title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>"> - <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> + <button class="action tocart primary" data-post='<?php /* @noEscape */ echo $postData; ?>' type="button" title="<?php echo $block->escapeHtmlAttr(__('Add to Cart')) ?>"> + <span><?php echo $block->escapeHtml(__('Add to Cart')) ?></span> </button> <?php endif; ?> <?php else: ?> <?php if ($_item->getIsSalable()): ?> - <div class="stock available"><span><?php /* @escapeNotVerified */ echo __('In stock') ?></span></div> + <div class="stock available"><span><?php echo $block->escapeHtml(__('In stock')) ?></span></div> <?php else: ?> - <div class="stock unavailable"><span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span></div> + <div class="stock unavailable"><span><?php echo $block->escapeHtml(__('Out of stock')) ?></span></div> <?php endif; ?> <?php endif; ?> </div> @@ -93,18 +88,14 @@ <div class="actions-secondary" data-role="add-to-links"> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow() && $showWishlist): ?> <a href="#" - data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($_item); ?>' - class="action towishlist" data-action="add-to-wishlist" - title="<?php /* @escapeNotVerified */ echo __('Add to Wish List') ?>"> - <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span> + data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($_item); ?>' class="action towishlist" data-action="add-to-wishlist" title="<?php echo $block->escapeHtmlAttr(__('Add to Wish List')) ?>"> + <span><?php echo $block->escapeHtml(__('Add to Wish List')) ?></span> </a> <?php endif; ?> <?php if ($block->getAddToCompareUrl() && $showCompare): ?> <?php $compareHelper = $this->helper('Magento\Catalog\Helper\Product\Compare');?> - <a href="#" class="action tocompare" - data-post='<?php /* @noEscape */ echo $compareHelper->getPostDataParams($_item);?>' - title="<?php /* @escapeNotVerified */ echo __('Add to Compare') ?>"> - <span><?php /* @escapeNotVerified */ echo __('Add to Compare') ?></span> + <a href="#" class="action tocompare" data-post='<?php /* @noEscape */ echo $compareHelper->getPostDataParams($_item);?>' title="<?php echo $block->escapeHtmlAttr(__('Add to Compare')) ?>"> + <span><?php echo $block->escapeHtml(__('Add to Compare')) ?></span> </a> <?php endif; ?> </div> diff --git a/app/code/Magento/Checkout/Controller/Cart/Add.php b/app/code/Magento/Checkout/Controller/Cart/Add.php index fddfa63b5983e5f508f5211c19f8980d56aafc34..bfbf0008bf5892067aaa7b0ba53ca1bbb7632339 100644 --- a/app/code/Magento/Checkout/Controller/Cart/Add.php +++ b/app/code/Magento/Checkout/Controller/Cart/Add.php @@ -84,6 +84,7 @@ class Add extends \Magento\Checkout\Controller\Cart } $params = $this->getRequest()->getParams(); + try { if (isset($params['qty'])) { $filter = new \Zend_Filter_LocalizedToNormalized( diff --git a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php index 2b3f65728068bee22560f06943f88eea69e36d79..0498b22d550e7f8c78cc2af53819a31aebeb3d47 100644 --- a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php +++ b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php @@ -90,26 +90,17 @@ class CouponPost extends \Magento\Checkout\Controller\Cart if ($codeLength) { $escaper = $this->_objectManager->get(\Magento\Framework\Escaper::class); + $coupon = $this->couponFactory->create(); + $coupon->load($couponCode, 'code'); if (!$itemsCount) { - if ($isCodeLengthValid) { - $coupon = $this->couponFactory->create(); - $coupon->load($couponCode, 'code'); - if ($coupon->getId()) { - $this->_checkoutSession->getQuote()->setCouponCode($couponCode)->save(); - $this->messageManager->addSuccess( - __( - 'You used coupon code "%1".', - $escaper->escapeHtml($couponCode) - ) - ); - } else { - $this->messageManager->addError( - __( - 'The coupon code "%1" is not valid.', - $escaper->escapeHtml($couponCode) - ) - ); - } + if ($isCodeLengthValid && $coupon->getId()) { + $this->_checkoutSession->getQuote()->setCouponCode($couponCode)->save(); + $this->messageManager->addSuccess( + __( + 'You used coupon code "%1".', + $escaper->escapeHtml($couponCode) + ) + ); } else { $this->messageManager->addError( __( @@ -119,7 +110,7 @@ class CouponPost extends \Magento\Checkout\Controller\Cart ); } } else { - if ($isCodeLengthValid && $couponCode == $cartQuote->getCouponCode()) { + if ($isCodeLengthValid && $coupon->getId() && $couponCode == $cartQuote->getCouponCode()) { $this->messageManager->addSuccess( __( 'You used coupon code "%1".', diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php index 4ce23c9c7f7090980d48f4c3bb231d4214a7e893..236c716f572d91e4bd4b88366414480567ccabc0 100644 --- a/app/code/Magento/Checkout/Model/Cart.php +++ b/app/code/Magento/Checkout/Model/Cart.php @@ -91,6 +91,11 @@ class Cart extends DataObject implements CartInterface */ protected $productRepository; + /** + * @var \Magento\Checkout\Model\Cart\RequestInfoFilterInterface + */ + private $requestInfoFilter; + /** * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig @@ -315,6 +320,7 @@ class Cart extends DataObject implements CartInterface * * @param \Magento\Framework\DataObject|int|array $requestInfo * @return \Magento\Framework\DataObject + * @throws \Magento\Framework\Exception\LocalizedException */ protected function _getProductRequest($requestInfo) { @@ -322,11 +328,14 @@ class Cart extends DataObject implements CartInterface $request = $requestInfo; } elseif (is_numeric($requestInfo)) { $request = new \Magento\Framework\DataObject(['qty' => $requestInfo]); - } else { + } elseif (is_array($requestInfo)) { $request = new \Magento\Framework\DataObject($requestInfo); + } else { + throw new \Magento\Framework\Exception\LocalizedException( + __('We found an invalid request for adding product to quote.') + ); } - - !$request->hasFormKey() ?: $request->unsFormKey(); + $this->getRequestInfoFilter()->filter($request); return $request; } @@ -722,4 +731,19 @@ class Cart extends DataObject implements CartInterface $this->_checkoutSession->setLastAddedProductId($productId); return $result; } + + /** + * Getter for RequestInfoFilter + * + * @deprecated + * @return \Magento\Checkout\Model\Cart\RequestInfoFilterInterface + */ + private function getRequestInfoFilter() + { + if ($this->requestInfoFilter === null) { + $this->requestInfoFilter = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Checkout\Model\Cart\RequestInfoFilterInterface::class); + } + return $this->requestInfoFilter; + } } diff --git a/app/code/Magento/Checkout/Model/Cart/RequestInfoFilter.php b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..10f3b81386b8febcee8f2b49ee4acd6242d1e5e8 --- /dev/null +++ b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilter.php @@ -0,0 +1,44 @@ +<?php +/** + * + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Checkout\Model\Cart; + +/** + * Class RequestInfoFilter used for filtering data from a request + */ +class RequestInfoFilter implements RequestInfoFilterInterface +{ + /** + * @var array $params + */ + private $filterList; + + /** + * @param array $filterList + */ + public function __construct( + array $filterList = [] + ) { + $this->filterList = $filterList; + } + + /** + * Filters the data with values from filterList + * + * @param \Magento\Framework\DataObject $params + * @return $this + */ + public function filter(\Magento\Framework\DataObject $params) + { + foreach ($this->filterList as $filterKey) { + /** @var string $filterKey */ + if ($params->hasData($filterKey)) { + $params->unsetData($filterKey); + } + } + return $this; + } +} diff --git a/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterComposite.php b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterComposite.php new file mode 100644 index 0000000000000000000000000000000000000000..2ef24c0a5f28a198be28cbb4fc0ba212ebbd9097 --- /dev/null +++ b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterComposite.php @@ -0,0 +1,41 @@ +<?php +/** + * + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Checkout\Model\Cart; + +/** + * Class RequestInfoFilterComposite + */ +class RequestInfoFilterComposite implements RequestInfoFilterInterface +{ + /** + * @var RequestInfoFilter[] $params + */ + private $filters = []; + + /** + * @param RequestInfoFilter[] $filters + */ + public function __construct( + $filters = [] + ) { + $this->filters = $filters; + } + + /** + * Loops through all leafs of the composite and calls filter method + * + * @param \Magento\Framework\DataObject $params + * @return $this + */ + public function filter(\Magento\Framework\DataObject $params) + { + foreach ($this->filters as $filter) { + $filter->filter($params); + } + return $this; + } +} diff --git a/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterInterface.php b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..4bd268f6c896e149bf042ccdbaaa85e411ec6153 --- /dev/null +++ b/app/code/Magento/Checkout/Model/Cart/RequestInfoFilterInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Checkout\Model\Cart; + +/** + * Interface RequestInfoFilterInterface used by composite and leafs to implement filtering + */ +interface RequestInfoFilterInterface +{ + /** + * Filters the data object by an array of parameters + * + * @param \Magento\Framework\DataObject $params + * @return RequestInfoFilterInterface + */ + public function filter(\Magento\Framework\DataObject $params); +} diff --git a/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php b/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php index b07e90384c1647b51d59405022bb63a0b8e108d3..f2ad294d06cbe45d0b5d77ebe8658d546d27efd3 100644 --- a/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php +++ b/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php @@ -9,6 +9,9 @@ namespace Magento\Checkout\Model; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Framework\Exception\CouldNotSaveException; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPaymentInformationManagementInterface { @@ -42,6 +45,11 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa */ protected $cartRepository; + /** + * @var \Psr\Log\LoggerInterface + */ + private $logger; + /** * @param \Magento\Quote\Api\GuestBillingAddressManagementInterface $billingAddressManagement * @param \Magento\Quote\Api\GuestPaymentMethodManagementInterface $paymentMethodManagement @@ -79,7 +87,13 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa $this->savePaymentInformation($cartId, $email, $paymentMethod, $billingAddress); try { $orderId = $this->cartManagement->placeOrder($cartId); + } catch (\Magento\Framework\Exception\LocalizedException $e) { + throw new CouldNotSaveException( + __($e->getMessage()), + $e + ); } catch (\Exception $e) { + $this->getLogger()->critical($e); throw new CouldNotSaveException( __('An error occurred on the server. Please try to place the order again.'), $e @@ -117,4 +131,18 @@ class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPa $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id'); return $this->paymentInformationManagement->getPaymentInformation($quoteIdMask->getQuoteId()); } + + /** + * Get logger instance + * + * @return \Psr\Log\LoggerInterface + * @deprecated + */ + private function getLogger() + { + if (!$this->logger) { + $this->logger = \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class); + } + return $this->logger; + } } diff --git a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php index 140917dcdfeff22eaa73b9a1dc928d5d83f6ccd5..79e76feb4366190cb1d81389e7c54ac4f97cca9e 100644 --- a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php +++ b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php @@ -7,6 +7,9 @@ namespace Magento\Checkout\Model; use Magento\Framework\Exception\CouldNotSaveException; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInformationManagementInterface { /** @@ -34,6 +37,11 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor */ protected $cartTotalsRepository; + /** + * @var \Psr\Log\LoggerInterface + */ + private $logger; + /** * @param \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement * @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement @@ -67,7 +75,13 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor $this->savePaymentInformation($cartId, $paymentMethod, $billingAddress); try { $orderId = $this->cartManagement->placeOrder($cartId); + } catch (\Magento\Framework\Exception\LocalizedException $e) { + throw new CouldNotSaveException( + __($e->getMessage()), + $e + ); } catch (\Exception $e) { + $this->getLogger()->critical($e); throw new CouldNotSaveException( __('An error occurred on the server. Please try to place the order again.'), $e @@ -102,4 +116,18 @@ class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInfor $paymentDetails->setTotals($this->cartTotalsRepository->get($cartId)); return $paymentDetails; } + + /** + * Get logger instance + * + * @return \Psr\Log\LoggerInterface + * @deprecated + */ + private function getLogger() + { + if (!$this->logger) { + $this->logger = \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class); + } + return $this->logger; + } } diff --git a/app/code/Magento/Checkout/Test/Unit/Controller/Cart/CouponPostTest.php b/app/code/Magento/Checkout/Test/Unit/Controller/Cart/CouponPostTest.php index 16ffb7c2b1437da5e7ffadcc6ebe2fc4b3c479d3..93100df3d8c32182912d59f96f9149200f5f0139 100644 --- a/app/code/Magento/Checkout/Test/Unit/Controller/Cart/CouponPostTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Controller/Cart/CouponPostTest.php @@ -69,6 +69,16 @@ class CouponPostTest extends \PHPUnit_Framework_TestCase */ protected $quoteRepository; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $redirect; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $redirectFactory; + /** * @return void */ @@ -204,6 +214,12 @@ class CouponPostTest extends \PHPUnit_Framework_TestCase ->method('getCouponCode') ->willReturn('OLDCODE'); + $coupon = $this->getMock(\Magento\SalesRule\Model\Coupon::class, [], [], '', false); + $this->couponFactory->expects($this->once()) + ->method('create') + ->willReturn($coupon); + $coupon->expects($this->once())->method('load')->willReturnSelf(); + $coupon->expects($this->once())->method('getId')->willReturn(1); $this->quote->expects($this->any()) ->method('getItemsCount') ->willReturn(1); diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterCompositeTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterCompositeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6c758cf4661fdab253a58b04f70969dc845e89d1 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterCompositeTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Checkout\Test\Unit\Model\Cart; + +/** + * Class RequestInfoFilterTest + */ +class RequestInfoFilterCompositeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Checkout\Model\Cart\RequestInfoFilterComposite + */ + protected $model; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManager; + + /** + * Setup the test + */ + protected function setUp() + { + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $requestInfoFilterMock1 = $this->getMock( + \Magento\Checkout\Model\Cart\RequestInfoFilter::class, + ['filter'], + [], + '', + false + ); + $requestInfoFilterMock2 = $this->getMock( + \Magento\Checkout\Model\Cart\RequestInfoFilter::class, + ['filter'], + [], + '', + false + ); + + $requestInfoFilterMock1->expects($this->atLeastOnce()) + ->method('filter'); + $requestInfoFilterMock2->expects($this->atLeastOnce()) + ->method('filter'); + + $filterList = [ $requestInfoFilterMock1, $requestInfoFilterMock2]; + + $this->model = $this->objectManager->getObject( + \Magento\Checkout\Model\Cart\RequestInfoFilterComposite::class, + [ + 'filters' => $filterList, + ] + ); + } + + /** + * Test Filter method + */ + public function testFilter() + { + /** @var \Magento\Framework\DataObject $params */ + $params = $this->objectManager->getObject( + \Magento\Framework\DataObject::class, + ['data' => ['abc' => 1, 'efg' => 1, 'xyz' => 1]] + ); + $result = $this->model->filter($params); + $this->assertEquals($this->model, $result); + } +} diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cd6ca330da1b2d7252b8911f1820d7bc217d3561 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestInfoFilterTest.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Checkout\Test\Unit\Model\Cart; + +/** + * Class RequestInfoFilterTest + */ +class RequestInfoFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Checkout\Model\Cart\RequestInfoFilter + */ + protected $model; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManager; + + /** + * Setup the test + */ + protected function setUp() + { + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->model = $this->objectManager->getObject( + \Magento\Checkout\Model\Cart\RequestInfoFilter::class, + [ + 'filterList' => ['efg', 'xyz'], + ] + ); + } + + /** + * Test Filter method + */ + public function testFilter() + { + /** @var \Magento\Framework\DataObject $params */ + $params = $this->objectManager->getObject( + \Magento\Framework\DataObject::class, + ['data' => ['abc' => 1, 'efg' => 1, 'xyz' => 1]] + ); + $result = $this->model->filter($params); + $this->assertEquals($this->model, $result); + $this->assertEquals(['abc' => 1], $params->convertToArray()); + } +} diff --git a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php index 199e6692e68d1777c382c8125391cac88326a549..9984fe12d3792e95f0b29d0d2c71ff36b37a5897 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/CartTest.php @@ -29,7 +29,7 @@ class CartTest extends \PHPUnit_Framework_TestCase */ protected $customerSessionMock; - /** @var \Magento\CatalogInventory\Api\StockItem|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogInventory\Api\Data\StockItemInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $stockItemMock; /** @@ -57,16 +57,39 @@ class CartTest extends \PHPUnit_Framework_TestCase */ protected $stockState; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $productRepository; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $requestInfoFilterMock; + protected function setUp() { $this->checkoutSessionMock = $this->getMock(\Magento\Checkout\Model\Session::class, [], [], '', false); $this->customerSessionMock = $this->getMock(\Magento\Customer\Model\Session::class, [], [], '', false); $this->scopeConfigMock = $this->getMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); + $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false); + $this->eventManagerMock = $this->getMock(\Magento\Framework\Event\ManagerInterface::class); + $this->storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); + $this->productRepository = $this->getMock(\Magento\Catalog\Api\ProductRepositoryInterface::class); $this->stockRegistry = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockRegistry::class) ->disableOriginalConstructor() ->setMethods(['getStockItem', '__wakeup']) ->getMock(); - $this->stockItemMock = $this->getMock( \Magento\CatalogInventory\Model\Stock\Item::class, ['getMinSaleQty', '__wakeup'], @@ -74,7 +97,6 @@ class CartTest extends \PHPUnit_Framework_TestCase '', false ); - $this->stockState = $this->getMock( \Magento\CatalogInventory\Model\StockState::class, ['suggestQty', '__wakeup'], @@ -82,12 +104,22 @@ class CartTest extends \PHPUnit_Framework_TestCase '', false ); + $this->storeMock = + $this->getMock(\Magento\Store\Model\Store::class, ['getWebsiteId', 'getId', '__wakeup'], [], '', false); + $this->requestInfoFilterMock = $this->getMock(\Magento\Checkout\Model\Cart\RequestInfoFilterInterface::class); $this->stockRegistry->expects($this->any()) ->method('getStockItem') ->will($this->returnValue($this->stockItemMock)); - $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false); - $this->eventManagerMock = $this->getMock(\Magento\Framework\Event\ManagerInterface::class); + $this->storeMock->expects($this->any()) + ->method('getWebsiteId') + ->will($this->returnValue(10)); + $this->storeMock->expects($this->any()) + ->method('getId') + ->will($this->returnValue(10)); + $this->storeManagerMock->expects($this->any()) + ->method('getStore') + ->will($this->returnValue($this->storeMock)); $this->objectManagerHelper = new ObjectManagerHelper($this); $this->cart = $this->objectManagerHelper->getObject( @@ -98,9 +130,14 @@ class CartTest extends \PHPUnit_Framework_TestCase 'stockRegistry' => $this->stockRegistry, 'stockState' => $this->stockState, 'customerSession' => $this->customerSessionMock, - 'eventManager' => $this->eventManagerMock + 'eventManager' => $this->eventManagerMock, + 'storeManager' => $this->storeManagerMock, + 'productRepository' => $this->productRepository ] ); + + $this->objectManagerHelper + ->setBackwardCompatibleProperty($this->cart, 'requestInfoFilter', $this->requestInfoFilterMock); } public function testSuggestItemsQty() @@ -169,10 +206,17 @@ class CartTest extends \PHPUnit_Framework_TestCase */ public function prepareQuoteItemMock($itemId) { - $store = $this->getMock(\Magento\Store\Model\Store::class, ['getWebsiteId', '__wakeup'], [], '', false); + $store = $this->getMock(\Magento\Store\Model\Store::class, ['getId', '__wakeup'], [], '', false); $store->expects($this->any()) ->method('getWebsiteId') ->will($this->returnValue(10)); + $store->expects($this->any()) + ->method('getId') + ->will($this->returnValue(10)); + $this->storeManagerMock->expects($this->any()) + ->method('getStore') + ->will($this->returnValue($store)); + switch ($itemId) { case 2: $product = $this->getMock( @@ -255,4 +299,162 @@ class CartTest extends \PHPUnit_Framework_TestCase ['useQty' => false] ]; } + + /** + * Test successful scenarios for AddProduct + * + * @param int|\Magento\Catalog\Model\Product $productInfo + * @param \Magento\Framework\DataObject|int|array $requestInfo + * @dataProvider addProductDataProvider + */ + public function testAddProduct($productInfo, $requestInfo) + { + $product = $this->getMock( + \Magento\Catalog\Model\Product::class, + ['getStore', 'getWebsiteIds', 'getProductUrl', 'getId', '__wakeup'], + [], + '', + false + ); + $product->expects($this->any()) + ->method('getId') + ->will($this->returnValue(4)); + $product->expects($this->once()) + ->method('getStore') + ->will($this->returnValue($this->storeMock)); + $product->expects($this->any()) + ->method('getWebsiteIds') + ->will($this->returnValue([10])); + $product->expects($this->any()) + ->method('getProductUrl') + ->will($this->returnValue('url')); + $this->productRepository->expects($this->any()) + ->method('getById') + ->will($this->returnValue($product)); + $this->quoteMock->expects($this->once()) + ->method('addProduct') + ->will($this->returnValue(1)); + $this->checkoutSessionMock->expects($this->once()) + ->method('getQuote') + ->will($this->returnValue($this->quoteMock)); + + $this->eventManagerMock->expects($this->at(0))->method('dispatch')->with( + 'checkout_cart_product_add_after', + ['quote_item' => 1, 'product' => $product] + ); + + if (!$productInfo) { + $productInfo = $product; + } + $result = $this->cart->addProduct($productInfo, $requestInfo); + $this->assertSame($this->cart, $result); + } + + /** + * Test exception on adding product for AddProduct + * + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testAddProductException() + { + $product = $this->getMock( + \Magento\Catalog\Model\Product::class, + ['getStore', 'getWebsiteIds', 'getProductUrl', 'getId', '__wakeup'], + [], + '', + false + ); + $product->expects($this->any()) + ->method('getId') + ->will($this->returnValue(4)); + $product->expects($this->once()) + ->method('getStore') + ->will($this->returnValue($this->storeMock)); + $product->expects($this->any()) + ->method('getWebsiteIds') + ->will($this->returnValue([10])); + $product->expects($this->any()) + ->method('getProductUrl') + ->will($this->returnValue('url')); + $this->productRepository->expects($this->any()) + ->method('getById') + ->will($this->returnValue($product)); + $this->quoteMock->expects($this->once()) + ->method('addProduct') + ->will($this->returnValue('error')); + $this->checkoutSessionMock->expects($this->once()) + ->method('getQuote') + ->will($this->returnValue($this->quoteMock)); + + $this->eventManagerMock->expects($this->never())->method('dispatch')->with( + 'checkout_cart_product_add_after', + ['quote_item' => 1, 'product' => $product] + ); + $this->setExpectedException(\Magento\Framework\Exception\LocalizedException::class); + $this->cart->addProduct(4, 4); + } + + /** + * Test bad parameters on adding product for AddProduct + * + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testAddProductExceptionBadParams() + { + $product = $this->getMock( + \Magento\Catalog\Model\Product::class, + ['getWebsiteIds', 'getId', '__wakeup'], + [], + '', + false + ); + $product->expects($this->any()) + ->method('getId') + ->will($this->returnValue(4)); + $product->expects($this->any()) + ->method('getWebsiteIds') + ->will($this->returnValue([10])); + $this->productRepository->expects($this->any()) + ->method('getById') + ->will($this->returnValue($product)); + + $this->eventManagerMock->expects($this->never())->method('dispatch')->with( + 'checkout_cart_product_add_after', + ['quote_item' => 1, 'product' => $product] + ); + $this->setExpectedException(\Magento\Framework\Exception\LocalizedException::class); + $this->cart->addProduct(4, 'bad'); + } + + /** + * Data provider for testAddProduct + * + * @return array + */ + public function addProductDataProvider() + { + $obj = new ObjectManagerHelper($this) ; + $data = ['qty' => 5.5, 'sku' => 'prod']; + + return [ + 'prod_int_info_int' => [4, 4], + 'prod_int_info_array' => [ 4, $data], + 'prod_int_info_object' => [ + 4, + $obj->getObject( + \Magento\Framework\DataObject::class, + ['data' => $data] + ) + ], + 'prod_obj_info_int' => [null, 4], + 'prod_obj_info_array' => [ null, $data], + 'prod_obj_info_object' => [ + null, + $obj->getObject( + \Magento\Framework\DataObject::class, + ['data' => $data] + ) + ] + ]; + } } diff --git a/app/code/Magento/Checkout/Test/Unit/Model/GuestPaymentInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/GuestPaymentInformationManagementTest.php index 093bbf4a5accc66bdd5c00fa4f30660409e09f79..76cbafb48ebd47e4fd83d01ef1361ef29df2f3be 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/GuestPaymentInformationManagementTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/GuestPaymentInformationManagementTest.php @@ -42,6 +42,11 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase */ protected $model; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $loggerMock; + protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -61,6 +66,7 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase '', false ); + $this->loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class); $this->model = $objectManager->getObject( \Magento\Checkout\Model\GuestPaymentInformationManagement::class, [ @@ -71,6 +77,7 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase 'quoteIdMaskFactory' => $this->quoteIdMaskFactoryMock ] ); + $objectManager->setBackwardCompatibleProperty($this->model, 'logger', $this->loggerMock); } public function testSavePaymentInformationAndPlaceOrder() @@ -112,7 +119,7 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase ->method('assign') ->with($cartId, $billingAddressMock); $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); - $exception = new CouldNotSaveException(__('DB exception')); + $exception = new \Exception(__('DB exception')); $this->cartManagementMock->expects($this->once())->method('placeOrder')->willThrowException($exception); $this->model->savePaymentInformationAndPlaceOrder($cartId, $email, $paymentMock, $billingAddressMock); @@ -161,4 +168,29 @@ class GuestPaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $billingAddressMock->expects($this->once())->method('setEmail')->with($email); $this->assertTrue($this->model->savePaymentInformation($cartId, $email, $paymentMock)); } + + /** + * @expectedExceptionMessage DB exception + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testSavePaymentInformationAndPlaceOrderWithLocolizedException() + { + $cartId = 100; + $email = 'email@magento.com'; + $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class); + $billingAddressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class); + + $billingAddressMock->expects($this->once())->method('setEmail')->with($email)->willReturnSelf(); + + $this->billingAddressManagementMock->expects($this->once()) + ->method('assign') + ->with($cartId, $billingAddressMock); + $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); + $phrase = new \Magento\Framework\Phrase(__('DB exception')); + $exception = new \Magento\Framework\Exception\LocalizedException($phrase); + $this->loggerMock->expects($this->never())->method('critical'); + $this->cartManagementMock->expects($this->once())->method('placeOrder')->willThrowException($exception); + + $this->model->savePaymentInformationAndPlaceOrder($cartId, $email, $paymentMock, $billingAddressMock); + } } diff --git a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php index 496054b2c7b1e0a0b9e60c119a8c25d322832a26..8da67a1fcb71512dd218a2c62d51b7922bb36c25 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/PaymentInformationManagementTest.php @@ -29,6 +29,11 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase */ protected $model; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $loggerMock; + protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -40,6 +45,8 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase ); $this->cartManagementMock = $this->getMock(\Magento\Quote\Api\CartManagementInterface::class); + $this->loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class); + $this->model = $objectManager->getObject( \Magento\Checkout\Model\PaymentInformationManagement::class, [ @@ -48,6 +55,7 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase 'cartManagement' => $this->cartManagementMock ] ); + $objectManager->setBackwardCompatibleProperty($this->model, 'logger', $this->loggerMock); } public function testSavePaymentInformationAndPlaceOrder() @@ -83,7 +91,8 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase ->method('assign') ->with($cartId, $billingAddressMock); $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); - $exception = new CouldNotSaveException(__('DB exception')); + $exception = new \Exception(__('DB exception')); + $this->loggerMock->expects($this->once())->method('critical'); $this->cartManagementMock->expects($this->once())->method('placeOrder')->willThrowException($exception); $this->model->savePaymentInformationAndPlaceOrder($cartId, $paymentMock, $billingAddressMock); @@ -129,4 +138,26 @@ class PaymentInformationManagementTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->model->savePaymentInformation($cartId, $paymentMock)); } + + /** + * @expectedExceptionMessage DB exception + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testSavePaymentInformationAndPlaceOrderWithLocolizedException() + { + $cartId = 100; + $paymentMock = $this->getMock(\Magento\Quote\Api\Data\PaymentInterface::class); + $billingAddressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class); + + $this->billingAddressManagementMock->expects($this->once()) + ->method('assign') + ->with($cartId, $billingAddressMock); + $this->paymentMethodManagementMock->expects($this->once())->method('set')->with($cartId, $paymentMock); + $phrase = new \Magento\Framework\Phrase(__('DB exception')); + $exception = new \Magento\Framework\Exception\LocalizedException($phrase); + $this->loggerMock->expects($this->never())->method('critical'); + $this->cartManagementMock->expects($this->once())->method('placeOrder')->willThrowException($exception); + + $this->model->savePaymentInformationAndPlaceOrder($cartId, $paymentMock, $billingAddressMock); + } } diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json index 5545e409b65abb3fb381e593c4ec34298dba6b80..60919d9fa2ca949817641c43328ad3be88edc8be 100644 --- a/app/code/Magento/Checkout/composer.json +++ b/app/code/Magento/Checkout/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-checkout", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-sales": "100.2.*", "magento/module-backend": "100.2.*", diff --git a/app/code/Magento/Checkout/etc/di.xml b/app/code/Magento/Checkout/etc/di.xml index c55598fdff5e792dd7404967d12f9fcc5e78e828..a2243b33a04edc0af4dc71ed79b802eac68f4cc2 100644 --- a/app/code/Magento/Checkout/etc/di.xml +++ b/app/code/Magento/Checkout/etc/di.xml @@ -26,4 +26,20 @@ <preference for="Magento\Checkout\Api\GuestTotalsInformationManagementInterface" type="Magento\Checkout\Model\GuestTotalsInformationManagement" /> <preference for="Magento\Checkout\Api\TotalsInformationManagementInterface" type="Magento\Checkout\Model\TotalsInformationManagement" /> <preference for="Magento\Checkout\Api\AgreementsValidatorInterface" type="Magento\Checkout\Model\AgreementsValidator" /> + <preference for="Magento\Checkout\Model\Cart\RequestInfoFilterInterface" + type="Magento\Checkout\Model\Cart\RequestInfoFilterComposite"/> + <type name="Magento\Checkout\Model\Cart\RequestInfoFilter"> + <arguments> + <argument name="filterList" xsi:type="array"> + <item name="form_key" xsi:type="string">form_key</item> + </argument> + </arguments> + </type> + <type name="Magento\Checkout\Model\Cart\RequestInfoFilterComposite"> + <arguments> + <argument name="filters" xsi:type="array"> + <item name="filter" xsi:type="object">Magento\Checkout\Model\Cart\RequestInfoFilter</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Checkout/etc/frontend/di.xml b/app/code/Magento/Checkout/etc/frontend/di.xml index bccf81bcb6ee81c97bd6bef98d3c5f08ec33b9cc..6fb9058c3b7681c8905a40a5eace5d88d8566b6f 100644 --- a/app/code/Magento/Checkout/etc/frontend/di.xml +++ b/app/code/Magento/Checkout/etc/frontend/di.xml @@ -72,4 +72,12 @@ </argument> </arguments> </type> + <type name="Magento\Checkout\Model\Cart\RequestInfoFilter"> + <arguments> + <argument name="filterList" xsi:type="array"> + <item name="form_key" xsi:type="string">form_key</item> + <item name="custom_price" xsi:type="string">custom_price</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/full-screen-loader.js b/app/code/Magento/Checkout/view/frontend/web/js/model/full-screen-loader.js index ca9d6493a16740f1a43555d84459df4403bd3c88..9005015d2460e12c5462551aecce97f1bd31c003 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/full-screen-loader.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/full-screen-loader.js @@ -24,7 +24,7 @@ define([ /** * Stop full page loader action * - * @param {Boolean} forceStop + * @param {Boolean} [forceStop] */ stopLoader: function (forceStop) { var $elem = $(containerId), diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index e06b8922b2252fd497db66a79db35af8c543db09..eba77927be79ea6189884f412be03be7ec7a76be 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -7,9 +7,10 @@ define([ 'jquery', 'mage/template', + 'underscore', 'jquery/ui', 'mage/validation' -], function ($, mageTemplate) { +], function ($, mageTemplate, _) { 'use strict'; $.widget('mage.regionUpdater', { @@ -124,6 +125,8 @@ define([ * @private */ _clearError: function () { + var args = ['clearError', this.options.regionListId, this.options.regionInputId, this.options.postcodeId]; + if (this.options.clearError && typeof this.options.clearError === 'function') { this.options.clearError.call(this); } else { @@ -133,8 +136,8 @@ define([ this.options.form = $(this.options.form); - this.options.form && this.options.form.data('validator') && this.options.form.validation('clearError', - this.options.regionListId, this.options.regionInputId, this.options.postcodeId); + this.options.form && this.options.form.data('validator') && + this.options.form.validation.apply(this.options.form, _.compact(args)); // Clean up errors on region & zip fix $(this.options.regionInputId).removeClass('mage-error').parent().find('[generated]').remove(); diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json index afb706a39a25ec97915abfe0bc6bfcb99c95f6d4..56a2b567745c2dd81fa3ca691309c4a76fe05aed 100644 --- a/app/code/Magento/CheckoutAgreements/composer.json +++ b/app/code/Magento/CheckoutAgreements/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-checkout-agreements", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-checkout": "100.2.*", "magento/module-quote": "100.2.*", "magento/module-store": "100.2.*", diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js index 3d030a62eb425cdb0365331c8fac5325a5dbc91d..2fa3c2cddd3d5af870f02db0e189cae8456c51aa 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js @@ -12,9 +12,8 @@ define( function ($) { 'use strict'; var checkoutConfig = window.checkoutConfig, - agreementsConfig = checkoutConfig ? checkoutConfig.checkoutAgreements : {}; - - var agreementsInputPath = '.payment-method._active div.checkout-agreements input'; + agreementsConfig = checkoutConfig ? checkoutConfig.checkoutAgreements : {}, + agreementsInputPath = '.payment-method._active div.checkout-agreements input'; return { /** @@ -23,26 +22,11 @@ define( * @returns {boolean} */ validate: function() { - if (!agreementsConfig.isEnabled) { - return true; - } - - if ($(agreementsInputPath).length == 0) { + if (!agreementsConfig.isEnabled || $(agreementsInputPath).length == 0) { return true; } - return $('#co-payment-form').validate({ - errorClass: 'mage-error', - errorElement: 'div', - meta: 'validate', - errorPlacement: function (error, element) { - var errorPlacement = element; - if (element.is(':checkbox') || element.is(':radio')) { - errorPlacement = element.siblings('label').last(); - } - errorPlacement.after(error); - } - }).element(agreementsInputPath); + return $.validator.validateSingleElement(agreementsInputPath, {errorElement: 'div'}); } } } diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html index bb7d5de636ce5fd98b5f98943500910603d56267..7d8ef43084f3264c09bb65d2939f6660fa343f7f 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html @@ -8,14 +8,13 @@ <div class="checkout-agreements" data-bind="visible: isVisible"> <!-- ko foreach: agreements --> <!-- ko if: ($parent.isAgreementRequired($data)) --> - <div class="checkout-agreement"> - <input type="checkbox" + <div class="checkout-agreement required"> + <input type="checkbox" class="required-entry" data-bind="attr: { 'id': 'agreement_' + agreementId, 'name': 'agreement[' + agreementId + ']', 'value': agreementId - }" - data-validate="{required:true}" /> + }"/> <label data-bind="attr: {'for': 'agreement_' + agreementId}"> <button type="button" class="action action-show" diff --git a/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php b/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php index ec5a438247e5cddc205d2f49c8d49ea746943e34..1bd96eff4dceef562040df73978679cc236a00bb 100644 --- a/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php +++ b/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php @@ -41,6 +41,7 @@ class Collection extends AbstractCollection { $this->_init(\Magento\Cms\Model\Block::class, \Magento\Cms\Model\ResourceModel\Block::class); $this->_map['fields']['store'] = 'store_table.store_id'; + $this->_map['fields']['block_id'] = 'main_table.block_id'; } /** diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4e1de289e5ef0e004a34d70dd793c1715a8bf292 --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php @@ -0,0 +1,134 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Test\Unit\Ui\Component\Listing\Column; + +use Magento\Cms\Ui\Component\Listing\Column\BlockActions; +use Magento\Framework\Escaper; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\UrlInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\Processor; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * BlockActionsTest contains unit tests for \Magento\Cms\Ui\Component\Listing\Column\BlockActions class + */ +class BlockActionsTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var BlockActions + */ + private $blockActions; + + /** + * @var Escaper|MockObject + */ + private $escaper; + + /** + * @var UrlInterface|MockObject + */ + private $urlBuilder; + + protected function setUp() + { + $objectManager = new ObjectManager($this); + + $context = $this->getMock(ContextInterface::class); + + $processor = $this->getMockBuilder(Processor::class) + ->disableOriginalConstructor() + ->getMock(); + $context->expects(static::once()) + ->method('getProcessor') + ->willReturn($processor); + + $this->urlBuilder = $this->getMock(UrlInterface::class); + + $this->escaper = $this->getMockBuilder(Escaper::class) + ->disableOriginalConstructor() + ->setMethods(['escapeHtml']) + ->getMock(); + + $this->blockActions = $objectManager->getObject(BlockActions::class, [ + 'context' => $context, + 'urlBuilder' => $this->urlBuilder + ]); + + $objectManager->setBackwardCompatibleProperty($this->blockActions, 'escaper', $this->escaper); + } + + /** + * @covers \Magento\Cms\Ui\Component\Listing\Column\BlockActions::prepareDataSource + */ + public function testPrepareDataSource() + { + $blockId = 1; + $title = 'block title'; + $items = [ + 'data' => [ + 'items' => [ + [ + 'block_id' => $blockId, + 'title' => $title + ] + ] + ] + ]; + $name = 'item_name'; + $expectedItems = [ + [ + 'block_id' => $blockId, + 'title' => $title, + $name => [ + 'edit' => [ + 'href' => 'test/url/edit', + 'label' => __('Edit'), + ], + 'delete' => [ + 'href' => 'test/url/delete', + 'label' => __('Delete'), + 'confirm' => [ + 'title' => __('Delete %1', $title), + 'message' => __('Are you sure you wan\'t to delete a %1 record?', $title) + ], + ] + ], + ] + ]; + + $this->escaper->expects(static::once()) + ->method('escapeHtml') + ->with($title) + ->willReturn($title); + + $this->urlBuilder->expects(static::exactly(2)) + ->method('getUrl') + ->willReturnMap( + [ + [ + BlockActions::URL_PATH_EDIT, + [ + 'block_id' => $blockId + ], + 'test/url/edit', + ], + [ + BlockActions::URL_PATH_DELETE, + [ + 'block_id' => $blockId + ], + 'test/url/delete', + ], + ] + ); + + $this->blockActions->setData('name', $name); + + $actual = $this->blockActions->prepareDataSource($items); + static::assertEquals($expectedItems, $actual['data']['items']); + } +} diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php index 4b6ce1ae2ff42d39bf53a9e57bd3b9f6aa639f89..731c08fbc64dd59a967b4d74ea52ba188336d0a9 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php @@ -6,6 +6,7 @@ namespace Magento\Cms\Test\Unit\Ui\Component\Listing\Column; use Magento\Cms\Ui\Component\Listing\Column\PageActions; +use Magento\Framework\Escaper; class PageActionsTest extends \PHPUnit_Framework_TestCase { @@ -34,12 +35,20 @@ class PageActionsTest extends \PHPUnit_Framework_TestCase ] ); + $escaper = $this->getMockBuilder(Escaper::class) + ->disableOriginalConstructor() + ->setMethods(['escapeHtml']) + ->getMock(); + $objectManager->setBackwardCompatibleProperty($model, 'escaper', $escaper); + // Define test input and expectations + $title = 'page title'; $items = [ 'data' => [ 'items' => [ [ - 'page_id' => $pageId + 'page_id' => $pageId, + 'title' => $title ] ] ] @@ -48,6 +57,7 @@ class PageActionsTest extends \PHPUnit_Framework_TestCase $expectedItems = [ [ 'page_id' => $pageId, + 'title' => $title, $name => [ 'edit' => [ 'href' => 'test/url/edit', @@ -57,14 +67,19 @@ class PageActionsTest extends \PHPUnit_Framework_TestCase 'href' => 'test/url/delete', 'label' => __('Delete'), 'confirm' => [ - 'title' => __('Delete ${ $.$data.title }'), - 'message' => __('Are you sure you wan\'t to delete a ${ $.$data.title } record?') + 'title' => __('Delete %1', $title), + 'message' => __('Are you sure you wan\'t to delete a %1 record?', $title) ], ] ], ] ]; + $escaper->expects(static::once()) + ->method('escapeHtml') + ->with($title) + ->willReturn($title); + // Configure mocks and object data $urlBuilderMock->expects($this->any()) ->method('getUrl') diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php index e71352c465333396312cc0bd0242cbe45f62bd17..f0a1fe7981f8c3007055973eb4e296c23afe5ab8 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php @@ -9,6 +9,8 @@ use Magento\Framework\UrlInterface; use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Framework\View\Element\UiComponentFactory; use Magento\Ui\Component\Listing\Columns\Column; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Escaper; /** * Class BlockActions @@ -27,6 +29,11 @@ class BlockActions extends Column */ protected $urlBuilder; + /** + * @var Escaper + */ + private $escaper; + /** * Constructor * @@ -47,10 +54,6 @@ class BlockActions extends Column parent::__construct($context, $uiComponentFactory, $components, $data); } - /** - * @param array $items - * @return array - */ /** * Prepare Data Source * @@ -62,6 +65,7 @@ class BlockActions extends Column if (isset($dataSource['data']['items'])) { foreach ($dataSource['data']['items'] as & $item) { if (isset($item['block_id'])) { + $title = $this->getEscaper()->escapeHtml($item['title']); $item[$this->getData('name')] = [ 'edit' => [ 'href' => $this->urlBuilder->getUrl( @@ -81,8 +85,8 @@ class BlockActions extends Column ), 'label' => __('Delete'), 'confirm' => [ - 'title' => __('Delete "${ $.$data.title }"'), - 'message' => __('Are you sure you wan\'t to delete a "${ $.$data.title }" record?') + 'title' => __('Delete %1', $title), + 'message' => __('Are you sure you wan\'t to delete a %1 record?', $title) ] ] ]; @@ -92,4 +96,17 @@ class BlockActions extends Column return $dataSource; } + + /** + * Get instance of escaper + * @return Escaper + * @deprecated + */ + private function getEscaper() + { + if (!$this->escaper) { + $this->escaper = ObjectManager::getInstance()->get(Escaper::class); + } + return $this->escaper; + } } diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php index fe85fd0ef314070c5c6cdb6f34435e72af3e152b..f23afbffa792e6b5b92166b5268e3942735bd21f 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php @@ -5,11 +5,13 @@ */ namespace Magento\Cms\Ui\Component\Listing\Column; +use Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Escaper; +use Magento\Framework\UrlInterface; use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Framework\View\Element\UiComponentFactory; use Magento\Ui\Component\Listing\Columns\Column; -use Magento\Cms\Block\Adminhtml\Page\Grid\Renderer\Action\UrlBuilder; -use Magento\Framework\UrlInterface; /** * Class PageActions @@ -31,6 +33,11 @@ class PageActions extends Column */ private $editUrl; + /** + * @var Escaper + */ + private $escaper; + /** * @param ContextInterface $context * @param UiComponentFactory $uiComponentFactory @@ -71,12 +78,13 @@ class PageActions extends Column 'href' => $this->urlBuilder->getUrl($this->editUrl, ['page_id' => $item['page_id']]), 'label' => __('Edit') ]; + $title = $this->getEscaper()->escapeHtml($item['title']); $item[$name]['delete'] = [ 'href' => $this->urlBuilder->getUrl(self::CMS_URL_PATH_DELETE, ['page_id' => $item['page_id']]), 'label' => __('Delete'), 'confirm' => [ - 'title' => __('Delete ${ $.$data.title }'), - 'message' => __('Are you sure you wan\'t to delete a ${ $.$data.title } record?') + 'title' => __('Delete %1', $title), + 'message' => __('Are you sure you wan\'t to delete a %1 record?', $title) ] ]; } @@ -95,4 +103,17 @@ class PageActions extends Column return $dataSource; } + + /** + * Get instance of escaper + * @return Escaper + * @deprecated + */ + private function getEscaper() + { + if (!$this->escaper) { + $this->escaper = ObjectManager::getInstance()->get(Escaper::class); + } + return $this->escaper; + } } diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json index 66f6da042e6c9a77e25eb5c9e8f1595c16e3e5f6..7f2ed4d7a7dcdc59916c34c796f7f3fc05ec6cc9 100644 --- a/app/code/Magento/Cms/composer.json +++ b/app/code/Magento/Cms/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-cms", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-theme": "100.2.*", "magento/module-widget": "100.2.*", diff --git a/app/code/Magento/Cms/i18n/en_US.csv b/app/code/Magento/Cms/i18n/en_US.csv index 6f3a2955a5c65b5cf1760519741fd60d49133123..9a9f6ac4c6888e386d44c679c94a87533844342d 100644 --- a/app/code/Magento/Cms/i18n/en_US.csv +++ b/app/code/Magento/Cms/i18n/en_US.csv @@ -84,10 +84,8 @@ Exception,Exception "All Store Views","All Store Views" Edit,Edit Delete,Delete -"Delete ${ $.$data.title }","Delete ${ $.$data.title }" -"Are you sure you wan\'t to delete a ${ $.$data.title } record?","Are you sure you wan\'t to delete a ${ $.$data.title } record?" -"Delete ""${ $.$data.title }""","Delete ""${ $.$data.title }""" -"Are you sure you wan\'t to delete a ""${ $.$data.title }"" record?","Are you sure you wan\'t to delete a ""${ $.$data.title }"" record?" +"Delete %1","Delete %1" +"Are you sure you wan\'t to delete a %1 record?","Are you sure you wan\'t to delete a %1 record?" View,View px.,px. "No files found","No files found" diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml index a6185c454189770f39d00ae0c54c95086dc1fcf1..827f2ee938e41378a158090c16a383e62fa9e74e 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml @@ -21,11 +21,11 @@ $_height = $block->getImagesHeight(); <?php endif; ?> </p> <?php if ($block->getFileWidth($file)): ?> - <small><?php echo $block->escapeHtml($block->getFileWidth($file)) ?>x<?php echo $block->escapeHtml($block->getFileHeight($file)) ?> <?php /* @escapeNotVerified */ echo __('px.') ?></small><br/> + <small><?php echo $block->escapeHtml($block->getFileWidth($file)) ?>x<?php echo $block->escapeHtml($block->getFileHeight($file)) ?> <?php echo $block->escapeHtml(__('px.')) ?></small><br/> <?php endif; ?> <small><?php echo $block->escapeHtml($block->getFileShortName($file)); ?></small> </div> <?php endforeach; ?> <?php else: ?> - <div class="empty"><?php /* @escapeNotVerified */ echo __('No files found') ?></div> + <div class="empty"><?php echo $block->escapeHtml(__('No files found')) ?></div> <?php endif; ?> diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index 6a29cb1497175d418723af26a041c6bb80a990f8..3233bb17c09a319f27a987e47cb4cdd16661c20d 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -11,7 +11,7 @@ <div id="<?php echo $block->getHtmlId() ?>" class="uploader"> <span class="fileinput-button form-buttons"> - <span><?php /* @escapeNotVerified */ echo __('Browse Files...') ?></span> + <span><?php echo $block->escapeHtml(__('Browse Files...')) ?></span> <input class="fileupload" type="file" name="<?php echo $block->escapeHtmlAttr($block->getConfig()->getFileField()) ?>" data-url="<?php echo $block->escapeUrl($block->getConfig()->getUrl()) ?>" multiple> </span> <div class="clear"></div> diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/tree.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/tree.phtml index 90a00c32015b7733b54e08cda63217c897f0bf58..2e6204496eba453a40c8288ed041db7781ec27e7 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/tree.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/tree.phtml @@ -11,9 +11,9 @@ <div class="tree-panel" > <div class="categories-side-col"> <div class="tree-actions"> - <a onclick="jQuery('[data-role=tree]').jstree('close_all');"><?php /* @escapeNotVerified */ echo __('Collapse All'); ?></a> + <a onclick="jQuery('[data-role=tree]').jstree('close_all');"><?php echo $block->escapeHtml(__('Collapse All')) ?></a> <span class="separator">|</span> - <a onclick="jQuery('[data-role=tree]').jstree('open_all');"><?php /* @escapeNotVerified */ echo __('Expand All'); ?></a> + <a onclick="jQuery('[data-role=tree]').jstree('open_all');"><?php echo $block->escapeHtml(__('Expand All')) ?></a> </div> </div> <div data-role="tree" data-mage-init='<?php echo $block->escapeHtml($this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getTreeWidgetOptions())); ?>'> diff --git a/app/code/Magento/Cms/view/frontend/templates/widget/link/link_block.phtml b/app/code/Magento/Cms/view/frontend/templates/widget/link/link_block.phtml index 55c1b02be8797a45a9f4b27914e3195d7695da61..82a27c7aa0d78f1b44f44c9ca9f108d8df1ae586 100644 --- a/app/code/Magento/Cms/view/frontend/templates/widget/link/link_block.phtml +++ b/app/code/Magento/Cms/view/frontend/templates/widget/link/link_block.phtml @@ -3,9 +3,13 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/** + * @var \Magento\Cms\Block\Widget\Page\Link $block + */ ?> <div class="widget block block-cms-link"> - <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes() ?>> + <a <?php /* @noEscape */ echo $block->getLinkAttributes() ?>> <span><?php echo $block->escapeHtml($block->getLabel()) ?></span> </a> </div> diff --git a/app/code/Magento/Cms/view/frontend/templates/widget/link/link_inline.phtml b/app/code/Magento/Cms/view/frontend/templates/widget/link/link_inline.phtml index 382b492db3da5c815530d87f13ee959d82e2c083..d906826507d73b50f1c8cbf50a85f8ae2e09c5c8 100644 --- a/app/code/Magento/Cms/view/frontend/templates/widget/link/link_inline.phtml +++ b/app/code/Magento/Cms/view/frontend/templates/widget/link/link_inline.phtml @@ -3,9 +3,13 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/** + * @var \Magento\Cms\Block\Widget\Page\Link $block + */ ?> <span class="widget block block-cms-link-inline"> - <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes() ?>> + <a <?php /* @noEscape */ echo $block->getLinkAttributes() ?>> <span><?php echo $block->escapeHtml($block->getLabel()) ?></span> </a> </span> diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json index 1ae1efd9350a760846e76fcac8939ef574194361..1d2e70c74eb4f9fd0876f92c37b30b5e9387d2cd 100644 --- a/app/code/Magento/CmsUrlRewrite/composer.json +++ b/app/code/Magento/CmsUrlRewrite/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-cms-url-rewrite", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-cms": "101.1.*", "magento/module-url-rewrite": "100.2.*", diff --git a/app/code/Magento/Config/Model/Config/Backend/Baseurl.php b/app/code/Magento/Config/Model/Config/Backend/Baseurl.php index 09fd99773813117a71b43240eaafc5b96bf967ca..f08c2f8e04434c7a26645669ff3a4c1c8d1840c7 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Baseurl.php +++ b/app/code/Magento/Config/Model/Config/Backend/Baseurl.php @@ -5,6 +5,9 @@ */ namespace Magento\Config\Model\Config\Backend; +use Magento\Framework\Validator\Url as UrlValidator; +use Magento\Framework\App\ObjectManager; + class Baseurl extends \Magento\Framework\App\Config\Value { /** @@ -12,6 +15,11 @@ class Baseurl extends \Magento\Framework\App\Config\Value */ protected $_mergeService; + /** + * @var UrlValidator + */ + private $urlValidator; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -193,8 +201,7 @@ class Baseurl extends \Magento\Framework\App\Config\Value */ private function _isFullyQualifiedUrl($value) { - $url = parse_url($value); - return isset($url['scheme']) && isset($url['host']) && preg_match('/\/$/', $value); + return preg_match('/\/$/', $value) && $this->getUrlValidator()->isValid($value, ['http', 'https']); } /** @@ -216,4 +223,18 @@ class Baseurl extends \Magento\Framework\App\Config\Value } return parent::afterSave(); } + + /** + * Get URL Validator + * + * @deprecated + * @return UrlValidator + */ + private function getUrlValidator() + { + if (!$this->urlValidator) { + $this->urlValidator = ObjectManager::getInstance()->get(UrlValidator::class); + } + return $this->urlValidator; + } } diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json index bdd1a9c14ae6894d052f6e7e2994f2c87c6554b0..b14dd825b0d12d819fd511222e80de12a7cf8c3a 100644 --- a/app/code/Magento/Config/composer.json +++ b/app/code/Magento/Config/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-config", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*", "magento/module-store": "100.2.*", "magento/module-cron": "100.2.*", diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json index 6c249134d28626b4c8846fd7491cf25b2e278638..d292e73198435431015dff6bcfe1a69d516debc9 100644 --- a/app/code/Magento/ConfigurableImportExport/composer.json +++ b/app/code/Magento/ConfigurableImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-configurable-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-catalog-import-export": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php index 0fdfbd3bfa172ee597414ed3ab4c46bbac2a9549..5575d6f7ef56fa4f7f2fed433299c01eaa4ba98d 100644 --- a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php +++ b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php @@ -32,6 +32,16 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI */ private $dataObjectHelper; + /** + * @var \Magento\ConfigurableProduct\Helper\Product\Options\Factory; + */ + private $optionsFactory; + + /** + * @var \Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory + */ + private $attributeFactory; + /** * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository * @param \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory @@ -102,9 +112,28 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI throw new StateException(__('Product has been already attached')); } + $configurableProductOptions = $product->getExtensionAttributes()->getConfigurableProductOptions(); + if (empty($configurableProductOptions)) { + throw new StateException(__('Parent product does not have configurable product options')); + } + + $attributeIds = []; + foreach ($configurableProductOptions as $configurableProductOption) { + $attributeCode = $configurableProductOption->getProductAttribute()->getAttributeCode(); + if (!$child->getData($attributeCode)) { + throw new StateException(__('Child product does not have attribute value %1', $attributeCode)); + } + $attributeIds[] = $configurableProductOption->getAttributeId(); + } + $configurableOptionData = $this->getConfigurableAttributesData($attributeIds); + + /** @var \Magento\ConfigurableProduct\Helper\Product\Options\Factory $optionFactory */ + $optionFactory = $this->getOptionsFactory(); + $options = $optionFactory->create($configurableOptionData); $childrenIds[] = $child->getId(); + $product->getExtensionAttributes()->setConfigurableProductOptions($options); $product->getExtensionAttributes()->setConfigurableProductLinks($childrenIds); - $product->save(); + $this->productRepository->save($product); return true; } @@ -133,7 +162,75 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI throw new NoSuchEntityException(__('Requested option doesn\'t exist')); } $product->getExtensionAttributes()->setConfigurableProductLinks($ids); - $product->save(); + $this->productRepository->save($product); return true; } + + /** + * Get Options Factory + * + * @return \Magento\ConfigurableProduct\Helper\Product\Options\Factory + * + * @deprecated + */ + private function getOptionsFactory() + { + if (!$this->optionsFactory) { + $this->optionsFactory = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\ConfigurableProduct\Helper\Product\Options\Factory::class); + } + return $this->optionsFactory; + } + + /** + * Get Attribute Factory + * + * @return \Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory + * + * @deprecated + */ + private function getAttributeFactory() + { + if (!$this->attributeFactory) { + $this->attributeFactory = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory::class); + } + return $this->attributeFactory; + } + + /** + * Get Configurable Attribute Data + * + * @param int[] $attributeIds + * @return array + */ + private function getConfigurableAttributesData($attributeIds) + { + $configurableAttributesData = []; + $attributeValues = []; + $attributes = $this->getAttributeFactory()->create() + ->getCollection() + ->addFieldToFilter('attribute_id', $attributeIds) + ->getItems(); + foreach ($attributes as $attribute) { + foreach ($attribute->getOptions() as $option) { + if ($option->getValue()) { + $attributeValues[] = [ + 'label' => $option->getLabel(), + 'attribute_id' => $attribute->getId(), + 'value_index' => $option->getValue(), + ]; + } + } + $configurableAttributesData[] = + [ + 'attribute_id' => $attribute->getId(), + 'code' => $attribute->getAttributeCode(), + 'label' => $attribute->getStoreLabel(), + 'values' => $attributeValues, + ]; + } + + return $configurableAttributesData; + } } diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php index 0b8a4aee9feced6e4f104208b7563bda16b6305c..0bd2f23418221770d4562eb67d6af9d3e8bd4646 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php @@ -1287,4 +1287,19 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType } return $this->catalogConfig; } + + /** + * @inheritdoc + */ + public function isPossibleBuyFromList($product) + { + $isAllCustomOptionsDisplayed = true; + foreach ($this->getConfigurableAttributes($product) as $attribute) { + $eavAttribute = $attribute->getProductAttribute(); + + $isAllCustomOptionsDisplayed = ($isAllCustomOptionsDisplayed && $eavAttribute->getUsedInProductListing()); + } + + return $isAllCustomOptionsDisplayed; + } } diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php index 4e6fa8ae5210d77726b393047a7433ca03d69c7d..fbb69798ff94fbdf8caafc7486e564da662cf655 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php @@ -8,6 +8,7 @@ namespace Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice { @@ -166,6 +167,9 @@ class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\ $this->_prepareConfigurableOptionAggregateTable(); $this->_prepareConfigurableOptionPriceTable(); + $statusAttribute = $this->_getAttribute(ProductInterface::STATUS); + $linkField = $metadata->getLinkField(); + $select = $connection->select()->from( ['i' => $this->_getDefaultFinalPriceTable()], [] @@ -175,7 +179,7 @@ class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\ ['parent_id' => 'e.entity_id'] )->join( ['l' => $this->getTable('catalog_product_super_link')], - 'l.parent_id = e.' . $metadata->getLinkField(), + 'l.parent_id = e.' . $linkField, ['product_id'] )->columns( ['customer_group_id', 'website_id'], @@ -186,11 +190,21 @@ class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\ [] )->where( 'le.required_options=0' + )->join( + ['product_status' => $this->getTable($statusAttribute->getBackend()->getTable())], + sprintf( + 'le.%1$s = product_status.%1$s AND product_status.attribute_id = %2$s', + $linkField, + $statusAttribute->getAttributeId() + ), + [] + )->where( + 'product_status.value=' . ProductStatus::STATUS_ENABLED )->group( - ['parent_id', 'i.customer_group_id', 'i.website_id', 'l.product_id'] + ['e.entity_id', 'i.customer_group_id', 'i.website_id', 'l.product_id'] ); - $priceColumn = $this->_addAttributeToSelect($select, 'price', 'l.product_id', 0, null, true); - $tierPriceColumn = $connection->getCheckSql("MIN(i.tier_price) IS NOT NULL", "i.tier_price", 'NULL'); + $priceColumn = $this->_addAttributeToSelect($select, 'price', 'le.' . $linkField, 0, null, true); + $tierPriceColumn = $connection->getIfNullSql('MIN(i.tier_price)', 'NULL'); $select->columns( ['price' => $priceColumn, 'tier_price' => $tierPriceColumn] diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php index 6b69888e6dd0924cf6e090bdb1eb0af2daddaab1..5a7886ea3ea640c2f276ffb7eedeaa243ff9e790 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php @@ -6,8 +6,8 @@ namespace Magento\ConfigurableProduct\Test\Unit\Model; +use Magento\ConfigurableProduct\Model\LinkManagement; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; -use Magento\ConfigurableProduct\Test\Unit\Model\Product\ProductExtensionAttributes; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -146,15 +146,59 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase $configurable = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) ->disableOriginalConstructor() + ->setMethods(['getId', 'getExtensionAttributes']) + ->getMock(); + $simple = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->setMethods(['getId', 'getData']) ->getMock(); - $configurable->expects($this->any())->method('getId')->will($this->returnValue(666)); + $extensionAttributesMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductExtension::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getConfigurableProductOptions', 'setConfigurableProductOptions', 'setConfigurableProductLinks' + ]) + ->getMock(); + $optionMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Api\Data\Option::class) + ->disableOriginalConstructor() + ->setMethods(['getProductAttribute', 'getAttributeId']) + ->getMock(); + $productAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class) + ->disableOriginalConstructor() + ->setMethods(['getAttributeCode']) + ->getMock(); + $optionsFactoryMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Helper\Product\Options\Factory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $reflectionClass = new \ReflectionClass(\Magento\ConfigurableProduct\Model\LinkManagement::class); + $optionsFactoryReflectionProperty = $reflectionClass->getProperty('optionsFactory'); + $optionsFactoryReflectionProperty->setAccessible(true); + $optionsFactoryReflectionProperty->setValue($this->object, $optionsFactoryMock); - $simple = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + $attributeFactoryMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory::class) ->disableOriginalConstructor() + ->setMethods(['create']) ->getMock(); + $attributeFactoryReflectionProperty = $reflectionClass->getProperty('attributeFactory'); + $attributeFactoryReflectionProperty->setAccessible(true); + $attributeFactoryReflectionProperty->setValue($this->object, $attributeFactoryMock); - $simple->expects($this->any())->method('getId')->will($this->returnValue(999)); + $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) + ->disableOriginalConstructor() + ->setMethods(['getCollection', 'getOptions', 'getId', 'getAttributeCode', 'getStoreLabel']) + ->getMock(); + $attributeOptionMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Option::class) + ->disableOriginalConstructor() + ->setMethods(['getValue', 'getLabel']) + ->getMock(); + + $attributeCollectionMock = $this->getMockBuilder( + \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection::class + ) + ->disableOriginalConstructor() + ->setMethods(['addFieldToFilter', 'getItems']) + ->getMock(); $this->productRepository->expects($this->at(0))->method('get')->with($productSku)->willReturn($configurable); $this->productRepository->expects($this->at(1))->method('get')->with($childSku)->willReturn($simple); @@ -164,15 +208,30 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase $this->returnValue([0 => [1, 2, 3]]) ); - $extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class) - ->setMethods(['setConfigurableProductLinks']) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); + $configurable->expects($this->any())->method('getId')->will($this->returnValue(666)); + $simple->expects($this->any())->method('getId')->will($this->returnValue(999)); + + $configurable->expects($this->any())->method('getExtensionAttributes')->willReturn($extensionAttributesMock); + $extensionAttributesMock->expects($this->any()) + ->method('getConfigurableProductOptions') + ->willReturn([$optionMock]); + $optionMock->expects($this->any())->method('getProductAttribute')->willReturn($productAttributeMock); + $productAttributeMock->expects($this->any())->method('getAttributeCode')->willReturn('color'); + $simple->expects($this->any())->method('getData')->willReturn('color'); + $optionMock->expects($this->any())->method('getAttributeId')->willReturn('1'); - $configurable->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes); - $extensionAttributes->expects($this->once())->method('setConfigurableProductLinks')->willReturnSelf(); + $optionsFactoryMock->expects($this->any())->method('create')->willReturn([$optionMock]); + $attributeFactoryMock->expects($this->any())->method('create')->willReturn($attributeMock); + $attributeMock->expects($this->any())->method('getCollection')->willReturn($attributeCollectionMock); + $attributeCollectionMock->expects($this->any())->method('addFieldToFilter')->willReturnSelf(); + $attributeCollectionMock->expects($this->any())->method('getItems')->willReturn([$attributeMock]); - $configurable->expects($this->once())->method('save'); + $attributeMock->expects($this->any())->method('getOptions')->willReturn([$attributeOptionMock]); + + $extensionAttributesMock->expects($this->any())->method('setConfigurableProductOptions'); + $extensionAttributesMock->expects($this->any())->method('setConfigurableProductLinks'); + + $this->productRepository->expects($this->once())->method('save'); $this->assertTrue(true, $this->object->addChild($productSku, $childSku)); } @@ -243,15 +302,13 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase $productType->expects($this->once())->method('getUsedProducts') ->will($this->returnValue([$option])); - $extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class) + $extensionAttributesMock = $this->getMockBuilder(\Magento\Framework\Api\ExtensionAttributesInterface::class) ->setMethods(['setConfigurableProductLinks']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $product->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes); - $extensionAttributes->expects($this->once())->method('setConfigurableProductLinks')->willReturnSelf(); - - $product->expects($this->once())->method('save'); + $product->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributesMock); + $this->productRepository->expects($this->once())->method('save'); $this->assertTrue($this->object->removeChild($productSku, $childSku)); } diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index 8dda841250ff126d0fed90a03dd4272169266392..755b94a600a099a0ada188d435f3682cf6736e69 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-configurable-product", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-catalog-inventory": "100.2.*", diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json index b541f1e7a0ed3afe8f8bfb8c25b7f27282bc9372..377e46256c0886c5479cbe256451310bac14b896 100644 --- a/app/code/Magento/Contact/composer.json +++ b/app/code/Magento/Contact/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-contact", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json index 5222975723385a48adf043f695c08e319f11d57b..96a050f2ad20dfa94958fd11f7a24cfb73010642 100644 --- a/app/code/Magento/Cookie/composer.json +++ b/app/code/Magento/Cookie/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-cookie", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/framework": "100.2.*" }, diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json index b1155c028f91971b5508269a06ebef675032e5b5..75a7ce27a2aa110d55398a0588ae4f4907c724c2 100644 --- a/app/code/Magento/Cron/composer.json +++ b/app/code/Magento/Cron/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-cron", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/framework": "100.2.*" }, diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json index 2cdfedadf7a38c7c792a27de4498772cc59c692b..29f0bd7435eef99279f54273163f17041d64a351 100644 --- a/app/code/Magento/CurrencySymbol/composer.json +++ b/app/code/Magento/CurrencySymbol/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-currency-symbol", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-page-cache": "100.2.*", diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php index 77bf7af2a4031ac71488b7644225a6c13dc520f2..fd2ceaf09695bfb4a413bc6f680f254ca4edca4c 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php @@ -72,6 +72,7 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index ) { $metadataForm = $this->getMetadataForm($entityType, $formCode, $scope); $formData = $metadataForm->extractData($this->getRequest(), $scope); + $formData = $metadataForm->compactData($formData); // Initialize additional attributes /** @var \Magento\Framework\DataObject $object */ @@ -81,11 +82,6 @@ class Save extends \Magento\Customer\Controller\Adminhtml\Index $formData[$attributeCode] = isset($requestData[$attributeCode]) ? $requestData[$attributeCode] : false; } - $result = $metadataForm->compactData($formData); - - // Re-initialize additional attributes - $formData = array_replace($formData, $result); - // Unset unused attributes $formAttributes = $metadataForm->getAttributes(); foreach ($formAttributes as $attribute) { diff --git a/app/code/Magento/Customer/Controller/Section/Load.php b/app/code/Magento/Customer/Controller/Section/Load.php index 19b361b2c830d763681184b5055f0d477c4641ae..c1ec593e4a7aeec51a53323052aeae62cb7036ff 100644 --- a/app/code/Magento/Customer/Controller/Section/Load.php +++ b/app/code/Magento/Customer/Controller/Section/Load.php @@ -5,10 +5,10 @@ */ namespace Magento\Customer\Controller\Section; +use Magento\Customer\CustomerData\Section\Identifier; use Magento\Customer\CustomerData\SectionPoolInterface; use Magento\Framework\App\Action\Context; use Magento\Framework\Controller\Result\JsonFactory; -use Magento\Framework\Exception\LocalizedException; /** * Customer section controller @@ -22,6 +22,7 @@ class Load extends \Magento\Framework\App\Action\Action /** * @var Identifier + * @deprecated */ protected $sectionIdentifier; @@ -30,26 +31,34 @@ class Load extends \Magento\Framework\App\Action\Action */ protected $sectionPool; + /** + * @var \Magento\Framework\Escaper + */ + private $escaper; + /** * @param Context $context * @param JsonFactory $resultJsonFactory - * @param \Magento\Customer\CustomerData\Section\Identifier $sectionIdentifier + * @param Identifier $sectionIdentifier * @param SectionPoolInterface $sectionPool + * @param Escaper $escaper */ public function __construct( Context $context, JsonFactory $resultJsonFactory, - \Magento\Customer\CustomerData\Section\Identifier $sectionIdentifier, - SectionPoolInterface $sectionPool + Identifier $sectionIdentifier, + SectionPoolInterface $sectionPool, + \Magento\Framework\Escaper $escaper = null ) { parent::__construct($context); $this->resultJsonFactory = $resultJsonFactory; $this->sectionIdentifier = $sectionIdentifier; $this->sectionPool = $sectionPool; + $this->escaper = $escaper ?: $this->_objectManager->get(\Magento\Framework\Escaper::class); } /** - * @return \Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\Result\Redirect + * @return \Magento\Framework\Controller\Result\Json */ public function execute() { @@ -60,7 +69,7 @@ class Load extends \Magento\Framework\App\Action\Action $sectionNames = $sectionNames ? array_unique(\explode(',', $sectionNames)) : null; $updateSectionId = $this->getRequest()->getParam('update_section_id'); - if ('false' == $updateSectionId) { + if ('false' === $updateSectionId) { $updateSectionId = false; } $response = $this->sectionPool->getSectionsData($sectionNames, (bool)$updateSectionId); @@ -70,7 +79,7 @@ class Load extends \Magento\Framework\App\Action\Action \Zend\Http\AbstractMessage::VERSION_11, 'Bad Request' ); - $response = ['message' => $e->getMessage()]; + $response = ['message' => $this->escaper->escapeHtml($e->getMessage())]; } return $resultJson->setData($response); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php index 8fb48fe9f87e76dcf4f5d489a830bb15bf910c79..11fd1b5a7fc3356f54cc1e72b76e111b22446383 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php @@ -304,33 +304,28 @@ class SaveTest extends \PHPUnit_Framework_TestCase ], 'subscription' => $subscription, ]; - $filteredData = [ + $extractedData = [ 'entity_id' => $customerId, 'code' => 'value', 'coolness' => false, 'disable_auto_group_change' => 'false', ]; - $dataToCompact = [ + $compactedData = [ 'entity_id' => $customerId, 'code' => 'value', 'coolness' => false, 'disable_auto_group_change' => 'false', - CustomerInterface::DEFAULT_BILLING => false, - CustomerInterface::DEFAULT_SHIPPING => false, - 'confirmation' => false, - 'sendemail_store_id' => false, - 'extension_attributes' => false, + CustomerInterface::DEFAULT_BILLING => 2, + CustomerInterface::DEFAULT_SHIPPING => 2 ]; - $addressFilteredData = [ + $addressExtractedData = [ 'entity_id' => $addressId, - 'default_billing' => 'true', - 'default_shipping' => 'true', 'code' => 'value', 'coolness' => false, 'region' => 'region', 'region_id' => 'region_id', ]; - $addressDataToCompact = [ + $addressCompactedData = [ 'entity_id' => $addressId, 'default_billing' => 'true', 'default_shipping' => 'true', @@ -430,11 +425,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase $customerFormMock->expects($this->once()) ->method('extractData') ->with($this->requestMock, 'customer') - ->willReturn($filteredData); + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('compactData') - ->with($dataToCompact) - ->willReturn($filteredData); + ->with($extractedData) + ->willReturn($compactedData); $customerFormMock->expects($this->once()) ->method('getAttributes') ->willReturn($attributes); @@ -445,11 +440,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase $customerAddressFormMock->expects($this->once()) ->method('extractData') ->with($this->requestMock, 'address/' . $addressId) - ->willReturn($addressFilteredData); + ->willReturn($addressExtractedData); $customerAddressFormMock->expects($this->once()) ->method('compactData') - ->with($addressDataToCompact) - ->willReturn($addressFilteredData); + ->with($addressExtractedData) + ->willReturn($addressCompactedData); $customerAddressFormMock->expects($this->once()) ->method('getAttributes') ->willReturn($attributes); @@ -625,8 +620,6 @@ class SaveTest extends \PHPUnit_Framework_TestCase '_template_' => '_template_', $addressId => [ 'entity_id' => $addressId, - 'default_billing' => 'false', - 'default_shipping' => 'false', 'code' => 'value', 'coolness' => false, 'region' => 'region', @@ -635,32 +628,12 @@ class SaveTest extends \PHPUnit_Framework_TestCase ], 'subscription' => $subscription, ]; - $filteredData = [ + $extractedData = [ 'coolness' => false, 'disable_auto_group_change' => 'false', ]; - $dataToCompact = [ - 'coolness' => false, - 'disable_auto_group_change' => 'false', - CustomerInterface::DEFAULT_BILLING => false, - CustomerInterface::DEFAULT_SHIPPING => false, - 'confirmation' => false, - 'sendemail_store_id' => false, - 'extension_attributes' => false, - ]; - $addressFilteredData = [ + $addressExtractedData = [ 'entity_id' => $addressId, - 'default_billing' => 'false', - 'default_shipping' => 'false', - 'code' => 'value', - 'coolness' => false, - 'region' => 'region', - 'region_id' => 'region_id', - ]; - $addressDataToCompact = [ - 'entity_id' => $addressId, - 'default_billing' => 'false', - 'default_shipping' => 'false', 'code' => 'value', 'coolness' => false, 'region' => 'region', @@ -739,11 +712,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase $customerFormMock->expects($this->once()) ->method('extractData') ->with($this->requestMock, 'customer') - ->willReturn($filteredData); + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('compactData') - ->with($dataToCompact) - ->willReturn($filteredData); + ->with($extractedData) + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('getAttributes') ->willReturn($attributes); @@ -754,11 +727,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase $customerAddressFormMock->expects($this->once()) ->method('extractData') ->with($this->requestMock, 'address/' . $addressId) - ->willReturn($addressFilteredData); + ->willReturn($addressExtractedData); $customerAddressFormMock->expects($this->once()) ->method('compactData') - ->with($addressDataToCompact) - ->willReturn($addressFilteredData); + ->with($addressExtractedData) + ->willReturn($addressExtractedData); $customerAddressFormMock->expects($this->once()) ->method('getAttributes') ->willReturn($attributes); @@ -910,19 +883,10 @@ class SaveTest extends \PHPUnit_Framework_TestCase ], 'subscription' => $subscription, ]; - $filteredData = [ + $extractedData = [ 'coolness' => false, 'disable_auto_group_change' => 'false', ]; - $dataToCompact = [ - 'coolness' => false, - 'disable_auto_group_change' => 'false', - CustomerInterface::DEFAULT_BILLING => false, - CustomerInterface::DEFAULT_SHIPPING => false, - 'confirmation' => false, - 'sendemail_store_id' => false, - 'extension_attributes' => false, - ]; /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */ $attributeMock = $this->getMockBuilder( @@ -971,11 +935,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase $customerFormMock->expects($this->once()) ->method('extractData') ->with($this->requestMock, 'customer') - ->willReturn($filteredData); + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('compactData') - ->with($dataToCompact) - ->willReturn($filteredData); + ->with($extractedData) + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('getAttributes') ->willReturn($attributes); @@ -1062,19 +1026,10 @@ class SaveTest extends \PHPUnit_Framework_TestCase ], 'subscription' => $subscription, ]; - $filteredData = [ + $extractedData = [ 'coolness' => false, 'disable_auto_group_change' => 'false', ]; - $dataToCompact = [ - 'coolness' => false, - 'disable_auto_group_change' => 'false', - CustomerInterface::DEFAULT_BILLING => false, - CustomerInterface::DEFAULT_SHIPPING => false, - 'confirmation' => false, - 'sendemail_store_id' => false, - 'extension_attributes' => false, - ]; /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */ $attributeMock = $this->getMockBuilder( @@ -1124,11 +1079,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase $customerFormMock->expects($this->once()) ->method('extractData') ->with($this->requestMock, 'customer') - ->willReturn($filteredData); + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('compactData') - ->with($dataToCompact) - ->willReturn($filteredData); + ->with($extractedData) + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('getAttributes') ->willReturn($attributes); @@ -1214,18 +1169,9 @@ class SaveTest extends \PHPUnit_Framework_TestCase ], 'subscription' => $subscription, ]; - $filteredData = [ - 'coolness' => false, - 'disable_auto_group_change' => 'false', - ]; - $dataToCompact = [ + $extractedData = [ 'coolness' => false, 'disable_auto_group_change' => 'false', - CustomerInterface::DEFAULT_BILLING => false, - CustomerInterface::DEFAULT_SHIPPING => false, - 'confirmation' => false, - 'sendemail_store_id' => false, - 'extension_attributes' => false, ]; /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */ @@ -1275,11 +1221,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase $customerFormMock->expects($this->once()) ->method('extractData') ->with($this->requestMock, 'customer') - ->willReturn($filteredData); + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('compactData') - ->with($dataToCompact) - ->willReturn($filteredData); + ->with($extractedData) + ->willReturn($extractedData); $customerFormMock->expects($this->once()) ->method('getAttributes') ->willReturn($attributes); diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php index 9eed3d2b044ca166d35703d35e1fd1995e181108..28697fa5cf85faf8bb33dd61c9f5816fc0b60eed 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php @@ -1146,7 +1146,7 @@ class AccountManagementTest extends \PHPUnit_Framework_TestCase $storeId = 1; - mt_srand(mt_rand() + (100000000 * microtime()) % PHP_INT_MAX); + mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX); $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true)); $this->emailNotificationMock->expects($this->once()) @@ -1168,7 +1168,7 @@ class AccountManagementTest extends \PHPUnit_Framework_TestCase $templateIdentifier = 'Template Identifier'; $sender = 'Sender'; - mt_srand(mt_rand() + (100000000 * microtime()) % PHP_INT_MAX); + mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX); $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true)); $this->emailNotificationMock->expects($this->once()) @@ -1194,7 +1194,7 @@ class AccountManagementTest extends \PHPUnit_Framework_TestCase $templateIdentifier = 'Template Identifier'; $sender = 'Sender'; - mt_srand(mt_rand() + (100000000 * microtime()) % PHP_INT_MAX); + mt_srand(mt_rand() + (100000000 * (float)microtime()) % PHP_INT_MAX); $hash = md5(uniqid(microtime() . mt_rand(0, mt_getrandmax()), true)); $this->prepareInitiatePasswordReset($email, $templateIdentifier, $sender, $storeId, $customerId, $hash); diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json index 74f0ebc2b5e0026acbdc5061949c10ad04aa8d9c..53e1a270fb3b04a791a368a375ce7e8b1ef62d8d 100644 --- a/app/code/Magento/Customer/composer.json +++ b/app/code/Magento/Customer/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-customer", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-eav": "100.2.*", "magento/module-directory": "100.2.*", diff --git a/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html b/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html index 1ff64fffe20369a5675afcc573c99b9f926ba30a..9ad2cf5265043b4fd1850514258d99276d500ff3 100644 --- a/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html +++ b/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html @@ -78,7 +78,6 @@ <!-- ko foreach: getRegion('additional-login-form-fields') --> <!-- ko template: getTemplate() --><!-- /ko --> <!-- /ko --> - </div> <div class="actions-toolbar"> <input name="context" type="hidden" value="checkout" /> <div class="primary"> diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json index 533f40c7688e4aa8269bedfe84f5331a772b0b2a..cd02f6dbfb38b46bda32ebdcb87720124eab37e4 100644 --- a/app/code/Magento/CustomerImportExport/composer.json +++ b/app/code/Magento/CustomerImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-customer-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/Deploy/composer.json b/app/code/Magento/Deploy/composer.json index 856e0d8b3e542a37cdd7fcf7554b9e4e158de245..ed0b8520ca645afa8af2506616f9dccde6965f08 100644 --- a/app/code/Magento/Deploy/composer.json +++ b/app/code/Magento/Deploy/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-deploy", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*", "magento/module-store": "100.2.*", "magento/module-require-js": "100.2.*", diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json index 23f6d20c2aab74dc0f23c03f5727aa99379fbf54..73fd1c17750c6749bd0f89cd9fe55939fbe2d419 100644 --- a/app/code/Magento/Developer/composer.json +++ b/app/code/Magento/Developer/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-developer", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/framework": "100.2.*", "magento/module-config": "100.2.*" diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json index e88cd535952d628628bbc984137430d5370a6ecd..15ca7882331a145ba1993ded371bd084bc8c83b3 100644 --- a/app/code/Magento/Dhl/composer.json +++ b/app/code/Magento/Dhl/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-dhl", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-shipping": "100.2.*", diff --git a/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php b/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php index 9ea0babbfd9982c3e9c5657e218668c384b47501..ed36ad3ace22b232c8071bbb195184066a2ebd50 100644 --- a/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php +++ b/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php @@ -12,7 +12,10 @@ class Reader extends \Magento\Framework\Config\Reader\Filesystem * * @var array */ - protected $_idAttributes = ['/config/zip' => 'countryCode']; + protected $_idAttributes = [ + '/config/zip' => 'countryCode', + '/config/zip/codes/code' => 'id', + ]; /** * Construct the FileSystem Reader Class diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json index 9b3b253c26a35ed14c4de51c77624a10750ce5f2..82d8bca34da840e57511bb3912c9b531297d9e86 100644 --- a/app/code/Magento/Directory/composer.json +++ b/app/code/Magento/Directory/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-directory", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json index 8d8814740ccd13248b1e7ab903052ca429567ead..ea8eef6436ef9174e9643c742684f29d1129799f 100644 --- a/app/code/Magento/Downloadable/composer.json +++ b/app/code/Magento/Downloadable/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-downloadable", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/DownloadableImportExport/composer.json b/app/code/Magento/DownloadableImportExport/composer.json index c99a0d6d05b822e792e24a27a69f68f240f8b002..4f95711b279d0f907934fc4cf2bc4b8056ff4817 100644 --- a/app/code/Magento/DownloadableImportExport/composer.json +++ b/app/code/Magento/DownloadableImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-downloadable-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-import-export": "100.2.*", "magento/module-catalog-import-export": "100.2.*", diff --git a/app/code/Magento/Eav/Model/AttributeManagement.php b/app/code/Magento/Eav/Model/AttributeManagement.php index 8d8674bcca0e7886d4a174840a7d55dea5bef8a4..102aafbd39fb1ba473dc1a346a857ccf695a5dab 100644 --- a/app/code/Magento/Eav/Model/AttributeManagement.php +++ b/app/code/Magento/Eav/Model/AttributeManagement.php @@ -6,10 +6,14 @@ */ namespace Magento\Eav\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class AttributeManagement implements \Magento\Eav\Api\AttributeManagementInterface { /** @@ -19,6 +23,7 @@ class AttributeManagement implements \Magento\Eav\Api\AttributeManagementInterfa /** * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection + * @deprecated please use instead \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory */ protected $attributeCollection; @@ -47,6 +52,11 @@ class AttributeManagement implements \Magento\Eav\Api\AttributeManagementInterfa */ protected $attributeResource; + /** + * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory + */ + private $attributeCollectionFactory; + /** * @param \Magento\Eav\Api\AttributeSetRepositoryInterface $setRepository * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $attributeCollection @@ -154,11 +164,26 @@ class AttributeManagement implements \Magento\Eav\Api\AttributeManagementInterfa if (!$attributeSet->getAttributeSetId() || $attributeSet->getEntityTypeId() != $requiredEntityTypeId) { throw NoSuchEntityException::singleField('attributeSetId', $attributeSetId); } - - $attributeCollection = $this->attributeCollection - ->setAttributeSetFilter($attributeSet->getAttributeSetId()) - ->load(); + /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $attributeCollection */ + $attributeCollection = $this->getCollectionFactory()->create(); + $attributeCollection->setAttributeSetFilter($attributeSet->getAttributeSetId())->load(); return $attributeCollection->getItems(); } + + /** + * Retrieve collection factory + * + * @deprecated + * @return \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory + */ + private function getCollectionFactory() + { + if ($this->attributeCollectionFactory === null) { + $this->attributeCollectionFactory = ObjectManager::getInstance()->create( + \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory::class + ); + } + return $this->attributeCollectionFactory; + } } diff --git a/app/code/Magento/Eav/Test/Unit/Model/AttributeManagementTest.php b/app/code/Magento/Eav/Test/Unit/Model/AttributeManagementTest.php index 88118e0b0f70fc54241d76b3895c644c5bd4a616..c45c575dffc2fa9fd87cf9e226ef06ceaa0ce2e2 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/AttributeManagementTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/AttributeManagementTest.php @@ -371,6 +371,24 @@ class AttributeManagementTest extends \PHPUnit_Framework_TestCase $entityType = 'type'; $attributeSetId = 148; + $attributeCollectionFactoryMock = $this->getMock( + \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory::class, + ['create'], + [], + '', + false + ); + $attributeCollectionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->attributeCollectionMock); + + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $objectManager->setBackwardCompatibleProperty( + $this->model, + 'attributeCollectionFactory', + $attributeCollectionFactoryMock + ); + $attributeSetMock = $this->getMock(\Magento\Eav\Api\Data\AttributeSetInterface::class, [], [], '', false); $this->setRepositoryMock->expects($this->once()) ->method('get') diff --git a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/AttributeTest.php b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/AttributeTest.php index bcad34654b98aa2d6d3844d1a780d585713c8d86..c18af6380a3b71ca7adfd6af5146f853926b419d 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/AttributeTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/AttributeTest.php @@ -29,7 +29,7 @@ class AttributeTest extends \PHPUnit_Framework_TestCase { $this->contextMock = $this->getMock( \Magento\Framework\Model\Context::class, - ['getCacheManager', 'getEventDispatcher', 'getLogger', 'getAppState', 'getActionValidator'], + [], [], '', false diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json index 16e62a6434a26aa358a3491d697ce7cd3bb54ad7..9863a89fff5d3d64ccbf8eaa4b3f5691168e0155 100644 --- a/app/code/Magento/Eav/composer.json +++ b/app/code/Magento/Eav/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-eav", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json index 33d04b921278d3c57ce0107792c6deef458c73ab..648c984de0bbb6e93d16f84110075dc36909cfda 100644 --- a/app/code/Magento/Email/composer.json +++ b/app/code/Magento/Email/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-email", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-theme": "100.2.*", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", diff --git a/app/code/Magento/EncryptionKey/composer.json b/app/code/Magento/EncryptionKey/composer.json index 6d7ff5558734ab1952b59b2e02db4cc5093f9984..11b1c034a76a792cd782be06db484e494764553f 100644 --- a/app/code/Magento/EncryptionKey/composer.json +++ b/app/code/Magento/EncryptionKey/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-encryption-key", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-backend": "100.2.*", "magento/framework": "100.2.*" diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json index d27d5c1c60d407ce4d1d5b3781b0209c5955a0d4..8d487485c0d210824949657ab7444ba937ef9996 100644 --- a/app/code/Magento/Fedex/composer.json +++ b/app/code/Magento/Fedex/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-fedex", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-shipping": "100.2.*", "magento/module-directory": "100.2.*", diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json index 04c620dc36db5829f9c8c6aa8a6aec620d211e95..067bf16017b231977183491ff6a4e8cdf91dfe68 100644 --- a/app/code/Magento/GiftMessage/composer.json +++ b/app/code/Magento/GiftMessage/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-gift-message", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-checkout": "100.2.*", diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json index ad3df5c0b8b2621f395acbfe81bfde3c6b7bae27..cacbbe2088c778ff4a3777f129aea263cf9dee79 100644 --- a/app/code/Magento/GoogleAdwords/composer.json +++ b/app/code/Magento/GoogleAdwords/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-google-adwords", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-sales": "100.2.*", "magento/framework": "100.2.*" diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json index 4cccc7bd0cbff69369ae852138045ed06a0dbf4a..8653e93d7a98338160895c65011cdc2f7471270f 100644 --- a/app/code/Magento/GoogleAnalytics/composer.json +++ b/app/code/Magento/GoogleAnalytics/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-google-analytics", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-sales": "100.2.*", "magento/framework": "100.2.*", diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json index 20a48fc78060b53fb144aa5da405b343ce696063..8c61e9f068ea122b74a7dea02ed5c110d26629b6 100644 --- a/app/code/Magento/GoogleOptimizer/composer.json +++ b/app/code/Magento/GoogleOptimizer/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-google-optimizer", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-google-analytics": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json index b036a8d5d528bd3959ea66b294d7b51736f7ba2c..50c061e5b56da30c1faf2bfab9439460be6908a3 100644 --- a/app/code/Magento/GroupedImportExport/composer.json +++ b/app/code/Magento/GroupedImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-grouped-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-import-export": "100.2.*", "magento/module-catalog-import-export": "100.2.*", diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json index 69aed214284454722708703068de37e3134393f0..0f207eb414789becda0c4e57846f0a48ced13d7a 100644 --- a/app/code/Magento/GroupedProduct/composer.json +++ b/app/code/Magento/GroupedProduct/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-grouped-product", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-catalog-inventory": "100.2.*", diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json index 35a088cbd9c91907c3f9f2c434f16cfb86ed57a8..5e403d2180652a6f3565bf03b573abf75310f19f 100644 --- a/app/code/Magento/ImportExport/composer.json +++ b/app/code/Magento/ImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json index cbaab12f6ee285ac1207f8c01d5ed5ff5af42c07..e80d8a9f7bc90d63dfbbced39431571d73fdc937 100644 --- a/app/code/Magento/Indexer/composer.json +++ b/app/code/Magento/Indexer/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-indexer", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-backend": "100.2.*", "magento/framework": "100.2.*" }, diff --git a/app/code/Magento/Integration/Model/Config.php b/app/code/Magento/Integration/Model/Config.php index 70795cae0035034a7801c6a21cc3bb90ab566e1f..3cea4d33743198988c44d8c8aae9bf6e9f247efa 100644 --- a/app/code/Magento/Integration/Model/Config.php +++ b/app/code/Magento/Integration/Model/Config.php @@ -5,6 +5,8 @@ */ namespace Magento\Integration\Model; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; use Magento\Integration\Model\Cache\Type; /** @@ -34,14 +36,24 @@ class Config */ protected $_integrations; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param Cache\Type $configCacheType * @param Config\Reader $configReader + * @param SerializerInterface $serializer */ - public function __construct(Cache\Type $configCacheType, Config\Reader $configReader) - { + public function __construct( + Cache\Type $configCacheType, + Config\Reader $configReader, + SerializerInterface $serializer = null + ) { $this->_configCacheType = $configCacheType; $this->_configReader = $configReader; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -55,10 +67,14 @@ class Config if (null === $this->_integrations) { $integrations = $this->_configCacheType->load(self::CACHE_ID); if ($integrations && is_string($integrations)) { - $this->_integrations = unserialize($integrations); + $this->_integrations = $this->serializer->unserialize($integrations); } else { $this->_integrations = $this->_configReader->read(); - $this->_configCacheType->save(serialize($this->_integrations), self::CACHE_ID, [Type::CACHE_TAG]); + $this->_configCacheType->save( + $this->serializer->serialize($this->_integrations), + self::CACHE_ID, + [Type::CACHE_TAG] + ); } } return $this->_integrations; diff --git a/app/code/Magento/Integration/Model/ConsolidatedConfig.php b/app/code/Magento/Integration/Model/ConsolidatedConfig.php index 9027bf774bc30a9a5b7cb6a427057efc45971742..9208d19e7028f8f753d6e20c2d43765163cb9bec 100644 --- a/app/code/Magento/Integration/Model/ConsolidatedConfig.php +++ b/app/code/Magento/Integration/Model/ConsolidatedConfig.php @@ -5,6 +5,8 @@ */ namespace Magento\Integration\Model; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; use Magento\Integration\Model\Cache\TypeConsolidated; /** @@ -31,14 +33,24 @@ class ConsolidatedConfig */ protected $integrations; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param Cache\TypeConsolidated $configCacheType * @param Config\Consolidated\Reader $configReader + * @param SerializerInterface $serializer */ - public function __construct(Cache\TypeConsolidated $configCacheType, Config\Consolidated\Reader $configReader) - { + public function __construct( + Cache\TypeConsolidated $configCacheType, + Config\Consolidated\Reader $configReader, + SerializerInterface $serializer = null + ) { $this->configCacheType = $configCacheType; $this->configReader = $configReader; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -51,11 +63,11 @@ class ConsolidatedConfig if (null === $this->integrations) { $integrations = $this->configCacheType->load(self::CACHE_ID); if ($integrations && is_string($integrations)) { - $this->integrations = unserialize($integrations); + $this->integrations = $this->serializer->unserialize($integrations); } else { $this->integrations = $this->configReader->read(); $this->configCacheType->save( - serialize($this->integrations), + $this->serializer->serialize($this->integrations), self::CACHE_ID, [TypeConsolidated::CACHE_TAG] ); diff --git a/app/code/Magento/Integration/Model/IntegrationConfig.php b/app/code/Magento/Integration/Model/IntegrationConfig.php index 647bff70efe4afdffd35e5294251e0fe9e98aa98..cde4fc20d22351ff4b9dedd9d93254f8d838438a 100644 --- a/app/code/Magento/Integration/Model/IntegrationConfig.php +++ b/app/code/Magento/Integration/Model/IntegrationConfig.php @@ -6,6 +6,8 @@ namespace Magento\Integration\Model; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; use Magento\Integration\Model\Cache\TypeIntegration; use Magento\Integration\Model\Config\Integration\Reader; @@ -36,14 +38,24 @@ class IntegrationConfig */ protected $_integrations; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param TypeIntegration $configCacheType * @param Reader $configReader + * @param SerializerInterface $serializer */ - public function __construct(TypeIntegration $configCacheType, Reader $configReader) - { + public function __construct( + TypeIntegration $configCacheType, + Reader $configReader, + SerializerInterface $serializer = null + ) { $this->_configCacheType = $configCacheType; $this->_configReader = $configReader; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -57,11 +69,11 @@ class IntegrationConfig if (null === $this->_integrations) { $integrations = $this->_configCacheType->load(self::CACHE_ID); if ($integrations && is_string($integrations)) { - $this->_integrations = unserialize($integrations); + $this->_integrations = $this->serializer->unserialize($integrations); } else { $this->_integrations = $this->_configReader->read(); $this->_configCacheType->save( - serialize($this->_integrations), + $this->serializer->serialize($this->_integrations), self::CACHE_ID, [TypeIntegration::CACHE_TAG] ); diff --git a/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php b/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php index 0b75592782773d504061e4e6f9a56c67ebe5982e..22b50a8aef8d070c479ca2a28b499308a6a95c80 100644 --- a/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php +++ b/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Integration\Test\Unit\Model; +use Magento\Framework\Serialize\SerializerInterface; use Magento\Integration\Model\ConsolidatedConfig as Config; use Magento\Integration\Model\Cache\TypeConsolidated as Type; @@ -18,17 +19,22 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase * * @var Config */ - protected $configModel; + private $configModel; /** * @var Type|\PHPUnit_Framework_MockObject_MockObject */ - protected $configCacheTypeMock; + private $configCacheTypeMock; /** * @var \Magento\Integration\Model\Config\Consolidated\Reader|\PHPUnit_Framework_MockObject_MockObject */ - protected $configReaderMock; + private $configReaderMock; + + /** + * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $serializer; protected function setUp() { @@ -38,12 +44,16 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase $this->configReaderMock = $this->getMockBuilder(\Magento\Integration\Model\Config\Consolidated\Reader::class) ->disableOriginalConstructor() ->getMock(); + $this->serializer = $this->getMockBuilder(SerializerInterface::class) + ->disableOriginalConstructor() + ->getMock(); $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->configModel = $objectManagerHelper->getObject( \Magento\Integration\Model\ConsolidatedConfig::class, [ 'configCacheType' => $this->configCacheTypeMock, - 'configReader' => $this->configReaderMock + 'configReader' => $this->configReaderMock, + 'serializer' => $this->serializer, ] ); } @@ -51,10 +61,15 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase public function testGetIntegrationsFromConfigCacheType() { $integrations = ['foo', 'bar', 'baz']; + $serializedIntegrations = '["foo","bar","baz"]'; $this->configCacheTypeMock->expects($this->once()) ->method('load') ->with(Config::CACHE_ID) - ->will($this->returnValue(serialize($integrations))); + ->will($this->returnValue($serializedIntegrations)); + $this->serializer->expects($this->once()) + ->method('unserialize') + ->with($serializedIntegrations) + ->willReturn($integrations); $this->assertEquals($integrations, $this->configModel->getIntegrations()); } @@ -62,17 +77,21 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase public function testGetIntegrationsFromConfigReader() { $integrations = ['foo', 'bar', 'baz']; + $serializedIntegrations = '["foo","bar","baz"]'; $this->configCacheTypeMock->expects($this->once()) ->method('load') ->with(Config::CACHE_ID) ->will($this->returnValue(null)); - $this->configCacheTypeMock->expects($this->once()) - ->method('save') - ->with(serialize($integrations), Config::CACHE_ID, [Type::CACHE_TAG]) - ->will($this->returnValue(null)); $this->configReaderMock->expects($this->once()) ->method('read') ->will($this->returnValue($integrations)); + $this->serializer->expects($this->once()) + ->method('serialize') + ->with($integrations) + ->willReturn($serializedIntegrations); + $this->configCacheTypeMock->expects($this->once()) + ->method('save') + ->with($serializedIntegrations, Config::CACHE_ID, [Type::CACHE_TAG]); $this->assertEquals($integrations, $this->configModel->getIntegrations()); } diff --git a/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php b/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php index aed4e02453dc435fa5ff87f30931560bace8721e..14871420a621aceec2d5dcb79f209c60fac1f9f6 100644 --- a/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php +++ b/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Integration\Test\Unit\Model; +use Magento\Framework\Serialize\SerializerInterface; use Magento\Integration\Model\IntegrationConfig; use Magento\Integration\Model\Cache\TypeIntegration; @@ -16,17 +17,22 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase /** * @var IntegrationConfig */ - protected $integrationConfigModel; + private $integrationConfigModel; /** * @var TypeIntegration|\PHPUnit_Framework_MockObject_MockObject */ - protected $configCacheTypeMock; + private $configCacheTypeMock; /** * @var \Magento\Integration\Model\Config\Integration\Reader|\PHPUnit_Framework_MockObject_MockObject */ - protected $configReaderMock; + private $configReaderMock; + + /** + * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $serializer; protected function setUp() { @@ -36,19 +42,28 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase $this->configReaderMock = $this->getMockBuilder(\Magento\Integration\Model\Config\Integration\Reader::class) ->disableOriginalConstructor() ->getMock(); + $this->serializer = $this->getMockBuilder(SerializerInterface::class) + ->disableOriginalConstructor() + ->getMock(); $this->integrationConfigModel = new IntegrationConfig( $this->configCacheTypeMock, - $this->configReaderMock + $this->configReaderMock, + $this->serializer ); } public function testGetIntegrationsFromConfigCacheType() { $integrations = ['foo', 'bar', 'baz']; + $serializedIntegrations = '["foo","bar","baz"]'; $this->configCacheTypeMock->expects($this->once()) ->method('load') ->with(IntegrationConfig::CACHE_ID) - ->will($this->returnValue(serialize($integrations))); + ->will($this->returnValue($serializedIntegrations)); + $this->serializer->expects($this->once()) + ->method('unserialize') + ->with($serializedIntegrations) + ->willReturn($integrations); $this->assertEquals($integrations, $this->integrationConfigModel->getIntegrations()); } @@ -56,17 +71,22 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase public function testGetIntegrationsFromConfigReader() { $integrations = ['foo', 'bar', 'baz']; + $serializedIntegrations = '["foo","bar","baz"]'; $this->configCacheTypeMock->expects($this->once()) ->method('load') ->with(IntegrationConfig::CACHE_ID) ->will($this->returnValue(null)); - $this->configCacheTypeMock->expects($this->once()) - ->method('save') - ->with(serialize($integrations), IntegrationConfig::CACHE_ID, [TypeIntegration::CACHE_TAG]) - ->will($this->returnValue(null)); $this->configReaderMock->expects($this->once()) ->method('read') ->will($this->returnValue($integrations)); + $this->serializer->expects($this->once()) + ->method('serialize') + ->with($integrations) + ->willReturn($serializedIntegrations); + $this->configCacheTypeMock->expects($this->once()) + ->method('save') + ->with($serializedIntegrations, IntegrationConfig::CACHE_ID, [TypeIntegration::CACHE_TAG]) + ->will($this->returnValue(null)); $this->assertEquals($integrations, $this->integrationConfigModel->getIntegrations()); } diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json index 028e56472268abc0e0fcc612107a5bd8072da806..f76d60c957c87d828cc773e96a5edf10266293c9 100644 --- a/app/code/Magento/Integration/composer.json +++ b/app/code/Magento/Integration/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-integration", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json index 99299c3e4a32cccd465af4131bc549b033142545..d1d82781bb5c881cceaaf0b8ccdf85fa02c54e86 100644 --- a/app/code/Magento/LayeredNavigation/composer.json +++ b/app/code/Magento/LayeredNavigation/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-layered-navigation", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-catalog": "101.1.*", "magento/framework": "100.2.*" diff --git a/app/code/Magento/Marketplace/Helper/Cache.php b/app/code/Magento/Marketplace/Helper/Cache.php index 1cb5fb9c710e67885f0e7266d57873ca29cb3e21..a0a4ce73e0373ac7d057777160c7ac5028321e8c 100644 --- a/app/code/Magento/Marketplace/Helper/Cache.php +++ b/app/code/Magento/Marketplace/Helper/Cache.php @@ -6,7 +6,8 @@ namespace Magento\Marketplace\Helper; -use Magento\Framework\Filesystem; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; /** * Cache helper @@ -25,15 +26,23 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper */ protected $cache; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Framework\Config\CacheInterface $cache + * @param SerializerInterface $serializer */ public function __construct( \Magento\Framework\App\Helper\Context $context, - \Magento\Framework\Config\CacheInterface $cache + \Magento\Framework\Config\CacheInterface $cache, + SerializerInterface $serializer = null ) { $this->cache = $cache; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); parent::__construct($context); } @@ -46,7 +55,7 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper { $data = $this->getCache()->load($this->pathToCacheFile); if (false !== $data) { - $data = unserialize($data); + $data = $this->serializer->unserialize($data); } return $data; } @@ -59,7 +68,7 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper */ public function savePartnersToCache($partners) { - return $this->getCache()->save(serialize($partners), $this->pathToCacheFile); + return $this->getCache()->save($this->serializer->serialize($partners), $this->pathToCacheFile); } /** diff --git a/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php b/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php index 75c6e6110389c5a920c3053aa451a6d0deab3775..00b78a47eb4b0be4c5b89cf3383dac80028dc899 100644 --- a/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php +++ b/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php @@ -6,70 +6,79 @@ namespace Magento\Marketplace\Test\Unit\Helper; +use Magento\Framework\Serialize\SerializerInterface; + class CacheTest extends \PHPUnit_Framework_TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Marketplace\Helper\Cache + * @var \Magento\Framework\Config\CacheInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $cache; + + /** + * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $cacheHelperMock; + private $serializer; + + /** + * @var \Magento\Marketplace\Helper\Cache + */ + private $cacheHelper; protected function setUp() { - $this->cacheHelperMock = $this->getCacheHelperMock(['getCache']); + $this->cache = $this->getMockForAbstractClass(\Magento\Framework\Config\CacheInterface::class); + $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class); + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->cacheHelper = $objectManagerHelper->getObject( + \Magento\Marketplace\Helper\Cache::class, + [ + 'cache' => $this->cache, + 'serializer' => $this->serializer, + ] + ); } - /** - * @covers \Magento\Marketplace\Helper\Cache::loadPartnersFromCache - */ public function testLoadPartnersFromCache() { - $cache = $this->getCacheMock(); - $this->cacheHelperMock - ->expects($this->once()) - ->method('getCache') - ->will($this->returnValue($cache)); - $cache->expects($this->once()) + $partners = ['partner1', 'partner2']; + $serializedPartners = '["partner1", "partner2"]'; + $this->cache->expects($this->once()) ->method('load') - ->will($this->returnValue('')); + ->with('partners') + ->willReturn($serializedPartners); + $this->serializer->expects($this->once()) + ->method('unserialize') + ->with($serializedPartners) + ->willReturn($partners); - $this->cacheHelperMock->loadPartnersFromCache(); + $this->assertSame($partners, $this->cacheHelper->loadPartnersFromCache()); } - /** - * @covers \Magento\Marketplace\Helper\Cache::savePartnersToCache - */ - public function testSavePartnersToCache() + public function testLoadPartnersFromCacheNoCachedData() { - $cache = $this->getCacheMock(); - $this->cacheHelperMock - ->expects($this->once()) - ->method('getCache') - ->will($this->returnValue($cache)); - $cache->expects($this->once()) - ->method('save') - ->will($this->returnValue(true)); + $this->cache->expects($this->once()) + ->method('load') + ->with('partners') + ->willReturn(false); + $this->serializer->expects($this->never()) + ->method('unserialize'); - $this->cacheHelperMock->savePartnersToCache([]); + $this->assertSame(false, $this->cacheHelper->loadPartnersFromCache()); } - /** - * Gets cache helper mock - * - * @param null $methods - * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Marketplace\Helper\Cache - */ - public function getCacheHelperMock($methods = null) + public function testSavePartnersToCache() { - return $this->getMock(\Magento\Marketplace\Helper\Cache::class, $methods, [], '', false); - } + $partners = ['partner1', 'partner2']; + $serializedPartners = '["partner1", "partner2"]'; + $this->serializer->expects($this->once()) + ->method('serialize') + ->with($partners) + ->willReturn($serializedPartners); + $this->cache->expects($this->once()) + ->method('save') + ->with($serializedPartners); - /** - * Gets Filesystem mock - * - * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Config\CacheInterface - */ - public function getCacheMock() - { - return $this->getMockForAbstractClass(\Magento\Framework\Config\CacheInterface::class); + $this->cacheHelper->savePartnersToCache($partners); } } diff --git a/app/code/Magento/Marketplace/composer.json b/app/code/Magento/Marketplace/composer.json index 2916ff94544bcc46cd59a9e48e9385e89ea6283b..ed79a80bc0c35d81efa3f27867b33846e3a19007 100644 --- a/app/code/Magento/Marketplace/composer.json +++ b/app/code/Magento/Marketplace/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-marketplace", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*", "magento/module-backend": "100.2.*" }, diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json index fa7858d5b0aff32de7d37f2756aca1891cb15cf7..141e1c19c532cc67f8152459de7e12d50fb0b9d8 100644 --- a/app/code/Magento/MediaStorage/composer.json +++ b/app/code/Magento/MediaStorage/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-media-storage", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-config": "100.2.*", diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json index b86374e6be2779d14fd3d2b3e8a4d5b46b1b881f..422aac99869919aa08c31e7ac4edd39d9e0a6f2e 100644 --- a/app/code/Magento/Msrp/composer.json +++ b/app/code/Magento/Msrp/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-msrp", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-downloadable": "100.2.*", diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json index 8d9ac91cd05a07b78c19588cbcd34ce3a110cc9f..970c7ea0569a28d226f8f50c419b3d5ee998a17f 100644 --- a/app/code/Magento/Multishipping/composer.json +++ b/app/code/Magento/Multishipping/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-multishipping", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-checkout": "100.2.*", "magento/module-sales": "100.2.*", diff --git a/app/code/Magento/NewRelicReporting/composer.json b/app/code/Magento/NewRelicReporting/composer.json index 9faa17d454e5072f7dc9ec5473057bfad1533dce..097de6bea926c60644bedefec56adde409f5aa04 100644 --- a/app/code/Magento/NewRelicReporting/composer.json +++ b/app/code/Magento/NewRelicReporting/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-new-relic-reporting", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json index 06a278aef6d48692c856f56daf213e4bab162db8..ab5cdd1510a35285d42698ee999737a74b699d54 100644 --- a/app/code/Magento/Newsletter/composer.json +++ b/app/code/Magento/Newsletter/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-newsletter", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-customer": "100.2.*", "magento/module-widget": "100.2.*", diff --git a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml index fb6989716cd2dfc64d1e97c487e77f3b47afeb35..0ee371c32817649669fe2bc20d88b08e132a9a11 100644 --- a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml +++ b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml @@ -10,7 +10,7 @@ ?> <div class="block newsletter"> - <div class="title"><strong>Newsletter</strong></div> + <div class="title"><strong><?php /* @escapeNotVerified */ echo __('Newsletter') ?></strong></div> <div class="content"> <form class="form subscribe" novalidate diff --git a/app/code/Magento/OfflinePayments/Block/Info/Checkmo.php b/app/code/Magento/OfflinePayments/Block/Info/Checkmo.php index 84b6e554d4cfb193e1418f3d9460f9fcc44f6a7d..8616c186555e3e71db0a13a13c648b5c20ff3e0c 100644 --- a/app/code/Magento/OfflinePayments/Block/Info/Checkmo.php +++ b/app/code/Magento/OfflinePayments/Block/Info/Checkmo.php @@ -49,20 +49,13 @@ class Checkmo extends \Magento\Payment\Block\Info } /** - * Enter description here... - * + * @deprecated * @return $this */ protected function _convertAdditionalData() { - $details = @unserialize($this->getInfo()->getAdditionalData()); - if (is_array($details)) { - $this->_payableTo = isset($details['payable_to']) ? (string)$details['payable_to'] : ''; - $this->_mailingAddress = isset($details['mailing_address']) ? (string)$details['mailing_address'] : ''; - } else { - $this->_payableTo = ''; - $this->_mailingAddress = ''; - } + $this->_payableTo = $this->getInfo()->getAdditionalInformation('payable_to'); + $this->_mailingAddress = $this->getInfo()->getAdditionalInformation('mailing_address'); return $this; } diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php index 848cfbae52b25a0b4b202b296f43ae4b79c5c19a..27209fc8d3538a1465e985929ef6adb52408de93 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php @@ -5,81 +5,118 @@ */ namespace Magento\OfflinePayments\Test\Unit\Block\Info; +use Magento\Framework\View\Element\Template\Context; +use Magento\OfflinePayments\Block\Info\Checkmo; +use Magento\Payment\Model\Info; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * CheckmoTest contains list of test for block methods testing + */ class CheckmoTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\OfflinePayments\Block\Info\Checkmo + * @var Info|MockObject + */ + private $info; + + /** + * @var Checkmo */ - protected $_model; + private $block; + /** + * @inheritdoc + */ protected function setUp() { - $context = $this->getMock(\Magento\Framework\View\Element\Template\Context::class, [], [], '', false); - $this->_model = new \Magento\OfflinePayments\Block\Info\Checkmo($context); + $context = $this->getMockBuilder(Context::class) + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + + $this->info = $this->getMockBuilder(Info::class) + ->disableOriginalConstructor() + ->setMethods(['getAdditionalInformation']) + ->getMock(); + + $this->block = new Checkmo($context); } /** + * @covers \Magento\OfflinePayments\Block\Info\Checkmo::getPayableTo + * @param array $details + * @param string|null $expected * @dataProvider getPayableToDataProvider */ public function testGetPayableTo($details, $expected) { - $info = $this->getMock(\Magento\Payment\Model\Info::class, ['getAdditionalData'], [], '', false); - $info->expects($this->once()) - ->method('getAdditionalData') - ->willReturn(serialize($details)); - $this->_model->setData('info', $info); + $this->info->expects(static::at(0)) + ->method('getAdditionalInformation') + ->with('payable_to') + ->willReturn($details); + $this->block->setData('info', $this->info); - $this->assertEquals($expected, $this->_model->getPayableTo()); + static::assertEquals($expected, $this->block->getPayableTo()); } /** + * Get list of variations for payable configuration option testing * @return array */ public function getPayableToDataProvider() { return [ - [['payable_to' => 'payable'], 'payable'], - ['', ''] + ['payable_to' => 'payable', 'payable'], + ['', null] ]; } /** + * @covers \Magento\OfflinePayments\Block\Info\Checkmo::getMailingAddress + * @param array $details + * @param string|null $expected * @dataProvider getMailingAddressDataProvider */ public function testGetMailingAddress($details, $expected) { - $info = $this->getMock(\Magento\Payment\Model\Info::class, ['getAdditionalData'], [], '', false); - $info->expects($this->once()) - ->method('getAdditionalData') - ->willReturn(serialize($details)); - $this->_model->setData('info', $info); + $this->info->expects(static::at(1)) + ->method('getAdditionalInformation') + ->with('mailing_address') + ->willReturn($details); + $this->block->setData('info', $this->info); - $this->assertEquals($expected, $this->_model->getMailingAddress()); + static::assertEquals($expected, $this->block->getMailingAddress()); } /** + * Get list of variations for mailing address testing * @return array */ public function getMailingAddressDataProvider() { return [ - [['mailing_address' => 'blah@blah.com'], 'blah@blah.com'], - ['', ''] + ['mailing_address' => 'blah@blah.com', 'blah@blah.com'], + ['mailing_address' => '', null] ]; } + /** + * @covers \Magento\OfflinePayments\Block\Info\Checkmo::getMailingAddress + */ public function testConvertAdditionalDataIsNeverCalled() { - $info = $this->getMock(\Magento\Payment\Model\Info::class, ['getAdditionalData'], [], '', false); - $info->expects($this->once()) - ->method('getAdditionalData') - ->willReturn(serialize(['mailing_address' => 'blah@blah.com'])); - $this->_model->setData('info', $info); + $mailingAddress = 'blah@blah.com'; + $this->info->expects(static::at(1)) + ->method('getAdditionalInformation') + ->with('mailing_address') + ->willReturn($mailingAddress); + $this->block->setData('info', $this->info); // First we set the property $this->_mailingAddress - $this->_model->getMailingAddress(); + $this->block->getMailingAddress(); // And now we get already setted property $this->_mailingAddress - $this->assertEquals('blah@blah.com', $this->_model->getMailingAddress()); + static::assertEquals($mailingAddress, $this->block->getMailingAddress()); } } diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json index 52deb08ba3d904a824faa762391ddf67ae29b026..cf728aaa1c5f6a7ea7c36163b021cb378d7df7f0 100644 --- a/app/code/Magento/OfflinePayments/composer.json +++ b/app/code/Magento/OfflinePayments/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-offline-payments", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-checkout": "100.2.*", "magento/module-payment": "100.2.*", "magento/framework": "100.2.*" diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml index d5bff77e002d17d5ad8a80349ea646aee0135fa4..8c5cfd50cc110f2f8c61414c14ed2d48965929d6 100644 --- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml +++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml @@ -10,7 +10,7 @@ */ ?> <?php echo $block->escapeHtml($block->getMethod()->getTitle()) ?> -<?php if ($block->getInfo()->getAdditionalData()): ?> +<?php if ($block->getInfo()->getAdditionalInformation()): ?> <?php if ($block->getPayableTo()): ?> <br /><?php echo $block->escapeHtml(__('Make Check payable to: %1', $block->getPayableTo())) ?> <?php endif; ?> diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml index 6195cdbd776548c229a6d1dfca03c8f4c1b2a61f..5587ac239d37e84a21348cfd994d9d0b73f0ba97 100644 --- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml +++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml @@ -11,7 +11,7 @@ ?> <?php echo $block->escapeHtml($block->getMethod()->getTitle()) ?> {{pdf_row_separator}} -<?php if ($block->getInfo()->getAdditionalData()): ?> +<?php if ($block->getInfo()->getAdditionalInformation()): ?> {{pdf_row_separator}} <?php if ($block->getPayableTo()): ?> <?php echo $block->escapeHtml(__('Make Check payable to: %1', $block->getPayableTo())) ?> diff --git a/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml b/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml index f0dbff1add32b2fd7d49e3b6ca5f14c4038fc2ca..3c0b6bb23086a67b48de1134cdb245daffeab045 100644 --- a/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml +++ b/app/code/Magento/OfflinePayments/view/frontend/templates/info/checkmo.phtml @@ -11,7 +11,7 @@ ?> <dl class="payment-method checkmemo"> <dt class="title"><?php echo $block->escapeHtml($block->getMethod()->getTitle()) ?></dt> - <?php if ($block->getInfo()->getAdditionalData()): ?> + <?php if ($block->getInfo()->getAdditionalInformation()): ?> <?php if ($block->getPayableTo()): ?> <dd class="content"> <strong><?php echo $block->escapeHtml(__('Make Check payable to')) ?></strong> diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json index 3c959b4dec766fe09cf81df46571051b714ee4e1..b429376c6cd7adc0a70b133a633b4edf068d684e 100644 --- a/app/code/Magento/OfflineShipping/composer.json +++ b/app/code/Magento/OfflineShipping/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-offline-shipping", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", diff --git a/app/code/Magento/OfflineShipping/etc/adminhtml/system.xml b/app/code/Magento/OfflineShipping/etc/adminhtml/system.xml index 50ed4cdc9417833683a04e3a715ff828f04b9674..4a4f550588f5366668f4ceee0ff895964246172b 100644 --- a/app/code/Magento/OfflineShipping/etc/adminhtml/system.xml +++ b/app/code/Magento/OfflineShipping/etc/adminhtml/system.xml @@ -52,6 +52,7 @@ <field id="showmethod" translate="label" type="select" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Show Method if Not Applicable</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + <frontend_class>shipping-skip-hide</frontend_class> </field> <field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Displayed Error Message</label> @@ -146,6 +147,7 @@ <field id="showmethod" translate="label" type="select" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Show Method if Not Applicable</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + <frontend_class>shipping-skip-hide</frontend_class> </field> <field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Displayed Error Message</label> diff --git a/app/code/Magento/PageCache/Model/Config.php b/app/code/Magento/PageCache/Model/Config.php index 222d9d57e467a31988fd6b6ac221f7ce640c06c5..786165728406f0162be0da04f869a10020d9d3bb 100644 --- a/app/code/Magento/PageCache/Model/Config.php +++ b/app/code/Magento/PageCache/Model/Config.php @@ -148,12 +148,17 @@ class Config ), '/* {{ ips }} */' => $this->_getAccessList(), '/* {{ design_exceptions_code }} */' => $this->_getDesignExceptions(), - // http headers get transformed by php `X-Forwarded-Proto: https` becomes $SERVER['HTTP_X_FORWARDED_PROTO'] = 'https' + // http headers get transformed by php `X-Forwarded-Proto: https` + // becomes $SERVER['HTTP_X_FORWARDED_PROTO'] = 'https' // Apache and Nginx drop all headers with underlines by default. - '/* {{ ssl_offloaded_header }} */' => str_replace('_', '-', $this->_scopeConfig->getValue( - \Magento\Framework\HTTP\PhpEnvironment\Request::XML_PATH_OFFLOADER_HEADER, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) - + '/* {{ ssl_offloaded_header }} */' => str_replace( + '_', + '-', + $this->_scopeConfig->getValue( + \Magento\Framework\HTTP\PhpEnvironment\Request::XML_PATH_OFFLOADER_HEADER, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ) + ) ]; } @@ -176,6 +181,7 @@ class Config \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); if (!empty($accessList)) { + $result = []; $ips = explode(',', $accessList); foreach ($ips as $ip) { $result[] = sprintf($tpl, trim($ip)); diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json index 5c29e4fc3c97081626ae4a77243ccd6ac9843d38..f18eb7bbe94edd31a48c4796dc41b21cdef38a8b 100644 --- a/app/code/Magento/PageCache/composer.json +++ b/app/code/Magento/PageCache/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-page-cache", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json index 35ff326d916bd43f8ae2366d9b50f5b77fe46dc8..c8d7254ce9e002ced1ecfb1067d821c63dbeb5be 100644 --- a/app/code/Magento/Payment/composer.json +++ b/app/code/Magento/Payment/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-payment", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-sales": "100.2.*", diff --git a/app/code/Magento/Paypal/composer.json b/app/code/Magento/Paypal/composer.json index bddc5d91a94587f4d26532246d8c83f8de6ba7f7..7503db18f008ca76252f8687df6d52f88dc0e02d 100644 --- a/app/code/Magento/Paypal/composer.json +++ b/app/code/Magento/Paypal/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-paypal", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-checkout": "100.2.*", diff --git a/app/code/Magento/Paypal/etc/adminhtml/system/express_checkout.xml b/app/code/Magento/Paypal/etc/adminhtml/system/express_checkout.xml index 1876f07830ba7b55df25230bc256b829f65b2fc3..90cb60186e34e3730ae6d068b34e4002add00a6c 100644 --- a/app/code/Magento/Paypal/etc/adminhtml/system/express_checkout.xml +++ b/app/code/Magento/Paypal/etc/adminhtml/system/express_checkout.xml @@ -23,7 +23,8 @@ <label>Express Checkout</label> <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model> <field id="business_account" translate="label comment tooltip" showInDefault="1" showInWebsite="1" sortOrder="5"> - <label>Email Associated with PayPal Merchant Account</label> + <label>Email Associated with PayPal Merchant Account (Optional)</label> + <frontend_class>not-required</frontend_class> <comment> <![CDATA[<a href="http://www.magentocommerce.com/paypal">Start accepting payments via PayPal!</a>]]> </comment> diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json index 25cc9d76acd768fe970363628abad60945e418d9..61f77a104c016d23f3734433efd8646bd21b42f4 100644 --- a/app/code/Magento/Persistent/composer.json +++ b/app/code/Magento/Persistent/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-persistent", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-checkout": "100.2.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json index a43a52209740318e0f5adcc8bea03a8860c04037..9c63c6958a465852ea3148cab659102880b07630 100644 --- a/app/code/Magento/ProductAlert/composer.json +++ b/app/code/Magento/ProductAlert/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-product-alert", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-backend": "100.2.*", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php b/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php index f0edccbaf812acbf8495d97817515395635af409..7a087f769877160a316635baf9017b8b37ebbd38 100644 --- a/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php +++ b/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php @@ -6,6 +6,7 @@ namespace Magento\ProductVideo\Controller\Adminhtml\Product\Gallery; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\File\Uploader; /** @@ -43,6 +44,13 @@ class RetrieveImage extends \Magento\Backend\App\Action */ protected $fileUtility; + /** + * URI validator + * + * @var \Magento\Framework\Validator\ValidatorInterface + */ + private $protocolValidator; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory @@ -51,6 +59,7 @@ class RetrieveImage extends \Magento\Backend\App\Action * @param \Magento\Framework\Image\AdapterFactory $imageAdapterFactory * @param \Magento\Framework\HTTP\Adapter\Curl $curl * @param \Magento\MediaStorage\Model\ResourceModel\File\Storage\File $fileUtility + * @param \Magento\Framework\Validator\ValidatorInterface $protocolValidator */ public function __construct( \Magento\Backend\App\Action\Context $context, @@ -59,7 +68,8 @@ class RetrieveImage extends \Magento\Backend\App\Action \Magento\Framework\Filesystem $fileSystem, \Magento\Framework\Image\AdapterFactory $imageAdapterFactory, \Magento\Framework\HTTP\Adapter\Curl $curl, - \Magento\MediaStorage\Model\ResourceModel\File\Storage\File $fileUtility + \Magento\MediaStorage\Model\ResourceModel\File\Storage\File $fileUtility, + \Magento\Framework\Validator\ValidatorInterface $protocolValidator = null ) { parent::__construct($context); $this->resultRawFactory = $resultRawFactory; @@ -68,6 +78,10 @@ class RetrieveImage extends \Magento\Backend\App\Action $this->imageAdapter = $imageAdapterFactory->create(); $this->curl = $curl; $this->fileUtility = $fileUtility; + + $this->protocolValidator = $protocolValidator ?: + \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Validator\ValidatorInterface::class); } /** @@ -78,15 +92,15 @@ class RetrieveImage extends \Magento\Backend\App\Action $baseTmpMediaPath = $this->mediaConfig->getBaseTmpMediaPath(); try { $remoteFileUrl = $this->getRequest()->getParam('remote_image'); - $originalFileName = basename($remoteFileUrl); - $localFileName = Uploader::getCorrectFileName($originalFileName); + $this->validateRemoteFile($remoteFileUrl); + $localFileName = Uploader::getCorrectFileName(basename($remoteFileUrl)); $localTmpFileName = Uploader::getDispretionPath($localFileName) . DIRECTORY_SEPARATOR . $localFileName; - $localFileMediaPath = $baseTmpMediaPath . ($localTmpFileName); - $localUniqueFileMediaPath = $this->appendNewFileName($localFileMediaPath); - $this->retrieveRemoteImage($remoteFileUrl, $localUniqueFileMediaPath); - $localFileFullPath = $this->appendAbsoluteFileSystemPath($localUniqueFileMediaPath); + $localFilePath = $baseTmpMediaPath . ($localTmpFileName); + $localUniqFilePath = $this->appendNewFileName($localFilePath); + $this->retrieveRemoteImage($remoteFileUrl, $localUniqFilePath); + $localFileFullPath = $this->appendAbsoluteFileSystemPath($localUniqFilePath); $this->imageAdapter->validateUploadFile($localFileFullPath); - $result = $this->appendResultSaveRemoteImage($localUniqueFileMediaPath); + $result = $this->appendResultSaveRemoteImage($localUniqFilePath); } catch (\Exception $e) { $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; } @@ -98,6 +112,25 @@ class RetrieveImage extends \Magento\Backend\App\Action return $response; } + /** + * Validate remote file + * + * @param string $remoteFileUrl + * @throws LocalizedException + * + * @return $this + */ + private function validateRemoteFile($remoteFileUrl) + { + if (!$this->protocolValidator->isValid($remoteFileUrl)) { + throw new LocalizedException( + __("Protocol isn't allowed") + ); + } + + return $this; + } + /** * @param string $fileName * @return mixed @@ -116,6 +149,8 @@ class RetrieveImage extends \Magento\Backend\App\Action } /** + * Trying to get remote image to save it locally + * * @param string $fileUrl * @param string $localFilePath * @return void @@ -127,7 +162,7 @@ class RetrieveImage extends \Magento\Backend\App\Action $this->curl->write('GET', $fileUrl); $image = $this->curl->read(); if (empty($image)) { - throw new \Magento\Framework\Exception\LocalizedException( + throw new LocalizedException( __('Could not get preview image information. Please check your connection and try again.') ); } diff --git a/app/code/Magento/ProductVideo/Test/Unit/Controller/Adminhtml/Product/Gallery/RetrieveImageTest.php b/app/code/Magento/ProductVideo/Test/Unit/Controller/Adminhtml/Product/Gallery/RetrieveImageTest.php index 79d83f38421bba1a2e582efc3bc90f261c8b79dc..64149d529e5ca8f993e300594279a7e0842f9b8b 100644 --- a/app/code/Magento/ProductVideo/Test/Unit/Controller/Adminhtml/Product/Gallery/RetrieveImageTest.php +++ b/app/code/Magento/ProductVideo/Test/Unit/Controller/Adminhtml/Product/Gallery/RetrieveImageTest.php @@ -73,17 +73,11 @@ class RetrieveImageTest extends \PHPUnit_Framework_TestCase */ protected function setUp() { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->contextMock = $this->getMock(\Magento\Backend\App\Action\Context::class, [], [], '', false); $this->rawFactoryMock = $this->getMock(\Magento\Framework\Controller\Result\RawFactory::class, ['create'], [], '', false); - $response = - $this->getMock( - \Magento\Framework\Controller\Result\Raw::class, - [], - [], - '', - false - ); + $response = new \Magento\Framework\DataObject(); $this->rawFactoryMock->expects($this->once())->method('create')->willReturn($response); $this->configMock = $this->getMock(\Magento\Catalog\Model\Product\Media\Config::class, [], [], '', false); $this->filesystemMock = $this->getMock(\Magento\Framework\Filesystem::class, [], [], '', false); @@ -101,11 +95,15 @@ class RetrieveImageTest extends \PHPUnit_Framework_TestCase $this->adapterFactoryMock->expects($this->once())->method('create')->willReturn($this->abstractAdapter); $this->curlMock = $this->getMock(\Magento\Framework\HTTP\Adapter\Curl::class, [], [], '', false); $this->storageFileMock = - $this->getMock(\Magento\MediaStorage\Model\ResourceModel\File\Storage\File::class, [], [], '', false); + $this->getMock(\Magento\MediaStorage\Model\ResourceModel\File\Storage\File::class, [], [], '', false); $this->request = $this->getMock(\Magento\Framework\App\RequestInterface::class); $this->contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->request)); - - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $managerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->setMethods(['get']) + ->getMockForAbstractClass(); + $this->contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->request)); + $this->contextMock->expects($this->any())->method('getObjectManager')->willReturn($managerMock); $this->image = $objectManager->getObject( \Magento\ProductVideo\Controller\Adminhtml\Product\Gallery\RetrieveImage::class, @@ -117,6 +115,7 @@ class RetrieveImageTest extends \PHPUnit_Framework_TestCase 'imageAdapterFactory' => $this->adapterFactoryMock, 'curl' => $this->curlMock, 'fileUtility' => $this->storageFileMock, + 'protocolValidator' => new \Magento\Framework\Validator\AllowedProtocols(), ] ); } diff --git a/app/code/Magento/ProductVideo/composer.json b/app/code/Magento/ProductVideo/composer.json index 362fd006d2690c9f9b60b7be3abb71d5ce0b4da7..08d21e4c2abbfb167aed2ca24c0ba012d6b2e8c8 100644 --- a/app/code/Magento/ProductVideo/composer.json +++ b/app/code/Magento/ProductVideo/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-product-video", "description": "Add Video to Products", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-backend": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/ProductVideo/etc/di.xml b/app/code/Magento/ProductVideo/etc/di.xml index 09c15d8fccecc64d3dd183e7940aa26b6819d6df..7242a9d48ce1e3c0da66a3f4d5953cda705132cd 100644 --- a/app/code/Magento/ProductVideo/etc/di.xml +++ b/app/code/Magento/ProductVideo/etc/di.xml @@ -7,6 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Framework\Api\Data\VideoContentInterface" type="Magento\ProductVideo\Model\Product\Attribute\Media\VideoEntry" /> + <preference for="Magento\Framework\Validator\ValidatorInterface" type="Magento\Framework\Validator\AllowedProtocols" /> <type name="Magento\Catalog\Model\Product\Attribute\Backend\Media\EntryConverterPool"> <arguments> <argument name="mediaGalleryEntryConvertersCollection" xsi:type="array"> diff --git a/app/code/Magento/ProductVideo/i18n/en_US.csv b/app/code/Magento/ProductVideo/i18n/en_US.csv index 4cfabe1592dd2d0ce5c8072f0bdaafbc847689e6..64a08075c19548bc092f3918e7dabf606dd2052e 100644 --- a/app/code/Magento/ProductVideo/i18n/en_US.csv +++ b/app/code/Magento/ProductVideo/i18n/en_US.csv @@ -40,3 +40,4 @@ Delete,Delete "Show related video","Show related video" "Auto restart video","Auto restart video" "Images And Videos","Images And Videos" +"Protocol isn't allowed", "Protocol isn't allowed" diff --git a/app/code/Magento/Quote/Model/QueryResolver.php b/app/code/Magento/Quote/Model/QueryResolver.php index cfc1480feb66386a122b21a6484107a205cad566..04d83bab85b2bf4b31c5d57e8c2b742614a4694b 100644 --- a/app/code/Magento/Quote/Model/QueryResolver.php +++ b/app/code/Magento/Quote/Model/QueryResolver.php @@ -5,8 +5,10 @@ */ namespace Magento\Quote\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Config\CacheInterface; use Magento\Framework\App\ResourceConnection\ConfigInterface; +use Magento\Framework\Serialize\SerializerInterface; class QueryResolver { @@ -37,19 +39,27 @@ class QueryResolver */ private $cacheTags = []; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param ConfigInterface $config * @param CacheInterface $cache * @param string $cacheId + * @param SerializerInterface $serializer */ public function __construct( ConfigInterface $config, CacheInterface $cache, - $cacheId = 'connection_config_cache' + $cacheId = 'connection_config_cache', + SerializerInterface $serializer = null ) { $this->config = $config; $this->cache = $cache; $this->cacheId = $cacheId; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -75,9 +85,9 @@ class QueryResolver if (false === $data) { $singleQuery = $this->config->getConnectionName('checkout_setup') == 'default' ? true : false; $data['checkout'] = $singleQuery; - $this->cache->save(serialize($data), $this->cacheId, $this->cacheTags); + $this->cache->save($this->serializer->serialize($data), $this->cacheId, $this->cacheTags); } else { - $data = unserialize($data); + $data = $this->serializer->unserialize($data); } $this->merge($data); } diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php b/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php index 8e62d1b942f1e2a5808e76ac293c94abd9830cad..d430bf3acc6cd08d22b0f352efde6b9dc7774fed 100644 --- a/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php +++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php @@ -5,6 +5,8 @@ */ namespace Magento\Quote\Model\Quote\Address\Total; +use Magento\Framework\Serialize\SerializerInterface; + /** * Address Total Collector model */ @@ -69,6 +71,7 @@ class Collector extends \Magento\Sales\Model\Config\Ordered * @param \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory * @param mixed $sourceData * @param mixed $store + * @param SerializerInterface $serializer */ public function __construct( \Magento\Framework\App\Cache\Type\Config $configCacheType, @@ -78,11 +81,12 @@ class Collector extends \Magento\Sales\Model\Config\Ordered \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory, $sourceData = null, - $store = null + $store = null, + SerializerInterface $serializer = null ) { $this->_scopeConfig = $scopeConfig; $this->_totalFactory = $totalFactory; - parent::__construct($configCacheType, $logger, $salesConfig, $sourceData); + parent::__construct($configCacheType, $logger, $salesConfig, $sourceData, $serializer); $this->_store = $store ?: $storeManager->getStore(); $this->_initModels()->_initCollectors()->_initRetrievers(); } diff --git a/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php b/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php index a2075b1161fc2a9cde83ba9af7bd2729244aa9a3..eb6828afff4edc79f0fb32bea383515ebacdcf86 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php @@ -6,83 +6,100 @@ namespace Magento\Quote\Test\Unit\Model; +use Magento\Framework\Serialize\SerializerInterface; + class QueryResolverTest extends \PHPUnit_Framework_TestCase { /** * @var \Magento\Quote\Model\QueryResolver */ - protected $quoteResolver; + private $quoteResolver; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $configMock; + private $configMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $cacheMock; + private $cacheMock; + + /** + * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $serializer; protected function setUp() { $this->configMock = $this->getMock(\Magento\Framework\App\ResourceConnection\ConfigInterface::class); $this->cacheMock = $this->getMock(\Magento\Framework\Config\CacheInterface::class); + $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class); $this->quoteResolver = new \Magento\Quote\Model\QueryResolver( $this->configMock, $this->cacheMock, - 'connection_config_cache' + 'connection_config_cache', + $this->serializer ); - } public function testIsSingleQueryWhenDataWereCached() { - $queryData['checkout'] = true; + $serializedData = '{"checkout":true}'; + $data = ['checkout' => true]; $this->cacheMock ->expects($this->once()) ->method('load') ->with('connection_config_cache') - ->willReturn(serialize($queryData)); + ->willReturn($serializedData); + $this->serializer->expects($this->once()) + ->method('unserialize') + ->with($serializedData) + ->willReturn($data); $this->assertTrue($this->quoteResolver->isSingleQuery()); } - public function testIsSingleQueryWhenDataNotCached() + /** + * @param string $connectionName + * @param bool $isSingleQuery + * + * @dataProvider isSingleQueryWhenDataNotCachedDataProvider + */ + public function testIsSingleQueryWhenDataNotCached($connectionName, $isSingleQuery) { - $queryData['checkout'] = true; + $data = ['checkout' => $isSingleQuery]; + $serializedData = '{"checkout":true}'; $this->cacheMock ->expects($this->once()) ->method('load') ->with('connection_config_cache') ->willReturn(false); + $this->serializer->expects($this->never()) + ->method('unserialize'); $this->configMock ->expects($this->once()) ->method('getConnectionName') ->with('checkout_setup') - ->willReturn('default'); + ->willReturn($connectionName); + $this->serializer->expects($this->once()) + ->method('serialize') + ->with($data) + ->willReturn($serializedData); $this->cacheMock ->expects($this->once()) ->method('save') - ->with(serialize($queryData), 'connection_config_cache', []); - $this->assertTrue($this->quoteResolver->isSingleQuery()); + ->with($serializedData, 'connection_config_cache', []); + $this->assertEquals($isSingleQuery, $this->quoteResolver->isSingleQuery()); } - public function testIsSingleQueryWhenSeveralConnectionsExist() + /** + * @return array + */ + public function isSingleQueryWhenDataNotCachedDataProvider() { - $queryData['checkout'] = false; - $this->cacheMock - ->expects($this->once()) - ->method('load') - ->with('connection_config_cache') - ->willReturn(false); - $this->configMock - ->expects($this->once()) - ->method('getConnectionName') - ->with('checkout_setup') - ->willReturn('checkout'); - $this->cacheMock - ->expects($this->once()) - ->method('save') - ->with(serialize($queryData), 'connection_config_cache', []); - $this->assertFalse($this->quoteResolver->isSingleQuery()); + return [ + ['default', true], + ['checkout', false], + ]; } } diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json index 79c3a1aaa9d907cea1c505ece12a22e4ee3986f2..76063b177d46c2eb93626dea77a346aaaeb5c21d 100644 --- a/app/code/Magento/Quote/composer.json +++ b/app/code/Magento/Quote/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-quote", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json index 0bb989cb54ac8cb84e3da943a231634b6707f256..9c76abd07b9b35276f1f923138c9dd47031c289d 100644 --- a/app/code/Magento/Reports/composer.json +++ b/app/code/Magento/Reports/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-reports", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json index 8c9fed33ab730dd2431b222b2edd04aa2252e12f..68428caa867bf7108fc466ebfd1fa2829a2b75fa 100644 --- a/app/code/Magento/RequireJs/composer.json +++ b/app/code/Magento/RequireJs/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-require-js", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*" }, "type": "magento2-module", diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json index 09f5529feabdd97512839be2dacd00f791083c3c..3ec82943476088c3aa307de1b5a934a3cac8ca0d 100644 --- a/app/code/Magento/Review/composer.json +++ b/app/code/Magento/Review/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-review", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml index 7c89fd8740c5607ec83f0d0a4dda761de50d97ed..bcac1dbca059833749faf9db4d759f8a06a6f24a 100644 --- a/app/code/Magento/Review/view/frontend/templates/form.phtml +++ b/app/code/Magento/Review/view/frontend/templates/form.phtml @@ -20,7 +20,7 @@ <?php if ($block->getRatings() && $block->getRatings()->getSize()): ?> <span id="input-message-box"></span> <fieldset class="field required review-field-ratings"> - <legend class="label"><span><?php echo $block->escapeHtml(__('Your Rating')) ?><span></legend><br/> + <legend class="label"><span><?php echo $block->escapeHtml(__('Your Rating')) ?></span></legend><br/> <div class="control"> <div class="nested" id="product-review-table"> <?php foreach ($block->getRatings() as $_rating): ?> diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json index d35f0ee6ebecbf75af87566d776f172ab3d22c0d..fedd0ffeaacfe9577ea6e5971411540d4925fe4c 100644 --- a/app/code/Magento/Rss/composer.json +++ b/app/code/Magento/Rss/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-rss", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/framework": "100.2.*", diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json index 95b8e6ffec2a682895b3459ca7bdcc7b4f001669..31ee3254d99b98a10ce9973e3a8a4adb1c5818da 100644 --- a/app/code/Magento/Rule/composer.json +++ b/app/code/Magento/Rule/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-rule", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-eav": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php index 36f1310079ed534d928fa03be511a64265f71dc5..ac3ffdc3d622c956074b3fc174df6c24e4cabff3 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php @@ -217,9 +217,9 @@ class CreditmemoLoader extends DataObject foreach ($creditmemo->getAllItems() as $creditmemoItem) { $orderItem = $creditmemoItem->getOrderItem(); $parentId = $orderItem->getParentItemId(); - if (isset($backToStock[$orderItem->getId()])) { + if ($parentId && isset($backToStock[$parentId]) && $backToStock[$parentId]) { $creditmemoItem->setBackToStock(true); - } elseif ($orderItem->getParentItem() && isset($backToStock[$parentId]) && $backToStock[$parentId]) { + } elseif (isset($backToStock[$orderItem->getId()])) { $creditmemoItem->setBackToStock(true); } elseif (empty($savedData)) { $creditmemoItem->setBackToStock( diff --git a/app/code/Magento/Sales/Model/Config/Ordered.php b/app/code/Magento/Sales/Model/Config/Ordered.php index 7ea7d1f8cc5fae05277754e033c9a4cb9fac37f6..806a7b522c189f495e080307981bf8fd95f3d420 100644 --- a/app/code/Magento/Sales/Model/Config/Ordered.php +++ b/app/code/Magento/Sales/Model/Config/Ordered.php @@ -5,6 +5,9 @@ */ namespace Magento\Sales\Model\Config; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; + /** * Configuration class for ordered items * @@ -69,22 +72,30 @@ abstract class Ordered extends \Magento\Framework\App\Config\Base */ protected $_salesConfig; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param \Magento\Framework\App\Cache\Type\Config $configCacheType * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Sales\Model\Config $salesConfig * @param \Magento\Framework\Simplexml\Element $sourceData + * @param SerializerInterface $serializer */ public function __construct( \Magento\Framework\App\Cache\Type\Config $configCacheType, \Psr\Log\LoggerInterface $logger, \Magento\Sales\Model\Config $salesConfig, - $sourceData = null + $sourceData = null, + SerializerInterface $serializer = null ) { parent::__construct($sourceData); $this->_configCacheType = $configCacheType; $this->_logger = $logger; $this->_salesConfig = $salesConfig; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -179,11 +190,11 @@ abstract class Ordered extends \Magento\Framework\App\Config\Base $sortedCodes = []; $cachedData = $this->_configCacheType->load($this->_collectorsCacheKey); if ($cachedData) { - $sortedCodes = unserialize($cachedData); + $sortedCodes = $this->serializer->unserialize($cachedData); } if (!$sortedCodes) { $sortedCodes = $this->_getSortedCollectorCodes($this->_modelsConfig); - $this->_configCacheType->save(serialize($sortedCodes), $this->_collectorsCacheKey); + $this->_configCacheType->save($this->serializer->serialize($sortedCodes), $this->_collectorsCacheKey); } foreach ($sortedCodes as $code) { $this->_collectors[$code] = $this->_models[$code]; diff --git a/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php b/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php index 21104933a51d6d8fda5d225ff4b879a07def3d20..ff687074e4a66cc50c457c685fc1757d1529dcb6 100644 --- a/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php +++ b/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Sales\Model\Order; /** @@ -23,6 +22,11 @@ class CreditmemoFactory */ protected $taxConfig; + /** + * @var \Magento\Framework\Unserialize\Unserialize + */ + protected $unserialize; + /** * Factory constructor * @@ -57,7 +61,12 @@ class CreditmemoFactory $item = $this->convertor->itemToCreditmemoItem($orderItem); if ($orderItem->isDummy()) { - $qty = 1; + if (isset($data['qtys'][$orderItem->getParentItemId()])) { + $parentQty = $data['qtys'][$orderItem->getParentItemId()]; + } else { + $parentQty = $orderItem->getParentItem() ? $orderItem->getParentItem()->getQtyToRefund() : 1; + } + $qty = $this->calculateProductOptions($orderItem, $parentQty); $orderItem->setLockedDoShip(true); } else { if (isset($qtys[$orderItem->getId()])) { @@ -132,7 +141,12 @@ class CreditmemoFactory $item = $this->convertor->itemToCreditmemoItem($orderItem); if ($orderItem->isDummy()) { - $qty = 1; + if (isset($data['qtys'][$orderItem->getParentItemId()])) { + $parentQty = $data['qtys'][$orderItem->getParentItemId()]; + } else { + $parentQty = $orderItem->getParentItem() ? $orderItem->getParentItem()->getQtyToRefund() : 1; + } + $qty = $this->calculateProductOptions($orderItem, $parentQty); } else { if (isset($qtys[$orderItem->getId()])) { $qty = (double)$qtys[$orderItem->getId()]; @@ -245,4 +259,38 @@ class CreditmemoFactory $creditmemo->setAdjustmentNegative($data['adjustment_negative']); } } + + /** + * @param \Magento\Sales\Api\Data\OrderItemInterface $orderItem + * @param array $qtys + * @return int + */ + private function calculateProductOptions(\Magento\Sales\Api\Data\OrderItemInterface $orderItem, $parentQty) + { + $qty = $parentQty; + $productOptions = $orderItem->getProductOptions(); + if (isset($productOptions['bundle_selection_attributes'])) { + $bundleSelectionAttributes = $this->getUnserialize() + ->unserialize($productOptions['bundle_selection_attributes']); + if ($bundleSelectionAttributes) { + $qty = $bundleSelectionAttributes['qty'] * $parentQty; + } + } + return $qty; + } + + /** + * Get Unserialize + * + * @return \Magento\Framework\Unserialize\Unserialize + * @deprecated + */ + private function getUnserialize() + { + if (!$this->unserialize) { + $this->unserialize = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Unserialize\Unserialize::class); + } + return $this->unserialize; + } } diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php index a0f56d6ea9a73ea02d4c852ef6ac4831be29b574..3cd5ecde21366c87d4ee746a0ddc1b453ec0bf95 100644 --- a/app/code/Magento/Sales/Model/Order/Payment.php +++ b/app/code/Magento/Sales/Model/Order/Payment.php @@ -1289,7 +1289,7 @@ class Payment extends Info implements OrderPaymentInterface */ public function isCaptureFinal($amountToCapture) { - $total = $this->getOrder()->getTotalDue(); + $total = $this->getOrder()->getBaseTotalDue(); return $this->formatAmount($total, true) == $this->formatAmount($amountToCapture, true); } diff --git a/app/code/Magento/Sales/Model/Order/Total/Config/Base.php b/app/code/Magento/Sales/Model/Order/Total/Config/Base.php index 22c71f48b6f35189bf532362a8647e53069a39a5..d96591118b82296a937445256e01e75ee942a569 100644 --- a/app/code/Magento/Sales/Model/Order/Total/Config/Base.php +++ b/app/code/Magento/Sales/Model/Order/Total/Config/Base.php @@ -5,6 +5,8 @@ */ namespace Magento\Sales\Model\Order\Total\Config; +use Magento\Framework\Serialize\SerializerInterface; + /** * Configuration class for totals */ @@ -42,15 +44,17 @@ class Base extends \Magento\Sales\Model\Config\Ordered * @param \Magento\Sales\Model\Config $salesConfig * @param \Magento\Sales\Model\Order\TotalFactory $orderTotalFactory * @param mixed $sourceData + * @param SerializerInterface $serializer */ public function __construct( \Magento\Framework\App\Cache\Type\Config $configCacheType, \Psr\Log\LoggerInterface $logger, \Magento\Sales\Model\Config $salesConfig, \Magento\Sales\Model\Order\TotalFactory $orderTotalFactory, - $sourceData = null + $sourceData = null, + SerializerInterface $serializer = null ) { - parent::__construct($configCacheType, $logger, $salesConfig, $sourceData); + parent::__construct($configCacheType, $logger, $salesConfig, $sourceData, $serializer); $this->_orderTotalFactory = $orderTotalFactory; } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php index f97e3be1dcb6dcb9ea6383efec081517751325b5..7f058b7c05053646af0272e5b4f206105b8b45aa 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php @@ -1548,7 +1548,7 @@ class PaymentTest extends \PHPUnit_Framework_TestCase $partialAmount = 12.00; $this->orderMock->expects(static::exactly(2)) - ->method('getTotalDue') + ->method('getBaseTotalDue') ->willReturn($amount); static::assertFalse($this->payment->isCaptureFinal($partialAmount)); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php index ed44331f577d06ebdbe4df00401f85f34c59284d..bd519e76585ba452bb066ccac2cfbd27c5d58d7f 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php @@ -5,24 +5,28 @@ */ namespace Magento\Sales\Test\Unit\Model\Order\Total\Config; +use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class BaseTest extends \PHPUnit_Framework_TestCase { /** @var \Magento\Sales\Model\Order\Total\Config\Base */ - protected $object; + private $object; + + /** @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $serializer; /** @var \Magento\Framework\App\Cache\Type\Config|\PHPUnit_Framework_MockObject_MockObject */ - protected $configCacheType; + private $configCacheType; /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $logger; + private $logger; /** @var \Magento\Sales\Model\Config|\PHPUnit_Framework_MockObject_MockObject */ - protected $salesConfig; + private $salesConfig; /** @var \Magento\Sales\Model\Order\TotalFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $orderTotalFactory; + private $orderTotalFactory; protected function setUp() { @@ -30,6 +34,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase $this->logger = $this->getMock(\Psr\Log\LoggerInterface::class); $this->salesConfig = $this->getMock(\Magento\Sales\Model\Config::class, [], [], '', false); $this->orderTotalFactory = $this->getMock(\Magento\Sales\Model\Order\TotalFactory::class, [], [], '', false); + $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class); $objectManager = new ObjectManager($this); $this->object = $objectManager->getObject( @@ -39,6 +44,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase 'logger' => $this->logger, 'salesConfig' => $this->salesConfig, 'orderTotalFactory' => $this->orderTotalFactory, + 'serializer' => $this->serializer, ] ); } @@ -59,8 +65,14 @@ class BaseTest extends \PHPUnit_Framework_TestCase ->with(\Magento\Sales\Model\Order\Total\AbstractTotal::class) ->will($this->returnValue($total)); + $sortedCodes = ['other_code', 'some_code']; + $serializedCodes = '["other_code", "some_code"]'; + $this->serializer->expects($this->once()) + ->method('serialize') + ->with($sortedCodes) + ->willReturn($serializedCodes); $this->configCacheType->expects($this->once())->method('save') - ->with('a:2:{i:0;s:10:"other_code";i:1;s:9:"some_code";}', 'sorted_collectors'); + ->with($serializedCodes, 'sorted_collectors'); $this->assertSame( ['other_code' => $total, 'some_code' => $total], @@ -106,8 +118,14 @@ class BaseTest extends \PHPUnit_Framework_TestCase ->with(\Magento\Sales\Model\Order\Total\AbstractTotal::class) ->will($this->returnValue($total)); + $sortedCodes = ['other_code', 'some_code']; + $serializedCodes = '["other_code", "some_code"]'; $this->configCacheType->expects($this->once())->method('load')->with('sorted_collectors') - ->will($this->returnValue('a:2:{i:0;s:10:"other_code";i:1;s:9:"some_code";}')); + ->will($this->returnValue($serializedCodes)); + $this->serializer->expects($this->once()) + ->method('unserialize') + ->with($serializedCodes) + ->willReturn($sortedCodes); $this->configCacheType->expects($this->never())->method('save'); $this->assertSame( diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json index 09d1a9d6b7dd41ea95a09b26c0f72276327fe245..6b5638455a1c5986fb487f7f9c948d9ddf19aad3 100644 --- a/app/code/Magento/Sales/composer.json +++ b/app/code/Magento/Sales/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-sales", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml index b2e779e330fe0582f855f17ee57e6f648f61a001..6acb23ab0910ea3e8dc1e8bd5e87c28900e19da5 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_index.xml @@ -16,7 +16,7 @@ <referenceBlock name="page.title"> <action method="setTitleId"> - <argument translate="true" name="id" xsi:type="string">order-header</argument> + <argument translate="false" name="id" xsi:type="string">order-header</argument> </action> </referenceBlock> <referenceContainer name="after.body.start"> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml index 59bb31a94fa0cadadf177f695271c1efeaa69aa6..a8ccf82c5fe06030055381d9c13228661308e04e 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml @@ -66,7 +66,13 @@ <?php endif; ?> <?php if ($block->canDisplayPrice()): ?> - <td class="col-price"><?php /* @noEscape */ echo $block->getItemPrice($_item) ?></td> + <td class="col-price"> + <?php if ($block->getDataId() == 'cart'): ?> + <?php /* @noEscape */ echo $block->getItemPrice($_item->getProduct()) ?> + <?php else: ?> + <?php /* @noEscape */ echo $block->getItemPrice($_item) ?> + <?php endif; ?> + </td> <?php endif; ?> <?php if ($block->canRemoveItems()): ?> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml index 775c7214c2f104771c79d5fd299229187595b167..20cfcdeadf22a0f18d81b262134058640c04877f 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml @@ -38,10 +38,10 @@ $orderStoreDate = $block->formatDate( <div class="admin__page-section-item-title"> <span class="title"> <?php if ($block->getNoUseOrderLink()): ?> - <?php /* @escapeNotVerified */ echo __('Order # %1', $_order->getRealOrderId()) ?> (<span><?php /* @escapeNotVerified */ echo $_email ?></span>) + <?php /* @escapeNotVerified */ echo __('Order # %1', $_order->getRealOrderId()) ?> (<span><?php echo $block->escapeHtml($_email) ?></span>) <?php else: ?> <a href="<?php /* @escapeNotVerified */ echo $block->getViewUrl($_order->getId()) ?>"><?php /* @escapeNotVerified */ echo __('Order # %1', $_order->getRealOrderId()) ?></a> - <span>(<?php /* @escapeNotVerified */ echo $_email ?>)</span> + <span>(<?php echo $block->escapeHtml($_email) ?>)</span> <?php endif; ?> </span> </div> @@ -49,7 +49,7 @@ $orderStoreDate = $block->formatDate( <table class="admin__table-secondary order-information-table"> <tr> <th><?php /* @escapeNotVerified */ echo __('Order Date') ?></th> - <td><?php /* @escapeNotVerified */ echo $orderAdminDate ?></td> + <td><?php echo $block->escapeHtml($orderAdminDate) ?></td> </tr> <?php if ($orderAdminDate != $orderStoreDate):?> <tr> @@ -57,12 +57,12 @@ $orderStoreDate = $block->formatDate( 'Order Date (%1)', $block->getTimezoneForStore($_order->getStore()) ) ?></th> - <td><?php /* @escapeNotVerified */ echo $orderStoreDate ?></td> + <td><?php echo $block->escapeHtml($orderStoreDate) ?></td> </tr> <?php endif;?> <tr> <th><?php /* @escapeNotVerified */ echo __('Order Status') ?></th> - <td><span id="order_status"><?php /* @escapeNotVerified */ echo $_order->getStatusLabel() ?></span></td> + <td><span id="order_status"><?php echo $block->escapeHtml($_order->getStatusLabel()) ?></span></td> </tr> <?php echo $block->getChildHtml(); ?> <?php if ($block->isSingleStoreMode() == false):?> @@ -136,13 +136,13 @@ $orderStoreDate = $block->formatDate( <?php if ($_groupName = $block->getCustomerGroupName()) : ?> <tr> <th><?php /* @escapeNotVerified */ echo __('Customer Group') ?></th> - <td><?php /* @escapeNotVerified */ echo $_groupName ?></td> + <td><?php echo $block->escapeHtml($_groupName) ?></td> </tr> <?php endif; ?> <?php foreach ($block->getCustomerAccountData() as $data):?> <tr> - <th><?php /* @escapeNotVerified */ echo $data['label'] ?></th> - <td><?php /* @escapeNotVerified */ echo $data['value'] ?></td> + <th><?php echo $block->escapeHtml($data['label']) ?></th> + <td><?php echo $block->escapeHtml($data['value']) ?></td> </tr> <?php endforeach;?> </table> diff --git a/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php b/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php index 7752d7131031cf0daa63f4c8b8bf49609e3090ed..3680bbb3a1eaefa3ee822eefd99b7b21b320a3f8 100644 --- a/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php +++ b/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php @@ -6,7 +6,6 @@ namespace Magento\SalesInventory\Model\Order; use Magento\Sales\Api\Data\CreditmemoInterface; -use Magento\Sales\Api\Data\CreditmemoItemInterface; use Magento\Sales\Api\Data\OrderInterface; /** @@ -29,52 +28,35 @@ class ReturnProcessor */ private $priceIndexer; - /** - * @var \Magento\Sales\Api\CreditmemoRepositoryInterface - */ - private $creditmemoRepository; - /** * @var \Magento\Store\Model\StoreManagerInterface */ private $storeManager; - /** - * @var \Magento\Sales\Api\OrderRepositoryInterface - */ - private $orderRepository; - /** * @var \Magento\Sales\Api\OrderItemRepositoryInterface */ private $orderItemRepository; /** - * ReturnToStockPlugin constructor. - * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration + * ReturnProcessor constructor. * @param \Magento\CatalogInventory\Api\StockManagementInterface $stockManagement * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexer * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer - * @param \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository * @param \Magento\Sales\Api\OrderItemRepositoryInterface $orderItemRepository */ public function __construct( \Magento\CatalogInventory\Api\StockManagementInterface $stockManagement, \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexer, \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer, - \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Sales\Api\OrderRepositoryInterface $orderRepository, \Magento\Sales\Api\OrderItemRepositoryInterface $orderItemRepository ) { $this->stockManagement = $stockManagement; $this->stockIndexerProcessor = $stockIndexer; $this->priceIndexer = $priceIndexer; - $this->creditmemoRepository = $creditmemoRepository; $this->storeManager = $storeManager; - $this->orderRepository = $orderRepository; $this->orderItemRepository = $orderItemRepository; } @@ -82,22 +64,22 @@ class ReturnProcessor * @param CreditmemoInterface $creditmemo * @param OrderInterface $order * @param array $returnToStockItems + * @param bool $isAutoReturn * @return void */ public function execute( CreditmemoInterface $creditmemo, OrderInterface $order, - array $returnToStockItems = [] + array $returnToStockItems = [], + $isAutoReturn = false ) { $itemsToUpdate = []; foreach ($creditmemo->getItems() as $item) { - $qty = $item->getQty(); $productId = $item->getProductId(); $orderItem = $this->orderItemRepository->get($item->getOrderItemId()); $parentItemId = $orderItem->getParentItemId(); - if ($this->canReturnItem($item, $qty, $parentItemId, $returnToStockItems)) { - $parentItem = $parentItemId ? $this->getItemByOrderId($creditmemo, $parentItemId) : false; - $qty = $parentItem ? $parentItem->getQty() * $qty : $qty; + $qty = $item->getQty(); + if ($isAutoReturn || $this->canReturnItem($item, $qty, $parentItemId, $returnToStockItems)) { if (isset($itemsToUpdate[$productId])) { $itemsToUpdate[$productId] += $qty; } else { @@ -122,21 +104,6 @@ class ReturnProcessor } } - /** - * @param \Magento\Sales\Api\Data\CreditmemoInterface $creditmemo - * @param int $parentItemId - * @return bool|CreditmemoItemInterface - */ - private function getItemByOrderId(\Magento\Sales\Api\Data\CreditmemoInterface $creditmemo, $parentItemId) - { - foreach ($creditmemo->getItems() as $item) { - if ($item->getOrderItemId() == $parentItemId) { - return $item; - } - } - return false; - } - /** * @param \Magento\Sales\Api\Data\CreditmemoItemInterface $item * @param int $qty diff --git a/app/code/Magento/CatalogInventory/Observer/RefundOrderInventoryObserver.php b/app/code/Magento/SalesInventory/Observer/RefundOrderInventoryObserver.php similarity index 57% rename from app/code/Magento/CatalogInventory/Observer/RefundOrderInventoryObserver.php rename to app/code/Magento/SalesInventory/Observer/RefundOrderInventoryObserver.php index 9702bfc7cfe425b2c8987c1aec4e86430e1d62ac..acdebcf976a2eead77eb6074611968a9831cd524 100644 --- a/app/code/Magento/CatalogInventory/Observer/RefundOrderInventoryObserver.php +++ b/app/code/Magento/SalesInventory/Observer/RefundOrderInventoryObserver.php @@ -4,54 +4,74 @@ * See COPYING.txt for license details. */ -namespace Magento\CatalogInventory\Observer; +namespace Magento\SalesInventory\Observer; use Magento\CatalogInventory\Api\StockConfigurationInterface; use Magento\CatalogInventory\Api\StockManagementInterface; use Magento\Framework\Event\Observer as EventObserver; use Magento\Framework\Event\ObserverInterface; +use Magento\Sales\Model\OrderRepository; +use Magento\SalesInventory\Model\Order\ReturnProcessor; /** * Catalog inventory module observer + * @deprecated */ class RefundOrderInventoryObserver implements ObserverInterface { /** * @var StockConfigurationInterface */ - protected $stockConfiguration; + private $stockConfiguration; /** * @var StockManagementInterface */ - protected $stockManagement; + private $stockManagement; /** * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor */ - protected $stockIndexerProcessor; + private $stockIndexerProcessor; /** * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor */ - protected $priceIndexer; + private $priceIndexer; /** + * @var \Magento\SalesInventory\Model\Order\ReturnProcessor + */ + private $returnProcessor; + + /** + * @var \Magento\Sales\Api\OrderRepositoryInterface + */ + private $orderRepository; + + /** + * RefundOrderInventoryObserver constructor. * @param StockConfigurationInterface $stockConfiguration * @param StockManagementInterface $stockManagement * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer + * @param ReturnProcessor $returnProcessor + * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository */ public function __construct( StockConfigurationInterface $stockConfiguration, StockManagementInterface $stockManagement, \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor, - \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer + \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer, + \Magento\SalesInventory\Model\Order\ReturnProcessor $returnProcessor, + \Magento\Sales\Api\OrderRepositoryInterface $orderRepository ) { $this->stockConfiguration = $stockConfiguration; $this->stockManagement = $stockManagement; $this->stockIndexerProcessor = $stockIndexerProcessor; $this->priceIndexer = $priceIndexer; + $this->returnProcessor = $returnProcessor; + $this->orderRepository = $orderRepository; } /** @@ -64,31 +84,18 @@ class RefundOrderInventoryObserver implements ObserverInterface { /* @var $creditmemo \Magento\Sales\Model\Order\Creditmemo */ $creditmemo = $observer->getEvent()->getCreditmemo(); - $itemsToUpdate = []; - foreach ($creditmemo->getAllItems() as $item) { - $qty = $item->getQty(); - if (($item->getBackToStock() && $qty) || $this->stockConfiguration->isAutoReturnEnabled()) { - $productId = $item->getProductId(); - $parentItemId = $item->getOrderItem()->getParentItemId(); - /* @var $parentItem \Magento\Sales\Model\Order\Creditmemo\Item */ - $parentItem = $parentItemId ? $creditmemo->getItemByOrderId($parentItemId) : false; - $qty = $parentItem ? $parentItem->getQty() * $qty : $qty; - if (isset($itemsToUpdate[$productId])) { - $itemsToUpdate[$productId] += $qty; - } else { - $itemsToUpdate[$productId] = $qty; - } + $order = $this->orderRepository->get($creditmemo->getOrderId()); + $returnToStockItems = []; + foreach ($creditmemo->getItems() as $item) { + if ($item->getBackToStock()) { + $returnToStockItems[] = $item->getOrderItemId(); } } - if (!empty($itemsToUpdate)) { - $this->stockManagement->revertProductsSale( - $itemsToUpdate, - $creditmemo->getStore()->getWebsiteId() - ); - - $updatedItemIds = array_keys($itemsToUpdate); - $this->stockIndexerProcessor->reindexList($updatedItemIds); - $this->priceIndexer->reindexList($updatedItemIds); - } + $this->returnProcessor->execute( + $creditmemo, + $order, + $returnToStockItems, + $this->stockConfiguration->isAutoReturnEnabled() + ); } } diff --git a/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php b/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php index 523759d54645a1e2db471db948fa116cf59cd32e..efa3bff32c0fa2b40c3a9a57ec04cb1ec5c9f257 100644 --- a/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php +++ b/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php @@ -5,9 +5,7 @@ */ namespace Magento\SalesInventory\Test\Unit\Model\Order; -use Magento\CatalogInventory\Api\StockConfigurationInterface; use Magento\CatalogInventory\Api\StockManagementInterface; -use Magento\Sales\Api\CreditmemoRepositoryInterface; use Magento\Sales\Api\Data\CreditmemoInterface; use Magento\Sales\Api\Data\CreditmemoItemInterface; use Magento\Sales\Api\Data\OrderInterface; @@ -49,21 +47,11 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase */ private $priceIndexerMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoRepositoryInterface - */ - private $creditmemoRepositoryMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject|StoreManagerInterface */ private $storeManagerMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject|OrderRepositoryInterface - */ - private $orderRepositoryMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject|OrderItemRepositoryInterface */ @@ -95,13 +83,10 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase $this->priceIndexerMock = $this->getMockBuilder(\Magento\Catalog\Model\Indexer\Product\Price\Processor::class) ->disableOriginalConstructor() ->getMock(); - $this->creditmemoRepositoryMock = $this->getMockBuilder(CreditmemoRepositoryInterface::class) - ->disableOriginalConstructor() - ->getMock(); $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class) ->disableOriginalConstructor() ->getMock(); - $this->orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class) + $this->orderItemRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class) ->disableOriginalConstructor() ->getMock(); $this->orderItemRepositoryMock = $this->getMockBuilder(OrderItemRepositoryInterface::class) @@ -127,9 +112,7 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase $this->stockManagementMock, $this->stockIndexerProcessorMock, $this->priceIndexerMock, - $this->creditmemoRepositoryMock, $this->storeManagerMock, - $this->orderRepositoryMock, $this->orderItemRepositoryMock ); } @@ -139,6 +122,7 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase $orderItemId = 99; $productId = 50; $returnToStockItems = [$orderItemId]; + $parentItemId = 52; $qty = 1; $storeId = 0; $webSiteId = 10; @@ -147,10 +131,6 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase ->method('getItems') ->willReturn([$this->creditmemoItemMock]); - $this->creditmemoItemMock->expects($this->once()) - ->method('getQty') - ->willReturn($qty); - $this->creditmemoItemMock->expects($this->exactly(2)) ->method('getOrderItemId') ->willReturn($orderItemId); @@ -190,6 +170,14 @@ class ReturnProcessorTest extends \PHPUnit_Framework_TestCase ->method('reindexList') ->with([$productId]); + $this->orderItemMock->expects($this->once()) + ->method('getParentItemId') + ->willReturn($parentItemId); + + $this->creditmemoItemMock->expects($this->once()) + ->method('getQty') + ->willReturn($qty); + $this->returnProcessor->execute($this->creditmemoMock, $this->orderMock, $returnToStockItems); } } diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php b/app/code/Magento/SalesInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php similarity index 65% rename from app/code/Magento/CatalogInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php rename to app/code/Magento/SalesInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php index e440ed3380498a0c8d0deb9fb4edbd68a5d2c295..4e553493d07f63ed9f7d0a2d0d0ec7129d7580e7 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php +++ b/app/code/Magento/SalesInventory/Test/Unit/Observer/RefundOrderInventoryObserverTest.php @@ -3,9 +3,12 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\CatalogInventory\Test\Unit\Observer; +namespace Magento\SalesInventory\Test\Unit\Observer; -use Magento\CatalogInventory\Observer\RefundOrderInventoryObserver; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Model\OrderRepository; +use Magento\SalesInventory\Model\Order\ReturnProcessor; +use Magento\SalesInventory\Observer\RefundOrderInventoryObserver; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -47,6 +50,26 @@ class RefundOrderInventoryObserverTest extends \PHPUnit_Framework_TestCase */ protected $eventObserver; + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + protected $objectManagerHelper; + + /** + * @var OrderRepository|\PHPUnit_Framework_MockObject_MockObject + */ + protected $orderRepositoryMock; + + /** + * @var ReturnProcessor|\PHPUnit_Framework_MockObject_MockObject + */ + protected $returnProcessorMock; + + /** + * @var OrderInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderMock; + protected function setUp() { $this->stockIndexerProcessor = $this->getMock( @@ -93,8 +116,22 @@ class RefundOrderInventoryObserverTest extends \PHPUnit_Framework_TestCase ->method('getEvent') ->will($this->returnValue($this->event)); - $this->observer = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject( - \Magento\CatalogInventory\Observer\RefundOrderInventoryObserver::class, + $this->orderRepositoryMock = $this->getMockBuilder(OrderRepository::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->returnProcessorMock = $this->getMockBuilder(ReturnProcessor::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->orderMock = $this->getMockBuilder(OrderInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->observer = $this->objectManagerHelper->getObject( + \Magento\SalesInventory\Observer\RefundOrderInventoryObserver::class, [ 'stockConfiguration' => $this->stockConfiguration, 'stockManagement' => $this->stockManagement, @@ -102,83 +139,67 @@ class RefundOrderInventoryObserverTest extends \PHPUnit_Framework_TestCase 'priceIndexer' => $this->priceIndexer, ] ); + + $this->objectManagerHelper->setBackwardCompatibleProperty( + $this->observer, + 'orderRepository', + $this->orderRepositoryMock + ); + $this->objectManagerHelper->setBackwardCompatibleProperty( + $this->observer, + 'returnProcessor', + $this->returnProcessorMock + ); } public function testRefundOrderInventory() { - $websiteId = 0; $ids = ['1', '14']; $items = []; $isAutoReturnEnabled = true; - $store = $this->getMock( - \Magento\Store\Model\Store::class, - ['getWebsiteId'], - [], - '', - false - ); - $store->expects($this->once())->method('getWebsiteId')->will($this->returnValue($websiteId)); + $creditMemo = $this->getMock(\Magento\Sales\Model\Order\Creditmemo::class, [], [], '', false); - $itemsToUpdate = []; foreach ($ids as $id) { $item = $this->getCreditMemoItem($id); $items[] = $item; - $itemsToUpdate[$item->getProductId()] = $item->getQty(); } - $creditMemo = $this->getMock(\Magento\Sales\Model\Order\Creditmemo::class, [], [], '', false); + $creditMemo->expects($this->once()) - ->method('getAllItems') + ->method('getItems') ->will($this->returnValue($items)); - $creditMemo->expects($this->once())->method('getStore')->will($this->returnValue($store)); $this->stockConfiguration->expects($this->any()) ->method('isAutoReturnEnabled') ->will($this->returnValue($isAutoReturnEnabled)); - $this->stockManagement->expects($this->once()) - ->method('revertProductsSale') - ->with($itemsToUpdate, $websiteId); - - $this->stockIndexerProcessor->expects($this->once()) - ->method('reindexList') - ->with($ids); - - $this->priceIndexer->expects($this->once()) - ->method('reindexList') - ->with($ids); - $this->event->expects($this->once()) ->method('getCreditmemo') ->will($this->returnValue($creditMemo)); + $this->orderRepositoryMock->expects($this->once()) + ->method('get') + ->willReturn($this->orderMock); + + $this->returnProcessorMock->expects($this->once()) + ->method('execute') + ->with($creditMemo, $this->orderMock, $ids, $isAutoReturnEnabled); + $this->observer->execute($this->eventObserver); } private function getCreditMemoItem($productId) { - $parentItemId = false; $backToStock = true; - $qty = 1; $item = $this->getMock( \Magento\Sales\Model\Order\Creditmemo\Item::class, - ['getProductId', 'getOrderItem', 'getBackToStock', 'getQty', '__wakeup'], - [], - '', - false - ); - $orderItem = $this->getMock( - \Magento\Sales\Model\Order\Item::class, - ['getParentItemId', '__wakeup'], + ['getOrderItemId', 'getBackToStock', 'getQty', '__wakeup'], [], '', false ); - $orderItem->expects($this->any())->method('getParentItemId')->willReturn($parentItemId); - $item->expects($this->any())->method('getOrderItem')->willReturn($orderItem); - $item->expects($this->any())->method('getProductId')->will($this->returnValue($productId)); $item->expects($this->any())->method('getBackToStock')->willReturn($backToStock); - $item->expects($this->any())->method('getQty')->willReturn($qty); + $item->expects($this->any())->method('getOrderItemId')->willReturn($productId); return $item; } } diff --git a/app/code/Magento/SalesInventory/composer.json b/app/code/Magento/SalesInventory/composer.json index ff72ce7f0022690682b356235c506512e65497b9..d7f9075cdd310141bab6b25869f33d6229f513dc 100644 --- a/app/code/Magento/SalesInventory/composer.json +++ b/app/code/Magento/SalesInventory/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-sales-inventory", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog-inventory": "100.2.*", "magento/module-sales": "100.2.*", "magento/module-store": "100.2.*", diff --git a/app/code/Magento/SalesInventory/etc/events.xml b/app/code/Magento/SalesInventory/etc/events.xml new file mode 100644 index 0000000000000000000000000000000000000000..a71ed7f8a28a16a4ded03e507876757ec94f436c --- /dev/null +++ b/app/code/Magento/SalesInventory/etc/events.xml @@ -0,0 +1,12 @@ +<?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="urn:magento:framework:Event/etc/events.xsd"> + <event name="sales_order_creditmemo_save_after"> + <observer name="inventory" instance="Magento\SalesInventory\Observer\RefundOrderInventoryObserver"/> + </event> +</config> diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php index 57477b5ce0623f57bfc048839cc8bdaee8d40593..efa45512acc8320cd878c97b92c5912c7713f882 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php @@ -26,8 +26,13 @@ class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); + + $filterValues = ['from_date' => $this->_dateFilter]; + if ($this->getRequest()->getParam('to_date')) { + $filterValues['to_date'] = $this->_dateFilter; + } $inputFilter = new \Zend_Filter_Input( - ['from_date' => $this->_dateFilter, 'to_date' => $this->_dateFilter], + $filterValues, [], $data ); diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json index fabef581762a84cac8844bf7e7099b0bb8b6b6c0..8479acad47246a1f91bc6b098d88cfa6f6027f76 100644 --- a/app/code/Magento/SalesRule/composer.json +++ b/app/code/Magento/SalesRule/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-sales-rule", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-rule": "100.2.*", diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js b/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js index ed5744feb6ce84df31a5a59b42f520bb97316792..d1e294c9a8f0c1dc4edf82e52cbe509b09da8fbe 100644 --- a/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js +++ b/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js @@ -17,16 +17,20 @@ define( 'mage/storage', 'Magento_Checkout/js/action/get-payment-information', 'Magento_Checkout/js/model/totals', - 'mage/translate' + 'mage/translate', + 'Magento_Checkout/js/model/full-screen-loader' ], - function ($, quote, urlManager, errorProcessor, messageContainer, storage, getPaymentInformationAction, totals, $t) { + function ($, quote, urlManager, errorProcessor, messageContainer, storage, getPaymentInformationAction, totals, $t, + fullScreenLoader) { 'use strict'; - return function (isApplied, isLoading) { + return function (isApplied) { var quoteId = quote.getQuoteId(), url = urlManager.getCancelCouponUrl(quoteId), message = $t('Your coupon was successfully removed.'); + messageContainer.clear(); + fullScreenLoader.startLoader(); return storage.delete( url, @@ -39,6 +43,7 @@ define( $.when(deferred).done(function () { isApplied(false); totals.isLoading(false); + fullScreenLoader.stopLoader(); }); messageContainer.addSuccessMessage({ 'message': message @@ -47,12 +52,9 @@ define( ).fail( function (response) { totals.isLoading(false); + fullScreenLoader.stopLoader(); errorProcessor.process(response, messageContainer); } - ).always( - function () { - isLoading(false); - } ); }; } diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js b/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js index 606fe4013ea762c5460c49202907463d7c7952f2..a2b7ff19f2139ffa7e23b37eda039d5b9ccc32a8 100644 --- a/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js +++ b/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js @@ -18,25 +18,22 @@ define( 'mage/storage', 'mage/translate', 'Magento_Checkout/js/action/get-payment-information', - 'Magento_Checkout/js/model/totals' + 'Magento_Checkout/js/model/totals', + 'Magento_Checkout/js/model/full-screen-loader' ], function ( - ko, - $, - quote, - urlManager, - errorProcessor, - messageContainer, - storage, - $t, - getPaymentInformationAction, - totals + ko, $, quote, urlManager, errorProcessor, messageContainer, storage, $t, getPaymentInformationAction, totals, + fullScreenLoader ) { 'use strict'; - return function (couponCode, isApplied, isLoading) { - var quoteId = quote.getQuoteId(); - var url = urlManager.getApplyCouponUrl(couponCode, quoteId); - var message = $t('Your coupon was successfully applied.'); + + return function (couponCode, isApplied) { + var quoteId = quote.getQuoteId(), + url = urlManager.getApplyCouponUrl(couponCode, quoteId), + message = $t('Your coupon was successfully applied.'); + + fullScreenLoader.startLoader(); + return storage.put( url, {}, @@ -45,19 +42,22 @@ define( function (response) { if (response) { var deferred = $.Deferred(); - isLoading(false); + isApplied(true); totals.isLoading(true); getPaymentInformationAction(deferred); $.when(deferred).done(function () { + fullScreenLoader.stopLoader(); totals.isLoading(false); }); - messageContainer.addSuccessMessage({'message': message}); + messageContainer.addSuccessMessage({ + 'message': message + }); } } ).fail( function (response) { - isLoading(false); + fullScreenLoader.stopLoader(); totals.isLoading(false); errorProcessor.process(response, messageContainer); } diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js b/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js index 8e8c0798ff3b59ce0ffa0a803242abe1d02fcee7..6dc973a7a1e4298469251f71f6e26f09a95cc5d0 100644 --- a/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js +++ b/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js @@ -13,49 +13,53 @@ define( ], function ($, ko, Component, quote, setCouponCodeAction, cancelCouponAction) { 'use strict'; - var totals = quote.getTotals(); - var couponCode = ko.observable(null); + + var totals = quote.getTotals(), + couponCode = ko.observable(null), + isApplied = ko.observable(couponCode() != null); + if (totals()) { couponCode(totals()['coupon_code']); } - var isApplied = ko.observable(couponCode() != null); - var isLoading = ko.observable(false); + return Component.extend({ defaults: { template: 'Magento_SalesRule/payment/discount' }, couponCode: couponCode, + /** * Applied flag */ isApplied: isApplied, - isLoading: isLoading, + /** * Coupon code application procedure */ apply: function() { if (this.validate()) { - isLoading(true); - setCouponCodeAction(couponCode(), isApplied, isLoading); + setCouponCodeAction(couponCode(), isApplied); } }, + /** * Cancel using coupon */ cancel: function() { if (this.validate()) { - isLoading(true); couponCode(''); - cancelCouponAction(isApplied, isLoading); + cancelCouponAction(isApplied); } }, + /** * Coupon form validation * - * @returns {boolean} + * @returns {Boolean} */ - validate: function() { + validate: function () { var form = '#discount-form'; + return $(form).validation() && $(form).validation('isValid'); } }); diff --git a/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html b/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html index d6bc4c764d5714382d017adce856deaf84c8b3ff..4ba38906fe9c1e98c8d248574585cc01ef815914 100644 --- a/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html +++ b/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html @@ -15,7 +15,7 @@ <!-- ko foreach: getRegion('messages') --> <!-- ko template: getTemplate() --><!-- /ko --> <!--/ko--> - <form class="form form-discount" id="discount-form" data-bind="blockLoader: isLoading"> + <form class="form form-discount" id="discount-form"> <div class="payment-option-inner"> <div class="field"> <label class="label" for="discount-code"> diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json index eeda2be05e68f86cb5552e6f48ca502dd96cb9be..5b9efe61f72724e28d23c1af0dc197fede8e117f 100644 --- a/app/code/Magento/SalesSequence/composer.json +++ b/app/code/Magento/SalesSequence/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-sales-sequence", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*" }, "type": "magento2-module", diff --git a/app/code/Magento/SampleData/composer.json b/app/code/Magento/SampleData/composer.json index 936bbf0d6be3a7399babc2e835282e7c71bea4c2..4c98a5abd3a16ab72b5ea04e0606955986924ebd 100644 --- a/app/code/Magento/SampleData/composer.json +++ b/app/code/Magento/SampleData/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-sample-data", "description": "Sample Data fixtures", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*" }, "suggest": { diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json index cc95e6784526f33bb65246b599a4147e8a1afa1d..8f809fb3b8af3533c4715aea1e13854650e0cbac 100644 --- a/app/code/Magento/Search/composer.json +++ b/app/code/Magento/Search/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-search", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-catalog-search": "100.2.*", diff --git a/app/code/Magento/Security/composer.json b/app/code/Magento/Security/composer.json index f64c0f0b29d282b0feaefb24ebb3963086f0e083..4048b63bf607030d27ae7fa84dbec6a0da838957 100644 --- a/app/code/Magento/Security/composer.json +++ b/app/code/Magento/Security/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-security", "description": "Security management module", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-backend": "100.2.*", "magento/module-store": "100.2.*", "magento/framework": "100.2.*" diff --git a/app/code/Magento/SendFriend/composer.json b/app/code/Magento/SendFriend/composer.json index de9dbf7a84576022d8f6b1a38324f902565870df..1095dedc0ba6606107660d65373096d8c82b204c 100644 --- a/app/code/Magento/SendFriend/composer.json +++ b/app/code/Magento/SendFriend/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-send-friend", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-customer": "100.2.*", diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json index dc9ea808c0f7b19e396a7c73f2b416221729a34b..03f51bbd95e0ff5f65b88e565cfbe77102a44760 100644 --- a/app/code/Magento/Shipping/composer.json +++ b/app/code/Magento/Shipping/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-shipping", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-sales": "100.2.*", diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json index be553a4da194f4dbf64fb4237fd92bb27e4e17ff..9f556178fc2cccfd070c272a89164e438f1d33e8 100644 --- a/app/code/Magento/Sitemap/composer.json +++ b/app/code/Magento/Sitemap/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-sitemap", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index b9f76f6c2c3137aa21d8f4a6cf97880fdc3e72f6..d5b8a2b4b980b58648c04cfed916b5bd390db048 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-store", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-directory": "100.2.*", "magento/module-ui": "100.2.*", diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index dc2d1cbee003de647cf72f7312ad7f7fcc222e3b..47e347426c83fdb1b969c5a03bd46d1776e89950 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-swagger", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*" }, "type": "magento2-module", diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php index 68a18ef8be6a1b2d51403acac0ebaca1ecc83996..a973a822c4101671faa0fe57925a0e9b0c5b2f2a 100644 --- a/app/code/Magento/Swatches/Helper/Data.php +++ b/app/code/Magento/Swatches/Helper/Data.php @@ -63,6 +63,13 @@ class Data */ protected $imageHelper; + /** + * Product metadata pool + * + * @var \Magento\Framework\EntityManager\MetadataPool + */ + private $metadataPool; + /** * Data key which should populated to Attribute entity from "additional_data" field * @@ -196,7 +203,13 @@ class Data } $productCollection = $this->productCollectionFactory->create(); - $this->addFilterByParent($productCollection, $parentProduct->getId()); + + $productLinkedFiled = $this->getMetadataPool() + ->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class) + ->getLinkField(); + $parentId = $parentProduct->getData($productLinkedFiled); + + $this->addFilterByParent($productCollection, $parentId); $configurableAttributes = $this->getAttributesFromConfigurable($parentProduct); $allAttributesArray = []; @@ -491,4 +504,19 @@ class Data } return $attribute->getData(Swatch::SWATCH_INPUT_TYPE_KEY) == Swatch::SWATCH_INPUT_TYPE_TEXT; } + + /** + * Get product metadata pool. + * + * @return \Magento\Framework\EntityManager\MetadataPool + * @deprecared + */ + protected function getMetadataPool() + { + if (!$this->metadataPool) { + $this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\EntityManager\MetadataPool::class); + } + return $this->metadataPool; + } } diff --git a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php index 6cf79dae309a583aca3ced31bd1411eb9d53b27b..e5f2f887836eff5ad73ca95602d4d7aec411150e 100644 --- a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php @@ -46,6 +46,9 @@ class DataTest extends \PHPUnit_Framework_TestCase /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Api\ProductRepositoryInterface */ protected $productRepoMock; + /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\EntityManager\MetadataPool*/ + private $metaDataPoolMock; + protected function setUp() { $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -108,7 +111,13 @@ class DataTest extends \PHPUnit_Framework_TestCase '', false ); - + $this->metaDataPoolMock = $this->getMock( + \Magento\Framework\EntityManager\MetadataPool::class, + [], + [], + '', + false + ); $this->swatchHelperObject = $this->objectManager->getObject( \Magento\Swatches\Helper\Data::class, [ @@ -120,6 +129,11 @@ class DataTest extends \PHPUnit_Framework_TestCase 'imageHelper' => $this->imageHelperMock, ] ); + $this->objectManager->setBackwardCompatibleProperty( + $this->swatchHelperObject, + 'metadataPool', + $this->metaDataPoolMock + ); } public function dataForAdditionalData() @@ -246,12 +260,16 @@ class DataTest extends \PHPUnit_Framework_TestCase */ public function testLoadVariationByFallback($product) { + $metadataMock = $this->getMock(\Magento\Framework\EntityManager\EntityMetadataInterface::class); + $this->metaDataPoolMock->expects($this->once())->method('getMetadata')->willReturn($metadataMock); + $metadataMock->expects($this->once())->method('getLinkField')->willReturn('id'); + $this->getSwatchAttributes($product); $this->prepareVariationCollection(); $this->productCollectionMock->method('getFirstItem')->willReturn($this->productMock); - $this->productMock->method('getId')->willReturn(95); + $this->productMock->method('getData')->with('id')->willReturn(95); $this->productModelFactoryMock->method('create')->willReturn($this->productMock); $this->productMock->method('load')->with(95)->will($this->returnSelf()); diff --git a/app/code/Magento/Swatches/composer.json b/app/code/Magento/Swatches/composer.json index f87fdb635cb73386b40fec6ac932eaee3f9cd398..b61ff41d8c955890aae0c22baedcdb8abd22e004 100644 --- a/app/code/Magento/Swatches/composer.json +++ b/app/code/Magento/Swatches/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-swatches", "description": "Add Swatches to Products", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-configurable-product": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml index 86046fdce4b6ee3d264d86f94f3a7dcfbf4b13b3..9c3274627b984cc093ecf5f39c54190ead2412fa 100644 --- a/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml +++ b/app/code/Magento/Swatches/view/frontend/templates/product/listing/renderer.phtml @@ -7,15 +7,17 @@ <?php /** @var $block \Magento\Swatches\Block\Product\Renderer\Configurable */ ?> <div class="swatch-opt-<?php /* @escapeNotVerified */ echo $block->getProduct()->getId() ?>"></div> <script> - require(["jquery", "jquery/ui", "Magento_Swatches/js/swatch-renderer"], function ($) { - $('.swatch-opt-<?php /* @escapeNotVerified */ echo $block->getProduct()->getId() ?>').SwatchRenderer({ - selectorProduct: '.product-item-details', - onlySwatches: true, - enableControlLabel: false, - numberToShow: <?php /* @escapeNotVerified */ echo $block->getNumberSwatchesPerProduct(); ?>, - jsonConfig: <?php /* @escapeNotVerified */ echo $block->getJsonConfig(); ?>, - jsonSwatchConfig: <?php /* @escapeNotVerified */ echo $block->getJsonSwatchConfig(); ?>, - mediaCallback: '<?php /* @escapeNotVerified */ echo $block->getMediaCallback() ?>' - }); + require( + ["jquery", "jquery/ui", "Magento_Swatches/js/swatch-renderer", "Magento_Swatches/js/catalog-add-to-cart"], + function ($) { + $('.swatch-opt-<?php /* @escapeNotVerified */ echo $block->getProduct()->getId() ?>').SwatchRenderer({ + selectorProduct: '.product-item-details', + onlySwatches: true, + enableControlLabel: false, + numberToShow: <?php /* @escapeNotVerified */ echo $block->getNumberSwatchesPerProduct(); ?>, + jsonConfig: <?php /* @escapeNotVerified */ echo $block->getJsonConfig(); ?>, + jsonSwatchConfig: <?php /* @escapeNotVerified */ echo $block->getJsonSwatchConfig(); ?>, + mediaCallback: '<?php /* @escapeNotVerified */ echo $block->getMediaCallback() ?>' + }); }); </script> diff --git a/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js new file mode 100644 index 0000000000000000000000000000000000000000..7900ff67b09be952f13bcfd1bd88842327dd0db4 --- /dev/null +++ b/app/code/Magento/Swatches/view/frontend/web/js/catalog-add-to-cart.js @@ -0,0 +1,17 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +require([ + 'jquery' +], function ($) { + 'use strict'; + + $('body').on('catalogCategoryAddToCartRedirect', function (event, data) { + $(data.form).find('[name*="super"]').each(function (index, item) { + var $item = $(item); + + data.redirectParameters.push($item.attr('data-attr-name') + '=' + $item.val()); + }); + }); +}); diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 54e207c335ffb5b6a007a7774df4e2c4a0760628..452c9b6f94d3c60e83bd35a5a932c6b5f8a9092f 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -264,6 +264,8 @@ define([ */ _init: function () { if (this.options.jsonConfig !== '' && this.options.jsonSwatchConfig !== '') { + // store unsorted attributes + this.options.jsonConfig.mappedAttributes = _.clone(this.options.jsonConfig.attributes); this._sortAttributes(); this._RenderControls(); $(this.element).trigger('swatch.initialized'); @@ -617,6 +619,7 @@ define([ $parent.attr('option-selected', $this.attr('option-id')).find('.selected').removeClass('selected'); $label.text($this.attr('option-label')); $input.val($this.attr('option-id')); + $input.attr('data-attr-name', this._getAttributeCodeById(attributeId)); $this.addClass('selected'); $widget._toggleCheckedAttributes($this, $wrapper); } @@ -633,6 +636,19 @@ define([ $input.trigger('change'); }, + /** + * Get human readable attribute code (eg. size, color) by it ID from configuration + * + * @param {Number} attributeId + * @returns {*} + * @private + */ + _getAttributeCodeById: function (attributeId) { + var attribute = this.options.jsonConfig.mappedAttributes[attributeId]; + + return attribute ? attribute.code : attributeId; + }, + /** * Toggle accessibility attributes * @@ -1104,7 +1120,7 @@ define([ params = $.parseQuery(window.location.href.substr(hashIndex + 1)); selectedAttributes = _.invert(_.mapObject(_.invert(params), function (attributeId) { - var attribute = this.options.jsonConfig.attributes[attributeId]; + var attribute = this.options.jsonConfig.mappedAttributes[attributeId]; return attribute ? attribute.code : attributeId; }.bind(this))); diff --git a/app/code/Magento/SwatchesLayeredNavigation/composer.json b/app/code/Magento/SwatchesLayeredNavigation/composer.json index 9b658d0a42e61e0b556f1aa5aed6e12ed8cfdbe7..67c6d90c51e7f81de645451da6553bcdb750fddd 100644 --- a/app/code/Magento/SwatchesLayeredNavigation/composer.json +++ b/app/code/Magento/SwatchesLayeredNavigation/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-swatches-layered-navigation", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*", "magento/magento-composer-installer": "*" }, diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json index 4553fdbb383323732b667df9be3e140aca011744..3dfacaaecd9635dec8229175de2876da6c957a77 100644 --- a/app/code/Magento/Tax/composer.json +++ b/app/code/Magento/Tax/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-tax", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-config": "100.2.*", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json index c3d09e4926e02d67a98c0e15c050d67997ae1ecd..9d9cac5dec59c94e8013bc5ab3275fee84c73b6b 100644 --- a/app/code/Magento/TaxImportExport/composer.json +++ b/app/code/Magento/TaxImportExport/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-tax-import-export", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-tax": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-directory": "100.2.*", diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index 49382f9642fa5d2b88d7d2f4cea79c07d5306cb1..7158ac314076d38aae4766bbea1a917dc869b5dd 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-theme", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-customer": "100.2.*", "magento/module-backend": "100.2.*", diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json index 9ea00544d805094927499672f98fb72ad12ae97a..b9ed830c9053ea492d76a2402ec8f523fb03a46a 100644 --- a/app/code/Magento/Translation/composer.json +++ b/app/code/Magento/Translation/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-translation", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-backend": "100.2.*", "magento/module-developer": "100.2.*", "magento/module-store": "100.2.*", diff --git a/app/code/Magento/Ui/README.md b/app/code/Magento/Ui/README.md index 1337383ea3fb83bf3e2927589859587aad5a48f7..b7dd1a858e4a8161f836b3ea73d1483ae56ba2dd 100644 --- a/app/code/Magento/Ui/README.md +++ b/app/code/Magento/Ui/README.md @@ -1,7 +1,7 @@ # Overview ## Purpose of module -The Magento\Ui module introduces a set of common UI components, which could be easily used and configured via layout XML files. +The Magento\Ui module introduces a set of common UI components, which could be used and configured via layout XML files. # Deployment ## System requirements diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json index 43c7b7fa3011fd7c6386fcde17eb45b6c5e02695..a3de6c6dfbdde7860dbb07503e0e6fe25e8b3dcf 100644 --- a/app/code/Magento/Ui/composer.json +++ b/app/code/Magento/Ui/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-ui", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-backend": "100.2.*", "magento/framework": "100.2.*", "magento/module-eav": "100.2.*", diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js index de10c065d123bf773f9fba66135b2308a2abe3e9..518f09fa73ba6c6771654c7c9fc3f3ce07be79be 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js @@ -52,13 +52,15 @@ define([ obj; if (this.recordData().length && !this.update) { - this.recordData.each(function (recordData) { + _.each(this.recordData(), function (recordData) { obj = {}; obj[this.map[this.identificationProperty]] = recordData[this.identificationProperty]; insertData.push(obj); }, this); - this.source.set(this.dataProvider, insertData); + if (insertData.length) { + this.source.set(this.dataProvider, insertData); + } } }, @@ -178,7 +180,7 @@ define([ tmpObj = {}; if (data.length !== this.relatedData.length) { - data.forEach(function (obj) { + _.each(data, function (obj) { tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty]; if (!_.findWhere(this.relatedData, tmpObj)) { @@ -193,7 +195,7 @@ define([ /** * Processing insert data * - * @param {Array} data + * @param {Object} data */ processingInsertData: function (data) { var changes, diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js index 16c102b8367f4b8762030057c4d249adb132693b..77d3a069ccef76bbcacad28459820b3359b025e7 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js @@ -51,7 +51,12 @@ define([ observable() && $(el).datepicker( 'setDate', - moment(observable(), utils.normalizeDate(config.options.dateFormat)).toDate() + moment( + observable(), + utils.normalizeDate( + options.dateFormat + (options.showsTime ? ' ' + options.timeFormat : '') + ) + ).toDate() ); $(el).blur(); diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html index f3319a05525f2f55bc4ba43ec5ce9bc1e4e2c300..d1ec1d26df6c56dff099b09aa0eb83232687573e 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html @@ -43,6 +43,7 @@ </div> <button class="action-delete" + data-index="delete_button" type="button" title="'Delete'" click="function(){ diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json index ade4e738a68efe0499041830892bb6b61f5a3156..c20dd28ba88876a70c04ea49038b94f82d3d9b06 100644 --- a/app/code/Magento/Ups/composer.json +++ b/app/code/Magento/Ups/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-ups", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-sales": "100.2.*", diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json index ac75ecdf61b8fd0531f2b14f76d2aec7d72581be..290ffc6731d89ce142e94c58616ca1a74c82c54b 100644 --- a/app/code/Magento/UrlRewrite/composer.json +++ b/app/code/Magento/UrlRewrite/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-url-rewrite", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-catalog": "101.1.*", "magento/module-store": "100.2.*", "magento/framework": "100.2.*", diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml index 7aa02ab019c46b9ad7094764118a9f5d07519293..d0f9678602707ff2950b8b051b8dd50f0b4c7df0 100644 --- a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml +++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml @@ -9,7 +9,7 @@ /** @var \Magento\UrlRewrite\Block\Catalog\Category\Tree $block */ ?> <fieldset class="admin__fieldset" data-ui-id="category-selector"> - <legend class="admin__legend"><span><?php /* @escapeNotVerified */ echo __('Select Category') ?></span></legend> + <legend class="admin__legend"><span><?php echo $block->escapeHtml(__('Select Category')) ?></span></legend> <div class="content content-category-tree"> <input type="hidden" name="categories" id="product_categories" value="" /> <?php if ($block->getRoot()): ?> diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json index 755c47ac1147612e1e55b589e72afa705b39b0ce..4632e32bc17f90549f7271cadc5e1ef7ba08869e 100644 --- a/app/code/Magento/User/composer.json +++ b/app/code/Magento/User/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-user", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-authorization": "100.2.*", "magento/module-backend": "100.2.*", diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index d12341659cb6d8ad1fc4acabe0b8052e346ca102..b2345a86bff4d6349035950373d1e7975076f513 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -426,9 +426,14 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C if (!$service) { $service = $r->getService(); } - if ($r->getContainer() == 'FLAT RATE BOX' || $r->getContainer() == 'FLAT RATE ENVELOPE') { + + if ( + strpos($r->getContainer(), 'FLAT RATE ENVELOPE') !== false || + strpos($r->getContainer(), 'FLAT RATE BOX') !== false + ) { $service = 'Priority'; } + $package->addChild('Service', $service); // no matter Letter, Flat or Parcel, use Parcel @@ -794,8 +799,15 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'first_class_mail_type' => ['LETTER' => __('Letter'), 'FLAT' => __('Flat'), 'PARCEL' => __('Parcel')], 'container' => [ 'VARIABLE' => __('Variable'), - 'FLAT RATE BOX' => __('Flat-Rate Box'), + 'SM FLAT RATE BOX' => __('Small Flat-Rate Box'), + 'MD FLAT RATE BOX' => __('Medium Flat-Rate Box'), + 'LG FLAT RATE BOX' => __('Large Flat-Rate Box'), 'FLAT RATE ENVELOPE' => __('Flat-Rate Envelope'), + 'SM FLAT RATE ENVELOPE' => __('Small Flat-Rate Envelope'), + 'WINDOW FLAT RATE ENVELOPE' => __('Window Flat-Rate Envelope'), + 'GIFT CARD FLAT RATE ENVELOPE' => __('Gift Card Flat-Rate Envelope'), + 'LEGAL FLAT RATE ENVELOPE' => __('Legal Flat-Rate Envelope'), + 'PADDED FLAT RATE ENVELOPE' => __('Padded Flat-Rate Envelope'), 'RECTANGULAR' => __('Rectangular'), 'NONRECTANGULAR' => __('Non-rectangular'), ], @@ -805,73 +817,103 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'filters' => [ 'within_us' => [ 'method' => [ - 'Priority Mail Express Flat Rate Envelope', - 'Priority Mail Express Flat Rate Envelope Hold For Pickup', - 'Priority Mail Flat Rate Envelope', - 'Priority Mail Large Flat Rate Box', - 'Priority Mail Medium Flat Rate Box', - 'Priority Mail Small Flat Rate Box', - 'Priority Mail Express Hold For Pickup', - 'Priority Mail Express', - 'Priority Mail', - 'Priority Mail Hold For Pickup', - 'Priority Mail Large Flat Rate Box Hold For Pickup', - 'Priority Mail Medium Flat Rate Box Hold For Pickup', - 'Priority Mail Small Flat Rate Box Hold For Pickup', - 'Priority Mail Flat Rate Envelope Hold For Pickup', - 'Priority Mail Small Flat Rate Envelope', - 'Priority Mail Small Flat Rate Envelope Hold For Pickup', - 'First-Class Package Service Hold For Pickup', - 'Retail Ground', - 'Media Mail', - 'First-Class Mail Large Envelope', - 'Priority Mail Express Sunday/Holiday Delivery', - 'Priority Mail Express Sunday/Holiday Delivery Flat Rate Envelope', - 'Priority Mail Express Sunday/Holiday Delivery Flat Rate Boxes', + '13', '27', '16', '22', '17', '28', '2', '3', '1', '33', '34', '35', + '36', '37', '42', '43', '53', '4', '6', '15', '23', '25', '57' ], ], 'from_us' => [ 'method' => [ - 'Priority Mail Express International Flat Rate Envelope', - 'Priority Mail International Flat Rate Envelope', - 'Priority Mail International Large Flat Rate Box', - 'Priority Mail International Medium Flat Rate Box', - 'Priority Mail International Small Flat Rate Box', - 'Priority Mail International Small Flat Rate Envelope', - 'Priority Mail Express International Flat Rate Boxes', - 'Global Express Guaranteed (GXG)', - 'USPS GXG Envelopes', - 'Priority Mail Express International', - 'Priority Mail International', - 'First-Class Mail International Letter', - 'First-Class Mail International Large Envelope', - 'First-Class Package International Service', + 'INT_10', 'INT_8', 'INT_11', 'INT_9', 'INT_16', 'INT_20', 'INT_4', + 'INT_12', 'INT_1', 'INT_2', 'INT_13', 'INT_14', 'INT_15' ], ], ], ], [ - 'containers' => ['FLAT RATE BOX'], + 'containers' => ['SM FLAT RATE BOX'], 'filters' => [ 'within_us' => [ - 'method' => [ - 'Priority Mail Large Flat Rate Box', - 'Priority Mail Medium Flat Rate Box', - 'Priority Mail Small Flat Rate Box', - 'Priority Mail International Large Flat Rate Box', - 'Priority Mail International Medium Flat Rate Box', - 'Priority Mail International Small Flat Rate Box', - 'Priority Mail Express Sunday/Holiday Delivery Flat Rate Boxes', - ], + 'method' => ['28', '57'], ], 'from_us' => [ - 'method' => [ - 'Priority Mail International Large Flat Rate Box', - 'Priority Mail International Medium Flat Rate Box', - 'Priority Mail International Small Flat Rate Box', - 'Priority Mail International DVD Flat Rate priced box', - 'Priority Mail International Large Video Flat Rate priced box', - ], + 'method' => ['INT_16', 'INT_24'], + ], + ] + ], + [ + 'containers' => ['MD FLAT RATE BOX'], + 'filters' => [ + 'within_us' => [ + 'method' => ['17', '57'], + ], + 'from_us' => [ + 'method' => ['INT_9', 'INT_24'], + ], + ] + ], + [ + 'containers' => ['LG FLAT RATE BOX'], + 'filters' => [ + 'within_us' => [ + 'method' => ['22', '57'], + ], + 'from_us' => [ + 'method' => ['INT_11', 'INT_24', 'INT_25'], + ], + ] + ], + [ + 'containers' => ['SM FLAT RATE ENVELOPE'], + 'filters' => [ + 'within_us' => [ + 'method' => ['42', '43'], + ], + 'from_us' => [ + 'method' => ['INT_20'], + ], + ] + ], + [ + 'containers' => ['WINDOW FLAT RATE ENVELOPE'], + 'filters' => [ + 'within_us' => [ + 'method' => ['40', '41'], + ], + 'from_us' => [ + 'method' => ['INT_19'], + ], + ] + ], + [ + 'containers' => ['GIFT CARD FLAT RATE ENVELOPE'], + 'filters' => [ + 'within_us' => [ + 'method' => ['38', '39'], + ], + 'from_us' => [ + 'method' => ['INT_18'], + ], + ] + ], + [ + 'containers' => ['PADDED FLAT RATE ENVELOPE'], + 'filters' => [ + 'within_us' => [ + 'method' => ['62', '63', '64', '46', '29'], + ], + 'from_us' => [ + 'method' => ['INT_27', 'INT_23'], + ], + ] + ], + [ + 'containers' => ['LEGAL FLAT RATE ENVELOPE'], + 'filters' => [ + 'within_us' => [ + 'method' => ['44', '45', '30', '31', '32'], + ], + 'from_us' => [ + 'method' => ['INT_17', 'INT_22'], ], ] ], @@ -879,30 +921,11 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'containers' => ['FLAT RATE ENVELOPE'], 'filters' => [ 'within_us' => [ - 'method' => [ - 'Priority Mail Flat Rate Envelope', - 'Priority Mail Express Flat Rate Envelope', - 'Priority Mail Express Flat Rate Envelope Hold For Pickup', - 'Priority Mail Flat Rate Envelope', - 'First-Class Mail Large Envelope', - 'Priority Mail Flat Rate Envelope Hold For Pickup', - 'Priority Mail Small Flat Rate Envelope', - 'Priority Mail Small Flat Rate Envelope Hold For Pickup', - 'Priority Mail Express Sunday/Holiday Delivery Flat Rate Envelope', - 'Priority Mail Express Padded Flat Rate Envelope', - ], + 'method' => ['16', '13', '27', '16', '15', '37', '42', '43', '25', '62'], ], 'from_us' => [ 'method' => [ - 'Priority Mail Express International Flat Rate Envelope', - 'Priority Mail International Flat Rate Envelope', - 'First-Class Mail International Large Envelope', - 'Priority Mail International Small Flat Rate Envelope', - 'Priority Mail Express International Legal Flat Rate Envelope', - 'Priority Mail International Gift Card Flat Rate Envelope', - 'Priority Mail International Window Flat Rate Envelope', - 'Priority Mail International Legal Flat Rate Envelope', - 'Priority Mail Express International Padded Flat Rate Envelope', + 'INT_10', 'INT_8', 'INT_14', 'INT_20', 'INT_17', 'INT_18', 'INT_19', 'INT_22', 'INT_27' ], ], ] @@ -911,22 +934,10 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'containers' => ['RECTANGULAR'], 'filters' => [ 'within_us' => [ - 'method' => [ - 'Priority Mail Express', - 'Priority Mail', - 'Retail Ground', - 'Media Mail', - 'Library Mail', - 'First-Class Package Service', - ], + 'method' => ['3', '1', '4', '6', '7', '61'], ], 'from_us' => [ - 'method' => [ - 'USPS GXG Envelopes', - 'Priority Mail Express International', - 'Priority Mail International', - 'First-Class Package International Service', - ], + 'method' => ['INT_12', 'INT_1', 'INT_2', 'INT_15'], ], ] ], @@ -934,21 +945,10 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'containers' => ['NONRECTANGULAR'], 'filters' => [ 'within_us' => [ - 'method' => [ - 'Priority Mail Express', - 'Priority Mail', - 'Retail Ground', - 'Media Mail', - 'Library Mail', - ], + 'method' => ['3', '1', '4', '6', '7'], ], 'from_us' => [ - 'method' => [ - 'Global Express Guaranteed (GXG)', - 'Priority Mail Express International', - 'Priority Mail International', - 'First-Class Package International Service', - ], + 'method' => ['INT_4', 'INT_1', 'INT_2', 'INT_15'], ], ] ], diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json index 5baccddf4884307f4ebdeed9199fedb00debf4bc..15e93d0bea4fb6d0e89f21f180b2c91486c8f5aa 100644 --- a/app/code/Magento/Usps/composer.json +++ b/app/code/Magento/Usps/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-usps", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-shipping": "100.2.*", "magento/module-directory": "100.2.*", diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json index 21f3ec1dd467f240c609d5931ffa5cbde8dc3e15..e4b06d0edb34ab25d4d1279fb463a4f630ee77e9 100644 --- a/app/code/Magento/Variable/composer.json +++ b/app/code/Magento/Variable/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-variable", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-backend": "100.2.*", "magento/module-email": "100.2.*", "magento/module-store": "100.2.*", diff --git a/app/code/Magento/Vault/composer.json b/app/code/Magento/Vault/composer.json index 74dd568e3b45ee4e3e7f9e235d3389191b7a93e4..b2edf040674d83f6335d407089201b46fe16ecce 100644 --- a/app/code/Magento/Vault/composer.json +++ b/app/code/Magento/Vault/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-vault", "description": "", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*", "magento/module-sales": "100.2.*", "magento/module-store": "100.2.*", diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json index 3a972432101154fa2c4f167473fc6f4d6aa113a0..4396f1fb2b3bf4e114dd2ab4dfbd37eb7c2ffd7e 100644 --- a/app/code/Magento/Version/composer.json +++ b/app/code/Magento/Version/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-version", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*" }, "type": "magento2-module", diff --git a/app/code/Magento/Webapi/Model/Config.php b/app/code/Magento/Webapi/Model/Config.php index 45d29bc59cf0d6a1c9c1be78ff84343f50b1029d..fb6dc894e3c0ae87915f12bdf38311a5be541874 100644 --- a/app/code/Magento/Webapi/Model/Config.php +++ b/app/code/Magento/Webapi/Model/Config.php @@ -8,6 +8,8 @@ namespace Magento\Webapi\Model; use Magento\Webapi\Model\Cache\Type\Webapi as WebapiCache; use Magento\Webapi\Model\Config\Reader; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; /** * Web API Config Model. @@ -40,16 +42,26 @@ class Config */ protected $services; + /** + * @var SerializerInterface + */ + private $serializer; + /** * Initialize dependencies. * * @param WebapiCache $cache * @param Reader $configReader + * @param SerializerInterface|null $serializer */ - public function __construct(WebapiCache $cache, Reader $configReader) - { + public function __construct( + WebapiCache $cache, + Reader $configReader, + SerializerInterface $serializer = null + ) { $this->cache = $cache; $this->configReader = $configReader; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -62,10 +74,10 @@ class Config if (null === $this->services) { $services = $this->cache->load(self::CACHE_ID); if ($services && is_string($services)) { - $this->services = unserialize($services); + $this->services = $this->serializer->unserialize($services); } else { $this->services = $this->configReader->read(); - $this->cache->save(serialize($this->services), self::CACHE_ID); + $this->cache->save($this->serializer->serialize($this->services), self::CACHE_ID); } } return $this->services; diff --git a/app/code/Magento/Webapi/Model/ServiceMetadata.php b/app/code/Magento/Webapi/Model/ServiceMetadata.php index b75d10f9a271f7a3f39fff2ac9494f020b5cf660..14e45ccb409db24df2dd2f1c4f8d5693a55d3126 100644 --- a/app/code/Magento/Webapi/Model/ServiceMetadata.php +++ b/app/code/Magento/Webapi/Model/ServiceMetadata.php @@ -7,6 +7,8 @@ namespace Magento\Webapi\Model; use Magento\Webapi\Model\Config\Converter; use Magento\Webapi\Model\Cache\Type\Webapi as WebApiCache; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; /** * Service Metadata Model @@ -74,6 +76,11 @@ class ServiceMetadata */ protected $typeProcessor; + /** + * @var SerializerInterface + */ + private $serializer; + /** * Initialize dependencies. * @@ -81,17 +88,20 @@ class ServiceMetadata * @param WebApiCache $cache * @param \Magento\Webapi\Model\Config\ClassReflector $classReflector * @param \Magento\Framework\Reflection\TypeProcessor $typeProcessor + * @param SerializerInterface|null $serializer */ public function __construct( \Magento\Webapi\Model\Config $config, WebApiCache $cache, \Magento\Webapi\Model\Config\ClassReflector $classReflector, - \Magento\Framework\Reflection\TypeProcessor $typeProcessor + \Magento\Framework\Reflection\TypeProcessor $typeProcessor, + SerializerInterface $serializer = null ) { $this->config = $config; $this->cache = $cache; $this->classReflector = $classReflector; $this->typeProcessor = $typeProcessor; + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -142,12 +152,18 @@ class ServiceMetadata $servicesConfig = $this->cache->load(self::SERVICES_CONFIG_CACHE_ID); $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID); if ($servicesConfig && is_string($servicesConfig) && $typesData && is_string($typesData)) { - $this->services = unserialize($servicesConfig); - $this->typeProcessor->setTypesData(unserialize($typesData)); + $this->services = $this->serializer->unserialize($servicesConfig); + $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData)); } else { $this->services = $this->initServicesMetadata(); - $this->cache->save(serialize($this->services), self::SERVICES_CONFIG_CACHE_ID); - $this->cache->save(serialize($this->typeProcessor->getTypesData()), self::REFLECTED_TYPES_CACHE_ID); + $this->cache->save( + $this->serializer->serialize($this->services), + self::SERVICES_CONFIG_CACHE_ID + ); + $this->cache->save( + $this->serializer->serialize($this->typeProcessor->getTypesData()), + self::REFLECTED_TYPES_CACHE_ID + ); } } return $this->services; @@ -256,12 +272,18 @@ class ServiceMetadata $routesConfig = $this->cache->load(self::ROUTES_CONFIG_CACHE_ID); $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID); if ($routesConfig && is_string($routesConfig) && $typesData && is_string($typesData)) { - $this->routes = unserialize($routesConfig); - $this->typeProcessor->setTypesData(unserialize($typesData)); + $this->routes = $this->serializer->unserialize($routesConfig); + $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData)); } else { $this->routes = $this->initRoutesMetadata(); - $this->cache->save(serialize($this->routes), self::ROUTES_CONFIG_CACHE_ID); - $this->cache->save(serialize($this->typeProcessor->getTypesData()), self::REFLECTED_TYPES_CACHE_ID); + $this->cache->save( + $this->serializer->serialize($this->routes), + self::ROUTES_CONFIG_CACHE_ID + ); + $this->cache->save( + $this->serializer->serialize($this->typeProcessor->getTypesData()), + self::REFLECTED_TYPES_CACHE_ID + ); } } return $this->routes; diff --git a/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php b/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php new file mode 100644 index 0000000000000000000000000000000000000000..74280f61916d7182e90bdf1e9b6125da55a6c31b --- /dev/null +++ b/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php @@ -0,0 +1,96 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Webapi\Test\Unit\Model; + +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Webapi\Model\Config; +use Magento\Webapi\Model\Config\Reader; +use Magento\Webapi\Model\Cache\Type\Webapi; + +class ConfigTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Config + */ + private $config; + + /** + * @var Webapi|\PHPUnit_Framework_MockObject_MockObject + */ + private $webapiCacheMock; + + /** + * @var Reader|\PHPUnit_Framework_MockObject_MockObject + */ + private $configReaderMock; + + /** + * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $serializerMock; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->webapiCacheMock = $this->getMock(\Magento\Webapi\Model\Cache\Type\Webapi::class, [], [], '', false); + $this->configReaderMock = $this->getMock(\Magento\Webapi\Model\Config\Reader::class, [], [], '', false); + $this->serializerMock = $this->getMock(SerializerInterface::class); + + $this->config = $objectManager->getObject( + Config::class, + [ + 'cache' => $this->webapiCacheMock, + 'configReader' => $this->configReaderMock, + 'serializer' => $this->serializerMock + ] + ); + } + + public function testGetServices() + { + $data = ['foo' => 'bar']; + $serializedData = 'serialized data'; + $this->webapiCacheMock->expects($this->once()) + ->method('load') + ->with(Config::CACHE_ID) + ->willReturn($serializedData); + $this->serializerMock->expects($this->once()) + ->method('unserialize') + ->with($serializedData) + ->willReturn($data); + $this->config->getServices(); + $this->assertEquals($data, $this->config->getServices()); + } + + public function testGetServicesNoCache() + { + $data = ['foo' => 'bar']; + $serializedData = 'serialized data'; + $this->webapiCacheMock->expects($this->once()) + ->method('load') + ->with(Config::CACHE_ID) + ->willReturn(false); + $this->serializerMock->expects($this->never()) + ->method('unserialize'); + $this->configReaderMock->expects($this->once()) + ->method('read') + ->willReturn($data); + $this->serializerMock->expects($this->once()) + ->method('serialize') + ->with($data) + ->willReturn($serializedData); + $this->webapiCacheMock->expects($this->once()) + ->method('save') + ->with( + $serializedData, + Config::CACHE_ID + ); + + $this->config->getServices(); + $this->assertEquals($data, $this->config->getServices()); + } +} diff --git a/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php b/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php index 29c1bf90402ebe36d6ca91c5585cacb03f739cc3..4125f82b7923ffb30a3bfc0d86f3414255498231 100644 --- a/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php @@ -1,187 +1,450 @@ <?php /** - * ServiceMetadata Unit tests. - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - -/** - * Class implements tests for \Magento\Webapi\Model\ServiceMetadata class. - */ namespace Magento\Webapi\Test\Unit\Model; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Webapi\Model\Config; +use Magento\Webapi\Model\Cache\Type\Webapi; +use Magento\Webapi\Model\Config\ClassReflector; +use Magento\Framework\Reflection\TypeProcessor; +use Magento\Webapi\Model\ServiceMetadata; +use Magento\Customer\Api\CustomerRepositoryInterface; + class ServiceMetadataTest extends \PHPUnit_Framework_TestCase { - /** @var \Magento\Webapi\Model\ServiceMetadata */ - protected $serviceMetadata; + /** + * @var ServiceMetadata + */ + private $serviceMetadata; /** - * Set up helper. - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @var Webapi|\PHPUnit_Framework_MockObject_MockObject + */ + private $cacheMock; + + /** + * @var Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; + + /** + * @var ClassReflector|\PHPUnit_Framework_MockObject_MockObject + */ + private $classReflectorMock; + + /** + * @var TypeProcessor|\PHPUnit_Framework_MockObject_MockObject + */ + private $typeProcessorMock; + + /** + * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $serializerMock; + protected function setUp() { - $interfaceParameters = [ - 'activateById' => [ + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->configMock = $this->getMock(Config::class, [], [], '', false); + $this->cacheMock = $this->getMock(Webapi::class, [], [], '', false); + $this->classReflectorMock = $this->getMock(ClassReflector::class, [], [], '', false); + $this->typeProcessorMock = $this->getMock(TypeProcessor::class, [], [], '', false); + $this->serializerMock = $this->getMock(SerializerInterface::class); + + $this->serviceMetadata = $objectManager->getObject( + ServiceMetadata::class, + [ + 'config' => $this->configMock, + 'cache' => $this->cacheMock, + 'classReflector' => $this->classReflectorMock, + 'typeProcessor' => $this->typeProcessorMock, + 'serializer' => $this->serializerMock + ] + ); + } + + public function testGetServicesConfig() + { + $servicesConfig = ['foo' => 'bar']; + $typeData = ['bar' => 'foo']; + $serializedServicesConfig = 'serialized services config'; + $serializedTypeData = 'serialized type data'; + $this->cacheMock->expects($this->at(0)) + ->method('load') + ->with(ServiceMetadata::SERVICES_CONFIG_CACHE_ID) + ->willReturn($serializedServicesConfig); + $this->cacheMock->expects($this->at(1)) + ->method('load') + ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID) + ->willReturn($serializedTypeData); + $this->serializerMock->expects($this->at(0)) + ->method('unserialize') + ->with($serializedServicesConfig) + ->willReturn($servicesConfig); + $this->serializerMock->expects($this->at(1)) + ->method('unserialize') + ->with($serializedTypeData) + ->willReturn($typeData); + $this->typeProcessorMock->expects($this->once()) + ->method('setTypesData') + ->with($typeData); + $this->serviceMetadata->getServicesConfig(); + $this->assertEquals($servicesConfig, $this->serviceMetadata->getServicesConfig()); + } + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testGetServicesConfigNoCache() + { + $servicesConfig = [ + 'services' => [ + CustomerRepositoryInterface::class => [ + 'V1' => [ + 'methods' => [ + 'getById' => [ + 'resources' => [ + [ + 'Magento_Customer::customer', + ] + ], + 'secure' => false + ] + ] + ] + ] + ] + ]; + $methodsReflectionData = [ + 'getById' => [ + 'documentation' => 'Get customer by customer ID.', 'interface' => [ 'in' => [ 'parameters' => [ 'customerId' => [ - 'force' => true, - 'value' => '%customer_id%', - ], - 'requiredInputParameter' => [ + 'type' => 'int', 'required' => true, - ], - ], + 'documentation' => null + ] + ] ], 'out' => [ 'parameters' => [ - 'outputParameter' => [ - 'type' => 'string', + 'result' => [ + 'type' => 'CustomerDataCustomerInterface', + 'required' => true, + 'documentation' => null + ] + ] + ] + ] + ] + ]; + $servicesMetadata = [ + 'customerCustomerRepositoryV1' => [ + 'methods' => array_merge_recursive( + [ + 'getById' => [ + 'resources' => [ + [ + 'Magento_Customer::customer', + ], ], - ], + 'method' => 'getById', + 'inputRequired' => false, + 'isSecure' => false, + ] ], - ], - ], + $methodsReflectionData + ), + 'class' => CustomerRepositoryInterface::class, + 'description' => 'Customer CRUD interface.' + ] ]; - $classReflection = $this->getMock( - \Magento\Webapi\Model\Config\ClassReflector::class, - ['reflectClassMethods', 'extractClassDescription'], - [], - '', - false - ); - $classReflection->expects($this->any()) + $typeData = [ + 'CustomerDataCustomerInterface' => [ + 'documentation' => 'Customer interface.', + 'parameters' => [ + 'id' => [ + 'type' => 'int', + 'required' => false, + 'documentation' => 'Customer id' + ] + ] + ] + ]; + $serializedServicesConfig = 'serialized services config'; + $serializedTypeData = 'serialized type data'; + $this->cacheMock->expects($this->at(0)) + ->method('load') + ->with(ServiceMetadata::SERVICES_CONFIG_CACHE_ID) + ->willReturn(false); + $this->cacheMock->expects($this->at(1)) + ->method('load') + ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID) + ->willReturn(false); + $this->serializerMock->expects($this->never()) + ->method('unserialize'); + $this->configMock->expects($this->once()) + ->method('getServices') + ->willReturn($servicesConfig); + $this->classReflectorMock->expects($this->once()) ->method('reflectClassMethods') - ->will($this->returnValue($interfaceParameters)); - $classReflection->expects($this->any()) + ->willReturn($methodsReflectionData); + $this->classReflectorMock->expects($this->once()) ->method('extractClassDescription') - ->will($this->returnValue('classDescription')); + ->with(CustomerRepositoryInterface::class) + ->willReturn('Customer CRUD interface.'); + $this->typeProcessorMock->expects($this->once()) + ->method('getTypesData') + ->willReturn($typeData); + $this->serializerMock->expects($this->at(0)) + ->method('serialize') + ->with($servicesMetadata) + ->willReturn($serializedServicesConfig); + $this->serializerMock->expects($this->at(1)) + ->method('serialize') + ->with($typeData) + ->willReturn($serializedTypeData); + $this->cacheMock->expects($this->at(2)) + ->method('save') + ->with( + $serializedServicesConfig, + ServiceMetadata::SERVICES_CONFIG_CACHE_ID + ); + $this->cacheMock->expects($this->at(3)) + ->method('save') + ->with( + $serializedTypeData, + ServiceMetadata::REFLECTED_TYPES_CACHE_ID + ); + $this->serviceMetadata->getServicesConfig(); + $this->assertEquals($servicesMetadata, $this->serviceMetadata->getServicesConfig()); + } + + public function testGetRoutesConfig() + { + $routesConfig = ['foo' => 'bar']; + $typeData = ['bar' => 'foo']; + $serializedRoutesConfig = 'serialized routes config'; + $serializedTypeData = 'serialized type data'; + $this->cacheMock->expects($this->at(0)) + ->method('load') + ->with(ServiceMetadata::ROUTES_CONFIG_CACHE_ID) + ->willReturn($serializedRoutesConfig); + $this->cacheMock->expects($this->at(1)) + ->method('load') + ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID) + ->willReturn($serializedTypeData); + $this->serializerMock->expects($this->at(0)) + ->method('unserialize') + ->with($serializedRoutesConfig) + ->willReturn($routesConfig); + $this->serializerMock->expects($this->at(1)) + ->method('unserialize') + ->with($serializedTypeData) + ->willReturn($typeData); + $this->typeProcessorMock->expects($this->once()) + ->method('setTypesData') + ->with($typeData); + $this->serviceMetadata->getRoutesConfig(); + $this->assertEquals($routesConfig, $this->serviceMetadata->getRoutesConfig()); + } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testGetRoutesConfigNoCache() + { $servicesConfig = [ - 'services' => [\Magento\Customer\Api\AccountManagementInterface::class => [ - 'V1' => [ - 'methods' => [ - 'activateById' => [ - 'resources' => [ - [ - 'Magento_Customer::manage', - ], - ], - 'secure' => false, - ], - ], - ], - ], \Magento\Customer\Api\CustomerRepositoryInterface::class => [ + 'services' => [ + CustomerRepositoryInterface::class => [ 'V1' => [ 'methods' => [ 'getById' => [ 'resources' => [ [ 'Magento_Customer::customer', - ], + ] ], - 'secure' => false, - ], - ], - ], - ], + 'secure' => false + ] + ] + ] + ] ], 'routes' => [ - '/V1/customers/me/activate' => [ - 'PUT' => [ + '/V1/customers/:customerId' => [ + 'GET' => [ 'secure' => false, 'service' => [ - 'class' => \Magento\Customer\Api\AccountManagementInterface::class, - 'method' => 'activateById', + 'class' => CustomerRepositoryInterface::class, + 'method' => 'getById' ], 'resources' => [ - 'self' => true, + 'Magento_Customer::customer' => true ], + 'parameters' => [] + ] + ] + ], + 'class' => CustomerRepositoryInterface::class, + 'description' => 'Customer CRUD interface.', + ]; + $methodsReflectionData = [ + 'getById' => [ + 'documentation' => 'Get customer by customer ID.', + 'interface' => [ + 'in' => [ 'parameters' => [ 'customerId' => [ - 'force' => true, - 'value' => '%customer_id%', - ], - ], + 'type' => 'int', + 'required' => true, + 'documentation' => null + ] + ] ], - ], - '/V1/customers/:customerId' => [ - 'GET' => [ - 'secure' => false, - 'service' => [ - 'class' => \Magento\Customer\Api\CustomerRepositoryInterface::class, - 'method' => 'getById', - ], - 'resources' => [ - 'Magento_Customer::customer' => true, - ], + 'out' => [ 'parameters' => [ - ], + 'result' => [ + 'type' => 'CustomerDataCustomerInterface', + 'required' => true, + 'documentation' => null + ] + ] + ] + ] + ] + ]; + $routesMetadata = [ + 'customerCustomerRepositoryV1' => [ + 'methods' => array_merge_recursive( + [ + 'getById' => [ + 'resources' => [ + [ + 'Magento_Customer::customer', + ] + ], + 'method' => 'getById', + 'inputRequired' => false, + 'isSecure' => false, + ] ], + $methodsReflectionData + ), + 'routes' => [ + '/V1/customers/:customerId' => [ + 'GET' => [ + 'method' => 'getById', + 'parameters' => [] + ] + ] ], + 'class' => CustomerRepositoryInterface::class, + 'description' => 'Customer CRUD interface.' ] ]; - - /** - * @var $cacheMock \Magento\Webapi\Model\Cache\Type\Webapi - */ - $cacheMock = $this->getMockBuilder(\Magento\Webapi\Model\Cache\Type\Webapi::class) - ->disableOriginalConstructor() - ->getMock(); - - /** @var $readerMock \Magento\Webapi\Model\Config\Reader */ - $readerMock = $this->getMockBuilder(\Magento\Webapi\Model\Config\Reader::class) - ->disableOriginalConstructor() - ->getMock(); - $readerMock->expects($this->any())->method('read')->will($this->returnValue($servicesConfig)); - - /** @var $config \Magento\Webapi\Model\Config */ - $config = new \Magento\Webapi\Model\Config($cacheMock, $readerMock); - - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $typeProcessor = $objectManager->getObject(\Magento\Framework\Reflection\TypeProcessor::class); - - /** @var $config \Magento\Webapi\Model\ServiceMetadata */ - $this->serviceMetadata = new \Magento\Webapi\Model\ServiceMetadata( - $config, - $cacheMock, - $classReflection, - $typeProcessor - ); - - parent::setUp(); + $typeData = [ + 'CustomerDataCustomerInterface' => [ + 'documentation' => 'Customer interface.', + 'parameters' => [ + 'id' => [ + 'type' => 'int', + 'required' => false, + 'documentation' => 'Customer id' + ] + ] + ] + ]; + $serializedRoutesConfig = 'serialized routes config'; + $serializedTypeData = 'serialized type data'; + $this->cacheMock->expects($this->at(0)) + ->method('load') + ->with(ServiceMetadata::ROUTES_CONFIG_CACHE_ID) + ->willReturn(false); + $this->cacheMock->expects($this->at(1)) + ->method('load') + ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID) + ->willReturn(false); + $this->serializerMock->expects($this->never()) + ->method('unserialize'); + $this->configMock->expects($this->exactly(2)) + ->method('getServices') + ->willReturn($servicesConfig); + $this->classReflectorMock->expects($this->once()) + ->method('reflectClassMethods') + ->willReturn($methodsReflectionData); + $this->classReflectorMock->expects($this->once()) + ->method('extractClassDescription') + ->with(CustomerRepositoryInterface::class) + ->willReturn('Customer CRUD interface.'); + $this->typeProcessorMock->expects($this->exactly(2)) + ->method('getTypesData') + ->willReturn($typeData); + $this->serializerMock->expects($this->at(2)) + ->method('serialize') + ->with($routesMetadata) + ->willReturn($serializedRoutesConfig); + $this->serializerMock->expects($this->at(3)) + ->method('serialize') + ->with($typeData) + ->willReturn($serializedTypeData); + $this->cacheMock->expects($this->at(6)) + ->method('save') + ->with( + $serializedRoutesConfig, + ServiceMetadata::ROUTES_CONFIG_CACHE_ID + ); + $this->cacheMock->expects($this->at(7)) + ->method('save') + ->with( + $serializedTypeData, + ServiceMetadata::REFLECTED_TYPES_CACHE_ID + ); + $this->serviceMetadata->getRoutesConfig(); + $this->assertEquals($routesMetadata, $this->serviceMetadata->getRoutesConfig()); } /** - * Test identifying service name including subservices using class name. - * - * @dataProvider serviceNameDataProvider + * @dataProvider getServiceNameDataProvider */ public function testGetServiceName($className, $version, $preserveVersion, $expected) { - $actual = $this->serviceMetadata->getServiceName($className, $version, $preserveVersion); - $this->assertEquals($expected, $actual); + $this->assertEquals( + $expected, + $this->serviceMetadata->getServiceName($className, $version, $preserveVersion) + ); } /** - * Dataprovider for testGetServiceName - * * @return string */ - public function serviceNameDataProvider() + public function getServiceNameDataProvider() { return [ - [\Magento\Customer\Api\AccountManagementInterface::class, 'V1', false, 'customerAccountManagement'], - [\Magento\Customer\Api\AddressRepositoryInterface::class, 'V1', true, 'customerAddressRepositoryV1'], + [ + \Magento\Customer\Api\AccountManagementInterface::class, + 'V1', + false, + 'customerAccountManagement' + ], + [ + \Magento\Customer\Api\AddressRepositoryInterface::class, + 'V1', + true, + 'customerAddressRepositoryV1' + ], ]; } /** * @expectedException \InvalidArgumentException - * @dataProvider dataProviderForTestGetServiceNameInvalidName + * @dataProvider getServiceNameInvalidNameDataProvider */ public function testGetServiceNameInvalidName($interfaceClassName, $version) { @@ -189,111 +452,18 @@ class ServiceMetadataTest extends \PHPUnit_Framework_TestCase } /** - * Dataprovider for testGetServiceNameInvalidName - * * @return string */ - public function dataProviderForTestGetServiceNameInvalidName() + public function getServiceNameInvalidNameDataProvider() { return [ - ['BarV1Interface', 'V1'], // Missed vendor, module, 'Service' + ['BarV1Interface', 'V1'], // Missed vendor, module and Service ['Service\\V1Interface', 'V1'], // Missed vendor and module ['Magento\\Foo\\Service\\BarVxInterface', 'V1'], // Version number should be a number - ['Magento\\Foo\\Service\\BarInterface', 'V1'], // Version missed - ['Magento\\Foo\\Service\\BarV1', 'V1'], // 'Interface' missed - ['Foo\\Service\\BarV1Interface', 'V1'], // Module missed - ['Foo\\BarV1Interface', 'V1'] // Module and 'Service' missed - ]; - } - - public function testGetServiceMetadata() - { - $expectedResult = [ - 'methods' => [ - 'activateById' => [ - 'method' => 'activateById', - 'inputRequired' => '', - 'isSecure' => '', - 'resources' => [['Magento_Customer::manage']], - 'interface' => [ - 'in' => [ - 'parameters' => [ - 'customerId' => [ - 'force' => true, - 'value' => '%customer_id%', - ], - 'requiredInputParameter' => [ - 'required' => true, - ], - ], - ], - 'out' => [ - 'parameters' => [ - 'outputParameter' => [ - 'type' => 'string', - ], - ], - ], - ], - ], - ], - 'class' => \Magento\Customer\Api\AccountManagementInterface::class, - 'description' => 'classDescription', + ['Magento\\Foo\\Service\\BarInterface', 'V1'], // Missed version + ['Magento\\Foo\\Service\\BarV1', 'V1'], // Missed Interface + ['Foo\\Service\\BarV1Interface', 'V1'], // Missed module + ['Foo\\BarV1Interface', 'V1'] // Missed module and Service ]; - $result = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1'); - $this->assertEquals($expectedResult, $result); - } - - public function testGetRouteMetadata() - { - $expectedResult = [ - 'methods' => [ - 'activateById' => [ - 'method' => 'activateById', - 'inputRequired' => '', - 'isSecure' => '', - 'resources' => [['Magento_Customer::manage']], - 'interface' => [ - 'in' => [ - 'parameters' => [ - 'customerId' => [ - 'force' => true, - 'value' => '%customer_id%', - ], - 'requiredInputParameter' => [ - 'required' => true, - ], - ], - ], - 'out' => [ - 'parameters' => [ - 'outputParameter' => [ - 'type' => 'string', - ], - ], - ], - ], - ], - ], - 'class' => \Magento\Customer\Api\AccountManagementInterface::class, - 'description' => 'classDescription', - 'routes' => [ - '/V1/customers/me/activate' => [ - 'PUT' => [ - 'method' => 'activateById', - 'parameters' => [ - 'customerId' => [ - 'force' => true, - 'value' => '%customer_id%' - ] - ] - ] - ] - ] - ]; - $result = $this->serviceMetadata->getRouteMetadata('customerAccountManagementV1'); - $this->assertEquals($expectedResult, $result); } } - -require_once realpath(__DIR__ . '/../_files/test_interfaces.php'); diff --git a/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php b/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php deleted file mode 100644 index aa5d1a7bfab7e5a1858ae9b321d41a1accba3955..0000000000000000000000000000000000000000 --- a/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php -/** - * Config helper Unit tests. - * - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -/** - * Class implements tests for \Magento\Webapi\Model\Soap\Config class. - */ -namespace Magento\Webapi\Test\Unit\Model\Soap; - -class ConfigTest extends \PHPUnit_Framework_TestCase -{ - /** @var \Magento\Webapi\Model\Soap\Config */ - protected $_soapConfig; - - /** @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ - protected $objectManager; - - /** - * Set up helper. - */ - protected function setUp() - { - $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $typeProcessor = $this->objectManager->getObject(\Magento\Framework\Reflection\TypeProcessor::class); - - $objectManagerMock = $this->getMockBuilder( - \Magento\Framework\App\ObjectManager::class - )->disableOriginalConstructor()->getMock(); - - $classReflection = $this->getMock( - \Magento\Webapi\Model\Config\ClassReflector::class, - ['reflectClassMethods'], - ['_typeProcessor' => $typeProcessor], - '' - ); - $classReflection->expects($this->any())->method('reflectClassMethods')->will($this->returnValue([])); - - $servicesConfig = [ - 'services' => [\Magento\Customer\Api\AccountManagementInterface::class => [ - 'V1' => [ - 'methods' => [ - 'activate' => [ - 'resources' => [ - [ - 'Magento_Customer::manage', - ], - ], - 'secure' => false, - ], - ], - ], - ], \Magento\Customer\Api\CustomerRepositoryInterface::class => [ - 'V1' => [ - 'methods' => [ - 'getById' => [ - 'resources' => [ - [ - 'Magento_Customer::customer', - ], - ], - 'secure' => false, - ], - ], - ], - ], - ], - ]; - - /** - * @var $registryMock \Magento\Framework\Registry - */ - $registryMock = $this->getMockBuilder(\Magento\Framework\Registry::class) - ->disableOriginalConstructor() - ->getMock(); - - /** - * @var $cacheMock \Magento\Webapi\Model\Cache\Type\Webapi - */ - $cacheMock = $this->getMockBuilder(\Magento\Webapi\Model\Cache\Type\Webapi::class) - ->disableOriginalConstructor() - ->getMock(); - - /** @var $readerMock \Magento\Webapi\Model\Config\Reader */ - $readerMock = $this->getMockBuilder(\Magento\Webapi\Model\Config\Reader::class) - ->disableOriginalConstructor() - ->getMock(); - $readerMock->expects($this->any())->method('read')->will($this->returnValue($servicesConfig)); - - /** @var $config \Magento\Webapi\Model\Config */ - $config = new \Magento\Webapi\Model\Config($cacheMock, $readerMock); - - /** @var $config \Magento\Webapi\Model\ServiceMetadata */ - $serviceMetadata = new \Magento\Webapi\Model\ServiceMetadata( - $config, - $cacheMock, - $classReflection, - $typeProcessor); - - $this->_soapConfig = $this->objectManager->getObject( - \Magento\Webapi\Model\Soap\Config::class, - [ - 'objectManager' => $objectManagerMock, - 'registry' => $registryMock, - 'serviceMetadata' => $serviceMetadata, - ] - ); - parent::setUp(); - } - - public function testGetRequestedSoapServices() - { - $expectedResult = [ - 'customerAccountManagementV1' => - [ - 'methods' => [ - 'activate' => [ - 'method' => 'activate', - 'inputRequired' => '', - 'isSecure' => '', - 'resources' => [['Magento_Customer::manage']], - ], - ], - 'class' => \Magento\Customer\Api\AccountManagementInterface::class, - 'description' => 'Interface for managing customers accounts.', - ], - ]; - - $result = $this->_soapConfig->getRequestedSoapServices( - ['customerAccountManagementV1', 'moduleBarV2', 'moduleBazV1'] - ); - - $this->assertEquals($expectedResult, $result); - } - - public function testGetServiceMethodInfo() - { - $expectedResult = [ - 'class' => \Magento\Customer\Api\CustomerRepositoryInterface::class, - 'method' => 'getById', - 'isSecure' => false, - 'resources' => [['Magento_Customer::customer']], - ]; - $methodInfo = $this->_soapConfig->getServiceMethodInfo( - 'customerCustomerRepositoryV1GetById', - ['customerCustomerRepositoryV1', 'moduleBazV1'] - ); - $this->assertEquals($expectedResult, $methodInfo); - } - - public function testGetSoapOperation() - { - $expectedResult = 'customerAccountManagementV1Activate'; - $soapOperation = $this->_soapConfig - ->getSoapOperation(\Magento\Customer\Api\AccountManagementInterface::class, 'activate', 'V1'); - $this->assertEquals($expectedResult, $soapOperation); - } -} - -require_once realpath(__DIR__ . '/../../_files/test_interfaces.php'); diff --git a/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php b/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php deleted file mode 100644 index 288a747cefd89cec4182de66890127eebd552806..0000000000000000000000000000000000000000 --- a/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -namespace Magento\Framework\Module\Service; - -/** - * The list of test interfaces. - */ -interface FooV1Interface -{ - public function someMethod(); -} -interface BarV1Interface -{ - public function someMethod(); -} -interface FooBarV1Interface -{ - public function someMethod(); -} -namespace Magento\Framework\Module\Service\Foo; - -interface BarV1Interface -{ - public function someMethod(); -} diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json index f2796df70a8fae522a34d0c94e079afd9f525f9c..6fc712722adddf10c16e4add70913a62c2ef2bc7 100644 --- a/app/code/Magento/Webapi/composer.json +++ b/app/code/Magento/Webapi/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-webapi", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-authorization": "100.2.*", "magento/module-integration": "100.2.*", diff --git a/app/code/Magento/WebapiSecurity/composer.json b/app/code/Magento/WebapiSecurity/composer.json index 506975f1aa188d4f0d90f8d2f0484153998f2c39..0f4ef7b3dc8839518bcc2982e9975c53d99a6c1b 100644 --- a/app/code/Magento/WebapiSecurity/composer.json +++ b/app/code/Magento/WebapiSecurity/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-webapi-security", "description": "WebapiSecurity module provides option to loosen security on some webapi resources.", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-webapi": "100.2.*", "magento/framework": "100.2.*" }, diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json index 035d66e5a96b416f1f5e3140ef9e45e299c1b52a..70fd4a25d0310d94d4254a8079755eab01ad610f 100644 --- a/app/code/Magento/Weee/composer.json +++ b/app/code/Magento/Weee/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-weee", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-catalog": "101.1.*", "magento/module-tax": "100.2.*", diff --git a/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/ThemeId.php b/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/ThemeId.php index f5197dd7d0435d672023a0027d7bbb7674036abb..dc048d41612b800c9d291b5067b0106bb1fbf079 100644 --- a/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/ThemeId.php +++ b/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/ThemeId.php @@ -10,6 +10,10 @@ */ namespace Magento\Widget\Model\ResourceModel\Widget\Instance\Options; +/** + * @deprecated created new class that correctly loads theme options and whose name follows naming convention + * @see \Magento\Widget\Model\ResourceModel\Widget\Instance\Options\Themes + */ class ThemeId implements \Magento\Framework\Option\ArrayInterface { /** diff --git a/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/Themes.php b/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/Themes.php new file mode 100644 index 0000000000000000000000000000000000000000..403dfeb40ff2ea3330440c0a22db4247e9a5e377 --- /dev/null +++ b/app/code/Magento/Widget/Model/ResourceModel/Widget/Instance/Options/Themes.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Widget\Model\ResourceModel\Widget\Instance\Options; + +use Magento\Framework\Data\OptionSourceInterface; +use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory as ThemeCollectionFactory; + +/** + * Option source of the widget theme property. + * + * Can be used as a data provider for UI components that shows possible themes as a list. + */ +class Themes implements OptionSourceInterface +{ + /** + * @var ThemeCollectionFactory + */ + private $themeCollectionFactory; + + /** + * @param ThemeCollectionFactory $themeCollectionFactory + */ + public function __construct(ThemeCollectionFactory $themeCollectionFactory) + { + $this->themeCollectionFactory = $themeCollectionFactory; + } + + /** + * Return array of options as value-label pairs + * + * @return array Format: array('<theme ID>' => '<theme label>', ...) + */ + public function toOptionArray() + { + // Load only visible themes that are used in frontend area + return $this->themeCollectionFactory->create()->loadRegisteredThemes()->toOptionHash(); + } +} diff --git a/app/code/Magento/Widget/Test/Unit/Model/ResourceModel/Widget/Instance/Options/ThemesTest.php b/app/code/Magento/Widget/Test/Unit/Model/ResourceModel/Widget/Instance/Options/ThemesTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e3854a599013298e0b3bbd6439183611d14b95d3 --- /dev/null +++ b/app/code/Magento/Widget/Test/Unit/Model/ResourceModel/Widget/Instance/Options/ThemesTest.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Widget\Test\Unit\Model\ResourceModel\Widget\Instance\Options; + +use Magento\Widget\Model\ResourceModel\Widget\Instance\Options\Themes; +use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection; +use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory as ThemeCollectionFactory; + +/** + * Test class for \Magento\Widget\Model\ResourceModel\Widget\Instance\Options\Themes + */ +class ThemesTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Themes + */ + private $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $themeCollectionFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $themeCollectionMock; + + protected function setUp() + { + $this->themeCollectionMock = $this->getMock(ThemeCollection::class, [], [], '', false); + $this->themeCollectionFactoryMock = $this->getMock(ThemeCollectionFactory::class, ['create'], [], '', false); + $this->model = new Themes( + $this->themeCollectionFactoryMock + ); + } + + public function testToOptionArray() + { + $expectedResult = [ + 1 => 'Theme Label', + ]; + $this->themeCollectionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->themeCollectionMock); + + $this->themeCollectionMock->expects($this->once())->method('loadRegisteredThemes')->willReturnSelf(); + $this->themeCollectionMock->expects($this->once())->method('toOptionHash')->willReturn($expectedResult); + + $this->assertEquals($expectedResult, $this->model->toOptionArray()); + } +} diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json index f59c4180eb2bb56522ae20f3615da92dd0c60370..b5a5e9e5569e3c62641cfc2d3cbc34030229020b 100644 --- a/app/code/Magento/Widget/composer.json +++ b/app/code/Magento/Widget/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-widget", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-cms": "101.1.*", "magento/module-backend": "100.2.*", diff --git a/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml b/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml index 2d9cf935afa0d4281e46f997e22465285f69e53d..db73e302f4a7629e380292308cce534693560d99 100644 --- a/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml +++ b/app/code/Magento/Widget/view/adminhtml/layout/adminhtml_widget_instance_block.xml @@ -52,7 +52,7 @@ <argument name="header" xsi:type="string" translate="true">Design Theme</argument> <argument name="index" xsi:type="string">theme_id</argument> <argument name="type" xsi:type="string">options</argument> - <argument name="options" xsi:type="options" model="Magento\Widget\Model\ResourceModel\Widget\Instance\Options\ThemeId"/> + <argument name="options" xsi:type="options" model="Magento\Widget\Model\ResourceModel\Widget\Instance\Options\Themes"/> <argument name="with_empty" xsi:type="string">1</argument> </arguments> </block> diff --git a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml index 4e240770b04622e4ec6c68bfa796a6a83da006e1..94ee88698111f72c81cbd86eb16adef0e9b94317 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml @@ -79,7 +79,7 @@ jQuery(function() // Add empty node to reset category filter if(!emptyNodeAdded) { var empty = Object.clone(_node); - empty.text = '<?php /* @escapeNotVerified */ echo __('None') ?>'; + empty.text = '<?php echo $block->escapeJs($block->escapeHtml(__('None'))); ?>'; empty.children = []; empty.id = 'none'; empty.path = '1/none'; diff --git a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml index 62d92ac38aecdbc22f13de959eba3f419b47c431..5d55ba4035873d028f27e5662814cc838b7e18a8 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml @@ -10,7 +10,7 @@ ?> <fieldset class="fieldset"> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Layout Updates') ?></span></legend> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Layout Updates')); ?></span></legend> <br /> <div class="widget-layout-updates"> <div id="page_group_container"></div> diff --git a/app/code/Magento/Wishlist/Pricing/ConfiguredPrice/ConfigurableProduct.php b/app/code/Magento/Wishlist/Pricing/ConfiguredPrice/ConfigurableProduct.php index 6d8e4bcd2fd1c41844cd4398043b61dec4ff36ff..be995258794cc05f1fca4a2124cac04e8c0e1c87 100644 --- a/app/code/Magento/Wishlist/Pricing/ConfiguredPrice/ConfigurableProduct.php +++ b/app/code/Magento/Wishlist/Pricing/ConfiguredPrice/ConfigurableProduct.php @@ -21,15 +21,12 @@ class ConfigurableProduct extends FinalPrice implements ConfiguredPriceInterface */ public function getValue() { - $result = 0.; /** @var \Magento\Wishlist\Model\Item\Option $customOption */ $customOption = $this->getProduct()->getCustomOption('simple_product'); - if ($customOption) { - /** @var \Magento\Framework\Pricing\PriceInfoInterface $priceInfo */ - $priceInfo = $customOption->getProduct()->getPriceInfo(); - $result = $priceInfo->getPrice(self::PRICE_CODE)->getValue(); - } - return max(0, $result); + $product = $customOption ? $customOption->getProduct() : $this->getProduct(); + $price = $product->getPriceInfo()->getPrice(self::PRICE_CODE)->getValue(); + + return max(0, $price); } /** diff --git a/app/code/Magento/Wishlist/Test/Unit/Pricing/ConfiguredPrice/ConfigurableProductTest.php b/app/code/Magento/Wishlist/Test/Unit/Pricing/ConfiguredPrice/ConfigurableProductTest.php index 9e05a578080efbd7ec91f49babfbbafc447e330d..ee4841ef79f2e6e31545f12e44fe49073166a8e3 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Pricing/ConfiguredPrice/ConfigurableProductTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Pricing/ConfiguredPrice/ConfigurableProductTest.php @@ -5,36 +5,30 @@ */ namespace Magento\Wishlist\Test\Unit\Pricing\ConfiguredPrice; -use Magento\Framework\Pricing\Adjustment\CalculatorInterface; -use Magento\Framework\Pricing\PriceCurrencyInterface; -use Magento\Framework\Pricing\PriceInfoInterface; -use Magento\Framework\Pricing\SaleableInterface; -use Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct; - class ConfigurableProductTest extends \PHPUnit_Framework_TestCase { /** - * @var SaleableInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Pricing\SaleableInterface|\PHPUnit_Framework_MockObject_MockObject */ private $saleableItem; /** - * @var CalculatorInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Pricing\Adjustment\CalculatorInterface|\PHPUnit_Framework_MockObject_MockObject */ private $calculator; /** - * @var PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Pricing\PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject */ private $priceCurrency; /** - * @var ConfigurableProduct + * @var \Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct */ private $model; /** - * @var PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject */ private $priceInfoMock; @@ -49,9 +43,6 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase 'getCustomOption', ]) ->getMockForAbstractClass(); - $this->saleableItem->expects($this->once()) - ->method('getPriceInfo') - ->willReturn($this->priceInfoMock); $this->calculator = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\CalculatorInterface::class) ->getMockForAbstractClass(); @@ -59,7 +50,7 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase $this->priceCurrency = $this->getMockBuilder(\Magento\Framework\Pricing\PriceCurrencyInterface::class) ->getMockForAbstractClass(); - $this->model = new ConfigurableProduct( + $this->model = new \Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct( $this->saleableItem, null, $this->calculator, @@ -82,7 +73,7 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase ->getMock(); $this->priceInfoMock->expects($this->once()) ->method('getPrice') - ->with(ConfigurableProduct::PRICE_CODE) + ->with(\Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct::PRICE_CODE) ->willReturn($priceMock); $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) @@ -109,11 +100,28 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase public function testGetValueWithNoCustomOption() { + $priceValue = 100; + + $priceMock = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class) + ->getMockForAbstractClass(); + $priceMock->expects($this->once()) + ->method('getValue') + ->willReturn($priceValue); + $this->saleableItem->expects($this->once()) ->method('getCustomOption') ->with('simple_product') ->willReturn(null); - $this->assertEquals(0, $this->model->getValue()); + $this->saleableItem->expects($this->once()) + ->method('getPriceInfo') + ->willReturn($this->priceInfoMock); + + $this->priceInfoMock->expects($this->once()) + ->method('getPrice') + ->with(\Magento\Wishlist\Pricing\ConfiguredPrice\ConfigurableProduct::PRICE_CODE) + ->willReturn($priceMock); + + $this->assertEquals(100, $this->model->getValue()); } } diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json index 3faee8912493c96092f70d7fc3ca0e77164b39bc..b341edde760b0761872aecc488216faa37392c22 100644 --- a/app/code/Magento/Wishlist/composer.json +++ b/app/code/Magento/Wishlist/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-wishlist", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/module-store": "100.2.*", "magento/module-customer": "100.2.*", "magento/module-catalog": "101.1.*", diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json index 29569db622d2ccc9fad9e9b87b3ad4f7ae4757d2..ff0eda055bba6a9e9899d66839216c14bbdbe02e 100644 --- a/app/design/adminhtml/Magento/backend/composer.json +++ b/app/design/adminhtml/Magento/backend/composer.json @@ -2,7 +2,7 @@ "name": "magento/theme-adminhtml-backend", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*" }, "type": "magento2-theme", diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less index 3804721026db50a77ebaf752c75f5dc35a23cf09..d861d4dcae256222cb30cc81ee21359a40e12582 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less @@ -23,8 +23,7 @@ & when (@media-common = true) { - .checkout-index-index, - .checkout-onepage-success { + .checkout-index-index { .page-title-wrapper { &:extend(.abs-visually-hidden all); } @@ -61,6 +60,14 @@ margin-left: 0; } } + + .checkout-onepage-success { + &:extend(.abs-add-clearfix all); + + .print { + display: none; + } + } } // @@ -87,4 +94,12 @@ .lib-layout-column(2, 1, @checkout-wrapper__columns); padding-right: @indent__l; } + + .checkout-onepage-success { + .print { + display: block; + float: right; + margin: 22px 0 0; + } + } } diff --git a/app/design/frontend/Magento/blank/Magento_Rma/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Rma/web/css/source/_module.less index a8d0bf8b584822f7e0084d690f9feb5ad04246a2..6596fe2fd79762908b1a87d2fbeac90fd8be7824 100644 --- a/app/design/frontend/Magento/blank/Magento_Rma/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Rma/web/css/source/_module.less @@ -158,11 +158,12 @@ .block-returns-tracking { .block-title { .action { - margin: 12px 0 0 30px; + margin: 0 0 0 30px; + } - &.track { - float: right; - } + .actions-track { + float: right; + margin-top: 12px; } } } diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json index 27ed40860dd5b065dc51e82f487722eb519ba215..7c03167ebc23278eaab5a72cddd381de7cd5afcc 100644 --- a/app/design/frontend/Magento/blank/composer.json +++ b/app/design/frontend/Magento/blank/composer.json @@ -2,7 +2,7 @@ "name": "magento/theme-frontend-blank", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.2.*" }, "type": "magento2-theme", diff --git a/app/design/frontend/Magento/blank/etc/view.xml b/app/design/frontend/Magento/blank/etc/view.xml index 3a92ad0a6741040e0adb3fc25e00948520cfa565..6c53a8613f09ca1f91c9e024b8e2cec723f0b309 100644 --- a/app/design/frontend/Magento/blank/etc/view.xml +++ b/app/design/frontend/Magento/blank/etc/view.xml @@ -227,7 +227,7 @@ </var> <var name="options"> <var name="options"> - <var name="navigation">dots</var> + <var name="nav">dots</var> </var> </var> </var> diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less index f037c1c5777cbf8f761fddf779f7c8e9942278f8..a1109523d26b5ea6b85e794a66ebad3100a551c0 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less @@ -27,8 +27,7 @@ & when (@media-common = true) { - .checkout-index-index, - .checkout-onepage-success { + .checkout-index-index { .page-title-wrapper { &:extend(.abs-visually-hidden all); } @@ -66,6 +65,14 @@ margin-left: 0; } } + + .checkout-onepage-success { + &:extend(.abs-add-clearfix all); + + .print { + display: none; + } + } } // @@ -96,4 +103,12 @@ .lib-layout-column(2, 1, @checkout-wrapper__columns); padding-right: @indent__l; } + + .checkout-onepage-success { + .print { + display: block; + float: right; + margin: 23px 0 0; + } + } } diff --git a/app/design/frontend/Magento/luma/Magento_Rma/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Rma/web/css/source/_module.less index cfec28464244e59e48aeb16e674d8afcc33407b4..c7e955e69c3a66864e073365d2863968f014ed66 100644 --- a/app/design/frontend/Magento/luma/Magento_Rma/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Rma/web/css/source/_module.less @@ -176,11 +176,12 @@ .block-returns-tracking { .block-title { .action { - margin: 12px 0 0 30px; + margin: 0 0 0 30px; + } - &.track { - float: right; - } + .actions-track { + float: right; + margin-top: 12px; } } } diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json index 98fe0ebf8061c23fa37d30a9551f05d5c41bce1b..97eb48f3c7e9efe028eae034757a6a17c4d98bd0 100644 --- a/app/design/frontend/Magento/luma/composer.json +++ b/app/design/frontend/Magento/luma/composer.json @@ -2,7 +2,7 @@ "name": "magento/theme-frontend-luma", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/theme-frontend-blank": "100.2.*", "magento/framework": "100.2.*" }, diff --git a/app/etc/di.xml b/app/etc/di.xml index 643390068a5e3e857ccb0e0d2d07fb5e26b8ea81..e430c15729d3d0cced20bf2b326d40f152b174e6 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -154,6 +154,7 @@ <preference for="Magento\Framework\EntityManager\MapperInterface" type="Magento\Framework\EntityManager\CompositeMapper"/> <preference for="Magento\Framework\Console\CommandListInterface" type="Magento\Framework\Console\CommandList"/> <preference for="Magento\Framework\DataObject\IdentityGeneratorInterface" type="Magento\Framework\DataObject\IdentityService" /> + <preference for="Magento\Framework\Serialize\SerializerInterface" type="Magento\Framework\Serialize\Serializer\Json" /> <type name="Magento\Framework\Model\ResourceModel\Db\TransactionManager" shared="false" /> <type name="Magento\Framework\Logger\Handler\Base"> <arguments> diff --git a/composer.json b/composer.json index fed4465140724cef3c24cd7facdd2ec5ceeba5b6..f9e49415d6ad3aff6976144df442861909155d2d 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "AFL-3.0" ], "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "zendframework/zend-stdlib": "~2.4.6", "zendframework/zend-code": "~2.4.6", "zendframework/zend-server": "~2.4.6", diff --git a/composer.lock b/composer.lock index 7feb568d766d012e009c59a50226f3ea8bd7b74a..02f0e31a325638840641667cac1c6783cf381e87 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "c23e80be1cc71ab108ce5ac19b3fe509", - "content-hash": "5b9734c1bdbda68cf20507525cafa0f2", + "hash": "1f34dce6d48c9e4e694c27e001414000", + "content-hash": "600aca1692cf3fe5c2ea1cbf66de09ab", "packages": [ { "name": "braintree/braintree_php", @@ -56,7 +56,7 @@ }, { "name": "colinmollenhour/cache-backend-file", - "version": "1.4", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/colinmollenhour/Cm_Cache_Backend_File.git", @@ -818,16 +818,16 @@ }, { "name": "paragonie/random_compat", - "version": "v2.0.2", + "version": "v2.0.3", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf" + "reference": "c0125896dbb151380ab47e96c621741e79623beb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf", - "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c0125896dbb151380ab47e96c621741e79623beb", + "reference": "c0125896dbb151380ab47e96c621741e79623beb", "shasum": "" }, "require": { @@ -862,7 +862,7 @@ "pseudorandom", "random" ], - "time": "2016-04-03 06:00:07" + "time": "2016-10-17 15:23:22" }, { "name": "pelago/emogrifier", @@ -922,16 +922,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "41f85e9c2582b3f6d1b7d20395fb40c687ad5370" + "reference": "ab8028c93c03cc8d9c824efa75dc94f1db2369bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/41f85e9c2582b3f6d1b7d20395fb40c687ad5370", - "reference": "41f85e9c2582b3f6d1b7d20395fb40c687ad5370", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/ab8028c93c03cc8d9c824efa75dc94f1db2369bf", + "reference": "ab8028c93c03cc8d9c824efa75dc94f1db2369bf", "shasum": "" }, "require": { @@ -1010,20 +1010,20 @@ "x.509", "x509" ], - "time": "2016-08-18 18:49:14" + "time": "2016-10-04 00:57:04" }, { "name": "psr/log", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "5277094ed527a1c4477177d102fe4c53551953e0" + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0", - "reference": "5277094ed527a1c4477177d102fe4c53551953e0", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, "require": { @@ -1057,7 +1057,7 @@ "psr", "psr-3" ], - "time": "2016-09-19 16:02:08" + "time": "2016-10-10 12:19:37" }, { "name": "ramsey/uuid", @@ -1390,7 +1390,7 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.11", + "version": "v2.8.12", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -1450,7 +1450,7 @@ }, { "name": "symfony/filesystem", - "version": "v2.8.11", + "version": "v2.8.12", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", @@ -1499,16 +1499,16 @@ }, { "name": "symfony/finder", - "version": "v3.1.4", + "version": "v3.1.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577" + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e568ef1784f447a0e54dcb6f6de30b9747b0f577", - "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577", + "url": "https://api.github.com/repos/symfony/finder/zipball/205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", + "reference": "205b5ffbb518a98ba2ae60a52656c4a31ab00c6f", "shasum": "" }, "require": { @@ -1544,20 +1544,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-08-26 12:04:02" + "time": "2016-09-28 00:11:12" }, { "name": "symfony/process", - "version": "v2.8.11", + "version": "v2.8.12", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "05a03ed27073638658cab9405d99a67dd1014987" + "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/05a03ed27073638658cab9405d99a67dd1014987", - "reference": "05a03ed27073638658cab9405d99a67dd1014987", + "url": "https://api.github.com/repos/symfony/process/zipball/024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f", + "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f", "shasum": "" }, "require": { @@ -1593,7 +1593,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-09-06 10:55:00" + "time": "2016-09-29 14:03:54" }, { "name": "tedivm/jshrink", @@ -4329,16 +4329,16 @@ }, { "name": "symfony/config", - "version": "v2.8.11", + "version": "v2.8.12", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "005bf10c156335ede2e89fb9a9ee10a0b742bc84" + "reference": "f8b1922bbda9d2ac86aecd649399040bce849fde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/005bf10c156335ede2e89fb9a9ee10a0b742bc84", - "reference": "005bf10c156335ede2e89fb9a9ee10a0b742bc84", + "url": "https://api.github.com/repos/symfony/config/zipball/f8b1922bbda9d2ac86aecd649399040bce849fde", + "reference": "f8b1922bbda9d2ac86aecd649399040bce849fde", "shasum": "" }, "require": { @@ -4378,20 +4378,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-08-16 14:56:08" + "time": "2016-09-14 20:31:12" }, { "name": "symfony/dependency-injection", - "version": "v2.8.11", + "version": "v2.8.12", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "0a732a9cafc30e54077967da4d019e1d618a8cb9" + "reference": "ee9ec9ac2b046462d341e9de7c4346142d335e75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0a732a9cafc30e54077967da4d019e1d618a8cb9", - "reference": "0a732a9cafc30e54077967da4d019e1d618a8cb9", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ee9ec9ac2b046462d341e9de7c4346142d335e75", + "reference": "ee9ec9ac2b046462d341e9de7c4346142d335e75", "shasum": "" }, "require": { @@ -4441,11 +4441,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-09-06 23:19:39" + "time": "2016-09-24 09:47:20" }, { "name": "symfony/stopwatch", - "version": "v3.1.4", + "version": "v3.1.5", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -4494,7 +4494,7 @@ }, { "name": "symfony/yaml", - "version": "v2.8.11", + "version": "v2.8.12", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", @@ -4590,7 +4590,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "lib-libxml": "*", "ext-ctype": "*", "ext-gd": "*", diff --git a/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json b/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json index 629afd442a46e7549206c1520b1b6c75f024dcb1..00888c7baf74990c6ba4d98ba6569c210ba08c7e 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json +++ b/dev/tests/api-functional/_files/Magento/TestModuleIntegrationFromConfig/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-test-module-integration-from-config", "description": "test integration create from config", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "0.42.0-beta8", "magento/module-integration": "0.42.0-beta8" }, @@ -16,4 +16,4 @@ ] ] } -} \ No newline at end of file +} diff --git a/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json index 1e2d9c0fa13dd80fcfe69374a7e02700f6b570ea..a9aa5a2ede89ce314a1f2257bc70c6b20b3bb2a0 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json +++ b/dev/tests/api-functional/_files/Magento/TestModuleJoinDirectives/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-test-join-directives", "description": "test integration for join directives", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "0.42.0-beta8", "magento/module-sales": "0.42.0-beta8" }, diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 4191ec1faa959aa1203ee45850c298f1d43bb988..cd02c6d4d7500ef9adf7d17ac9f866bfc8ef0711 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -713,6 +713,18 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract $this->assertNotNull($response['items'][0]['sku']); $this->assertEquals('simple', $response['items'][0]['sku']); + + $index = null; + foreach ($response['items'][0]['custom_attributes'] as $key => $customAttribute) { + if ($customAttribute['attribute_code'] == 'category_ids') { + $index = $key; + break; + } + } + $this->assertNotNull($index, 'Category information wasn\'t set'); + + $expectedResult = (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ? ['string' => '2'] : ['2']; + $this->assertEquals($expectedResult, $response['items'][0]['custom_attributes'][$index]['value']); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php index e4129a0739912c05dbb8546beab7f028945ad5f6..1a06be978d34c897f10aadd32e7f3e1720b1983b 100644 --- a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php @@ -6,12 +6,33 @@ */ namespace Magento\ConfigurableProduct\Api; +use Magento\Eav\Model\AttributeRepository; + class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract { const SERVICE_NAME = 'configurableProductLinkManagementV1'; const SERVICE_VERSION = 'V1'; const RESOURCE_PATH = '/V1/configurable-products'; + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + protected $objectManager; + + /** + * @var AttributeRepository + */ + protected $attributeRepository; + + /** + * Execute per test initialization + */ + public function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->attributeRepository = $this->objectManager->get(\Magento\Eav\Model\AttributeRepository::class); + } + /** * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php */ @@ -40,14 +61,76 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract } /** - * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_simple_77.php * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_simple_77.php * @magentoApiDataFixture Magento/ConfigurableProduct/_files/delete_association.php */ public function testAddChild() { $productSku = 'configurable'; $childSku = 'simple_77'; + $res = $this->addChild($productSku, $childSku); + $this->assertTrue($res); + } + + /** + * Test the full flow of creating a configurable product and adding a child via REST + * + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php + */ + public function testAddChildFullRestCreation() + { + $productSku = 'configurable-product-sku'; + $childSku = 'simple-product-sku'; + + $this->createConfigurableProduct($productSku); + $attribute = $this->attributeRepository->get('catalog_product', 'test_configurable'); + $attributeValue = $attribute->getOptions()[1]->getValue(); + $this->addOptionToConfigurableProduct($productSku, $attribute->getAttributeId(), $attributeValue); + $this->createSimpleProduct($childSku, $attributeValue); + $res = $this->addChild($productSku, $childSku); + $this->assertTrue($res); + + // confirm that the simple product was added + $children = $this->getChildren($productSku); + $added = false; + foreach ($children as $child) { + if ($child['sku'] == $childSku) { + $added = true; + break; + } + } + $this->assertTrue($added); + + // clean up products + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/products/' . $productSku, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE + ], + 'soap' => [ + 'service' => 'catalogProductRepositoryV1', + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => 'catalogProductRepositoryV1DeleteById', + ], + ]; + $this->_webApiCall($serviceInfo, ['sku' => $productSku]); + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/products/' . $childSku, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE + ], + 'soap' => [ + 'service' => 'catalogProductRepositoryV1', + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => 'catalogProductRepositoryV1DeleteById', + ], + ]; + $this->_webApiCall($serviceInfo, ['sku' => $childSku]); + } + + private function addChild($productSku, $childSku) + { $serviceInfo = [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/child', @@ -59,8 +142,90 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract 'operation' => self::SERVICE_NAME . 'AddChild' ] ]; - $res = $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'childSku' => $childSku]); - $this->assertTrue($res); + return $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'childSku' => $childSku]); + } + + protected function createConfigurableProduct($productSku) + { + $requestData = [ + 'product' => [ + 'sku' => $productSku, + 'name' => 'configurable-product-' . $productSku, + 'type_id' => 'configurable', + 'price' => 50, + 'attribute_set_id' => 4 + ] + ]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/products', + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST + ], + 'soap' => [ + 'service' => 'catalogProductRepositoryV1', + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => 'catalogProductRepositoryV1Save', + ], + ]; + return $this->_webApiCall($serviceInfo, $requestData); + } + + protected function addOptionToConfigurableProduct($productSku, $attributeId, $attributeValue) + { + $requestData = [ + 'sku' => $productSku, + 'option' => [ + 'attribute_id' => $attributeId, + 'label' => 'test_configurable', + 'position' => 0, + 'is_use_default' => true, + 'values' => [ + ['value_index' => $attributeValue], + ] + ] + ]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/configurable-products/'. $productSku .'/options', + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => 'configurableProductOptionRepositoryV1', + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => 'configurableProductOptionRepositoryV1Save', + ], + ]; + return $this->_webApiCall($serviceInfo, $requestData); + } + + protected function createSimpleProduct($sku, $attributeValue) + { + $requestData = [ + 'product' => [ + 'sku' => $sku, + 'name' => 'simple-product-' . $sku, + 'type_id' => 'simple', + 'attribute_set_id' => 4, + 'price' => 3.62, + 'status' => 1, + 'visibility' => 4, + 'custom_attributes' => [ + ['attribute_code' => 'test_configurable', 'value' => $attributeValue], + ] + ] + ]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/products', + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => 'catalogProductRepositoryV1', + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => 'catalogProductRepositoryV1Save', + ], + ]; + return $this->_webApiCall($serviceInfo, $requestData); } /** @@ -93,7 +258,7 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract /** * @param string $productSku - * @return string + * @return string[] */ protected function getChildren($productSku) { diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json index 512c5bc8d5df666ced655806af0da64952d0f4ef..cef145167860c8ebad9695d870b6cc73580e47f3 100644 --- a/dev/tests/functional/composer.json +++ b/dev/tests/functional/composer.json @@ -1,7 +1,7 @@ { "require": { "magento/mtf": "1.0.0-rc48", - "php": "~5.6.0|7.0.2|~7.0.6", + "php": "~5.6.5|7.0.2|~7.0.6", "phpunit/phpunit": "~4.8.0|~5.5.0", "phpunit/phpunit-selenium": ">=1.2" }, diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Template.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Template.php index 29361ced38bcc6b4ba344e2191f3c963eb92576d..fb22754faf483aa32b97d3e1672aeb17d58bec26 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Template.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Template.php @@ -19,7 +19,7 @@ class Template extends Block * * @var string */ - protected $spinner = '[data-role="spinner"]'; + protected $spinner = '#container [data-role="spinner"]'; /** * Magento loader. diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.xml index 269bff796c7bc618e4c257046426e35ab7a25eaa..accacc60fc5c07c386d02fdd4b038c15f6dcc166 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.xml @@ -8,26 +8,31 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Backend\Test\TestCase\GlobalSearchEntityTest" summary="Global Search Backend " ticketId="MAGETWO-28457"> <variation name="GlobalSearchEntityTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">search shows admin preview</data> <data name="search/data/query" xsi:type="string">Some search term</data> <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchPreview" /> </variation> <variation name="GlobalSearchEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">search with 2 sign return no results</data> <data name="search/data/query" xsi:type="string">:)</data> <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchNoRecordsFound" /> </variation> <variation name="GlobalSearchEntityTestVariation3"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">search product by sku</data> <data name="search/data/query" xsi:type="string">orderInjectable::default::product::sku</data> <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchProductName" /> </variation> <variation name="GlobalSearchEntityTestVariation4"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">search existed customer</data> <data name="search/data/query" xsi:type="string">customer::johndoe_unique::lastname</data> <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchCustomerName" /> </variation> <variation name="GlobalSearchEntityTestVariation5"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">search order (by order id)</data> <data name="search/data/query" xsi:type="string">orderInjectable::default::id</data> <constraint name="Magento\Backend\Test\Constraint\AssertGlobalSearchOrderId" /> diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderWithPayPalBraintreeVaultBackendTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderWithPayPalBraintreeVaultBackendTest.xml index 03e0ba330fa3b74e2a33c2983655ced95cf3dbfe..86b5ff79d648c0807a2bc346e3431fc2a7c975a2 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderWithPayPalBraintreeVaultBackendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOrderWithPayPalBraintreeVaultBackendTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Braintree\Test\TestCase\CreateOrderWithPayPalBraintreeVaultBackendTest" summary="Checkout with PayPal Braintree Vault token from Admin"> <variation name="CreateOrderWithPayPalBraintreeVaultBackendTestVariation1" summary="Checkout with PayPal Braintree Vault token from Admin" ticketId="MAGETWO-59259"> - <data name="tag" xsi:type="string">est_type:3rd_party_test, severity:S0</data> + <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data> diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml index 23fc729edb99f9645f7587d8e350464c81083fcd..f8ffa51982f1fae4d34a6290e1bebce28ba85712 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithDiscountTest.xml @@ -30,5 +30,25 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> </variation> + <variation name="OnePageCheckoutWithDiscountTestVariation2" summary="Checkout with 100% discount and free shipping if Braintree through PayPal is enabled" ticketId="MAGETWO-59940"> + <data name="description" xsi:type="string">Use saved for Braintree credit card on checkout</data> + <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data> + <data name="customer/dataset" xsi:type="string">default</data> + <data name="salesRule" xsi:type="string">active_sales_rule_with_fixed_price_discount_coupon</data> + <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data> + <data name="checkoutMethod" xsi:type="string">login</data> + <data name="shipping/shipping_service" xsi:type="string">Free Shipping</data> + <data name="shipping/shipping_method" xsi:type="string">Free</data> + <data name="payment/method" xsi:type="string">free</data> + <data name="prices" xsi:type="array"> + <item name="grandTotal" xsi:type="string">0.00</item> + </data> + <data name="configData" xsi:type="string">braintree, braintree_use_vault, freeshipping</data> + <data name="status" xsi:type="string">Pending</data> + <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S1</data> + <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> + <constraint name="Magento\Sales\Test\Constraint\AssertOrderStatusIsCorrect" /> + </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle.php index e94ec38d010f3d519e8ab2e06c5fdd21dccd544c..5cf84cf6764270708bd30327f2596253f510370d 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle.php @@ -8,7 +8,6 @@ namespace Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Section; use Magento\Mtf\Client\Element\SimpleElement; use Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Section\Bundle\Option; -use Magento\Mtf\Client\Element; use Magento\Mtf\Client\ElementInterface; use Magento\Mtf\Client\Locator; use Magento\Ui\Test\Block\Adminhtml\Section; @@ -53,6 +52,13 @@ class Bundle extends Section */ protected $bundleOptionRow = './tr[%d]'; + /** + * Selector for trash can button in bundle option row. + * + * @var string + */ + protected $deleteOption = './tr[%d]//*[@data-index="delete_button"]'; + /** * Get bundle options block. * @@ -83,17 +89,49 @@ class Bundle extends Section if (!isset($fields['bundle_selections'])) { return $this; } + + $context = $this->_rootElement->find($this->bundleOptions, Locator::SELECTOR_XPATH); + + if (isset($fields['bundle_selections']['value']['bundle_options'])) { + foreach ($fields['bundle_selections']['value']['bundle_options'] as $key => $bundleOption) { + $count = $key + 1; + $itemOption = $context->find(sprintf($this->openOption, $count), Locator::SELECTOR_XPATH); + $isContent = $context->find(sprintf($this->optionContent, $count), Locator::SELECTOR_XPATH) + ->isVisible(); + if ($itemOption->isVisible() && !$isContent) { + $itemOption->click(); + } elseif (!$itemOption->isVisible()) { + $this->_rootElement->find($this->addNewOption)->click(); + } + $this->getBundleOptionBlock($count, $context)->fillOption($bundleOption); + } + } + + if (isset($fields['bundle_selections']['value']['bundle_options_delete'])) { + $this->deleteFieldsData($fields['bundle_selections']['value']['bundle_options_delete']); + } + + return $this; + } + + /** + * Delete some bundle options. + * + * @param array $fields + * @return $this + */ + public function deleteFieldsData(array $fields) + { $context = $this->_rootElement->find($this->bundleOptions, Locator::SELECTOR_XPATH); - foreach ($fields['bundle_selections']['value']['bundle_options'] as $key => $bundleOption) { - $count = $key + 1; - $itemOption = $context->find(sprintf($this->openOption, $count), Locator::SELECTOR_XPATH); - $isContent = $context->find(sprintf($this->optionContent, $count), Locator::SELECTOR_XPATH)->isVisible(); - if ($itemOption->isVisible() && !$isContent) { - $itemOption->click(); - } elseif (!$itemOption->isVisible()) { - $this->_rootElement->find($this->addNewOption)->click(); + foreach (array_keys($fields) as $key) { + $bundleOptionIndex = $key + 1; + $deleteOption = $context->find( + sprintf($this->deleteOption, $bundleOptionIndex), + Locator::SELECTOR_XPATH + ); + if ($deleteOption->isVisible()) { + $deleteOption->click(); } - $this->getBundleOptionBlock($count, $context)->fillOption($bundleOption); } return $this; } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle/Option/Selection.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle/Option/Selection.xml index 3a124f0cc38b5a76620fce7265890775a047d79f..e8485df0733de8385e31f55f2c95db9b0061848c 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle/Option/Selection.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Bundle/Option/Selection.xml @@ -21,6 +21,10 @@ <selection_qty> <selector>[name$='[selection_qty]']</selector> </selection_qty> + <user_defined> + <selector>[name$='[selection_can_change_qty]']</selector> + <input>checkbox</input> + </user_defined> <getProductName> <selector>span[data-index="name"]</selector> </getProductName> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php index db349d16a86c673f7fcd89d57e94b42461f51012..ec96c5b27f50a39ffcfc6f88bfc5d1299a17af83 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View.php @@ -6,11 +6,10 @@ namespace Magento\Bundle\Test\Block\Catalog\Product; +use Magento\Bundle\Test\Block\Catalog\Product\View\Summary; use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Bundle; -use Magento\Bundle\Test\Fixture\BundleProduct; use Magento\Mtf\Client\Locator; use Magento\Mtf\Fixture\FixtureInterface; -use Magento\Mtf\Fixture\InjectableFixture; /** * Class View @@ -46,6 +45,13 @@ class View extends \Magento\Catalog\Test\Block\Product\View */ protected $newsletterFormSelector = '#newsletter-validate-detail[novalidate="novalidate"]'; + /** + * Summary Block selector. + * + * @var string + */ + private $summaryBlockSelector = '#bundleSummary'; + /** * Get bundle options block. * @@ -59,6 +65,19 @@ class View extends \Magento\Catalog\Test\Block\Product\View ); } + /** + * Get bundle Summary block. + * + * @return Summary + */ + public function getBundleSummaryBlock() + { + return $this->blockFactory->create( + Summary::class, + ['element' => $this->_rootElement->find($this->summaryBlockSelector)] + ); + } + /** * Click "Customize and add to cart button". * diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary.php new file mode 100644 index 0000000000000000000000000000000000000000..76a46bfe3088a47f79dafa7f8c71d649e324b130 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Test\Block\Catalog\Product\View; + +use Magento\Bundle\Test\Block\Catalog\Product\View\Summary\ConfiguredPrice; + +/** + * Bundle Summary block. + */ +class Summary extends \Magento\Catalog\Test\Block\Product\View +{ + /** + * Configured Price block selector. + * + * @var string + */ + private $configuredPriceBlockSelector = '.price-configured_price'; + + /** + * Get configured price block. + * + * @return ConfiguredPrice + */ + public function getConfiguredPriceBlock() + { + return $this->blockFactory->create( + ConfiguredPrice::class, + ['element' => $this->_rootElement->find($this->configuredPriceBlockSelector)] + ); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary/ConfiguredPrice.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary/ConfiguredPrice.php new file mode 100644 index 0000000000000000000000000000000000000000..30effcdeef060af5a81f92ed1a463e3f69bc57a0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Summary/ConfiguredPrice.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Test\Block\Catalog\Product\View\Summary; + +/** + * This class is used to access the price related information from the storefront. + */ +class ConfiguredPrice extends \Magento\Catalog\Test\Block\AbstractPriceBlock +{ + /** + * Mapping for different type of price. + * + * @var array + */ + protected $mapTypePrices = [ + 'configured_price' => [ + 'selector' => '.price', + ] + ]; + + /** + * This method returns the price represented by the block. + * + * @param string $currency + * @return string|null + */ + public function getPrice($currency = '$') + { + return $this->getTypePrice('configured_price', $currency); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php index 23ac2d25ee017dab9e869e35b1dea7cac4abb94c..ccf47420b11521f9f5bf1a6c4b0f347d86c1baa0 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php @@ -107,11 +107,11 @@ class Bundle extends Block /** @var SimpleElement $optionElement */ $optionElement = $listFormOptions[$title]; - $getTypeData = 'get' . $this->optionNameConvert($option['type']) . 'Data'; + $getTypeData = 'get' . $this->optionNameConvert($option['frontend_type']) . 'Data'; $optionData = $this->$getTypeData($optionElement); $optionData['title'] = $title; - $optionData['type'] = $option['type']; + $optionData['type'] = $option['frontend_type']; $optionData['is_require'] = $optionElement->find($this->required, Locator::SELECTOR_XPATH)->isVisible() ? 'Yes' : 'No'; @@ -266,7 +266,7 @@ class Bundle extends Block /** @var Option $optionBlock */ $optionBlock = $this->blockFactory->create( 'Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\\' - . $this->optionNameConvert($option['type']), + . $this->optionNameConvert($option['frontend_type']), ['element' => $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)] ); $optionBlock->fillOption($option['value']); diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Element/Qty.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Element/Qty.php new file mode 100644 index 0000000000000000000000000000000000000000..7506b81f8471c7ad8130aa45e31a1680cc26cd34 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Element/Qty.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\Element; + +use Magento\Mtf\Client\Element\SimpleElement; + +/** + * Typified element class for qty element. + */ +class Qty extends SimpleElement +{ + /** + * "Backspace" key code. + */ + const BACKSPACE = "\xEE\x80\x83"; + + /** + * "RIGHT" key code. + */ + const RIGHT = "\xEE\x80\x94"; + + /** + * Set the value. + * + * @param string|array $value + * @return void + */ + public function setValue($value) + { + $this->keys([self::RIGHT, self::BACKSPACE, $value]); + $this->context->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.php new file mode 100644 index 0000000000000000000000000000000000000000..9fa54759b8e579728cdf2ea053d94481eb520503 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; + +use Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option; + +/** + * Bundle option hidden type. + */ +class Hidden extends Option +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.xml new file mode 100644 index 0000000000000000000000000000000000000000..356f6a52d6b0c296abc0eb857fe2d8b3dccc4b84 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Option/Hidden.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" ?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<mapping strict="1"> + <fields> + <qty> + <selector>//input[contains(@class,"qty")]</selector> + <strategy>xpath</strategy> + <class>Magento\Bundle\Test\Block\Catalog\Product\View\Type\Option\Element\Qty</class> + </qty> + </fields> +</mapping> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php index ddd8e35a301d6907cf75c3790cefaf6d79b394da..411c53d982fcb8a2445e8a5d214383670ec7bf4a 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleItemsOnProductPage.php @@ -61,7 +61,7 @@ class AssertBundleItemsOnProductPage extends AbstractAssertForm foreach ($bundleOptions as $optionKey => $bundleOption) { $optionData = [ 'title' => $bundleOption['title'], - 'type' => $bundleOption['type'], + 'type' => $bundleOption['frontend_type'], 'is_require' => $bundleOption['required'], ]; diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleOptionsDeleted.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleOptionsDeleted.php new file mode 100644 index 0000000000000000000000000000000000000000..69e694abd261ab4ca4e4102f542b72f612552d5b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundleOptionsDeleted.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Test\Constraint; + +use Magento\Bundle\Test\Fixture\BundleProduct; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Mtf\Fixture\FixtureInterface; + +/** + * Assert bundle product form. + */ +class AssertBundleOptionsDeleted extends AbstractConstraint +{ + /** + * Assert that displayed price view for bundle product on product page equals passed from fixture. + * @param BundleProduct $product + * @param BundleProduct $originalProduct + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert( + BundleProduct $product, + BundleProduct $originalProduct, + CatalogProductIndex $productGrid, + CatalogProductEdit $productPage + ) { + $filter = ['sku' => $product->getSku()]; + $productGrid->open(); + $productGrid->getProductGrid()->searchAndOpen($filter); + + $productData = $product->getData()['bundle_selections']['bundle_options']; + $originalProductData = $originalProduct->getData()['bundle_selections']['bundle_options']; + $formData = $productPage->getProductForm()->getData($product)['bundle_selections']; + + $productDataLength = count($productData); + $formDataLength = count($productData); + \PHPUnit_Framework_Assert::assertEquals($productDataLength, $formDataLength); + + foreach ($productData as $index => $option) { + $productAssociatedDataLength = count($option['assigned_products']); + $formAssociatedDataLength = count($formData[$index]['assigned_products']); + \PHPUnit_Framework_Assert::assertEquals($productAssociatedDataLength, $formAssociatedDataLength); + + foreach ($option['assigned_products'] as $productIndex => $associatedProduct) { + $associatedProduct['data']['getProductName'] = + $originalProductData[$index+1]['assigned_products'][$productIndex]['search_data']['name']; + $associatedProduct = $associatedProduct['data']; + $errorAssociatedProducts = array_diff( + $associatedProduct, + $formData[$index]['assigned_products'][$productIndex] + ); + \PHPUnit_Framework_Assert::assertCount(0, $errorAssociatedProducts); + } + + unset($option['assigned_products']); + unset($formData[$index]['assigned_products']); + $errorFields = array_diff($option, $formData[$index]); + \PHPUnit_Framework_Assert::assertCount(0, $errorFields); + } + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function toString() + { + return 'Bundle options were not deleted correctly. There is difference with expected options'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceCalculatedOnProductPage.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceCalculatedOnProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..756fe75eea7db1f943f3a8c490b8eb2427e63095 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Constraint/AssertBundlePriceCalculatedOnProductPage.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Test\Constraint; + +use Magento\Bundle\Test\Fixture\BundleProduct; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Catalog\Test\TestStep\ConfigureProductOnProductPageStep; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Mtf\TestStep\TestStepFactory; + +/** + * Assert calculated price after configure bundle product on product page. + */ +class AssertBundlePriceCalculatedOnProductPage extends AbstractConstraint +{ + /** + * Assert calculated price after configure bundle product on product page. + * + * @param TestStepFactory $stepFactory + * @param BundleProduct $product + * @param CatalogProductView $catalogProductView + */ + public function processAssert( + TestStepFactory $stepFactory, + BundleProduct $product, + CatalogProductView $catalogProductView + ) { + $stepFactory->create(ConfigureProductOnProductPageStep::class, ['product' => $product])->run(); + + //Process assertions + $this->assertPrice($product, $catalogProductView); + } + + /** + * Assert prices on the product view Page. + * + * @param BundleProduct $product + * @param CatalogProductView $productView + * @return void + */ + protected function assertPrice(BundleProduct $product, CatalogProductView $productView) + { + $checkoutData = $product->getCheckoutData(); + \PHPUnit_Framework_Assert::assertEquals( + $checkoutData['cartItem']['configuredPrice'], + $productView->getBundleViewBlock()->getBundleSummaryBlock()->getConfiguredPriceBlock()->getPrice(), + 'Bundle price calculated is not correct.' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Bundle price calculates right on product view page.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php index 4a4aea603cf8619d0d12335f496b1e6a9e50fd33..6a3572ab15a7af1e9a84ee06841cedf772bc9283 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Curl.php @@ -68,6 +68,10 @@ class Curl extends ProductCurl implements BundleProductInterface 'gift_message_available' => [ 'Yes' => 1, 'No' => 0 + ], + 'user_defined' => [ + 'Yes' => 1, + 'No' => 0 ] ]; } diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Webapi.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Webapi.php index 634f6c00a6cc87aac749b187fafd2452e3fd98fb..2fbdaffefc7a33192c73309d0dde80729311b5d8 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Webapi.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/BundleProduct/Webapi.php @@ -64,25 +64,8 @@ class Webapi extends SimpleProductWebapi implements BundleProductInterface 'title' => $bundleOption['title'], 'type' => $bundleOption['type'], 'required' => $bundleOption['required'], - 'product_links' => [], + 'product_links' => $this->prepareLinksInfo($bundleSelections, $key) ]; - - $productLinksInfo = $bundleOption['assigned_products']; - $products = $bundleSelections['products'][$key]; - foreach ($productLinksInfo as $linkKey => $productLink) { - $product = $products[$linkKey]; - $bundleProductOptions[$key]['product_links'][] = [ - 'sku' => $product->getSku(), - 'qty' => $productLink['data']['selection_qty'], - 'is_default' => false, - 'price' => isset($productLink['data']['selection_price_value']) - ? $productLink['data']['selection_price_value'] - : null, - 'price_type' => isset($productLink['data']['selection_price_type']) - ? $productLink['data']['selection_price_type'] - : null, - ]; - } } } @@ -92,6 +75,39 @@ class Webapi extends SimpleProductWebapi implements BundleProductInterface unset($this->fields['product']['bundle_selections']); } + /** + * Prepare links info field. + * + * @param array $bundleSelections + * @param int $key + * @return array + */ + private function prepareLinksInfo(array $bundleSelections, $key) + { + $result = []; + $productLinksInfo = $bundleSelections['bundle_options'][$key]['assigned_products']; + $products = $bundleSelections['products'][$key]; + foreach ($productLinksInfo as $linkKey => $productLink) { + $product = $products[$linkKey]; + $result[] = [ + 'sku' => $product->getSku(), + 'qty' => $productLink['data']['selection_qty'], + 'is_default' => false, + 'price' => isset($productLink['data']['selection_price_value']) + ? $productLink['data']['selection_price_value'] + : null, + 'price_type' => isset($productLink['data']['selection_price_type']) + ? $productLink['data']['selection_price_type'] + : null, + 'can_change_quantity' => isset($productLink['data']['user_defined']) + ? $productLink['data']['user_defined'] + : 0, + ]; + } + + return $result; + } + /** * Parse response. * diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml index 2b5e9a437b32bdec615fd9e2a928b3784ba68fb4..6a507a7a99b437a793b4096f8f10d9e33ccb825a 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct.xml @@ -225,5 +225,27 @@ <item name="dataset" xsi:type="string">bundle_fixed_100_dollar</item> </field> </dataset> + + <dataset name="with_3_bundle_options"> + <field name="name" xsi:type="string">Bundle with 3 options %isolation%</field> + <field name="url_key" xsi:type="string">with_3_bundle_options-%isolation%</field> + <field name="sku" xsi:type="string">sku_with_3_bundle_options_%isolation%</field> + <field name="sku_type" xsi:type="string">No</field> + <field name="price_type" xsi:type="string">No</field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">100</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="bundle_selections" xsi:type="array"> + <item name="dataset" xsi:type="string">with_3_options</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/BundleSelections.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/BundleSelections.xml index 3e9b055c48ca5a1bfa5df3410ec48ef708a71fa7..c19a78f64894e17b256a1ec13828b0612bdada08 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/BundleSelections.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/BundleSelections.xml @@ -12,6 +12,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -46,6 +47,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -84,6 +86,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -122,6 +125,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -160,6 +164,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -187,6 +192,7 @@ <item name="1" xsi:type="array"> <item name="title" xsi:type="string">Radio Button Option</item> <item name="type" xsi:type="string">Radio Buttons</item> + <item name="frontend_type" xsi:type="string">Radio Buttons</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -214,6 +220,7 @@ <item name="2" xsi:type="array"> <item name="title" xsi:type="string">Checkbox Option</item> <item name="type" xsi:type="string">Checkbox</item> + <item name="frontend_type" xsi:type="string">Checkbox</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -241,6 +248,7 @@ <item name="3" xsi:type="array"> <item name="title" xsi:type="string">Multiple Select Option</item> <item name="type" xsi:type="string">Multiple Select</item> + <item name="frontend_type" xsi:type="string">Multiple Select</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -291,6 +299,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -314,6 +323,7 @@ <item name="1" xsi:type="array"> <item name="title" xsi:type="string">Radio Button Option</item> <item name="type" xsi:type="string">Radio Buttons</item> + <item name="frontend_type" xsi:type="string">Radio Buttons</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -337,6 +347,7 @@ <item name="2" xsi:type="array"> <item name="title" xsi:type="string">Checkbox Option</item> <item name="type" xsi:type="string">Checkbox</item> + <item name="frontend_type" xsi:type="string">Checkbox</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -360,6 +371,7 @@ <item name="3" xsi:type="array"> <item name="title" xsi:type="string">Multiple Select Option</item> <item name="type" xsi:type="string">Multiple Select</item> + <item name="frontend_type" xsi:type="string">Multiple Select</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -406,6 +418,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">No</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -433,6 +446,7 @@ <item name="1" xsi:type="array"> <item name="title" xsi:type="string">Radio Button Option</item> <item name="type" xsi:type="string">Radio Buttons</item> + <item name="frontend_type" xsi:type="string">Radio Buttons</item> <item name="required" xsi:type="string">No</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -475,6 +489,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -513,6 +528,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -547,6 +563,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -572,6 +589,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -610,6 +628,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -633,6 +652,7 @@ <item name="1" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="required" xsi:type="string">Yes</item> <item name="assigned_products" xsi:type="array"> <item name="0" xsi:type="array"> @@ -665,5 +685,197 @@ </item> </field> </dataset> + + <dataset name="with_3_options"> + <field name="bundle_options" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Option 1</item> + <item name="type" xsi:type="string">Drop-down</item> + <item name="required" xsi:type="string">No</item> + <item name="assigned_products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">1</item> + <item name="selection_price_value" xsi:type="string">1</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + </item> + </item> + <item name="1" xsi:type="array"> + <item name="title" xsi:type="string">Option 2</item> + <item name="type" xsi:type="string">Radio Buttons</item> + <item name="required" xsi:type="string">No</item> + <item name="assigned_products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">20</item> + <item name="selection_price_value" xsi:type="string">20</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + <item name="1" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">21</item> + <item name="selection_price_value" xsi:type="string">21</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + <item name="2" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">22</item> + <item name="selection_price_value" xsi:type="string">22</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + </item> + </item> + <item name="2" xsi:type="array"> + <item name="title" xsi:type="string">Option 3</item> + <item name="type" xsi:type="string">Drop-down</item> + <item name="required" xsi:type="string">No</item> + <item name="assigned_products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">3</item> + <item name="selection_price_value" xsi:type="string">3</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + </item> + </item> + </field> + <field name="products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="0" xsi:type="string">catalogProductSimple::default</item> + </item> + <item name="1" xsi:type="array"> + <item name="0" xsi:type="string">catalogProductSimple::default</item> + <item name="1" xsi:type="string">catalogProductSimple::product_100_dollar</item> + <item name="2" xsi:type="string">catalogProductSimple::product_without_category</item> + </item> + <item name="2" xsi:type="array"> + <item name="0" xsi:type="string">catalogProductSimple::default</item> + </item> + </field> + </dataset> + + <dataset name="with_3_options_delete"> + <field name="bundle_options_delete" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Option 1</item> + <item name="type" xsi:type="string">Drop-down</item> + <item name="required" xsi:type="string">No</item> + </item> + </field> + <field name="bundle_options" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Option 2</item> + <item name="type" xsi:type="string">Radio Buttons</item> + <item name="required" xsi:type="string">No</item> + <item name="assigned_products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">20</item> + <item name="selection_price_value" xsi:type="string">20</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + <item name="1" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">21</item> + <item name="selection_price_value" xsi:type="string">21</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + <item name="2" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">22</item> + <item name="selection_price_value" xsi:type="string">22</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + </item> + </item> + <item name="1" xsi:type="array"> + <item name="title" xsi:type="string">Option 3</item> + <item name="type" xsi:type="string">Drop-down</item> + <item name="required" xsi:type="string">No</item> + <item name="assigned_products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">3</item> + <item name="selection_price_value" xsi:type="string">3</item> + <item name="selection_price_type" xsi:type="string">Fixed</item> + </item> + </item> + </item> + </item> + </field> + <field name="products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="0" xsi:type="string">catalogProductSimple::default</item> + <item name="1" xsi:type="string">catalogProductSimple::product_100_dollar</item> + <item name="2" xsi:type="string">catalogProductSimple::product_without_category</item> + </item> + <item name="1" xsi:type="array"> + <item name="0" xsi:type="string">catalogProductSimple::default</item> + </item> + </field> + </dataset> + + <dataset name="one_required_option_with_one_item"> + <field name="bundle_options" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Drop-down Option</item> + <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Hidden</item> + <item name="required" xsi:type="string">Yes</item> + <item name="assigned_products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="search_data" xsi:type="array"> + <item name="name" xsi:type="string">%product_name%</item> + </item> + <item name="data" xsi:type="array"> + <item name="selection_qty" xsi:type="string">1</item> + <item name="user_defined" xsi:type="string">Yes</item> + </item> + </item> + </item> + </item> + </field> + <field name="products" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="0" xsi:type="string">catalogProductSimple::default</item> + </item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml index 3e7550b9d784e3858bd9800e66b88b8c60326b1b..d68fb0d0b83f8ff3520508a1c72bc51dcf8ff1c1 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml @@ -13,6 +13,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -27,6 +28,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -47,6 +49,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -67,6 +70,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_10_dollar</item> </item> @@ -87,6 +91,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">Simple Product</item> </item> @@ -107,6 +112,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -114,6 +120,7 @@ <item name="1" xsi:type="array"> <item name="title" xsi:type="string">Radio Button Option</item> <item name="type" xsi:type="string">Radio Buttons</item> + <item name="frontend_type" xsi:type="string">Radio Buttons</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -128,6 +135,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -192,6 +200,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -212,6 +221,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_10_dollar</item> </item> @@ -242,6 +252,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -249,6 +260,7 @@ <item name="1" xsi:type="array"> <item name="title" xsi:type="string">Radio Button Option</item> <item name="type" xsi:type="string">Radio Buttons</item> + <item name="frontend_type" xsi:type="string">Radio Buttons</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -256,6 +268,7 @@ <item name="2" xsi:type="array"> <item name="title" xsi:type="string">Checkbox Option</item> <item name="type" xsi:type="string">Checkbox</item> + <item name="frontend_type" xsi:type="string">Checkbox</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -263,6 +276,7 @@ <item name="3" xsi:type="array"> <item name="title" xsi:type="string">Multiple Select Option</item> <item name="type" xsi:type="string">Multiple</item> + <item name="frontend_type" xsi:type="string">Multiple</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -315,6 +329,7 @@ <item name="0" xsi:type="array"> <item name="title" xsi:type="string">Drop-down Option</item> <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Drop-down</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -322,6 +337,7 @@ <item name="1" xsi:type="array"> <item name="title" xsi:type="string">Radio Button Option</item> <item name="type" xsi:type="string">Radio Buttons</item> + <item name="frontend_type" xsi:type="string">Radio Buttons</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -329,6 +345,7 @@ <item name="2" xsi:type="array"> <item name="title" xsi:type="string">Checkbox Option</item> <item name="type" xsi:type="string">Checkbox</item> + <item name="frontend_type" xsi:type="string">Checkbox</item> <item name="value" xsi:type="array"> <item name="name" xsi:type="string">product_100_dollar</item> </item> @@ -357,5 +374,24 @@ </item> </field> </dataset> + + <dataset name="one_required_option_with_one_item"> + <field name="options" xsi:type="array"> + <item name="bundle_options" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="title" xsi:type="string">Drop-down Option</item> + <item name="type" xsi:type="string">Drop-down</item> + <item name="frontend_type" xsi:type="string">Hidden</item> + <item name="value" xsi:type="array"> + <item name="name" xsi:type="string">Simple Product</item> + <item name="qty" xsi:type="string">3</item> + </item> + </item> + </item> + </field> + <field name="cartItem" xsi:type="array"> + <item name="configuredPrice" xsi:type="string">1680</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml index 211e09861995f27e22a446b93e465a7197936965..56b2ceb917fe6d46296e408954bdfc88380af5a3 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Bundle\Test\TestCase\CreateBundleProductEntityTest" summary="Create Bundle Product" ticketId="MAGETWO-24118"> <variation name="CreateBundleProductEntityTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Create default bundle with dynamic options</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data> @@ -44,7 +45,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductNotSearchableBySku" /> </variation> <variation name="CreateBundleProductEntityTestVariation3"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="description" xsi:type="string">Create dynamic bundle with price randle and all types options</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data> @@ -74,6 +75,7 @@ <constraint name="Magento\Bundle\Test\Constraint\AssertBundlePriceType" /> </variation> <variation name="CreateBundleProductEntityTestVariation4"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Create fixed bundle</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data> @@ -97,6 +99,7 @@ <constraint name="Magento\Bundle\Test\Constraint\AssertBundleItemsOnProductPage" /> </variation> <variation name="CreateBundleProductEntityTestVariation5"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Create fixed bundle with all types options</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data> @@ -161,6 +164,7 @@ <constraint name="Magento\Bundle\Test\Constraint\AssertBundlePriceView" /> </variation> <variation name="CreateBundleProductEntityTestVariation7" summary="Check bundle dynamic product with tier price"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data> <data name="product/data/sku_type" xsi:type="string">Yes</data> @@ -187,6 +191,7 @@ <constraint name="Magento\Bundle\Test\Constraint\AssertTierPriceOnBundleProductPage" /> </variation> <variation name="CreateBundleProductEntityTestVariation8"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Create dynamic bundle with special price</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">Bundle Dynamic %isolation%</data> @@ -236,6 +241,7 @@ <constraint name="Magento\Bundle\Test\Constraint\AssertBundlePriceType" /> </variation> <variation name="CreateBundleProductEntityTestVariation11"> + <data name="issue" xsi:type="string">MAGETWO-52788: Dynamic Rows: support status being changed</data> <data name="description" xsi:type="string">Create fixed product with checkout first option</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">Bundle Fixed %isolation%</data> @@ -334,6 +340,7 @@ <constraint name="Magento\Bundle\Test\Constraint\AssertBundleProductPage" /> </variation> <variation name="CreateBundleProductEntityTestVariation17" summary="Create fixed bundle product with tier price and custom options with fixed and percent price"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">Bundle Fixed %isolation%</data> <data name="product/data/sku_type" xsi:type="string">No</data> @@ -359,6 +366,7 @@ <constraint name="Magento\Bundle\Test\Constraint\AssertBundleProductInCart" /> </variation> <variation name="CreateBundleProductEntityTestVariation18" summary="Create dynamic bundle product with tier price for sub-item"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">BundleProduct %isolation%</data> <data name="product/data/sku_type" xsi:type="string">Yes</data> @@ -394,6 +402,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" /> </variation> <variation name="CreateBundleProductEntityTestVariation21" summary="Create default fixed bundle with custom Website"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> <data name="product/data/name" xsi:type="string">Bundle Fixed %isolation%</data> <data name="product/data/sku_type" xsi:type="string">No</data> @@ -446,5 +455,17 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Bundle\Test\Constraint\AssertBundleProductPage" /> </variation> + <variation name="CreateBundleProductEntityTestVariation25" summary="Create Bundle (dynamic) Product with one require option with one item" ticketId="MAGETWO-59841"> + <data name="product/data/url_key" xsi:type="string">bundle-product-%isolation%</data> + <data name="product/data/name" xsi:type="string">Bundle Dynamic %isolation%</data> + <data name="product/data/sku" xsi:type="string">sku_bundle_dynamic_%isolation%</data> + <data name="product/data/price_type" xsi:type="string">Yes</data> + <data name="product/data/category" xsi:type="string">category_%isolation%</data> + <data name="product/data/shipment_type" xsi:type="string">Together</data> + <data name="product/data/bundle_selections/dataset" xsi:type="string">one_required_option_with_one_item</data> + <data name="product/data/checkout_data/dataset" xsi:type="string">one_required_option_with_one_item</data> + <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> + <constraint name="Magento\Bundle\Test\Constraint\AssertBundlePriceCalculatedOnProductPage" /> + </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3c17360200f44f2fe8875590578c6960ea7757d0 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.php @@ -0,0 +1,94 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Test\TestCase; + +use Magento\Bundle\Test\Fixture\BundleProduct; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Mtf\TestCase\Injectable; + +/** + * Test Flow: + * 1. Login as admin + * 2. Navigate to the Products>Inventory>Catalog + * 3. Click on Bundle product in the grid to edit it + * 4. Fill in some Bundle Options data according to data set + * 5. Delete some Bundle Options data according to data set + * 6. Save product + * 7. Verify Bundle Options in the updated product + * + * @group Bundle_Product + * @ZephyrId MAGETWO-26195 + */ +class UpdateBundleOptionsTest extends Injectable +{ + /* tags */ + const MVP = 'yes'; + /* end tags */ + + /** + * Page product on backend + * + * @var CatalogProductIndex + */ + protected $catalogProductIndex; + + /** + * Edit page on backend + * + * @var CatalogProductEdit + */ + protected $catalogProductEdit; + + /** + * Injection data + * + * @param CatalogProductIndex $catalogProductIndexNewPage + * @param CatalogProductEdit $catalogProductEditPage + * @return void + */ + public function __inject( + CatalogProductIndex $catalogProductIndexNewPage, + CatalogProductEdit $catalogProductEditPage + ) { + $this->catalogProductIndex = $catalogProductIndexNewPage; + $this->catalogProductEdit = $catalogProductEditPage; + } + + /** + * Test update bundle product + * + * @param BundleProduct $product + * @param BundleProduct $originalProduct + * @return void + */ + public function test(BundleProduct $product, BundleProduct $originalProduct) + { + // Preconditions + $originalProduct->persist(); + + // Steps + $filter = ['sku' => $originalProduct->getSku()]; + + $this->catalogProductIndex->open(); + $this->catalogProductIndex->getProductGrid()->searchAndOpen($filter); + + $form = $this->catalogProductEdit->getProductForm(); + $form->openSection('bundle'); + $container = $form->getSection('bundle'); + $containerFields = $product->getData()['bundle_selections']['bundle_options_delete']; + $container->deleteFieldsData($containerFields); + + $form->openSection('product-details'); + $container = $form->getSection('product-details'); + $containerFields = $product->getData(); + unset($containerFields['bundle_selections']); + $container->setFieldsData($containerFields); + + $this->catalogProductEdit->getFormPageActions()->save(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..795665d66d2bf7d34438381d3390e94c8458d3b7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleOptionsTest.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\Bundle\Test\TestCase\UpdateBundleOptionsTest" summary="Update Bundle Product Options" ticketId="MAGETWO-26195"> + <variation name="UpdateBundleOptionsTestVariation1"> + <data name="description" xsi:type="string">Update bundle product options</data> + <data name="originalProduct/dataset" xsi:type="string">with_3_bundle_options</data> + <data name="product/data/name" xsi:type="string">bundle_3_options_%isolation%</data> + <data name="product/data/sku" xsi:type="string">bundle_3_options_%isolation%</data> + <data name="product/data/bundle_selections/dataset" xsi:type="string">with_3_options_delete</data> + <constraint name="Magento\Bundle\Test\Constraint\AssertBundleOptionsDeleted" /> + </variation> + </testCase> +</config> \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php index bf17d216bcf9b479e6279f449e782bc94438600e..8326b1ba4d9ae9b0589b1d55bd973f9db6efe970 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php @@ -73,6 +73,7 @@ class UpdateBundleProductEntityTest extends Injectable */ public function test(BundleProduct $product, BundleProduct $originalProduct) { + $this->markTestIncomplete('MAGETWO-56584: [FT] Custom options are not created for product in test'); // Preconditions $originalProduct->persist(); $originalCategory = $originalProduct->hasData('category_ids') diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/BlockGallery.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/BlockGallery.php new file mode 100644 index 0000000000000000000000000000000000000000..bc0d0b87f24bba19d2e249fa37be7e59e16cca92 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/BlockGallery.php @@ -0,0 +1,49 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section; + +use Magento\Mtf\Client\Element\SimpleElement; +use Magento\Mtf\Client\Locator; +use Magento\Ui\Test\Block\Adminhtml\Section; + +/** + * Class for product gallery block. + */ +class BlockGallery extends Section +{ + /** + * Selector for image loader container. + * + * @var string + */ + private $imageLoader = '.image.image-placeholder .file-row'; + + /** + * Selector for image upload input. + * + * @var string + */ + private $imageUploadInput = '[name="image"]'; + + /** + * Upload product images. + * + * @param array $data + * @param SimpleElement|null $element + * @return $this + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function setFieldsData(array $data, SimpleElement $element = null) + { + foreach ($data['image']['value'] as $imageData) { + $uploadElement = $element->find($this->imageUploadInput, Locator::SELECTOR_CSS, 'upload'); + $uploadElement->setValue($imageData['file']); + $this->waitForElementNotVisible($this->imageLoader); + } + return $this; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml index 407b5c9cb20a3b2097ea87e9d1f5a8240e5566b2..3b66164ebe658097e05fdba2e8b53c6cb3d643d2 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml @@ -143,7 +143,7 @@ </fields> </attributes> <gallery> - <class>\Magento\Ui\Test\Block\Adminhtml\Section</class> + <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Section\BlockGallery</class> <selector>[data-index='block_gallery']</selector> <strategy>css selector</strategy> </gallery> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php index 3134fda0d2b2b3f98b3e9d0ef5c835e8cb1aad53..de6adb0efd8b21df23cf0531624fa0b90983225d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php @@ -10,7 +10,7 @@ use Magento\Catalog\Test\Block\AbstractConfigureBlock; use Magento\Catalog\Test\Fixture\CatalogProductSimple; use Magento\Mtf\Client\Locator; use Magento\Mtf\Fixture\FixtureInterface; -use Magento\Mtf\Fixture\InjectableFixture; +use Magento\Checkout\Test\Block\Cart\Sidebar; /** * Product view block on the product page. @@ -145,7 +145,14 @@ class View extends AbstractConfigureBlock * * @var string */ - protected $miniCartBlock = '[data-block="minicart"]'; + protected $miniCartBlockSelector = '[data-block="minicart"]'; + + /** + * Minicart block element. + * + * @var Sidebar + */ + private $miniCartBlock; /** * Success message selector. @@ -222,21 +229,44 @@ class View extends AbstractConfigureBlock */ public function addToCart(FixtureInterface $product) { - /** @var \Magento\Checkout\Test\Block\Cart\Sidebar $miniCart */ - $miniCart = $this->blockFactory->create( - \Magento\Checkout\Test\Block\Cart\Sidebar::class, - ['element' => $this->browser->find($this->miniCartBlock)] - ); + $this->configure($product); + $this->clickAddToCart(); + $this->getMiniCartBlock()->waitLoader(); + } + + /** + * Configure Product. + * + * @param FixtureInterface $product + * @return void + */ + public function configure(FixtureInterface $product) + { /** @var CatalogProductSimple $product */ $checkoutData = $product->getCheckoutData(); - $miniCart->waitInit(); + $this->getMiniCartBlock()->waitInit(); $this->fillOptions($product); if (isset($checkoutData['qty'])) { $this->setQty($checkoutData['qty']); } - $this->clickAddToCart(); - $miniCart->waitLoader(); + } + + /** + * Get MiniCart block. + * + * @return Sidebar + */ + private function getMiniCartBlock() + { + if ($this->miniCartBlock === null) { + $this->miniCartBlock = $this->blockFactory->create( + Sidebar::class, + ['element' => $this->browser->find($this->miniCartBlockSelector)] + ); + } + + return $this->miniCartBlock; } /** @@ -313,14 +343,8 @@ class View extends AbstractConfigureBlock public function braintreePaypalCheckout() { $currentWindow = $this->browser->getCurrentWindow(); - /** @var \Magento\Checkout\Test\Block\Cart\Sidebar $miniCart */ - $miniCart = $this->blockFactory->create( - \Magento\Checkout\Test\Block\Cart\Sidebar::class, - ['element' => $this->browser->find($this->miniCartBlock)] - ); - - $miniCart->openMiniCart(); - $miniCart->clickBraintreePaypalButton(); + $this->getMiniCartBlock()->openMiniCart(); + $this->getMiniCartBlock()->clickBraintreePaypalButton(); return $currentWindow; } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php index 54bf06f70b5f1c0f192b79bda3ade75a85cd37f7..da1ec8f71a1121bceba80b6a3138f77b07663310 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php @@ -13,9 +13,11 @@ use Magento\Mtf\Constraint\AbstractConstraint; use Magento\Catalog\Test\Fixture\CatalogProductAttribute; use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Mtf\Client\BrowserInterface; /** * Check attribute on product form. + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint { @@ -45,6 +47,13 @@ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint */ protected $catalogProductEdit; + /** + * Locator for attributes section. + * + * @var string + */ + protected $attributes = '[data-index="attributes"]'; + /** * Add this attribute to Default attribute Template. Create product and Assert that created attribute * is displayed on product form (Products > Inventory > Catalog). @@ -66,6 +75,7 @@ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint CatalogProductEdit $catalogProductEdit, CatalogProductAttribute $attribute, CatalogAttributeSet $attributeSet, + BrowserInterface $browser, CatalogProductAttribute $productAttributeOriginal = null ) { $this->fixtureFactory = $fixtureFactory; @@ -92,7 +102,9 @@ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint $catalogProductAttribute = ($productAttributeOriginal !== null) ? array_merge($productAttributeOriginal->getData(), $attribute->getData()) : $attribute->getData(); - $catalogProductEdit->getProductForm()->openSection(self::ATTRIBUTES); + if ($browser->find($this->attributes)->isVisible()) { + $catalogProductEdit->getProductForm()->openSection(self::ATTRIBUTES); + } \PHPUnit_Framework_Assert::assertTrue( $catalogProductEdit->getProductForm()->checkAttributeLabel($catalogProductAttribute), diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCanSaveProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCanSaveProduct.php new file mode 100644 index 0000000000000000000000000000000000000000..04e1c034b3db77a49a583ee819f9b8d97cb440ba --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCanSaveProduct.php @@ -0,0 +1,46 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Test\Constraint; + +/** + * Assert that can save already exist product. + */ +class AssertCanSaveProduct extends \Magento\Mtf\Constraint\AbstractConstraint +{ + /** + * Assert that can save already existing product. + * + * @param \Magento\Mtf\Fixture\FixtureInterface $product + * @param \Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit $catalogProductEdit + * @param \Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex $catalogProductIndex + * @return void + */ + public function processAssert( + \Magento\Mtf\Fixture\FixtureInterface $product, + \Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit $catalogProductEdit, + \Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex $catalogProductIndex + ) { + $filter = ['sku' => $product->getSku()]; + $catalogProductIndex->open()->getProductGrid()->searchAndOpen($filter); + $catalogProductEdit->getFormPageActions()->save(); + + \PHPUnit_Framework_Assert::assertNotEmpty( + $catalogProductEdit->getMessagesBlock()->getSuccessMessage(), + 'Can\'t save existing product.' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Product was saved without errors.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductHasImageInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductHasImageInGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..fed3b36c08d661bbc0297b6f87d08aa692d3c04e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductHasImageInGrid.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Test\Constraint; + +use Magento\Mtf\Fixture\InjectableFixture; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; + +class AssertProductHasImageInGrid extends AbstractConstraint +{ + /** + * Assert that product image is present in grid. + * + * @param CatalogProductIndex $productGrid + * @param InjectableFixture $product + * @return void + */ + public function processAssert( + CatalogProductIndex $productGrid, + InjectableFixture $product + ) { + $filter = ['sku' => $product->getSku()]; + $productGrid->open(); + $productGrid->getProductGrid()->search($filter); + $src = $productGrid->getProductGrid()->getBaseImageSource(); + \PHPUnit_Framework_Assert::assertTrue( + strpos($src, '/placeholder/') === false, + 'Product image is not present in product grid when it should be' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Product image is displayed in product grid.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml index b4514208a509358a6828a7b77d33ca0c2678072a..e8ceb1d0889247805746a401f6c60bb5a0556010 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml @@ -36,8 +36,8 @@ <field name="gallery" is_required="0" /> <field name="gift_message_available" is_required="0" /> <field name="has_options" is_required="0" /> - <field name="image" is_required="0" /> - <field name="image_label" is_required="0" /> + <field name="image" is_required="0" group="gallery" source="Magento\Catalog\Test\Fixture\Product\Image" /> + <field name="image_label" group="gallery" is_required="0" /> <field name="manufacturer" is_required="0" /> <field name="media_gallery" is_required="0" /> <field name="meta_description" is_required="0" group="search-engine-optimization" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/Image.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/Image.php new file mode 100644 index 0000000000000000000000000000000000000000..ad72a6db4f4cef615f4abb7edddc497886a73981 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/Image.php @@ -0,0 +1,60 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Test\Fixture\Product; + +use Magento\Mtf\Fixture\DataSource; +use Magento\Mtf\Fixture\FixtureFactory; + +/** + * Image entity data source. + */ +class Image extends DataSource +{ + /** + * Fixture Factory instance. + * + * @var FixtureFactory + */ + private $fixtureFactory; + + /** + * Fixture data. + * + * @var array + */ + private $fixtureData; + + /** + * @param FixtureFactory $fixtureFactory + * @param array $params + * @param array $data + */ + public function __construct(FixtureFactory $fixtureFactory, array $params, $data = []) + { + $this->fixtureFactory = $fixtureFactory; + $this->params = $params; + $this->fixtureData = $data; + } + + /** + * {@inheritdoc} + * @throws \Exception + */ + public function getData($key = null) + { + foreach ($this->fixtureData as &$imageData) { + if (isset($imageData['file']) && file_exists(MTF_TESTS_PATH . $imageData['file'])) { + $imageData['file'] = MTF_TESTS_PATH . $imageData['file']; + } else { + throw new \Exception("Image '{$imageData['file']}'' not found on the server."); + } + } + $this->data = $this->fixtureData; + + return parent::getData($key); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php index a4a773ae7c7ecd02e11b6e824d6ec3d50925523b..db43cc535ca01c4bbac96e425a435bd71ef3fcef 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php @@ -47,6 +47,14 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface 'No' => 0, 'Yes' => 1, ], + 'is_global' => [ + 'Store View' => '0', + 'Global' => '1', + ], + 'used_in_product_listing' => [ + 'No' => '0', + 'Yes' => '1', + ], ]; /** @@ -76,6 +84,7 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface unset($data['options']); } + $data = $this->changeStructureOfTheData($data); $url = $_ENV['app_backend_url'] . 'catalog/product_attribute/save/back/edit'; $curl = new BackendDecorator(new CurlTransport(), $this->_configuration); $curl->write($url, $data); @@ -104,4 +113,13 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface return $resultData; } + + /** + * @param array $data + * @return array + */ + protected function changeStructureOfTheData(array $data) + { + return $data; + } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml index 9ae1e2ebfacca405f8505496f546cf2182e2dd3f..c32999a6ebce7e0a4c44c1a10bc8fe4010a795f7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml @@ -34,5 +34,16 @@ <item name="inherit" xsi:type="number">1</item> </field> </dataset> + <dataset name="attribute_product_mask_sku"> + <field name="catalog/fields_masks/sku" xsi:type="array"> + <item name="value" xsi:type="string">{{name}} {{country_of_manufacture}}</item> + </field> + </dataset> + <dataset name="attribute_product_mask_sku_rollback"> + <field name="catalog/fields_masks/sku" xsi:type="array"> + <item name="value" xsi:type="string">{{name}}</item> + <item name="inherit" xsi:type="number">1</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 22cdab45ac875c6a6987892898e3c8dda3382944..fa81264dd2d4b061ef769f882408b104ba92793f 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,6 +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="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> @@ -56,6 +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="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> @@ -90,6 +92,7 @@ <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> @@ -150,7 +153,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForAssignedProducts" /> </variation> <variation name="CreateCategoryEntityTestVariation9_ThreeNesting"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</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/NavigateMenuTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/NavigateMenuTest.xml index 2c8528595f44b99bc70133cdc473841a0cbb0e22..1b61b92beef1310aa78e49acf49d2501410961b3 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/NavigateMenuTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/NavigateMenuTest.xml @@ -14,7 +14,7 @@ </variation> <variation name="NavigateMenuTest10"> <data name="menuItem" xsi:type="string">Products > Categories</data> - <data name="pageTitle" xsi:type="string">Default Category</data> + <data name="pageTitle" xsi:type="string">Default Category (ID: 2)</data> <constraint name="Magento\Backend\Test\Constraint\AssertBackendPageIsAvailable"/> </variation> <variation name="NavigateMenuTest11"> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php index 131163311bcd2af4d34031883d103b3c2341cdb8..eddb620feabb3a7b211d0a8d63e4b2bd6a9ec79d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.php @@ -29,6 +29,7 @@ class AddCompareProductsTest extends AbstractCompareProductsTest { /* tags */ const MVP = 'yes'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.xml index 64d2a1de8a28454df0498d0b8fed68f5064d38ba..c29c99193b75dc99ab725996b617ef1ff794353c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddCompareProductsTest.xml @@ -10,6 +10,7 @@ <variation name="AddCompareProductsTestVariation1"> <data name="products" xsi:type="string">catalogProductSimple::simple_for_composite_products</data> <data name="isCustomerLoggedIn" xsi:type="string">No</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductCompareItemsLink" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductComparePage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductCompareBlockOnCmsPage" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.xml index 16ebdf323e5920fb90074845b53ab61b8b91c68a..19fc527e71ab7672a96a6b0226e43ede2d356b25 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\Product\ClearAllCompareProductsTest" summary="Clear All Compare Products" ticketId="MAGETWO-25961"> <variation name="ClearAllCompareProductsTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="config/dataset" xsi:type="string">compare_products</data> <data name="products" xsi:type="string">catalogProductSimple::simple_for_composite_products,catalogProductVirtual::default,downloadableProduct::default,groupedProduct::grouped_product_with_price,configurableProduct::default,bundleProduct::bundle_dynamic_product,bundleProduct::bundle_fixed_product</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductCompareSuccessRemoveAllProductsMessage" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0884e93387b2ac60c0be00e56791ae2b03443d38 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.php @@ -0,0 +1,134 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Test\TestCase\Product; + +use Magento\Catalog\Test\Fixture\CatalogProductSimple; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; +use Magento\Mtf\TestCase\Injectable; + +/** + * Steps: + * 1. Login to the backend. + * 2. Navigate to Products > Catalog. + * 3. Start to create simple product. + * 4. Fill in data according to data set. + * 5. Save Product. + * 6. Perform appropriate assertions. + * + * @group Products + * @ZephyrId MAGETWO-59861 + */ +class CreateSimpleProductEntityByAttributeMaskSkuTest extends Injectable +{ + /** + * Configuration setting. + * + * @var string + */ + protected $configData; + + /** + * Should cache be flushed + * + * @var bool + */ + private $flushCache; + + /** + * @var \Magento\Mtf\Fixture\FixtureFactory + */ + private $fixtureFactory; + + /** + * Run create product simple entity by attribute mask SKU test. + * + * @param CatalogProductSimple $product + * @param CatalogProductIndex $productGrid + * @param CatalogProductNew $newProductPage + * @param string $configData + * @param bool $flushCache + * @return array + */ + public function testCreate( + CatalogProductSimple $product, + CatalogProductIndex $productGrid, + CatalogProductNew $newProductPage, + \Magento\Mtf\Fixture\FixtureFactory $fixtureFactory, + $flushCache = false, + $configData = null + ) { + $this->configData = $configData; + $this->flushCache = $flushCache; + $this->fixtureFactory = $fixtureFactory; + + // Preconditions + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData, 'flushCache' => $this->flushCache] + )->run(); + + // Steps + $productGrid->open(); + $productGrid->getGridPageActionBlock()->addProduct('simple'); + $newProductPage->getProductForm()->fill($product); + $newProductPage->getFormPageActions()->save(); + + $skuMask = $this->prepareSkuByMask($product); + + $productSimple = $fixtureFactory->createByCode( + 'catalogProductSimple', + ['data' => array_merge($product->getData(), ['sku' => $skuMask])] + ); + + return ['product' => $productSimple]; + } + + /** + * Obtains product sku based on attributes define in Stores > Configuration->Catalog > Catalog > Mask for SKU + * + * @param CatalogProductSimple $product + * @return string + */ + private function prepareSkuByMask(CatalogProductSimple $product) + { + $productData = $product->getData(); + $skuMask = ''; + $config = $this->fixtureFactory->createByCode('configData', ['dataset' => $this->configData]); + $section = $config->getData('section'); + if (is_array($section) && array_key_exists('catalog/fields_masks/sku', $section)) { + $skuMask = $section['catalog/fields_masks/sku']['value']; + } + + $attributesInPattern = []; + $count = preg_match_all('/{{(\w+)}}/', $skuMask, $matches); + if ($count > 0 && is_array($matches[0])) { + foreach ($matches[1] as $attributeName) { + if (array_key_exists($attributeName, $productData)) { + $attributesInPattern[$attributeName] = $productData[$attributeName]; + } + } + } + foreach ($attributesInPattern as $attributeName => $attributeValue) { + $skuMask = str_replace('{{' . $attributeName . '}}', $attributeValue, $skuMask); + } + return $skuMask; + } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData, 'rollback' => true, 'flushCache' => $this->flushCache] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..338f34a57ab5d8745a9cf53665d34e39a0369694 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityByAttributeMaskSkuTest.xml @@ -0,0 +1,23 @@ +<?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\Catalog\Test\TestCase\Product\CreateSimpleProductEntityByAttributeMaskSkuTest" summary="Create Simple Product with attribute sku mask" ticketId="MAGETWO-59861"> + <variation name="CreateSimpleProductEntityByAttributeMaskSkuTest1"> + <data name="configData" xsi:type="string">attribute_product_mask_sku</data> + <data name="description" xsi:type="string">Create product with country of manufacture attribute sku mask</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> + <data name="product/data/price/value" xsi:type="string">10000</data> + <data name="product/data/weight" xsi:type="string">50</data> + <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">657</data> + <data name="product/data/country_of_manufacture" xsi:type="string">Ukraine</data> + <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> + <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> + </variation> + </testCase> +</config> 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 9e410c525deef720573e7c93e0de4d463b9b2ac7..9f4a5e4bb71fea9293612125157757f7e3d965da 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 @@ -137,6 +137,7 @@ <data name="product/data/checkout_data/dataset" xsi:type="string">simple_drop_down_with_one_option_percent_price</data> <data name="product/data/price/dataset" xsi:type="string">MAGETWO-23030</data> <data name="product/data/tier_price/dataset" xsi:type="string">MAGETWO-23002</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" /> @@ -157,6 +158,7 @@ <data name="product/data/checkout_data/dataset" xsi:type="string">simple_drop_down_with_one_option_fixed_price</data> <data name="product/data/price/dataset" xsi:type="string">MAGETWO-23029</data> <data name="product/data/tier_price/dataset" xsi:type="string">MAGETWO-23002</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" /> @@ -238,6 +240,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> </variation> <variation name="CreateSimpleProductEntityTestVariation14"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Create simple product and check visibility in category</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> @@ -255,6 +258,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> </variation> <variation name="CreateSimpleProductEntityTestVariation15"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Create product with tax class and group price</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> @@ -303,6 +307,7 @@ <data name="product/data/weight" xsi:type="string">66</data> <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">143</data> <data name="product/data/tier_price/dataset" xsi:type="string">default</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> @@ -324,6 +329,7 @@ <data name="product/data/custom_options/dataset" xsi:type="string">options_suite</data> <data name="product/data/checkout_data/dataset" xsi:type="string">simple_options_suite</data> <data name="product/data/custom_options/import_products" xsi:type="string">catalogProductSimple::with_two_custom_option,catalogProductSimple::with_all_custom_option</data> + <data name="issue" xsi:type="string">MAGETWO-58181: All kind of Custom Options have dynamic view on Bamboo</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> @@ -333,6 +339,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductCustomOptionsOnProductPage" /> </variation> <variation name="CreateSimpleProductEntityTestVariation19" summary="Create product with cross-sell products" ticketId="MAGETWO-29081"> + <data name="tag" xsi:type="string">stable:no</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> <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data> @@ -349,6 +356,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductCrossSells" /> </variation> <variation name="CreateSimpleProductEntityTestVariation20" summary="Create product with up-sell products" ticketId="MAGETWO-29105"> + <data name="tag" xsi:type="string">stable:no</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> <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data> @@ -401,6 +409,7 @@ <data name="product/data/sku" xsi:type="string">simple%isolation%</data> <data name="product/data/price/value" xsi:type="string">10</data> <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">345</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> @@ -500,5 +509,19 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCart" /> </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> + <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">10</data> + <data name="product/data/weight" xsi:type="string">50</data> + <data name="tag" xsi:type="string">severity:S1</data> + <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">100</data> + <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> + <constraint name="Magento\Catalog\Test\Constraint\AssertProductHasImageInGrid" /> + <constraint name="Magento\Catalog\Test\Constraint\AssertCanSaveProduct" /> + </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.xml index bf158ce4d66b772daaa03f7795cf74d1826bbe59..ed124d152d29b280e2131d1a077a0ed41f5f79af 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\Product\CreateVirtualProductEntityTest" summary="Create Virtual Product" ticketId="MAGETWO-23417"> <variation name="CreateVirtualProductEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Create product with required fields</data> <data name="product/data/url_key" xsi:type="string">virtual-product-%isolation%</data> <data name="product/data/name" xsi:type="string">VirtualProduct %isolation%</data> @@ -17,7 +18,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> </variation> <variation name="CreateVirtualProductEntityTestVariation2" summary="Create product with tier price"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="product/data/url_key" xsi:type="string">virtual-product-%isolation%</data> <data name="product/data/name" xsi:type="string">VirtualProduct %isolation%</data> <data name="product/data/sku" xsi:type="string">virtual_sku_%isolation%</data> @@ -65,12 +66,14 @@ <data name="product/data/quantity_and_stock_status/is_in_stock" xsi:type="string">In Stock</data> <data name="product/data/visibility" xsi:type="string">Catalog, Search</data> <data name="customer/dataset" xsi:type="string">default</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductVisibleInCategory" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPageWithCustomer" /> </variation> <variation name="CreateVirtualProductEntityTestVariation5"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Create product with custom options suite and import options</data> <data name="product/data/url_key" xsi:type="string">virtual-product-%isolation%</data> <data name="product/data/name" xsi:type="string">VirtualProduct %isolation%</data> @@ -110,6 +113,7 @@ <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">999</data> <data name="product/data/tier_price/dataset" xsi:type="string">default</data> <data name="product/data/quantity_and_stock_status/is_in_stock" xsi:type="string">Out of Stock</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPage" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php index 7026b757bb7de03a00f18b525076a057749d2383..81cf672344d612224ff6cab99fec93bfa97b8253 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php @@ -28,6 +28,7 @@ class DeleteCompareProductsTest extends AbstractCompareProductsTest { /* tags */ const MVP = 'yes'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.xml index 883e7cdf6032c5813759db3d613378c34f04c277..9d983f52c08b6bde5c9edc5e59f30899e8da5f21 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\Product\DeleteCompareProductsTest" summary="Delete Compare Products" ticketId="MAGETWO-26161"> <variation name="DeleteCompareProductsTestVariation1_NotLoggedIn"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products" xsi:type="string">catalogProductSimple::simple_for_composite_products,catalogProductVirtual::default,downloadableProduct::default,groupedProduct::grouped_product_with_price,configurableProduct::default,bundleProduct::bundle_dynamic_product,bundleProduct::bundle_fixed_product</data> <data name="removeProductIndex" xsi:type="string">1</data> <data name="isCustomerLoggedIn" xsi:type="string">No</data> @@ -15,6 +16,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductIsNotVisibleInComparePage" /> </variation> <variation name="DeleteCompareProductsTestVariation2_LoggedIn"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products" xsi:type="string">catalogProductSimple::simple_for_composite_products,catalogProductVirtual::default,downloadableProduct::default,groupedProduct::grouped_product_with_price,configurableProduct::default,bundleProduct::bundle_dynamic_product,bundleProduct::bundle_fixed_product</data> <data name="removeProductIndex" xsi:type="string">6</data> <data name="isCustomerLoggedIn" xsi:type="string">Yes</data> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.xml index 3bef2716d35728fff7c3a2cd730688862acae1e4..32d534941e2b91ad5ba1a96d9ba6b0e47d523e70 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.xml @@ -10,6 +10,7 @@ <variation name="DeleteProductEntityTestVariation1"> <data name="products" xsi:type="string">catalogProductSimple::default</data> <data name="isRequired" xsi:type="string">Yes</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSuccessDeleteMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductNotInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductIsNotDisplayingOnFrontend" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.xml index 5b81bebbc6d04e9551fa6399c308a365895b9bd7..0dad886f05ed55c7b951e32dfec8a74b433d6067 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\Product\DuplicateProductEntityTest" summary="Duplicate Product" ticketId="MAGETWO-23294"> <variation name="DuplicateProductEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productType" xsi:type="string">catalogProductSimple::default</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml index 6cb89d424fee3a0e3ddc084dc304e3fe2f25751c..4ab490478958a81f7312dd1d7a9fc6fb9835a05a 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\Product\ProductTypeSwitchingOnCreationTest" summary="Product Type Switching on Creation" ticketId="MAGETWO-29398"> <variation name="ProductTypeSwitchingOnCreationTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="createProduct" xsi:type="string">simple</data> <data name="product" xsi:type="string">configurableProduct::default</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> @@ -44,6 +45,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> </variation> <variation name="ProductTypeSwitchingOnCreationTestVariation6"> + <data name="tag" xsi:type="string">stable:no</data> <data name="createProduct" xsi:type="string">virtual</data> <data name="product" xsi:type="string">configurableProduct::not_virtual_for_type_switching</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> @@ -56,6 +58,7 @@ <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductIsNotDisplayedSeparately" /> </variation> <variation name="ProductTypeSwitchingOnCreationTestVariation7"> + <data name="tag" xsi:type="string">stable:no</data> <data name="createProduct" xsi:type="string">virtual</data> <data name="product" xsi:type="string">downloadableProduct::default</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> @@ -73,6 +76,7 @@ <variation name="ProductTypeSwitchingOnCreationTestVariation9"> <data name="createProduct" xsi:type="string">downloadable</data> <data name="product" xsi:type="string">configurableProduct::not_virtual_for_type_switching</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductsInGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.xml index a2580cee9b91a342c30d21fb4356c682e68a8383..874cac5d4bc5828769a88badc87a41643799d4fc 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.xml @@ -11,6 +11,7 @@ <data name="productOrigin" xsi:type="string">catalogProductSimple::default</data> <data name="product" xsi:type="string">configurableProduct::default</data> <data name="actionName" xsi:type="string">-</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductsInGrid" /> @@ -20,6 +21,7 @@ <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductIsNotDisplayedSeparately" /> </variation> <variation name="ProductTypeSwitchingOnUpdateTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productOrigin" xsi:type="string">catalogProductSimple::default</data> <data name="product" xsi:type="string">catalogProductVirtual::default</data> <data name="actionName" xsi:type="string">-</data> @@ -27,6 +29,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> </variation> <variation name="ProductTypeSwitchingOnUpdateTestVariation3"> + <data name="tag" xsi:type="string">stable:no</data> <data name="productOrigin" xsi:type="string">configurableProduct::default</data> <data name="product" xsi:type="string">catalogProductSimple::product_without_category</data> <data name="actionName" xsi:type="string">deleteVariations</data> @@ -37,10 +40,12 @@ <data name="productOrigin" xsi:type="string">configurableProduct::default</data> <data name="product" xsi:type="string">catalogProductVirtual::required_fields</data> <data name="actionName" xsi:type="string">deleteVariations</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> </variation> <variation name="ProductTypeSwitchingOnUpdateTestVariation5"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productOrigin" xsi:type="string">catalogProductVirtual::default</data> <data name="product" xsi:type="string">catalogProductSimple::default</data> <data name="actionName" xsi:type="string">-</data> @@ -51,6 +56,7 @@ <data name="productOrigin" xsi:type="string">catalogProductVirtual::default</data> <data name="product" xsi:type="string">configurableProduct::not_virtual_for_type_switching</data> <data name="actionName" xsi:type="string">-</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductsInGrid" /> @@ -63,6 +69,7 @@ <data name="productOrigin" xsi:type="string">catalogProductVirtual::default</data> <data name="product" xsi:type="string">downloadableProduct::default</data> <data name="actionName" xsi:type="string">-</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" /> @@ -74,6 +81,7 @@ <data name="productOrigin" xsi:type="string">downloadableProduct::default</data> <data name="product" xsi:type="string">catalogProductSimple::default</data> <data name="actionName" xsi:type="string">-</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> </variation> @@ -81,6 +89,7 @@ <data name="productOrigin" xsi:type="string">downloadableProduct::default</data> <data name="product" xsi:type="string">configurableProduct::not_virtual_for_type_switching</data> <data name="actionName" xsi:type="string">-</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductsInGrid" /> @@ -90,6 +99,7 @@ <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductIsNotDisplayedSeparately" /> </variation> <variation name="ProductTypeSwitchingOnUpdateTestVariation10"> + <data name="tag" xsi:type="string">stable:no</data> <data name="productOrigin" xsi:type="string">downloadableProduct::default</data> <data name="product" xsi:type="string">catalogProductVirtual::default</data> <data name="actionName" xsi:type="string">clearDownloadableData</data> @@ -100,6 +110,7 @@ <data name="productOrigin" xsi:type="string">catalogProductSimple::default</data> <data name="product" xsi:type="string">downloadableProduct::default</data> <data name="actionName" xsi:type="string">-</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml index 0395f9f5ed8cf83c0aa570252cc5ed7df32da3c8..31aaad654f92a914c14276ab770fa7fe9790f5de 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\Product\UpdateSimpleProductEntityTest" summary="Update Simple Product" ticketId="MAGETWO-23544"> <variation name="UpdateSimpleProductEntityTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Update visibility to Catalog, Search</data> <data name="initialProduct/dataset" xsi:type="string">product_with_category</data> <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data> @@ -24,6 +25,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> </variation> <variation name="UpdateSimpleProductEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Update visibility to Not Visible Individually</data> <data name="initialProduct/dataset" xsi:type="string">product_with_category</data> <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data> @@ -47,6 +49,7 @@ <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data> <data name="product/data/weight" xsi:type="string">25.0000</data> <data name="product/data/visibility" xsi:type="string">Catalog</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInStock" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> @@ -64,6 +67,7 @@ <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data> <data name="product/data/weight" xsi:type="string">89.0000</data> <data name="product/data/visibility" xsi:type="string">Search</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInStock" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> @@ -81,6 +85,7 @@ <data name="product/data/quantity_and_stock_status/is_in_stock" xsi:type="string">Out of Stock</data> <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data> <data name="product/data/weight" xsi:type="string">125.0000</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" /> @@ -89,6 +94,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductSearchableBySku" /> </variation> <variation name="UpdateSimpleProductEntityTestVariation6"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Update product status to offline</data> <data name="initialProduct/dataset" xsi:type="string">product_with_category</data> <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data> @@ -112,6 +118,7 @@ <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">87</data> <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data> <data name="product/data/weight" xsi:type="string">333.0000</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteUpdatedProductInGrid" /> @@ -124,6 +131,7 @@ <data name="product/data/sku" xsi:type="string">test_simple_product_%isolation%</data> <data name="product/data/price/value" xsi:type="string">133.00</data> <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> </variation> @@ -142,10 +150,12 @@ <data name="product/data/sku" xsi:type="string">sku_simple_product_%isolation%</data> <data name="product/data/price/value" xsi:type="string">1.99</data> <data name="product/data/attribute_set_id/dataset" xsi:type="string">default</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" /> </variation> <variation name="EditSimpleProductTestVariation11" summary="Update simple product with custom option"> + <data name="tag" xsi:type="string">stable:no</data> <data name="initialProduct/dataset" xsi:type="string">product_with_category</data> <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data> <data name="product/data/sku" xsi:type="string">test_simple_product_%isolation%</data> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php index ddd788d7ee1c91dde5164b06ea2d908056031c25..2a18f9e37f953b91e06332ffc1e4090c1a4acd73 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php @@ -37,6 +37,7 @@ class UpdateVirtualProductEntityTest extends Injectable { /* tags */ const MVP = 'no'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.xml index 3bc4b3c780d627c6ec6e049574381f1ff726867c..a263a70e8bfc007cbcc0a224e8bc1255e86dfe2a 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\CreateAttributeSetEntityTest" summary="Create Attribute Set (Attribute Set)" ticketId="MAGETWO-25104"> <variation name="CreateAttributeSetEntityTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="attributeSet/data/attribute_set_name" xsi:type="string">AttributeSet%isolation%</data> <data name="attributeSet/data/skeleton_set/dataset" xsi:type="string">default</data> <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeSetSuccessSaveMessage" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml index 2a94a12c0dbdf0d37082a16c19cff02c152ed7f3..543bece9331f4d0968e38b7d8f887f563b9b8ec3 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\CreateProductAttributeEntityTest" summary="Create Product Attribute" ticketId="MAGETWO-24767"> <variation name="CreateProductAttributeEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttribute/data/frontend_label" xsi:type="string">Text_Field_Admin_%isolation%</data> <data name="productAttribute/data/frontend_input" xsi:type="string">Text Field</data> @@ -19,6 +20,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertAddedProductAttributeOnProductForm" /> </variation> <variation name="CreateProductAttributeEntityTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttribute/data/frontend_label" xsi:type="string">Text_Field_Admin_%isolation%</data> <data name="productAttribute/data/frontend_input" xsi:type="string">Text Area</data> @@ -57,6 +59,7 @@ <data name="productAttribute/data/used_in_product_listing" xsi:type="string">Yes</data> <data name="productAttribute/data/is_used_for_promo_rules" xsi:type="string">Yes</data> <data name="productAttribute/data/used_for_sort_by" xsi:type="string">Yes</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeForm" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductByAttribute" /> @@ -65,6 +68,7 @@ <constraint name="Magento\CatalogRule\Test\Constraint\AssertProductAttributeIsUsedPromoRules" /> </variation> <variation name="CreateProductAttributeEntityTestVariation4"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttribute/data/frontend_label" xsi:type="string">Yes/No_Admin_%isolation%</data> <data name="productAttribute/data/frontend_input" xsi:type="string">Yes/No</data> @@ -97,6 +101,7 @@ <data name="productAttribute/data/is_html_allowed_on_front" xsi:type="string">Yes</data> <data name="productAttribute/data/is_visible_on_front" xsi:type="string">Yes</data> <data name="productAttribute/data/used_in_product_listing" xsi:type="string">Yes</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeInGrid" /> <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeForm" /> <constraint name="Magento\Catalog\Test\Constraint\AssertAddedProductAttributeOnProductForm" /> @@ -110,7 +115,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeOptionsOnProductForm" /> </variation> <variation name="CreateProductAttributeEntityTestVariation6"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttribute/data/frontend_label" xsi:type="string">Dropdown_Admin_%isolation%</data> <data name="productAttribute/data/frontend_input" xsi:type="string">Dropdown</data> @@ -148,6 +153,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertAttributeOptionsOnProductForm" /> </variation> <variation name="CreateProductAttributeEntityTestVariation7"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttribute/data/frontend_label" xsi:type="string">Price_Admin_%isolation%</data> <data name="productAttribute/data/frontend_input" xsi:type="string">Price</data> @@ -169,6 +175,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeIsFilterableInSearch" /> </variation> <variation name="CreateProductAttributeEntityTestVariation8"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttribute/data/frontend_label" xsi:type="string">Fixed_Product_Tax_Admin_%isolation%</data> <data name="productAttribute/data/frontend_input" xsi:type="string">Fixed Product Tax</data> @@ -185,6 +192,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertAddedProductAttributeOnProductForm" /> </variation> <variation name="CreateProductAttributeEntityTestVariation9"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttribute/data/frontend_label" xsi:type="string">Text_Field_Admin_%isolation%</data> <data name="productAttribute/data/frontend_input" xsi:type="string">Text Field</data> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.xml index 3f547daa68eb58cfc8480f76ede8c1be5ea31ace..83b5be744f0251374798b2a151c9c1dabf737b53 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\DeleteAttributeSetTest" summary="Delete Attribute Set (Attribute Set)" ticketId="MAGETWO-25473"> <variation name="DeleteAttributeSetTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="attributeSet/data/assigned_attributes/dataset" xsi:type="string">default</data> <data name="product/dataset" xsi:type="string">default</data> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.xml index a11e2679b27e0860ba298008eaa48b9f2812fe01..83d819b7db1c4d6e0fc09d6209b0255c18f8f6c0 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.xml @@ -15,6 +15,7 @@ <constraint name="Magento\ImportExport\Test\Constraint\AssertProductAttributeAbsenceForExport" /> </variation> <variation name="DeleteProductAttributeEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="attribute/dataset" xsi:type="string">attribute_type_dropdown</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeSuccessDeleteMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductAttributeAbsenceInGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.xml index a7b233a7aae4b9d97f83638c80572d7f8888a9f1..ff80366fea097217450ad1d95eb4d0b5f4191944 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\UpdateAttributeSetTest" summary="Update Attribute Set" ticketId="MAGETWO-26251"> <variation name="UpdateAttributeSetTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="attributeSet/data/attribute_set_name" xsi:type="string">AttributeSetEdit1%isolation%</data> <data name="attributeSet/data/group" xsi:type="string">Custom-group%isolation%</data> <data name="attributeSetOriginal/dataset" xsi:type="string">custom_attribute_set</data> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.xml index b7e27854a82441e35328c31d0c81f2088cf50408..7077b8e852b5e06f7fa240be8a8e106f36686068 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\ProductAttribute\UpdateProductAttributeEntityTest" summary="Update Product Attribute" ticketId="MAGETWO-23459"> <variation name="UpdateProductAttributeEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttributeOriginal/dataset" xsi:type="string">attribute_type_text_field</data> <data name="attribute/data/frontend_label" xsi:type="string">Text_Field_%isolation%</data> @@ -28,6 +29,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertAddedProductAttributeOnProductForm" /> </variation> <variation name="UpdateProductAttributeEntityTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="attributeSet/dataset" xsi:type="string">custom_attribute_set</data> <data name="productAttributeOriginal/dataset" xsi:type="string">attribute_type_dropdown</data> <data name="attribute/data/frontend_label" xsi:type="string">Dropdown_%isolation%</data> @@ -60,6 +62,7 @@ <data name="cacheTags" xsi:type="array"> <item name="0" xsi:type="string">FPC</item> </data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\PageCache\Test\Constraint\AssertCacheIsRefreshableAndInvalidated" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductByAttribute" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/ConfigureProductOnProductPageStep.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/ConfigureProductOnProductPageStep.php new file mode 100644 index 0000000000000000000000000000000000000000..f2f08513d7297ad1a3fe3345c8bdca1b848e4819 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestStep/ConfigureProductOnProductPageStep.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Test\TestStep; + +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Mtf\Client\BrowserInterface; +use Magento\Mtf\Fixture\InjectableFixture; +use Magento\Mtf\TestStep\TestStepInterface; + +/** + * Configure Product on Product Page step. + */ +class ConfigureProductOnProductPageStep implements TestStepInterface +{ + /** + * Product fixture. + * + * @var InjectableFixture + */ + private $product; + + /** + * Frontend product view page. + * + * @var CatalogProductView + */ + private $catalogProductView; + + /** + * Interface Browser. + * + * @var BrowserInterface + */ + private $browser; + + /** + * @constructor + * @param CatalogProductView $catalogProductView + * @param BrowserInterface $browser + * @param InjectableFixture $product + */ + public function __construct( + CatalogProductView $catalogProductView, + BrowserInterface $browser, + InjectableFixture $product + ) { + $this->product = $product; + $this->catalogProductView = $catalogProductView; + $this->browser = $browser; + } + + /** + * Configure product. + * + * @return void + */ + public function run() + { + $this->browser->open($_ENV['app_frontend_url'] . $this->product->getUrlKey() . '.html'); + $this->catalogProductView->getViewBlock()->configure($this->product); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test1.png b/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test1.png new file mode 100644 index 0000000000000000000000000000000000000000..3077df38da2ffab3378a630914803dfad59e7961 Binary files /dev/null and b/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test1.png differ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test2.png b/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test2.png new file mode 100644 index 0000000000000000000000000000000000000000..3d219e6ee734b983a39e041a2386117a10d762be Binary files /dev/null and b/dev/tests/functional/tests/app/Magento/Catalog/Test/_files/test2.png differ diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.xml index 9359b0c402b953ba1b8fcd2343b5ca84af3a764f..3a2f2f8aa7816a53d674c6c665b058afb1a4b720 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.xml @@ -8,11 +8,13 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\CatalogSearch\Test\TestCase\SuggestSearchingResultEntityTest" summary="Suggest Searching Results" ticketId="MAGETWO-24671"> <variation name="SuggestSearchingResultEntityTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="catalogSearch/data/query_text/value" xsi:type="string">catalogProductSimple::name</data> <data name="catalogSearch/data/num_results" xsi:type="string">-</data> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSuggestSearchingResult" /> </variation> <variation name="SuggestSearchingResultEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="catalogSearch/data/query_text/value" xsi:type="string">catalogProductSimple::sku</data> <data name="catalogSearch/data/num_results" xsi:type="string">1</data> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSuggestSearchingResult" /> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment.php index f1776d2bf933e17d63006948795418309348ffe3..ce8f5a4cbfd99b41e990a11fc89527f28b0fec5f 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment.php @@ -8,7 +8,6 @@ namespace Magento\Checkout\Test\Block\Onepage; use Magento\Mtf\Block\Block; use Magento\Mtf\Fixture\InjectableFixture; -use Magento\Payment\Test\Fixture\CreditCard; /** * Checkout payment block. @@ -85,11 +84,17 @@ class Payment extends Block $paymentLabelSelector = sprintf($this->paymentMethodLabel, $payment['method']); try { + $this->waitForElementNotVisible($this->waitElement); $this->waitForElementVisible($paymentLabelSelector); } catch (\Exception $exception) { throw new \Exception('Such payment method is absent.'); } - + $browser = $this->browser; + $browser->waitUntil( + function () use ($browser, $paymentSelector) { + return $browser->find($paymentSelector); + } + ); $paymentRadioButton = $this->_rootElement->find($paymentSelector); if ($paymentRadioButton->isVisible()) { $paymentRadioButton->click(); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalOrderReview.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalOrderReview.php index 3bf6bda89ad939ad4ae100006996cf4077e1aeb9..dc1433506f2623d2122f293b063a0707017edc13 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalOrderReview.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertGrandTotalOrderReview.php @@ -14,6 +14,13 @@ use Magento\Mtf\Constraint\AbstractConstraint; */ class AssertGrandTotalOrderReview extends AbstractConstraint { + /** + * Wait element. + * + * @var string + */ + protected $waitElement = '.loading-mask'; + /** * Assert that Order Grand Total is correct on checkoutOnePage * @@ -23,6 +30,7 @@ class AssertGrandTotalOrderReview extends AbstractConstraint */ public function processAssert(CheckoutOnepage $checkoutOnepage, $grandTotal) { + $checkoutOnepage->getReviewBlock()->waitForElementNotVisible($this->waitElement); $checkoutReviewGrandTotal = $checkoutOnepage->getReviewBlock()->getGrandTotal(); \PHPUnit_Framework_Assert::assertEquals( diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml index 30688723ae8edb8c83b761e89f2805f5dcdcd588..9a539d856e7082ae5131e903d7d86eec5f37d6c5 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Checkout\Test\TestCase\AddProductsToShoppingCartEntityTest" summary="Add Products to Shopping Cart" ticketId="MAGETWO-25382"> <variation name="AddProductsToShoppingCartEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data> <data name="cart/data/grand_total" xsi:type="string">210</data> <data name="cart/data/subtotal" xsi:type="string">200</data> @@ -20,6 +21,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" /> </variation> <variation name="AddProductsToShoppingCartEntityTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">bundleProduct::bundle_fixed_product</data> <data name="cart/data/grand_total" xsi:type="string">761</data> <data name="cart/data/subtotal" xsi:type="string">756</data> @@ -32,6 +34,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" /> </variation> <variation name="AddProductsToShoppingCartEntityTestVariation3"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data> <data name="cart/data/grand_total" xsi:type="string">345</data> <data name="cart/data/subtotal" xsi:type="string">340</data> @@ -44,6 +47,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" /> </variation> <variation name="AddProductsToShoppingCartEntityTestVariation4"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">catalogProductVirtual::product_50_dollar</data> <data name="cart/data/grand_total" xsi:type="string">50</data> <data name="cart/data/subtotal" xsi:type="string">50</data> @@ -56,6 +60,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" /> </variation> <variation name="AddProductsToShoppingCartEntityTestVariation5"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">configurableProduct::default</data> <data name="cart/data/grand_total" xsi:type="string">135</data> <data name="cart/data/subtotal" xsi:type="string">120</data> @@ -80,6 +85,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" /> </variation> <variation name="AddProductsToShoppingCartEntityTestVariation7"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">groupedProduct::three_simple_products</data> <data name="cart/data/grand_total" xsi:type="string">1950</data> <data name="cart/data/subtotal" xsi:type="string">1920</data> @@ -92,6 +98,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInMiniShoppingCart" /> </variation> <variation name="AddProductsToShoppingCartEntityTestVariation8"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data> <data name="productsData/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data> <data name="productsData/2" xsi:type="string">downloadableProduct::with_two_separately_links</data> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.xml index 2f2177c6cc7efcdf9c7e1df8f71b8b4ca7752188..033ea76a2a5ff17c5233d7f1b543f6b72f013c61 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.xml +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.xml @@ -16,6 +16,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" /> </variation> <variation name="DeleteProductsFromShoppingCartTestVariation3"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data> <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" /> </variation> @@ -36,6 +37,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" /> </variation> <variation name="DeleteProductsFromShoppingCartTestVariation8"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="productsData/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data> <data name="productsData/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data> <data name="productsData/2" xsi:type="string">downloadableProduct::with_two_separately_links</data> 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 6a1f225bc9429e47b68ffb85bd06fc0443ebdbf9..797255d4e374acf001132647eee1121168ec0b50 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 @@ -27,6 +27,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation2" summary="US customer during checkout using coupon for all customer groups"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups</data> <data name="customer/dataset" xsi:type="string">default</data> @@ -48,6 +49,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation3" summary="Checkout as UK guest with simple product" ticketId="MAGETWO-42603"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="checkoutMethod" xsi:type="string">guest</data> @@ -167,6 +169,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation9" summary="One Page Checkout Products with Tier Prices"> + <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> @@ -183,6 +186,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal" /> </variation> <variation name="OnePageCheckoutTestVariation10" summary="One Page Checkout with all product types"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductVirtual::default</data> <data name="products/1" xsi:type="string">downloadableProduct::with_two_separately_links</data> <data name="products/2" xsi:type="string">configurableProduct::with_one_option</data> 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 1c60b0f156bae087433d03ac12e84c733bb9258f..5f9b069ab85ca92d37ac8773ac3d1694e5d6ee81 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 @@ -8,14 +8,14 @@ <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</data> + <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> <constraint name="Magento\Checkout\Test\Constraint\AssertProductDataInMiniShoppingCart" /> <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" /> </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</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="originalProduct/0" xsi:type="string">configurableProduct::default</data> <data name="checkoutData/dataset" xsi:type="string">configurable_update_mini_shopping_cart</data> <constraint name="Magento\Checkout\Test\Constraint\AssertCartItemsOptions" /> @@ -24,7 +24,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertProductOptionsAbsentInShoppingCart" /> </variation> <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation3" summary="Update Bundle 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</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="originalProduct/0" xsi:type="string">bundleProduct::bundle_fixed_product</data> <data name="checkoutData/dataset" xsi:type="string">bundle_update_mini_shopping_cart</data> <constraint name="Magento\Checkout\Test\Constraint\AssertCartItemsOptions" /> @@ -33,7 +33,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertProductOptionsAbsentInShoppingCart" /> </variation> <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation4" summary="Update Downloadable and check previous link was updated to new one in shopping cart and mini shopping cart"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="originalProduct/0" xsi:type="string">downloadableProduct::with_two_separately_links</data> <data name="checkoutData/dataset" xsi:type="string">downloadable_update_mini_shopping_cart</data> <constraint name="Magento\Checkout\Test\Constraint\AssertCartItemsOptions" /> @@ -42,7 +42,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertProductOptionsAbsentInShoppingCart" /> </variation> <variation name="UpdateProductFromMiniShoppingCartEntityTestVariation5" summary="Update Virtual product in mini shopping cart"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="originalProduct/0" xsi:type="string">catalogProductVirtual::default</data> <data name="checkoutData/dataset" xsi:type="string">virtual_update_mini_shopping_cart</data> <constraint name="Magento\Checkout\Test\Constraint\AssertProductDataInMiniShoppingCart" /> diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php index 809688cd8286a0afdc68ef3d236a6b1673b1c66b..3dba57e26e003726e856577f5e4b48a427428a24 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php @@ -33,6 +33,7 @@ class UpdateShoppingCartTest extends Injectable { /* tags */ const MVP = 'yes'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml index fc043effe5a77682ef1a30307350ad72aab8401b..34c70c9e2a33bea3418e394a241a1d87d48ee27a 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Cms\Test\TestCase\DeleteCmsBlockEntityTest" summary="Delete CMS Block" ticketId="MAGETWO-25698"> <variation name="DeleteCmsBlockEntityTestVariation1"> - <data name="tag" xsi:type="string">severity:S1</data> + <data name="tag" xsi:type="string">severity:S1, stable:no</data> <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockDeleteMessage" /> <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockNotInGrid" /> <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockNotOnCategoryPage" /> diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml index 2a85425890e8e455a4ba6e32960f6d329bfcdf5b..745d60dad9f8ac8c67d891e84e33e502db1b6659 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Cms\Test\TestCase\DeleteCmsPageEntityTest" summary="Delete CMS Page" ticketId="MAGETWO-23291"> <variation name="DeleteCmsPageEntityTestVariation1"> - <data name="tag" xsi:type="string">severity:S1</data> + <data name="tag" xsi:type="string">severity:S1, stable:no</data> <data name="cmsPage/dataset" xsi:type="string">default</data> <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageDeleteMessage" /> <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageNotInGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml index 893cfc2f0dacc75f92b31b3a14fcc54a41aaf6b5..fc279aad59d3d7e21590be2c256f83831e7295cf 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Ui\Test\TestCase\GridFullTextSearchTest" summary="Grid UI Component Full Text Search" ticketId="MAGETWO-41023"> <variation name="CmsPageGridFullTextSearch"> - <data name="tag" xsi:type="string">severity:S2</data> + <data name="tag" xsi:type="string">severity:S2, stable:no</data> <data name="description" xsi:type="string">Verify cms page grid full text search</data> <data name="itemsCount" xsi:type="string">2</data> <data name="fixtureName" xsi:type="string">cmsPage</data> diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml index d6467a53e15659a1e5859002c04be6ad3e91b3e3..1be7e61f6bd0ea27a99733a63828f438ab481215 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Ui\Test\TestCase\GridSortingTest" summary="Grid UI Component Sorting" ticketId="MAGETWO-41328"> <variation name="CmsPagesGridSorting"> - <data name="tag" xsi:type="string">severity:S2</data> + <data name="tag" xsi:type="string">severity:S2, stable:no</data> <data name="description" xsi:type="string">Verify cms page grid sorting</data> <data name="columnsForSorting" xsi:type="array"> <item name="id" xsi:type="string">ID</item> @@ -19,7 +19,7 @@ <constraint name="Magento\Ui\Test\Constraint\AssertGridSorting"/> </variation> <variation name="CmsBlocksGridSorting"> - <data name="tag" xsi:type="string">severity:S2</data> + <data name="tag" xsi:type="string">severity:S2, stable:no</data> <data name="description" xsi:type="string">Verify cms blocks grid sorting</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="string">-</item> diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml index 75f8cf63f645e333e001ba26ef940f62ae95581c..93d38321ab7db4c2fa8fcda830022a8c52970e14 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Cms\Test\TestCase\UpdateCmsPageEntityTest" summary="Update Cms Page" ticketId="MAGETWO-25186"> <variation name="UpdateCmsPageEntityTestVariation1"> - <data name="tag" xsi:type="string">severity:S3</data> + <data name="tag" xsi:type="string">severity:S3, to_maintain:yes</data> <data name="cms/data/title" xsi:type="string">CmsPageEdited%isolation%</data> <data name="cms/data/is_active" xsi:type="string">No</data> <data name="cms/data/content/content" xsi:type="string">cms_page_text_content_after_edit</data> @@ -16,7 +16,7 @@ <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageDisabledOnFrontend" /> </variation> <variation name="UpdateCmsPageEntityTestVariation2"> - <data name="tag" xsi:type="string">severity:S1</data> + <data name="tag" xsi:type="string">severity:S1, to_maintain:yes</data> <data name="cms/data/title" xsi:type="string">CmsPageEdited%isolation%</data> <data name="cms/data/identifier" xsi:type="string">cms_page_url_edited_%isolation%</data> <data name="cms/data/content_heading" xsi:type="string">Content Heading TextEdited</data> diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php index 30928810490d770c5ea8309748b07aeabf45314a..5df648a565dc7040c24e43d8b35bad5859a3b200 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php @@ -23,13 +23,14 @@ class VerifyAdminAccountSharingEntityTest extends Injectable /* tags */ const MVP = 'yes'; const DOMAIN = 'PS'; + const TO_MAINTAIN = 'yes'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ /** * Admin account settings page. * - * @var adminAccountSharing + * @var AdminAccountSharing */ private $adminAccountSharing; diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductPage.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductPage.php index 62d6c72efe8c6aa8d0a8ed4aff4594316318c9e3..ad9807b76d6e532fd00e9f22fac7bf4007a80502 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductPage.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductPage.php @@ -125,15 +125,23 @@ class AssertConfigurableProductPage extends AssertProductPage protected function getLowestConfigurablePrice() { $price = null; - $configurableOptions = $this->product->getConfigurableAttributesData(); - - foreach ($configurableOptions['matrix'] as $option) { - $price = $price === null ? $option['price'] : $price; - if ($price > $option['price']) { - $price = $option['price']; + $priceDataConfig = $this->product->getDataFieldConfig('price'); + if (isset($priceDataConfig['source'])) { + $priceData = $priceDataConfig['source']->getPriceData(); + if (isset($priceData['price_from'])) { + $price = $priceData['price_from']; } } + if (null === $price) { + $configurableOptions = $this->product->getConfigurableAttributesData(); + foreach ($configurableOptions['matrix'] as $option) { + $price = $price === null ? $option['price'] : $price; + if ($price > $option['price']) { + $price = $option['price']; + } + } + } return $price; } } diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php new file mode 100644 index 0000000000000000000000000000000000000000..e5c3ab4dad9ee121c1332649dabd8715c3544449 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php @@ -0,0 +1,118 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\ConfigurableProduct\Test\Constraint; + +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Mtf\Fixture\FixtureInterface; +use Magento\Mtf\ObjectManager; +use Magento\Mtf\System\Event\EventManagerInterface; +use Magento\Sales\Test\Fixture\OrderInjectable; + +/** + * Class AssertProductQtyDecreasedAfterCreditmemo + */ +class AssertProductQtyDecreasedAfterCreditmemo extends AbstractConstraint +{ + /** + * @var FixtureFactory + */ + protected $fixtureFactory; + + /** + * Skip fields for create product fixture. + * + * @var array + */ + protected $skipFields = [ + 'attribute_set_id', + 'website_ids', + 'checkout_data', + 'type_id', + 'price', + ]; + + /** + * AssertFirstProductForm constructor. + * @param ObjectManager $objectManager + */ + public function __construct( + ObjectManager $objectManager, + EventManagerInterface $eventManager, + FixtureFactory $fixtureFactory + ) { + $this->fixtureFactory = $fixtureFactory; + parent::__construct($objectManager, $eventManager); + } + + /** + * Assert form data equals fixture data + * + * @param OrderInjectable $order + * @param array $data + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert( + OrderInjectable $order, + array $data, + CatalogProductIndex $productGrid, + CatalogProductEdit $productPage + ) { + $product = $this->getProduct($order, $data); + $this->objectManager->get(\Magento\Catalog\Test\Constraint\AssertProductForm::class)->processAssert( + $product, + $productGrid, + $productPage + ); + } + + /** + * Get product's fixture. + * + * @param OrderInjectable $order + * @param array $data + * @param int $index [optional] + * @return FixtureInterface + */ + protected function getProduct(OrderInjectable $order, array $data, $index = 0) + { + if (!isset($data['items_data'][$index]['back_to_stock']) + || $data['items_data'][$index]['back_to_stock'] != 'Yes' + ) { + return $order->getEntityId()['products'][$index]; + } + $product = $order->getEntityId()['products'][$index]; + $productData = $product->getData(); + $checkoutDataQty = $productData['checkout_data']['qty']; + + $productKey = ''; + foreach ($productData['checkout_data']['options']['configurable_options'] as $option) { + $productKey .= ' ' . $option['title'] . ':' . $option['value']; + } + $productKey = trim($productKey); + $optionProduct = $productData['configurable_attributes_data']['matrix'][$productKey]; + $optionProduct['qty'] -= ($checkoutDataQty - $data['items_data'][$index]['qty']); + $productData = $optionProduct; + + $productData = array_diff_key($productData, array_flip($this->skipFields)); + + return $this->fixtureFactory->create(get_class($product), ['data' => $productData]); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Product qty was decreased after creditmemo creation.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php index bf5d5944aa3da0a7093d5bbe33ea00897f3b5397..626be7dee3652ee88407d47f1bac313a96dde225 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/ConfigurableProduct/Curl.php @@ -172,7 +172,7 @@ class Curl extends ProductCurl implements ConfigurableProductInterface $keyIds[] = $attribute['options'][$optionKey]['id']; $configurableAttribute[] = sprintf( '"%s":"%s"', - $attribute['attribute_code'], + isset($attribute['attribute_code']) ? $attribute['attribute_code'] : $attribute['frontend_label'], $attribute['options'][$optionKey]['id'] ); } diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml index 4a69a7604bca3d74119b07bdcea3b2115a1f6648..32f1957d4173f87b10069b60c8c428b921e260fb 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml @@ -71,7 +71,40 @@ </dataset> <dataset name="configurable_with_qty_1"> - <field name="name" xsi:type="string">Test configurable product %isolation%</field> + <field name="name" xsi:type="string">sku_test_configurable_product_%isolation%</field> + <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field> + <field name="price" xsi:type="array"> + <item name="dataset" xsi:type="string">price_40</item> + </field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">30</field> + <field name="status" xsi:type="string">Yes</field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="url_key" xsi:type="string">configurable-product-%isolation%</field> + <field name="configurable_attributes_data" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="quantity_and_stock_status" xsi:type="array"> + <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="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">default</item> + </field> + <field name="checkout_data" xsi:type="array"> + <item name="dataset" xsi:type="string">configurable_options_with_qty_1</item> + </field> + </dataset> + + <dataset name="configurable_with_qty_2"> + <field name="name" xsi:type="string">sku_test_configurable_product_%isolation%</field> <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field> <field name="price" xsi:type="array"> <item name="dataset" xsi:type="string">price_40</item> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml index 2e9d708dd42d82ca79d0507b6a698c0c5c897d3b..1b6282b9432c39fd444ca2089f1b8c8aa6bfb876 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/Price.xml @@ -17,5 +17,8 @@ <dataset name="MAGETWO-12620"> <field name="category_price" xsi:type="string">11</field> </dataset> + <dataset name="from-9"> + <field name="price_from" xsi:type="string">9</field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml index 58435b066261ed28cc7f33ff01fc250940b6eb17..14ff24f18908da187a0631662cf74bfdaad5db6f 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\ConfigurableProduct\Test\TestCase\CreateConfigurableProductEntityTest" summary="Create Configurable Product" ticketId="MAGETWO-26041"> <variation name="CreateConfigurableProductEntityTestVariation1" summary="Create product with category and two new options"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data> <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_new_options</data> <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_options</data> @@ -32,6 +33,7 @@ <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertChildProductIsNotDisplayedSeparately"/> </variation> <variation name="CreateConfigurableProductEntityTestVariation2" summary="Create product with two options"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data> <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options</data> <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_options</data> @@ -53,11 +55,13 @@ <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductInCart" /> </variation> <variation name="CreateConfigurableProductEntityTestVariation3" summary="Create product with special price"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data> <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options_with_assigned_product_special_price</data> <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_new_options_with_special_price</data> <data name="product/data/name" xsi:type="string">Configurable Product %isolation%</data> <data name="product/data/sku" xsi:type="string">configurable_sku_%isolation%</data> + <data name="product/data/price/dataset" xsi:type="string">from-9</data> <data name="product/data/price/value" xsi:type="string">100</data> <data name="product/data/special_price" xsi:type="string">9</data> <data name="product/data/short_description" xsi:type="string">Configurable short description</data> @@ -74,6 +78,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductSpecialPriceOnProductPage" /> </variation> <variation name="CreateConfigurableProductEntityTestVariation4" summary="Create product with assigned products to options"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data> <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options_with_assigned_product</data> <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_options_with_assigned_product</data> @@ -94,6 +99,7 @@ <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductInCart" /> </variation> <variation name="CreateConfigurableProductEntityTestVariation5" summary="Create Configurable Product and Assign it to Category" ticketId="MAGETWO-12620"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data> <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options_with_fixed_price</data> <data name="product/data/name" xsi:type="string">Configurable Product %isolation%</data> @@ -142,6 +148,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductAutoincrementedSkuNoticeMessage" /> </variation> <variation name="CreateConfigurableProductEntityTestVariation9" summary="Create configurable product and assign it to custom website"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/data/url_key" xsi:type="string">configurable-product-%isolation%</data> <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_options_with_assigned_product_special_price</data> <data name="product/data/checkout_data/dataset" xsi:type="string">configurable_two_new_options_with_special_price</data> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateCreditMemoEntityTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateCreditMemoEntityTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..dd92edc82b3310ad9610c70138578a220e4358cd --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateCreditMemoEntityTest.xml @@ -0,0 +1,21 @@ +<?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\Sales\Test\TestCase\CreateCreditMemoEntityTest" summary="Create Credit Memo for Offline Payment Methods" ticketId="MAGETWO-59074"> + <variation name="CreateCreditMemoEntityWithConfigurableTestVariation1" ticketId="MAGETWO-12447"> + <data name="description" xsi:type="string">Assert items return to stock (partial refund)</data> + <data name="data/items_data/0/back_to_stock" xsi:type="string">Yes</data> + <data name="data/items_data/0/qty" xsi:type="string">1</data> + <data name="order/dataset" xsi:type="string">default</data> + <data name="order/data/entity_id/products" xsi:type="string">configurableProduct::configurable_with_qty_1</data> + <data name="order/data/price/dataset" xsi:type="string">full_refund</data> + <constraint name="Magento\Sales\Test\Constraint\AssertRefundSuccessCreateMessage" /> + <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertProductQtyDecreasedAfterCreditmemo" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/DuplicateProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/DuplicateProductEntityTest.xml index 62279a9fa579c99b8fce18ca6c39279834ce22c6..b069371fe5bec2aa39ea7c5ce6c7a3e6eb1d8977 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/DuplicateProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/DuplicateProductEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\Product\DuplicateProductEntityTest"> <variation name="DuplicateProductEntityTestVariation2" firstConstraint="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" method="test"> + <data name="tag" xsi:type="string">stable:no</data> <data name="productType" xsi:type="string">configurableProduct::default</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" next="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" next="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductDuplicateForm" /> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml index 3d58645d618ffe4f34beb84cd3a1d58212649148..d1066de26d66c608bc96198585bb8a92112b3fbf 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Catalog\Test\TestCase\Product\MassProductUpdateTest" summary="Edit Products Using Mass Actions" ticketId="MAGETWO-21128"> <variation name="MassProductUpdateTestVariation2" summary="Update stock data for simple and configurable"> + <data name="tag" xsi:type="string">stable:no</data> <data name="configData" xsi:type="string">product_flat</data> <data name="initialProducts/1" xsi:type="string">configurableProduct::out_of_stock</data> <data name="initialProducts/0" xsi:type="string">catalogProductSimple::out_of_stock</data> diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php index 7ff2be303d677a944e5c2391a509882ecb7d3e96..d3ab2ffa6b026e0ec0fe8d0d93655a49193e6127 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php @@ -32,6 +32,7 @@ class UpdateConfigurableProductEntityTest extends Scenario { /* tags */ const MVP = 'yes'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php index 4919d364dc6fa07592556bc66674588ec84589c0..ac6b26e85fbeb23e9a04c8a8b709e57da3b696ee 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/AbstractCurrencySymbolEntityTest.php @@ -97,7 +97,7 @@ abstract class AbstractCurrencySymbolEntityTest extends Injectable $this->currencyIndex->getCurrencyRateForm()->clickImportButton(); $this->currencyIndex->getCurrencyRateForm()->fillCurrencyUSDUAHRate(); if ($this->currencyIndex->getMessagesBlock()->isVisibleMessage('warning')) { - throw new \Exception($this->currencyIndex->getMessagesBlock()->getWarningMessages()); + throw new \Exception($this->currencyIndex->getMessagesBlock()->getWarningMessage()); } $this->currencyIndex->getFormPageActions()->save(); } diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php index 14a9d6f283b278228f178f4f3a14ffbe7786aceb..302f23104d959119f125fb6ab3b82b78078efa3d 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php @@ -27,6 +27,7 @@ class EditCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest { /* tags */ const MVP = 'no'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php index 8740b0000ff58324787941a92213528b6c24d11d..e49f25bc4fa181ffce4e442e1dbda485b8c5a76b 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php @@ -28,6 +28,7 @@ class ResetCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest { /* tags */ const MVP = 'no'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** 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 9802ef998048a8f9cfb8914b7288c4f119a667d1..70191dc828af7aecada34068c5d0e93cce4736ee 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 @@ -61,8 +61,8 @@ <field name="postcode" xsi:type="string">90230</field> <field name="country_id" xsi:type="string">United States</field> <field name="telephone" xsi:type="string">555-55-555-55</field> - <field name="default_billing" xsi:type="string">Yes</field> - <field name="default_shipping" xsi:type="string">No</field> + <field name="default_billing" xsi:type="string">No</field> + <field name="default_shipping" xsi:type="string">Yes</field> </dataset> <dataset name="US_address_1"> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml index 14e3a9642d1a5d649536d0b84070c8ae3e9210a6..766cf96b3d6447029384715ea57e06bf21dda1e8 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.xml @@ -19,6 +19,7 @@ <constraint name="Magento\Customer\Test\Constraint\AssertCustomerForm" /> </variation> <variation name="CreateCustomerBackendEntityTestVariation2" summary="Customer with prefix"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="customerAction" xsi:type="string">save</data> <data name="customer/data/group_id/dataset" xsi:type="string">Wholesale</data> <data name="customer/data/prefix" xsi:type="string">M</data> @@ -92,6 +93,7 @@ <constraint name="Magento\Customer\Test\Constraint\AssertCustomerBackendFormTitle" /> </variation> <variation name="CreateCustomerBackendEntityTestVariation7" summary="Create customer with custom customer group"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="customerAction" xsi:type="string">saveAndContinue</data> <data name="customer/data/website_id" xsi:type="string">Main Website</data> <data name="customer/data/group_id/dataset" xsi:type="string">customer_group_retail_customer</data> @@ -131,6 +133,7 @@ <constraint name="Magento\Customer\Test\Constraint\AssertCustomerBackendRequiredFields" /> </variation> <variation name="CreateCustomerBackendEntityTestVariation10" summary="Create customer with 2 websites and with different allowed countries."> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="customerAction" xsi:type="string">save</data> <data name="customer/data/website_id" xsi:type="string">Main Website</data> <data name="customer/data/group_id/dataset" xsi:type="string">General</data> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php index 64051195daa32a808536adb8afaa6a5100c51ce6..c354e733a6913263d3b2ea1cb72d63bb7434c9a2 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php @@ -29,6 +29,7 @@ class CreateCustomerGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php index 61771665c059ed1783c3e3820a8005601d91e631..1f00df69dfb578e552429ccdeb43a02254951d95 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php @@ -30,6 +30,7 @@ class DeleteCustomerAddressTest extends Injectable { /* tags */ const MVP = 'yes'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml index 18791441b1d20754360d80d7757bffe922d6c40e..b967fbd184526fd1d71fcf2055799842d0d018f1 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/GridSortingTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Ui\Test\TestCase\GridSortingTest" summary="Grid UI Component Sorting" ticketId="MAGETWO-41328"> <variation name="CustomerGridSorting"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Verify customer page grid sorting</data> <data name="columnsForSorting" xsi:type="array"> <item name="id" xsi:type="string">ID</item> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.xml index e86104e992deebf2b925e8a67b3346be7a6e2907..af57affcd7f07bf42182f444b16fc85ffe274ade 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Customer\Test\TestCase\MassAssignCustomerGroupTest" summary="Mass Assign Customer's Group to Customers" ticketId="MAGETWO-27892"> <variation name="MassAssignCustomerGroupTestVariation1"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="customerGroup/dataset" xsi:type="string">default</data> <constraint name="Magento\Customer\Test\Constraint\AssertMassActionSuccessUpdateMessage" /> <constraint name="Magento\Customer\Test\Constraint\AssertCustomerGroupInGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.xml index 2985252d82ffae55c5a932927623ecf7cf470aa3..cdbfd91ddbd49dddc040569252bb1a988c262a5c 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Customer\Test\TestCase\MassDeleteCustomerBackendEntityTest" summary="Customer Mass Delete" ticketId="MAGETWO-26848"> <variation name="MassDeleteCustomerBackendEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="customersQty" xsi:type="string">3</data> <data name="customersQtyToDelete" xsi:type="string">2</data> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml index 31a947ad1ab02771464cdf9f8cd93f01f2451718..96e78f58d78c8402a133184b633614e4e4fd20c7 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Customer\Test\TestCase\RegisterCustomerFrontendEntityTest" summary="Register New Customer" ticketId="MAGETWO-23546"> <variation name="RegisterCustomerFrontendEntityTestVariation1" summary="Register new customer"> + <data name="tag" xsi:type="string">stable:no</data> <data name="customer/data/firstname" xsi:type="string">john</data> <data name="customer/data/lastname" xsi:type="string">doe</data> <data name="customer/data/email" xsi:type="string">johndoe%isolation%@example.com</data> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml index c2132672d900a65fe81b3f011266d036cd390e91..7855fb0f17dd2d709a383722475ec1e95fbfa737 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Customer\Test\TestCase\UpdateCustomerBackendEntityTest" summary="Update Backend Customer" ticketId="MAGETWO-23881"> <variation name="UpdateCustomerBackendEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="initialCustomer/dataset" xsi:type="string">default</data> <data name="customer/data/group_id/dataset" xsi:type="string">Wholesale</data> <data name="customer/data/prefix" xsi:type="string">%isolation%Prefix_</data> @@ -44,6 +45,7 @@ <constraint name="Magento\Customer\Test\Constraint\AssertCustomerInGrid" /> </variation> <variation name="UpdateCustomerBackendEntityTestVariation3" summary="Address with alphanumeric zip"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="initialCustomer/dataset" xsi:type="string">default</data> <data name="customer/data/group_id/dataset" xsi:type="string">Retailer</data> <data name="customer/data/prefix" xsi:type="string">%isolation%Prefix_</data> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php index 7fda95c0be7d2e48e58cb2a01317704cc54a0b57..bd21e9aca690525910b5500e69e6b5913449d2e5 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php @@ -32,6 +32,7 @@ class UpdateCustomerGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.xml index e2f49d40cac7395734acc42783f5fce6b0c74083..9d12218ccf0dddf72b15a21db85e6c211848f0b8 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.xml @@ -24,6 +24,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCart" /> </variation> <variation name="CreateDownloadableProductEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Create product with default set links</data> <data name="product/data/name" xsi:type="string">DownloadableProduct_%isolation%</data> <data name="product/data/sku" xsi:type="string">DownloadableProduct_%isolation%</data> @@ -53,6 +54,7 @@ <data name="product/data/downloadable_sample/dataset" xsi:type="string">with_two_samples</data> <data name="product/data/downloadable_links/dataset" xsi:type="string">with_two_separately_links</data> <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" /> @@ -91,6 +93,7 @@ <data name="product/data/downloadable_links/dataset" xsi:type="string">with_three_links</data> <data name="product/data/custom_options/dataset" xsi:type="string">two_options</data> <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductCustomOptionsOnProductPage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> @@ -118,6 +121,7 @@ <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" /> </variation> <variation name="CreateDownloadableProductEntityTestVariation7"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Create product with manage stock</data> <data name="product/data/name" xsi:type="string">DownloadableProduct_%isolation%</data> <data name="product/data/sku" xsi:type="string">DownloadableProduct_%isolation%</data> @@ -135,6 +139,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" /> </variation> <variation name="CreateDownloadableProductEntityTestVariation8"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Create product without tax class id</data> <data name="product/data/name" xsi:type="string">DownloadableProduct_%isolation%</data> <data name="product/data/sku" xsi:type="string">DownloadableProduct_%isolation%</data> @@ -166,6 +171,7 @@ <data name="product/data/custom_options/dataset" xsi:type="string">default</data> <data name="product/data/custom_options/import_products" xsi:type="string">catalogProductSimple::with_two_custom_option,catalogProductSimple::with_all_custom_option</data> <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" /> @@ -189,6 +195,7 @@ <data name="product/data/downloadable_links/dataset" xsi:type="string">with_three_links</data> <data name="product/data/custom_options/dataset" xsi:type="string">default</data> <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> @@ -210,6 +217,7 @@ <data name="product/data/downloadable_links/dataset" xsi:type="string">with_three_links</data> <data name="product/data/custom_options/dataset" xsi:type="string">default</data> <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" /> @@ -278,6 +286,7 @@ <data name="product/data/downloadable_links/dataset" xsi:type="string">with_two_separately_links</data> <data name="product/data/tier_price/dataset" xsi:type="string">default</data> <data name="product/data/url_key" xsi:type="string">downloadableproduct-%isolation%</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" /> <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableProductForm" /> @@ -285,6 +294,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPage" /> </variation> <variation name="CreateDownloadableProductEntityTestVariation16" summary="Create downloadable product and assign it to custom website"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/data/name" xsi:type="string">DownloadableProduct_%isolation%</data> <data name="product/data/sku" xsi:type="string">DownloadableProduct_%isolation%</data> <data name="product/data/price/value" xsi:type="string">350</data> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/DuplicateProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/DuplicateProductEntityTest.xml index be38a73902cd71a2a893b0f2aaf94ac70ebb4273..8e844fa90ddf94a48ed09bc1b7ed9285b51ef555 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/DuplicateProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/DuplicateProductEntityTest.xml @@ -9,6 +9,7 @@ <testCase name="Magento\Catalog\Test\TestCase\Product\DuplicateProductEntityTest"> <variation name="DuplicateProductEntityTestVariation3" firstConstraint="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" method="test"> <data name="productType" xsi:type="string">downloadableProduct::default</data> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" next="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" /> <constraint name="Magento\Catalog\Test\Constraint\AssertProductDuplicateMessage" next="Magento\Downloadable\Test\Constraint\AssertDownloadableDuplicateForm" /> <constraint name="Magento\Downloadable\Test\Constraint\AssertDownloadableDuplicateForm" next="Magento\Catalog\Test\Constraint\AssertProductDuplicatedInGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/TaxCalculationTest.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/TaxCalculationTest.xml index 87a124814fc222b7ae21df4b47b6b75284fdcdf0..e2afcbeb7cce01be9b5200b8a06c1af4392490f4 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/TaxCalculationTest.xml +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/TaxCalculationTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Tax\Test\TestCase\TaxCalculationTest"> <variation name="DownloadableTaxCalculationTestVariation1" summary="Downloadable product with sales rule, customer tax equals store tax and catalog price excluding tax" ticketId="MAGETWO-32076"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_incl, display_excluding_including_tax</data> <data name="product" xsi:type="string">downloadableProduct::with_two_separately_links_special_price_and_category</data> <data name="salesRule" xsi:type="string">active_sales_rule_for_all_groups_no_coupon</data> @@ -34,6 +35,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> </variation> <variation name="DownloadableTaxCalculationTestVariation2" summary="Downloadable product with catalog rule, customer tax greater than store tax and catalog price excluding tax" ticketId="MAGETWO-32076"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="configData" xsi:type="string">total_cat_excl_ship_incl_after_disc_on_incl, display_including_tax</data> <data name="product" xsi:type="string">downloadableProduct::with_two_separately_links_special_price_and_category</data> <data name="catalogRule" xsi:type="string">catalog_price_rule_all_groups</data> @@ -53,6 +55,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendIncludingTax" /> </variation> <variation name="DownloadableTaxCalculationTestVariation4" summary="Downloadable product with catalog rule, customer tax greater than store tax and catalog price including tax" ticketId="MAGETWO-32076"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="configData" xsi:type="string">total_cat_incl_ship_excl_before_disc_on_excl, display_excluding_including_tax</data> <data name="product" xsi:type="string">downloadableProduct::with_two_separately_links_custom_options_and_category</data> <data name="catalogRule" xsi:type="string">catalog_price_rule_all_groups</data> @@ -77,6 +80,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> </variation> <variation name="DownloadableTaxCalculationTestVariation6" summary="Downloadable product with catalog rule, customer tax equals store tax and catalog price including tax" ticketId="MAGETWO-32076"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="configData" xsi:type="string">total_cat_incl_ship_excl_before_disc_on_excl</data> <data name="product" xsi:type="string">downloadableProduct::with_two_separately_links_custom_options_and_category</data> <data name="catalogRule" xsi:type="string">catalog_price_rule_all_groups</data> diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php index 276cc08e8efb74f05c70868cdf67a77f452bb44a..91281de3cdbdaf1308d0aca1473aaf7aab808688 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php @@ -37,6 +37,7 @@ class UpdateDownloadableProductEntityTest extends Injectable { /* tags */ const MVP = 'yes'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php index dc86b6479757e00564877fa3f52c7e5c6c3ef4f5..69bae8412db119983edf5f99e73da7399af5f9a7 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php @@ -30,6 +30,7 @@ class CreateEmailTemplateEntityTest extends Injectable /* tags */ const MVP = 'yes'; const DOMAIN = 'PS'; + const TO_MAINTAIN = 'yes'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.xml b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.xml index 3913817d8f3205105356b39d39e48bc212e6ca66..6226713f316c5f0a90f06291a3a8160a65ac912f 100644 --- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.xml +++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.xml @@ -27,6 +27,7 @@ <constraint name="Magento\GiftMessage\Test\Constraint\AssertGiftMessageInFrontendOrder" /> </variation> <variation name="CheckoutWithGiftMessagesTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="products/1" xsi:type="string">catalogProductVirtual::default</data> <data name="customer/dataset" xsi:type="string">default</data> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml index 47592328f39c10d7a257b014de640e82f969c639..a8a2aebbf2f259875cf55fecd3ac5d59f7b2b52c 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml @@ -57,6 +57,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" /> </variation> <variation name="CreateGroupedProductEntityTestVariation5" summary="Create with no required products"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/data/url_key" xsi:type="string">test-grouped-product-%isolation%</data> <data name="product/data/name" xsi:type="string">GroupedProduct %isolation%</data> <data name="product/data/sku" xsi:type="string">GroupedProduct_sku%isolation%</data> @@ -109,6 +110,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> </variation> <variation name="CreateGroupedProductEntityTestVariation10" summary="Create Grouped Product and Assign it on Custom Website"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/data/url_key" xsi:type="string">test-grouped-product-%isolation%</data> <data name="product/data/name" xsi:type="string">GroupedProduct %isolation%</data> <data name="product/data/sku" xsi:type="string">GroupedProduct_sku%isolation%</data> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/DeleteProductFromMiniShoppingCartTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/DeleteProductFromMiniShoppingCartTest.xml index 91c26ddb6acbc1adf214828b7cbde9b041b81eb0..92a842ee5a71e4ea2bc8a2eeba6fd3bdc6bbbeb8 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/DeleteProductFromMiniShoppingCartTest.xml +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/DeleteProductFromMiniShoppingCartTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Checkout\Test\TestCase\DeleteProductFromMiniShoppingCartTest" summary="Delete Grouped Product from Mini Shopping Cart" ticketId="MAGETWO-29104"> <variation name="DeleteGroupedProductFromMiniShoppingCartTestVariation"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">groupedProduct::default</data> <data name="deletedProductIndex" xsi:type="string">0</data> <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" /> diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.xml index d2ae0836e5e7654ddc37288c582ebe9dece27e65..11f854749d3fdcde8d149fcc6e1519e359dee3d1 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\GroupedProduct\Test\TestCase\UpdateGroupedProductEntityTest" summary="Update Grouped Product" ticketId="MAGETWO-26462"> <variation name="UpdateGroupedProductEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="originalProduct/dataset" xsi:type="string">grouped_product_out_of_stock</data> <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data> <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data> @@ -21,6 +22,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" /> </variation> <variation name="UpdateGroupedProductEntityTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="originalProduct/dataset" xsi:type="string">default</data> <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data> <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data> @@ -31,6 +33,7 @@ <constraint name="Magento\GroupedProduct\Test\Constraint\AssertGroupedProductForm" /> </variation> <variation name="UpdateGroupedProductEntityTestVariation3"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="originalProduct/dataset" xsi:type="string">default</data> <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data> <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data> @@ -42,6 +45,7 @@ <constraint name="Magento\GroupedProduct\Test\Constraint\AssertGroupedProductForm" /> </variation> <variation name="UpdateGroupedProductEntityTestVariation4"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="originalProduct/dataset" xsi:type="string">default</data> <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data> <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data> @@ -52,6 +56,7 @@ <constraint name="Magento\GroupedProduct\Test\Constraint\AssertSpecialPriceOnGroupedProductPage" /> </variation> <variation name="UpdateGroupedProductEntityTestVariation5"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="originalProduct/dataset" xsi:type="string">default</data> <data name="product/data/name" xsi:type="string">GroupedProduct_edited %isolation%</data> <data name="product/data/sku" xsi:type="string">GroupedProduct_sku_edited %isolation%</data> diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php index 03dbfee05ca6973d90da4a4205eb1b64f9f2edca..bf4886a9f208d4a9bf308ee8f5f8b26daf9c6d6e 100644 --- a/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php +++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php @@ -21,7 +21,7 @@ class WebConfiguration extends Form * * @var string */ - protected $next = "[ng-click*='next']"; + protected $next = "[ng-click*='validateUrl']"; /** * 'Advanced Options' locator. diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml index e09d2a23559b97a904e59899177177ae38f9b93f..5965aa7ce3c581264c73106afd52197be71af583 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml @@ -20,6 +20,7 @@ <constraint name="Magento\Integration\Test\Constraint\AssertIntegrationInGrid" /> </variation> <variation name="UpdateIntegrationEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="integration/data/name" xsi:type="string">Integration_%isolation%</data> <data name="integration/data/email" xsi:type="string">-</data> <data name="integration/data/endpoint" xsi:type="string">-</data> diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php index a79ea3995eeff08464befe26a71e61171af3bc2e..0203cf89fe7d2d5b4745a65625df5cb14602be8d 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php @@ -31,6 +31,7 @@ class ActionNewsletterTemplateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.xml index 13b499fca5e3c40754fd78f54b158361514bbb8a..206e2d01468e7e03300fd328e798bd6b70069b73 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Newsletter\Test\TestCase\PreviewNewsletterTemplateEntityTest" summary="Newsletter Template Preview" ticketId="MAGETWO-51979"> <variation name="PreviewNewsletterTemplateEntityTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="newsletter/dataset" xsi:type="string">default</data> <constraint name="Magento\Newsletter\Test\Constraint\AssertNewsletterPreview" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/ExpressCheckout.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/ExpressCheckout.php index d83ae0c53ec0a575ba11280b9a8731bbe23a6f8a..6e4849669568851cbe4787766c6cf8b2f630e9e6 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/ExpressCheckout.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/ExpressCheckout.php @@ -20,8 +20,6 @@ class ExpressCheckout extends Block * @var array */ private $fields = [ - 'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_alternative_payment_methods_express_' . - 'checkout_us_express_checkout_required_express_checkout_required_express_checkout_business_account', 'API Username' => '#payment_us_paypal_alternative_payment_methods_express_checkout_us_express_checkout_' . 'required_express_checkout_required_express_checkout_api_username', 'API Password' => '#payment_us_paypal_alternative_payment_methods_express_checkout_us_express_checkout_' . @@ -72,8 +70,6 @@ class ExpressCheckout extends Block */ public function specifyCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account']) - ->setValue('test@test.com'); $this->_rootElement->find($this->fields['API Username'])->setValue('1'); $this->_rootElement->find($this->fields['API Password'])->setValue('1'); $this->_rootElement->find($this->fields['API Signature'])->setValue('1'); @@ -86,7 +82,6 @@ class ExpressCheckout extends Block */ public function clearCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue(''); $this->_rootElement->find($this->fields['API Username'])->setValue(''); $this->_rootElement->find($this->fields['API Password'])->setValue(''); $this->_rootElement->find($this->fields['API Signature'])->setValue(''); diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowLink.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowLink.php index de6eb107c61ce5e6b63451abdea0473351ddde43..f1af6acb6174e1b462651b7887d80159d6910952 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowLink.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowLink.php @@ -20,8 +20,6 @@ class PayflowLink extends Block * @var array */ private $fields = [ - 'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_payment_gateways_payflow_link_us_' . - 'payflow_link_required_payflow_link_payflow_link_business_account', 'Partner' => '#payment_us_paypal_payment_gateways_payflow_link_us_payflow_link_required_payflow_link_payflow_' . 'link_partner', 'Vendor' => '#payment_us_paypal_payment_gateways_payflow_link_us_payflow_link_required_payflow_link_payflow_' . @@ -60,8 +58,6 @@ class PayflowLink extends Block */ public function specifyCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account']) - ->setValue('test@test.com'); $this->_rootElement->find($this->fields['Partner'])->setValue('1'); $this->_rootElement->find($this->fields['Vendor'])->setValue('1'); $this->_rootElement->find($this->fields['User'])->setValue('1'); @@ -75,7 +71,6 @@ class PayflowLink extends Block */ public function clearCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue(''); $this->_rootElement->find($this->fields['Partner'])->setValue(''); $this->_rootElement->find($this->fields['Vendor'])->setValue(''); $this->_rootElement->find($this->fields['User'])->setValue(''); diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowPro.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowPro.php index e3b01aa3af9a0dfa4517ad3fe4b527eec9d30ad0..1db07ac435a37ed9c9d9d237f62b7debed956861 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowPro.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PayflowPro.php @@ -20,8 +20,6 @@ class PayflowPro extends Block * @var array */ private $fields = [ - 'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_payment_gateways_paypal_payflowpro_' . - 'with_express_checkout_paypal_payflow_required_paypal_payflow_api_settings_business_account', 'Partner' => '#payment_us_paypal_payment_gateways_paypal_payflowpro_with_express_checkout_paypal_payflow_' . 'required_paypal_payflow_api_settings_partner', 'Vendor' => '#payment_us_paypal_payment_gateways_paypal_payflowpro_with_express_checkout_paypal_payflow_' . @@ -60,8 +58,6 @@ class PayflowPro extends Block */ public function specifyCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account']) - ->setValue('test@test.com'); $this->_rootElement->find($this->fields['Partner'])->setValue('1'); $this->_rootElement->find($this->fields['Vendor'])->setValue('1'); $this->_rootElement->find($this->fields['User'])->setValue('1'); @@ -75,7 +71,6 @@ class PayflowPro extends Block */ public function clearCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue(''); $this->_rootElement->find($this->fields['Partner'])->setValue(''); $this->_rootElement->find($this->fields['Vendor'])->setValue(''); $this->_rootElement->find($this->fields['User'])->setValue(''); diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsAdvanced.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsAdvanced.php index cd6d1a5b1b38a016382ffa2e68ab73bd566c4116..87adb729a1646e6eb5b61e8e167d2eed20111e4e 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsAdvanced.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsAdvanced.php @@ -20,8 +20,6 @@ class PaymentsAdvanced extends Block * @var array */ private $fields = [ - 'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_group_all_in_one_payflow_advanced_' . - 'required_settings_payments_advanced_business_account', 'Partner' => '#payment_us_paypal_group_all_in_one_payflow_advanced_required_settings_payments_advanced_partner', 'Vendor' => '#payment_us_paypal_group_all_in_one_payflow_advanced_required_settings_payments_advanced_vendor', 'User' => '#payment_us_paypal_group_all_in_one_payflow_advanced_required_settings_payments_advanced_user', @@ -54,8 +52,6 @@ class PaymentsAdvanced extends Block */ public function specifyCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account']) - ->setValue('test@test.com'); $this->_rootElement->find($this->fields['Partner'])->setValue('1'); $this->_rootElement->find($this->fields['Vendor'])->setValue('1'); $this->_rootElement->find($this->fields['User'])->setValue('1'); @@ -69,7 +65,6 @@ class PaymentsAdvanced extends Block */ public function clearCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue(''); $this->_rootElement->find($this->fields['Partner'])->setValue(''); $this->_rootElement->find($this->fields['Vendor'])->setValue(''); $this->_rootElement->find($this->fields['User'])->setValue(''); diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsPro.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsPro.php index cd146aa8f809cf5de0cbddcb02be83a19e59928f..55fd7444ba50ad8dbf9662b758b10d7a70ee6c6d 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsPro.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/Block/System/Config/PaymentsPro.php @@ -20,8 +20,6 @@ class PaymentsPro extends Block * @var array */ private $fields = [ - 'Email Associated with PayPal Merchant Account' => '#payment_us_paypal_group_all_in_one_wpp_usuk_paypal_' . - 'payflow_required_paypal_payflow_api_settings_business_account', 'Partner' => '#payment_us_paypal_group_all_in_one_wpp_usuk_paypal_payflow_required_paypal_payflow_api_' . 'settings_partner', 'Vendor' => '#payment_us_paypal_group_all_in_one_wpp_usuk_paypal_payflow_required_paypal_payflow_api_' . @@ -60,8 +58,6 @@ class PaymentsPro extends Block */ public function specifyCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account']) - ->setValue('test@test.com'); $this->_rootElement->find($this->fields['Partner'])->setValue('1'); $this->_rootElement->find($this->fields['Vendor'])->setValue('1'); $this->_rootElement->find($this->fields['User'])->setValue('1'); @@ -75,7 +71,6 @@ class PaymentsPro extends Block */ public function clearCredentials() { - $this->_rootElement->find($this->fields['Email Associated with PayPal Merchant Account'])->setValue(''); $this->_rootElement->find($this->fields['Partner'])->setValue(''); $this->_rootElement->find($this->fields['Vendor'])->setValue(''); $this->_rootElement->find($this->fields['User'])->setValue(''); diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.xml index 9dfcc4d8bac35141a99400cb88df7e4206dfce44..0bcf0db70b2fba7a98b02e326f7d986d5f3c95f9 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.xml +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\ProductVideo\Test\TestCase\AddProductVideoTest" summary="Add Video to PCF" ticketId="MAGETWO-43672"> <variation name="AddProductVideoEntityTestVariation1" summary="Add youtube video with all available fields filled in"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/dataset" xsi:type="string">product_with_video_youtube</data> <data name="configData" xsi:type="string">youtube_api_key,play_if_base</data> <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoCategoryView" /> @@ -15,6 +16,7 @@ <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> </variation> <variation name="AddProductVideoEntityTestVariation2" summary="Add vimeo video with all available fields filled in"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/dataset" xsi:type="string">product_with_video_vimeo</data> <data name="configData" xsi:type="string">play_if_base</data> <constraint name="Magento\ProductVideo\Test\Constraint\AssertVideoCategoryView" /> diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.xml b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.xml index 78a7fe00ab9f43227ffe4828769dd3b627e8cfce..26df238f11b286f47d4a923084cc56dd7d6985dd 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.xml +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\ProductVideo\Test\TestCase\DeleteProductVideoTest" summary="Delete Video from PCF - Delete video" ticketId="MAGETWO-43660"> <variation name="DeleteVideoEntityTestVariation1" summary="Delete video youtube" ticketId="MAGETWO-43660"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/dataset" xsi:type="string">product_with_video_youtube</data> <data name="configData" xsi:type="string">youtube_api_key,play_if_base</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductNoImageInGrid" /> @@ -15,6 +16,7 @@ <constraint name="Magento\ProductVideo\Test\Constraint\AssertNoVideoProductView" /> </variation> <variation name="DeleteVideoEntityTestVariation2" summary="Delete video vimeo" ticketId="MAGETWO-43660"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/dataset" xsi:type="string">product_with_video_vimeo</data> <data name="configData" xsi:type="string">play_if_base</data> <constraint name="Magento\Catalog\Test\Constraint\AssertProductNoImageInGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php index 30df076817dff80416933e9bccf11d598fb28a87..a02ba30f716ecea19e2ec06a30e0627afcd997a6 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php @@ -33,8 +33,9 @@ use Magento\Mtf\TestCase\Injectable; class UpdateProductVideoTest extends Injectable { /* tags */ - const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; + const TEST_TYPE = 'extended_acceptance_test'; const MVP = 'yes'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php index 5930e63b9d3bd367a4c93fb241cc64613fa9aea6..95c9d518a391ddb679c3d5a4118ef79391d2cdca 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php @@ -34,6 +34,7 @@ class AbandonedCartsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php index cacb6e5a329bff99eb28fd62118f440c569ade46..7dc9b6106b7bb20d8507af83840abb030e9b24e7 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php @@ -31,6 +31,7 @@ class CustomersOrderCountReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.xml index 6e37965603c787083bfa0a9b337d1b770df3bfec..3a25f81d37fb6316e27a891a573503778443d57b 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.xml @@ -8,16 +8,19 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Reports\Test\TestCase\DownloadProductsReportEntityTest" summary="Download Products Report" ticketId="MAGETWO-28823"> <variation name="DownloadProductsReportEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="order/dataset" xsi:type="string">downloadable_product</data> <data name="downloads" xsi:type="string">1</data> <constraint name="Magento\Reports\Test\Constraint\AssertDownloadsReportResult" /> </variation> <variation name="DownloadProductsReportEntityTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="order/dataset" xsi:type="string">two_downloadable_product</data> <data name="downloads" xsi:type="string">2</data> <constraint name="Magento\Reports\Test\Constraint\AssertDownloadsReportResult" /> </variation> <variation name="DownloadProductsReportEntityTestVariation3"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="order/dataset" xsi:type="string">downloadable_product</data> <data name="downloads" xsi:type="string">0</data> <constraint name="Magento\Reports\Test\Constraint\AssertDownloadsReportResult" /> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.xml index c484c94a976f6340706e0b6f5ab045b16c83caf7..582d41a9d3bb2957abdb136a0032c051f3b5d949 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Reports\Test\TestCase\NewAccountsReportEntityTest" summary="New Accounts Report" ticketId="MAGETWO-27742"> <variation name="NewAccountsReportEntityTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="total" xsi:type="string">1</data> <data name="customersReport/report_from" xsi:type="string">m/d/Y</data> @@ -16,6 +17,7 @@ <constraint name="Magento\Reports\Test\Constraint\AssertNewAccountsReportTotalResult" /> </variation> <variation name="NewAccountsReportEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="total" xsi:type="string">1</data> <data name="customersReport/report_from" xsi:type="string">m/d/Y</data> @@ -24,6 +26,7 @@ <constraint name="Magento\Reports\Test\Constraint\AssertNewAccountsReportTotalResult" /> </variation> <variation name="NewAccountsReportEntityTestVariation3"> + <data name="tag" xsi:type="string">stable:no</data> <data name="customer/dataset" xsi:type="string">default</data> <data name="total" xsi:type="string">1</data> <data name="customersReport/report_from" xsi:type="string">m/d/Y</data> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php index 7d0d13862e7720b0b63516639d8b4968909c66cc..dc09819ab98790fd7b6b8acf6b69aad614ef7ccd 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php @@ -28,6 +28,7 @@ class OrderedProductsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php index 0d59b989fc25fc162e450ce719c96413229c45fe..8d686421a524bfc610ab22e16cc6780e559d32c9 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php @@ -34,6 +34,7 @@ class SalesCouponReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php index 3ebfd4746a858f92381e9c58e8b20cc84356c0be..b8e5a5276d616061eb1e2e0c30fe74801fb96479 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php @@ -37,6 +37,7 @@ class SalesInvoiceReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.xml index b1957b6315765538644619f27390d06ae0dd7aa0..1d8adebd6befdc04d23a4b6653eafeb3ce26d410 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.xml @@ -21,6 +21,7 @@ <constraint name="Magento\Reports\Test\Constraint\AssertSalesReportTotalResult" /> </variation> <variation name="SalesOrderReportEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="order/dataset" xsi:type="string">default</data> <data name="order/data/price/dataset" xsi:type="string">full_invoice</data> <data name="salesReport/report_type" xsi:type="string">Order Created</data> @@ -34,6 +35,7 @@ <constraint name="Magento\Reports\Test\Constraint\AssertSalesReportTotalResult" /> </variation> <variation name="SalesOrderReportEntityTestVariation3"> + <data name="tag" xsi:type="string">stable:no</data> <data name="order/dataset" xsi:type="string">default</data> <data name="order/data/price/dataset" xsi:type="string">full_invoice</data> <data name="salesReport/report_type" xsi:type="string">Order Updated</data> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.xml index a3b971ec5a8caf5332c9be61a1397a28c4e4ead0..927e461fc2181d818ecaca45a57d9876f44f2965 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.xml @@ -20,6 +20,7 @@ <constraint name="Magento\Reports\Test\Constraint\AssertRefundReportIntervalResult" /> </variation> <variation name="SalesRefundsReportEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">assert refunds month report</data> <data name="order/dataset" xsi:type="string">default</data> <data name="order/data/price/dataset" xsi:type="string">full_invoice</data> @@ -32,6 +33,7 @@ <constraint name="Magento\Reports\Test\Constraint\AssertRefundReportIntervalResult" /> </variation> <variation name="SalesRefundsReportEntityTestVariation3"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">assert refund Daily report</data> <data name="order/dataset" xsi:type="string">default</data> <data name="order/data/price/dataset" xsi:type="string">full_invoice</data> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.xml index df6eb7759fd5558110925b224de31d72090702c6..69440d5f15e3fe9508ae7d8a1efd3d31c8940417 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.xml @@ -22,6 +22,7 @@ <constraint name="Magento\Reports\Test\Constraint\AssertTaxReportNotInGrid" /> </variation> <variation name="SalesTaxReportEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="orderSteps" xsi:type="string">invoice</data> <data name="taxRule/dataset" xsi:type="string">custom_rule</data> <data name="order/dataset" xsi:type="string">default</data> @@ -37,6 +38,7 @@ <constraint name="Magento\Reports\Test\Constraint\AssertTaxReportInGrid" /> </variation> <variation name="SalesTaxReportEntityTestVariation3"> + <data name="tag" xsi:type="string">stable:no</data> <data name="orderSteps" xsi:type="string">invoice,shipment</data> <data name="taxRule/dataset" xsi:type="string">custom_rule</data> <data name="order/dataset" xsi:type="string">default</data> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php index 905fa8fb70f0cebff985cf4a99d193359969e5e1..6c22348179897ffa0d533dba563a5fce06657632 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php @@ -33,6 +33,7 @@ class ViewedProductsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php index 9130c5285848e2d04f5978403c23ae0b2278ff16..251cbd75a793f8a0382180041b20529784526e57 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php @@ -34,6 +34,7 @@ class CreateProductReviewBackendEntityTest extends Injectable { /* tags */ const MVP = 'no'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.xml b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.xml index 786203e93f24d8e29ba779c8ed0ad3b4b66f0626..8cd4e44b7622a2de828b9f2d9a96738a41ae2911 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Review\Test\TestCase\CreateProductReviewFrontendEntityTest" summary="Create Frontend Product Review" ticketId="MAGETWO-25519"> <variation name="CreateProductReviewFrontendEntityTestVariation1" summary="Create product review with rating"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="review/data/type" xsi:type="string">Guest</data> <data name="review/data/nickname" xsi:type="string">name_%isolation%</data> <data name="review/data/title" xsi:type="string">title_%isolation%</data> diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php index fc58266356223d48457d54a14d508a01712acc4c..3f1adc16694ccee1b7ba8aec945e71d8d2b30d52 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php @@ -43,6 +43,7 @@ class ManageProductReviewFromCustomerPageTest extends Injectable { /* tags */ const MVP = 'no'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.xml b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.xml index 5d731c736fd69245c110161823374f3ca2843ccc..86dca577d0094e3d3fd20e15b1a9b22eabd75a1e 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.xml +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Review\Test\TestCase\UpdateProductReviewEntityOnProductPageTest" summary="Update Product Review from Product Page" ticketId="MAGETWO-27743"> <variation name="UpdateProductReviewEntityOnProductPageTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="rating" xsi:type="string">3</data> <data name="review/data/status_id" xsi:type="string">Approved</data> <data name="productRating/data/select_stores" xsi:type="string">Main Website/Main Website Store/Default Store View</data> diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.xml b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.xml index 549c3c3ddc3a8d91292e1169c8fe3084f628b2e9..71c40ca27fac05b1b1c3b4e4c6609d98e788ea0b 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Review\Test\TestCase\UpdateProductReviewEntityTest" summary="Update Product Review" ticketId="MAGETWO-25604"> <variation name="UpdateProductReviewEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="reviewInitial/dataset" xsi:type="string">review_for_simple_product_with_rating</data> <data name="review/data/nickname" xsi:type="string">name_upd_%isolation%</data> <data name="review/data/title" xsi:type="string">title_upd_%isolation%</data> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php index c25b96a624bfda79865d81f73f3208f0bc38d74a..9e0c1517d3d7eae9c8945b6c822928eaef0ac64f 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php @@ -339,6 +339,7 @@ class Create extends Block $this->getTemplateBlock()->waitLoader(); $this->_rootElement->find($this->orderMethodsSelector)->click(); $this->getBillingMethodBlock()->selectPaymentMethod($paymentCode, $creditCard); + $this->_rootElement->click(); $this->getTemplateBlock()->waitLoader(); } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php new file mode 100644 index 0000000000000000000000000000000000000000..f48e9e198210c02a66870674cbc35178b7d91df4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertProductQtyDecreasedAfterCreditmemo.php @@ -0,0 +1,110 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Constraint; + +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit; +use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Mtf\Fixture\FixtureInterface; +use Magento\Mtf\ObjectManager; +use Magento\Mtf\System\Event\EventManagerInterface; +use Magento\Sales\Test\Fixture\OrderInjectable; + +/** + * Class AssertProductQtyDecreasedAfterCreditmemo + */ +class AssertProductQtyDecreasedAfterCreditmemo extends AbstractConstraint +{ + /** + * @var FixtureFactory + */ + protected $fixtureFactory; + + /** + * Skip fields for create product fixture. + * + * @var array + */ + protected $skipFields = [ + 'attribute_set_id', + 'website_ids', + 'checkout_data', + 'type_id', + 'price', + ]; + + /** + * AssertFirstProductForm constructor. + * @param ObjectManager $objectManager + */ + public function __construct( + ObjectManager $objectManager, + EventManagerInterface $eventManager, + FixtureFactory $fixtureFactory + ) { + $this->fixtureFactory = $fixtureFactory; + parent::__construct($objectManager, $eventManager); + } + + /** + * Assert form data equals fixture data + * + * @param OrderInjectable $order + * @param array $data + * @param CatalogProductIndex $productGrid + * @param CatalogProductEdit $productPage + * @return void + */ + public function processAssert( + OrderInjectable $order, + array $data, + CatalogProductIndex $productGrid, + CatalogProductEdit $productPage + ) { + $product = $this->getProduct($order, $data); + $this->objectManager->get(\Magento\Catalog\Test\Constraint\AssertProductForm::class)->processAssert( + $product, + $productGrid, + $productPage + ); + } + + /** + * Get product's fixture. + * + * @param OrderInjectable $order + * @param array $data + * @param int $index [optional] + * @return FixtureInterface + */ + protected function getProduct(OrderInjectable $order, array $data, $index = 0) + { + if (!isset($data['items_data'][$index]['back_to_stock']) + || $data['items_data'][$index]['back_to_stock'] != 'Yes' + ) { + return $order->getEntityId()['products'][$index]; + } + $product = $order->getEntityId()['products'][$index]; + $productData = $product->getData(); + $checkoutDataQty = $productData['checkout_data']['qty']; + $productData['quantity_and_stock_status']['qty'] -= ($checkoutDataQty - $data['items_data'][$index]['qty']); + + $productData = array_diff_key($productData, array_flip($this->skipFields)); + + return $this->fixtureFactory->create(get_class($product), ['data' => $productData]); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Product qty was decreased after creditmemo creation.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable/Price.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable/Price.xml index 3e2dfdd7125074ac64fdc6c7a39cdc762348585a..3da1f91925e0a1274cbe317d36f2bc40271cbeb6 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable/Price.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable/Price.xml @@ -43,5 +43,12 @@ <item name="grand_creditmemo_total" xsi:type="string">110</item> </field> </dataset> + + <dataset name="free_invoice"> + <field name="0" xsi:type="array"> + <item name="grand_order_total" xsi:type="string">0</item> + <item name="grand_invoice_total" xsi:type="string">0</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml index b65b9a31f72f3d7ff7290afb4393edeaf73679bc..e839681907c6d291b0855f138fa7d52c9b1dd4fa 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\CancelCreatedOrderTest" summary="Cancel Created Order for Offline Payment Methods" ticketId="MAGETWO-28191"> <variation name="CancelCreatedOrderTestVariationWithCheckMoneyOrderPaymentMethod" summary="Cancel order with check/money order payment method and check status on storefront"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="order/dataset" xsi:type="string">default</data> <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::default,catalogProductSimple::default</data> <data name="status" xsi:type="string">Canceled</data> @@ -17,6 +18,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" /> </variation> <variation name="CancelCreatedOrderTestVariationWithZeroSubtotalCheckout" summary="Cancel order with zero subtotal checkout payment method and check status on storefront"> + <data name="tag" xsi:type="string">stable:no</data> <data name="order/dataset" xsi:type="string">default</data> <data name="order/data/payment_auth_expiration/method" xsi:type="string">free</data> <data name="order/data/shipping_method" xsi:type="string">freeshipping_freeshipping</data> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php index 9d19d10f4d40c6c3e317a97e7e83cd3c79e6f8ae..92b341bef2675fe635f804da2d9a17c5eea54c49 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php @@ -90,32 +90,7 @@ class CreateCreditMemoEntityTest extends Injectable return [ 'ids' => ['creditMemoIds' => $result['creditMemoIds']], - 'product' => $this->getProduct($order, $data), 'customer' => $order->getDataFieldConfig('customer_id')['source']->getCustomer() ]; } - - /** - * Get product's fixture. - * - * @param OrderInjectable $order - * @param array $data - * @param int $index [optional] - * @return FixtureInterface - */ - protected function getProduct(OrderInjectable $order, array $data, $index = 0) - { - if (!isset($data['items_data'][$index]['back_to_stock']) - || $data['items_data'][$index]['back_to_stock'] != 'Yes' - ) { - return $order->getEntityId()['products'][$index]; - } - $product = $order->getEntityId()['products'][$index]; - $productData = $product->getData(); - $checkoutDataQty = $productData['checkout_data']['qty']; - $productData['quantity_and_stock_status']['qty'] -= ($checkoutDataQty - $data['items_data'][$index]['qty']); - $productData = array_diff_key($productData, array_flip($this->skipFields)); - - return $this->fixtureFactory->create(get_class($product), ['data' => $productData]); - } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml index 02b9640acbea4159c0560e8a4727a13cc36e1199..b2cf9843598f48af778edda5a4240409fd9d0365 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml @@ -22,7 +22,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertRefundOrderStatusInCommentsHistory" /> <constraint name="Magento\Sales\Test\Constraint\AssertOrderCommentsHistoryNotifyStatus" /> <constraint name="Magento\Sales\Test\Constraint\AssertRefundedGrandTotalOnFrontend" /> - <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" /> + <constraint name="Magento\Sales\Test\Constraint\AssertProductQtyDecreasedAfterCreditmemo" /> <constraint name="Magento\Sales\Test\Constraint\AssertCreditMemoItems" /> </variation> <variation name="CreateCreditMemoEntityTestVariation2" summary="Assert 0 shipping refund"> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php index f7cdaf74ab0f57e0544a392f6a936498bcb8efee..fc866fab6dc17fbf35d1176594ae2e8836ecf87e 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php @@ -31,6 +31,7 @@ class CreateInvoiceEntityTest extends Injectable { /* tags */ const MVP = 'yes'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml index 8753de91d1f4301710f15a968b7a7ea24e04d663..116d3cb5d4a5e36dcf30b04a953c0f94cdc3e7f0 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml @@ -68,7 +68,7 @@ </variation> <variation name="CreateInvoiceEntityTestVariationWithZeroSubtotalCheckout"> <data name="order/dataset" xsi:type="string">default</data> - <data name="order/data/price/dataset" xsi:type="string">partial_invoice</data> + <data name="order/data/price/dataset" xsi:type="string">free_invoice</data> <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::product_10_dollar</data> <data name="order/data/total_qty_ordered/0" xsi:type="string">-</data> <data name="order/data/payment_auth_expiration/method" xsi:type="string">free</data> 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 ad4cc670e43cdd6087ede4ffdb2ebffff5343f0a..bd592e9d71aaa1e9d74279af53c80ac3b319e376 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 @@ -69,6 +69,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" /> </variation> <variation name="CreateOrderBackendTestVariation4"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Create order with virtual product for registered UK customer using Bank Transfer payment method</data> <data name="products/0" xsi:type="string">catalogProductVirtual::default</data> <data name="customer/dataset" xsi:type="string">default</data> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFilteringTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFilteringTest.xml index 4e61abb7c5d50b783f407a926d56b6e60473a5ae..b4c3a7568a2a1dd4fb62fe0d013b6425d372d27d 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFilteringTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFilteringTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Ui\Test\TestCase\GridFilteringTest" summary="Grid UI Component Filtering" ticketId="MAGETWO-41328"> <variation name="SalesOrderGridFiltering"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Verify sales order grid filtering</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="string">-</item> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFullTextSearchTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFullTextSearchTest.xml index abd9432fe098e836ce34f0107f89e099620a33de..0979d0dcbff250a7f0bdb2d5151f60004f72efd0 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFullTextSearchTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridFullTextSearchTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Ui\Test\TestCase\GridFullTextSearchTest" summary="Grid UI Component Full Text Search" ticketId="MAGETWO-41023"> <variation name="SalesOrderGridFullTextSearch"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Verify sales order grid full text search</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="string">-</item> @@ -23,6 +24,7 @@ <constraint name="Magento\Ui\Test\Constraint\AssertGridFullTextSearch"/> </variation> <variation name="SalesInvoiceGridFullTextSearch"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Verify sales invoice grid full text search</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="string">Magento\Sales\Test\TestStep\CreateInvoiceStep</item> @@ -55,6 +57,7 @@ <constraint name="Magento\Ui\Test\Constraint\AssertGridFullTextSearch"/> </variation> <variation name="SalesCreditMemoGridFullTextSearch"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Verify sales credit memo grid full text search</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="array"> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridSortingTest.xml index 056fa5136d433ba1700b462ad12a1c0747b9dcc1..f82f232625841ddfdd77e66812970a4de31efea6 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridSortingTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/GridSortingTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Ui\Test\TestCase\GridSortingTest" summary="Grid UI Component Sorting" ticketId="MAGETWO-41328"> <variation name="SalesOrderGridSorting"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Verify sales order grid storting</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="string">-</item> @@ -26,6 +27,7 @@ <constraint name="\Magento\Ui\Test\Constraint\AssertGridSorting"/> </variation> <variation name="SalesInvoiceGridSorting"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Verify sales invoince grid storting</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="string">Magento\Sales\Test\TestStep\CreateInvoiceStep</item> @@ -43,6 +45,7 @@ <constraint name="\Magento\Ui\Test\Constraint\AssertGridSorting"/> </variation> <variation name="SalesShipmentGridSorting"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Verify sales shipment grid storting</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="string">Magento\Sales\Test\TestStep\CreateShipmentStep</item> @@ -60,6 +63,7 @@ <constraint name="\Magento\Ui\Test\Constraint\AssertGridSorting"/> </variation> <variation name="SalesCreditMemoGridSorting"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Verify sales credit memo grid storting</data> <data name="steps" xsi:type="array"> <item name="0" xsi:type="array"> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml index 02dbf74225ba9d69ffe88e7c933e5ac0cc82da9e..4d54654a04bbbf7f1d3ea0cc2f53199538d7910c 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\MassOrdersUpdateTest" summary="Mass Update Orders" ticketId="MAGETWO-27897"> <variation name="MassOrdersUpdateTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">cancel orders in status Pending and Processing</data> <data name="steps" xsi:type="string">-</data> <data name="action" xsi:type="string">Cancel</data> @@ -44,6 +45,7 @@ <constraint name="Magento\Sales\Test\Constraint\AssertOrdersInOrdersGrid" /> </variation> <variation name="MassOrdersUpdateTestVariation5"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Try to put order in status Complete on Hold</data> <data name="steps" xsi:type="string">invoice, shipment</data> <data name="action" xsi:type="string">Hold</data> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.xml index 8f6466b4edc4f538918c274564888758da706b62..5f4066c1d8027a7e95b2aeab2eb8f4a8aca12330 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.xml @@ -8,11 +8,13 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\MoveLastOrderedProductsOnOrderPageTest" summary="Add Products to Order from Last Ordered Products Section" ticketId="MAGETWO-27640"> <variation name="MoveLastOrderedProductsOnOrderPageTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="order/dataset" xsi:type="string">default</data> <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::default</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> </variation> <variation name="MoveLastOrderedProductsOnOrderPageTestVariation2"> + <data name="issue" xsi:type="string">MAGETWO-58762: Customer grid does not open in MoveLastOrderedProductsOnOrderPageTestVariation2 on Jenkins</data> <data name="order/dataset" xsi:type="string">default</data> <data name="order/data/entity_id/products" xsi:type="string">configurableProduct::configurable_with_qty_1</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.xml index 4fbfbe531e8fee71987f1881c70a889d7c3deba8..695948b8b10c9caa421ebe674cbe9fe078ec6c04 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.xml @@ -8,11 +8,13 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\MoveProductsInComparedOnOrderPageTest" summary="Add Products to Order from Products in Comparison List Section" ticketId="MAGETWO-28050"> <variation name="MoveProductsInComparedOnOrderPageTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="products/1" xsi:type="string">catalogProductSimple::default</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> </variation> <variation name="MoveProductsInComparedOnOrderPageTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="products/0" xsi:type="string">configurableProduct::configurable_with_qty_1</data> <data name="products/1" xsi:type="string">configurableProduct::configurable_with_qty_1</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.xml index e6f96da0367cae153191a4bf3c535bc33ed97b5a..601f550e4588bfd3c613ef8a50e8615174b298ae 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.xml @@ -8,11 +8,13 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\MoveRecentlyComparedProductsOnOrderPageTest" summary="Add Products to Order from Recently Compared Products Section" ticketId="MAGETWO-28109"> <variation name="MoveRecentlyComparedProductsOnOrderPageTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="products/1" xsi:type="string">catalogProductSimple::default</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> </variation> <variation name="MoveRecentlyComparedProductsOnOrderPageTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="products/0" xsi:type="string">configurableProduct::configurable_with_qty_1</data> <data name="products/1" xsi:type="string">configurableProduct::configurable_with_qty_1</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.xml index 2e1c3eeea7b8942febf1b8f3505f6c1c9e407106..ae955b301d95687cb1aad697fb79a591c4e5c2d2 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.xml @@ -8,10 +8,12 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\MoveRecentlyViewedProductsOnOrderPageTest" summary="Add Products to Order from Recently Viewed Products Section" ticketId="MAGETWO-29723"> <variation name="MoveRecentlyViewedProductsOnOrderPageTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="products/0" xsi:type="string">configurableProduct::default</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> </variation> <variation name="MoveRecentlyViewedProductsOnOrderPageTestVariation2"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="products/0" xsi:type="string">bundleProduct::bundle_fixed_product</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.xml index e29a63165ad03aa8eddb4186546632e0c97c7687..53f321366de5ecc53d2d87ade453478371572274 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.xml @@ -8,10 +8,12 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\MoveShoppingCartProductsOnOrderPageTest" summary="Add Products to Order from Shopping Cart " ticketId="MAGETWO-28540"> <variation name="MoveShoppingCartProductsOnOrderPageTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product" xsi:type="string">catalogProductSimple::default</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> </variation> <variation name="MoveShoppingCartProductsOnOrderPageTestVariation2" firstConstraint="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductInItemsOrderedGrid" method="test"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product" xsi:type="string">configurableProduct::configurable_with_qty_1</data> <constraint name="Magento\Sales\Test\Constraint\AssertProductInItemsOrderedGrid" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.xml index 4dc6ae8d2fcd1d55062da03c74b7dce41c70c08c..46349665259d03f2626dbbb2723e3a8d18e864f6 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\PrintOrderFrontendGuestTest" summary="Print Order from Guest on Frontend" ticketId="MAGETWO-30253"> <variation name="PrintOrderFrontendGuestTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="customer" xsi:type="array"> <item name="dataset" xsi:type="string">johndoe_with_addresses</item> </data> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.xml index 7608ec4f68ca0d01fd8c7f736d0429ad45972503..8124a32c66eb1149c2c3e30fd79ee41381b0ee15 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sales\Test\TestCase\ReorderOrderEntityTest" summary="Reorder Order from Admin for Offline Payment Methods" ticketId="MAGETWO-29007"> <variation name="ReorderOrderEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Reorder placed order (update products, billing address).</data> <data name="order/dataset" xsi:type="string">two_simple_product</data> <data name="salesRule" xsi:type="string">active_sales_rule_with_fixed_price_discount_coupon</data> diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php index bfe0bc9eabddfb0cc0f746f79efdad5b6ad0a43b..1f3f0e5a300b46ac9a193666796e52c584b8c944 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleForm.php @@ -25,8 +25,6 @@ class AssertCartPriceRuleForm extends AbstractConstraint protected $skippedFields = [ 'conditions_serialized', 'actions_serialized', - 'from_date', - 'to_date', 'rule_id' ]; diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml index 13b68aca6c6eb7867286019b3a9609b3b93db2a8..3a35215d841d50780d212084d76d014af8708aa4 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Repository/SalesRule.xml @@ -114,10 +114,10 @@ <field name="uses_per_coupon" xsi:type="string">13</field> <field name="uses_per_customer" xsi:type="string">63</field> <field name="from_date" xsi:type="array"> - <item name="pattern" xsi:type="string">3/25/2014</item> + <item name="pattern" xsi:type="string">03/25/2014</item> </field> <field name="to_date" xsi:type="array"> - <item name="pattern" xsi:type="string">6/29/2024</item> + <item name="pattern" xsi:type="string">-</item> </field> <field name="sort_order" xsi:type="string">1</field> <field name="is_rss" xsi:type="string">Yes</field> diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.xml index 4b837e442a4abc83219daf45301fe5a20570f1e0..b1893651726f8a562fe4ba3b9299c17e2ca082d3 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\SalesRule\Test\TestCase\ApplySeveralSalesRuleEntityTest" summary="Apply Several Sales Rules" ticketId="MAGETWO-45883"> <variation name="ApplySeveralSalesRuleEntityTestVariation1" summary="Rules with same priority, both are applied"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="salesRules/rule1" xsi:type="string">active_sales_rule_product_subselection</data> <data name="salesRules/rule2" xsi:type="string">active_sales_rule_product_attribute</data> <data name="cartPrice/sub_total" xsi:type="string">200.00</data> @@ -31,6 +32,7 @@ <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleConditionIsApplied" /> </variation> <variation name="ApplySeveralSalesRuleEntityTestVariation3" summary="Rules with different priority, both are applied"> + <data name="tag" xsi:type="string">stable:no</data> <data name="salesRules/rule1" xsi:type="string">active_sales_rule_product_attribute</data> <data name="salesRules/rule2" xsi:type="string">active_sales_total_items</data> <data name="cartPrice/sub_total" xsi:type="string">250.00</data> @@ -43,6 +45,7 @@ <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleConditionIsApplied" /> </variation> <variation name="ApplySeveralSalesRuleEntityTestVariation4" summary="Rules with different priority, none are applied"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="salesRules/rule1" xsi:type="string">active_sales_rule_row_total</data> <data name="salesRules/rule2" xsi:type="string">active_sales_total_items</data> <data name="productForSalesRule1/dataset" xsi:type="string">simple_for_salesrule_1</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 bfa18c65bdcf8362a49c2c2f25ddb6d439c4d99d..d0ad41011004a3fef531865ca1c6265f9406684e 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 @@ -145,6 +145,7 @@ <constraint name="Magento\SalesRule\Test\Constraint\AssertCartPriceRuleConditionIsApplied" /> </variation> <variation name="CreateSalesRuleEntityTestVariation6"> + <data name="tag" xsi:type="string">stable:no</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> diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/testcase.xml index 37f8366674e0573e6d7837a004b3d98fef1dadc0..b894aada2e2ba54ec7c0658b85492b66071dd1c1 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/testcase.xml +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/etc/testcase.xml @@ -32,8 +32,8 @@ <step name="applySalesRuleOnBackend" module="Magento_SalesRule" next="fillBillingAddress" /> </scenario> <scenario name="CreateOrderBackendTest"> - <step name="createSalesRule" module="Magento_SalesRule" next="applySalesRuleOnBackend" /> - <step name="applySalesRuleOnBackend" module="Magento_SalesRule" next="fillBillingAddress" /> + <step name="createSalesRule" module="Magento_SalesRule" prev="fillShippingAddress" next="applySalesRuleOnBackend" /> + <step name="applySalesRuleOnBackend" module="Magento_SalesRule" /> </scenario> <scenario name="CreateOrderFromCustomerPageTest"> <step name="createSalesRule" module="Magento_SalesRule" next="applySalesRuleOnBackend" /> diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.xml b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.xml index 21279437ea834b921f2a910714f25daf5735ca84..79a170819c50600ba0f2f15811a8b3cdfe94cb7a 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.xml @@ -25,7 +25,7 @@ </testCase> <testCase name="Magento\Search\Test\TestCase\CreateSynonymGroupEntityTest" summary="Create Synonym Group with custom Website and Store View" ticketId="MAGETWO-47681"> <variation name="CreateSynonymGroupEntityTestVariation3"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, stable:no</data> <data name="synonymGroup/data/synonyms" xsi:type="string">synonym_%isolation%</data> <data name="synonymGroup/data/scope_id/dataset" xsi:type="string">custom_store</data> <constraint name="Magento\Search\Test\Constraint\AssertSynonymGroupSuccessSaveMessage" /> diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.xml b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.xml index 2e6e6cb2e4812b13e0354bf9ec9794f1c845a4db..636cf66fd2c86da20cd331b9a0b1c9b3f549f45d 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.xml @@ -8,9 +8,9 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Search\Test\TestCase\UpdateSynonymGroupEntityTest" summary="Update Synonym Groups" ticketId="MAGETWO-49412"> <variation name="UpdateSynonymGroupEntityTestVariation1"> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, to_maintain:yes</data> <data name="initialSynonymGroup/dataset" xsi:type="string">prepareMerge</data> <data name="description" xsi:type="string">Update Synonym Groups Successfully</data> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> <data name="synonymGroup/data/synonyms" xsi:type="string">new_synonym_%isolation%</data> <data name="synonymGroup/data/scope_id/dataset" xsi:type="string">all_store_views</data> <constraint name="Magento\Search\Test\Constraint\AssertSynonymGroupSuccessSaveMessage" /> diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4b42430c0b8a81987b78d907f8b4a4c56d6db834 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.php @@ -0,0 +1,134 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Security\Test\TestCase; + + +use Magento\User\Test\Page\Adminhtml\UserEdit; +use Magento\User\Test\Page\Adminhtml\UserIndex; +use Magento\Mtf\TestCase\Injectable; +use Magento\User\Test\Fixture\User; +use Magento\Backend\Test\Page\AdminAuthLogin; + +/** + * Preconditions: + * 1. Create admin user. + * 2. Configure 'Maximum Login Failures to Lockout Account'. + * + * Steps: + * 1. Log in to backend as admin user. + * 2. Navigate to System > All Users. + * 3. Click on Add New User. + * 4. Fill in all data according to data set (password is incorrect). + * 5. Perform action 4 specified number of times. + * 6. "You have entered an invalid password for current user." appears after each attempt. + * 7. Perform all assertions. + * + * @ZephyrId MAGETWO-49034 + */ +class LockAdminUserWhenCreatingNewUserTest extends Injectable +{ + /* tags */ + const MVP = 'yes'; + const SEVERITY = 'S2'; + /* end tags */ + + /** + * User grid page + * + * @var UserIndex + */ + protected $userIndexPage; + + /** + * User new/edit page + * + * @var UserEdit + */ + protected $userEditPage; + + /** + * Configuration setting. + * + * @var string + */ + protected $configData; + + /** + * @var AdminAuthLogin page + */ + protected $adminAuthLogin; + + /** + * Setup data for test. + * @param UserIndex $userIndex + * @param UserEdit $userEdit + * @param AdminAuthLogin $adminAuthLogin + */ + public function __inject( + UserIndex $userIndex, + UserEdit $userEdit, + AdminAuthLogin $adminAuthLogin + ) { + $this->userIndexPage = $userIndex; + $this->userEditPage = $userEdit; + $this->adminAuthLogin = $adminAuthLogin; + } + + /** + * Runs Lock admin user when creating new user test. + * + * @param int $attempts + * @param User $customAdmin, + * @param User $user, + * @param string $configData + * @return void + */ + public function test( + $attempts, + User $customAdmin, + User $user, + $configData + ) { + $this->configData = $configData; + + // Preconditions + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData] + )->run(); + $customAdmin->persist(); + + // Steps + $this->adminAuthLogin->open(); + $this->adminAuthLogin->getLoginBlock()->fill($customAdmin); + $this->adminAuthLogin->getLoginBlock()->submit(); + $this->userIndexPage->open(); + $this->userIndexPage->getPageActions()->addNew(); + for ($i = 0; $i < $attempts; $i++) { + $this->userEditPage->getUserForm()->fill($user); + $this->userEditPage->getPageActions()->save(); + } + + // Reload + $this->adminAuthLogin->open(); + $this->adminAuthLogin->getLoginBlock()->fill($customAdmin); + $this->adminAuthLogin->getLoginBlock()->submit(); + } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData, 'rollback' => true] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..e36f8b4625dd66eeb5a41f15c74c4bdf6e7eeeea --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewUserTest.xml @@ -0,0 +1,25 @@ +<?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\Security\Test\TestCase\LockAdminUserWhenCreatingNewUserTest" summary="Lock admin user after entering incorrect password while creating new User"> + <variation name="LockAdminUserWhenCreatingNewUserTestVariation1"> + <data name="configData" xsi:type="string">user_lockout_failures</data> + <data name="tag" xsi:type="string">severity:S2</data> + <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data> + <data name="user/data/username" xsi:type="string">AdminUser%isolation%</data> + <data name="user/data/firstname" xsi:type="string">FirstName%isolation%</data> + <data name="user/data/lastname" xsi:type="string">LastName%isolation%</data> + <data name="user/data/email" xsi:type="string">email%isolation%@example.com</data> + <data name="user/data/password" xsi:type="string">123123q</data> + <data name="user/data/password_confirmation" xsi:type="string">123123q</data> + <data name="user/data/current_password" xsi:type="string">incorrect password</data> + <data name="attempts" xsi:type="string">4</data> + <constraint name="Magento\Security\Test\Constraint\AssertUserIsLocked" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4a1c1d0507c91ea3b9a86d254f6f2c01d58a7d2d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Security\Test\TestCase; + +use Magento\Integration\Test\Fixture\Integration; +use Magento\User\Test\Fixture\User; +use Magento\Integration\Test\Page\Adminhtml\IntegrationIndex; +use Magento\Integration\Test\Page\Adminhtml\IntegrationNew; +use Magento\Mtf\TestCase\Injectable; +use Magento\Backend\Test\Page\AdminAuthLogin; + +/** + * Preconditions: + * 1. Create admin user. + * 2. Create integration. + * 3. Configure 'Maximum Login Failures to Lockout Account'. + * + * Steps: + * 1. Log in to backend as admin user. + * 2. Navigate to System > Extensions > Integrations. + * 3. Start to edit existing Integration. + * 4. Fill in all data according to data set (password is incorrect). + * 5. Perform action 4 specified number of times. + * 6. "You have entered an invalid password for current user." appears after each attempt. + * 7. Perform all assertions. + * + * @ZephyrId MAGETWO-49039 + */ +class LockAdminUserWhenEditingIntegrationTest extends Injectable +{ + /* tags */ + const MVP = 'yes'; + const SEVERITY = 'S2'; + /* end tags */ + + /** + * Integration grid page. + * + * @var IntegrationIndex + */ + protected $integrationIndexPage; + + /** + * Integration new page. + * + * @var IntegrationNew + */ + protected $integrationNewPage; + + /** + * Configuration setting. + * + * @var string + */ + protected $configData; + + /** + * @var AdminAuthLogin + */ + protected $adminAuthLogin; + + /** + * Preparing pages for test. + * + * @param IntegrationIndex $integrationIndex + * @param IntegrationNew $integrationNew + * @param AdminAuthLogin $adminAuthLogin + * @return void + */ + public function __inject( + IntegrationIndex $integrationIndex, + IntegrationNew $integrationNew, + AdminAuthLogin $adminAuthLogin + ) { + $this->integrationIndexPage = $integrationIndex; + $this->integrationNewPage = $integrationNew; + $this->adminAuthLogin = $adminAuthLogin; + } + + /** + * Run Lock user when creating new integration test. + * + * @param Integration $initintegration + * @param Integration $integration + * @param int $attempts + * @param User $customAdmin + * @param string $configData + * @return void + */ + public function test( + Integration $initintegration, + Integration $integration, + $attempts, + User $customAdmin, + $configData + ) { + $this->configData = $configData; + + // Preconditions + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData] + )->run(); + $customAdmin->persist(); + $initintegration->persist(); + + // login to backend with new user + $this->adminAuthLogin->open(); + $this->adminAuthLogin->getLoginBlock()->fill($customAdmin); + $this->adminAuthLogin->getLoginBlock()->submit(); + + // Steps + $filter = ['name' => $initintegration->getName()]; + $this->integrationIndexPage->open(); + $this->integrationIndexPage->getIntegrationGrid()->searchAndOpen($filter); + for ($i = 0; $i < $attempts; $i++) { + $this->integrationNewPage->getIntegrationForm()->fill($integration); + $this->integrationNewPage->getFormPageActions()->save(); + } + + // Reload page + $this->adminAuthLogin->open(); + $this->adminAuthLogin->getLoginBlock()->fill($customAdmin); + $this->adminAuthLogin->getLoginBlock()->submit(); + } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData, 'rollback' => true] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..6efc88d78cd3836f00db79d2c567d3e6e38d1bb1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.xml @@ -0,0 +1,21 @@ +<?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\Security\Test\TestCase\LockAdminUserWhenEditingIntegrationTest" summary="Lock admin user after entering incorrect password while editing integration"> + <variation name="LockAdminUserWhenCreatingNewIntegrationTestVariation1"> + <data name="configData" xsi:type="string">user_lockout_failures</data> + <data name="tag" xsi:type="string">severity:S2</data> + <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data> + <data name="initintegration/dataset" xsi:type="string">default_active</data> + <data name="integration/data/name" xsi:type="string">Integration%isolation%</data> + <data name="integration/data/current_password" xsi:type="string">incorrect password</data> + <data name="attempts" xsi:type="string">4</data> + <constraint name="Magento\Security\Test\Constraint\AssertUserIsLocked" /> + </variation> + </testCase> +</config> \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bd7c8cef92d8a320b43615983a95ea724cce0d78 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.php @@ -0,0 +1,140 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Security\Test\TestCase; + +use Magento\User\Test\Page\Adminhtml\UserRoleEditRole; +use Magento\User\Test\Page\Adminhtml\UserRoleIndex; +use Magento\Mtf\TestCase\Injectable; +use Magento\User\Test\Fixture\User; +use Magento\User\Test\Fixture\Role; +use Magento\Backend\Test\Page\AdminAuthLogin; + +/** + * Preconditions: + * 1. Create new admin user and assign it to new role. + * 2. Configure 'Maximum Login Failures to Lockout Account'. + * + * Steps: + * 1. Log in to backend as new created admin user. + * 2. Navigate to System > User Roles. + * 3. Start editing existing User Role. + * 4. Fill in all data according to data set (password is incorrect). + * 5. Perform action 4 specified number of times. + * 6. Admin account is locked. + * 7. Perform all assertions. + * + * @ZephyrId MAGETWO-49037 + * @Group Security + * + */ +class LockAdminUserWhenEditingRoleTest extends Injectable +{ + /* tags */ + const MVP = 'yes'; + const SEVERITY = 'S2'; + /* end tags */ + + /** + * UserRoleIndex page. + * + * @var UserRoleIndex + */ + protected $userRoleIndex; + + /** + * UserRoleEditRole page. + * + * @var UserRoleEditRole + */ + protected $userRoleEditRole; + + /** + * Configuration setting. + * + * @var string + */ + protected $configData; + + /** + * Admin login Page. + * + * @var AdminAuthLogin + */ + protected $adminAuthLogin; + + /** + * Setup data for test. + * + * @param UserRoleIndex $userRoleIndex + * @param UserRoleEditRole $userRoleEditRole + * @param AdminAuthLogin $adminAuthLogin + * @return void + */ + public function __inject( + UserRoleIndex $userRoleIndex, + UserRoleEditRole $userRoleEditRole, + AdminAuthLogin $adminAuthLogin + ) { + $this->userRoleIndex = $userRoleIndex; + $this->userRoleEditRole = $userRoleEditRole; + $this->adminAuthLogin = $adminAuthLogin; + } + + /** + * Runs Lock admin user when editing existing role test. + * + * @param Role $role + * @param Role $initrole + * @param int $attempts + * @param User $customAdmin + * @param string $configData + * @return void + */ + public function test( + Role $role, + Role $initrole, + $attempts, + User $customAdmin, + $configData + ) { + $this->configData = $configData; + // Preconditions + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData] + )->run(); + $customAdmin->persist(); + $initrole->persist(); + // Steps login to backend with new user + $this->adminAuthLogin->open(); + $this->adminAuthLogin->getLoginBlock()->fill($customAdmin); + $this->adminAuthLogin->getLoginBlock()->submit(); + $filter = ['rolename' => $initrole->getRolename()]; + $this->userRoleIndex->open(); + $this->userRoleIndex->getRoleGrid()->searchAndOpen($filter); + for ($i = 0; $i < $attempts; $i++) { + $this->userRoleEditRole->getRoleFormTabs()->fill($role); + $this->userRoleEditRole->getPageActions()->save(); + } + // Reload + $this->adminAuthLogin->open(); + $this->adminAuthLogin->getLoginBlock()->fill($customAdmin); + $this->adminAuthLogin->getLoginBlock()->submit(); + } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData, 'rollback' => true] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..1d081e5d2dd9af69f90aeed8b787c966238e62de --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingRoleTest.xml @@ -0,0 +1,22 @@ +<?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\Security\Test\TestCase\LockAdminUserWhenEditingRoleTest" summary="Lock admin user after entering incorrect password while editing existing role"> + <variation name="LockAdminUserWhenEditingUserRoleTestVariation1"> + <data name="configData" xsi:type="string">user_lockout_failures</data> + <data name="tag" xsi:type="string">severity:S2</data> + <data name="initrole/dataset" xsi:type="string">default</data> + <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data> + <data name="role/data/rolename" xsi:type="string">NewAdminRole%isolation%</data> + <data name="role/data/current_password" xsi:type="string">incorrect password</data> + <data name="role/data/resource_access" xsi:type="string">All</data> + <data name="attempts" xsi:type="string">4</data> + <constraint name="Magento\Security\Test\Constraint\AssertUserIsLocked" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.php new file mode 100644 index 0000000000000000000000000000000000000000..912ebef9e91054236cc6b85b91c3cd8d973b54e9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.php @@ -0,0 +1,133 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Security\Test\TestCase; + +use Magento\User\Test\Page\Adminhtml\UserEdit; +use Magento\User\Test\Page\Adminhtml\UserIndex; +use Magento\Backend\Test\Page\AdminAuthLogin; +use Magento\User\Test\Fixture\User; +use Magento\Mtf\TestCase\Injectable; + +/** + * Preconditions: + * 1. Create new admin user. + * 2. Configure 'Maximum Login Failures to Lockout Account'. + * + * Steps: + * 1. Log in to backend as new created admin user. + * 2. Navigate to System > All Users. + * 3. Start editing existing User. + * 4. Fill in all data according to data set (password is incorrect). + * 5. Perform action 4 specified number of times. + * 6. Admin account is locked. + * 7. Perform all assertions. + * + * @ZephyrId MAGETWO-49035 + */ +class LockAdminUserWhenEditingUserTest extends Injectable +{ + /* tags */ + const MVP = 'yes'; + const SEVERITY = 'S2'; + /* end tags */ + + /** + * User grid page + * + * @var UserIndex + */ + protected $userIndexPage; + + /** + * User edit page + * + * @var UserEdit + */ + protected $userEditPage; + + /** + * @var $configData + */ + protected $configData; + + /** + * @var AdminAuthLogin page + */ + protected $adminAuthLogin; + + /** + * Setup data for test. + * @param UserIndex $userIndex + * @param UserEdit $userEdit + * @param AdminAuthLogin $adminAuthLogin + */ + public function __inject( + UserIndex $userIndex, + UserEdit $userEdit, + AdminAuthLogin $adminAuthLogin + ) { + $this->userIndexPage = $userIndex; + $this->userEditPage = $userEdit; + $this->adminAuthLogin = $adminAuthLogin; + } + + /** + * Runs Lock admin user when editing existing role test. + * + * @param User $user + * @param int $attempts + * @param User $customAdmin + * @param string $configData + * @return void + */ + public function test( + $attempts, + User $customAdmin, + User $user, + $configData + ) { + $this->configData = $configData; + + // Preconditions + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData] + )->run(); + $customAdmin->persist(); + + // Steps login to backend with new user + $this->adminAuthLogin->open(); + $this->adminAuthLogin->getLoginBlock()->fill($customAdmin); + $this->adminAuthLogin->getLoginBlock()->submit(); + // Select user to edit. + $filter = ['username' => $customAdmin->getUsername()]; + $this->userIndexPage->open(); + $this->userIndexPage->getUserGrid()->searchAndOpen($filter); + // Edit user with wrong password + for ($i = 0; $i < $attempts; $i++) { + $this->userEditPage->getUserForm()->fill($user); + $this->userEditPage->getPageActions()->save(); + } + // Reload + $this->adminAuthLogin->open(); + $this->adminAuthLogin->getLoginBlock()->fill($customAdmin); + $this->adminAuthLogin->getLoginBlock()->submit(); + } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create( + \Magento\Config\Test\TestStep\SetupConfigurationStep::class, + ['configData' => $this->configData, 'rollback' => true] + )->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..e1ec2f79ce6b5d306e694c9d2ae8e8adea0d3387 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingUserTest.xml @@ -0,0 +1,25 @@ +<?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\Security\Test\TestCase\LockAdminUserWhenEditingUserTest" summary="Lock admin user after entering incorrect password while editing existing user"> + <variation name="LockAdminUserWhenEditingUseruserTestVariation1"> + <data name="configData" xsi:type="string">user_lockout_failures</data> + <data name="tag" xsi:type="string">severity:S2</data> + <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data> + <data name="user/data/username" xsi:type="string">AdminUser%isolation%</data> + <data name="user/data/firstname" xsi:type="string">FirstName%isolation%</data> + <data name="user/data/lastname" xsi:type="string">LastName%isolation%</data> + <data name="user/data/email" xsi:type="string">email%isolation%@example.com</data> + <data name="user/data/password" xsi:type="string">123123qq</data> + <data name="user/data/password_confirmation" xsi:type="string">123123qq</data> + <data name="user/data/current_password" xsi:type="string">incorrect password</data> + <data name="attempts" xsi:type="string">4</data> + <constraint name="Magento\Security\Test\Constraint\AssertUserIsLocked" /> + </variation> + </testCase> +</config> \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml index eeb0dd7ab12e9e33eec107f17d3678d4ec1827ad..1a5443ec9e61558b5b7cad2a9ada57825c451581 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Security\Test\TestCase\LockCustomerOnEditPageTest" summary="Lock customer from edit page"> <variation name="LockCustomerOnEditPageTest1"> - <data name="tag" xsi:type="string">severity:S1</data> + <data name="tag" xsi:type="string">severity:S1, to_maintain:yes</data> <data name="configData" xsi:type="string">customer_max_login_failures_number</data> <data name="initialCustomer/dataset" xsi:type="string">default</data> <data name="customer/data/current_password" xsi:type="string">incorrect password</data> diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml index a5376d73685bad9e54d4ff094348b7100c2a2a8d..df5c5bce59fe0400b308530085e99c541da60323 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Security\Test\TestCase\LockCustomerOnLoginPageTest" summary="Lock customer on login page"> <variation name="LockCustomerOnLoginPageTestVariation1"> - <data name="tag" xsi:type="string">severity:S1</data> + <data name="tag" xsi:type="string">severity:S1, to_maintain:yes</data> <data name="configData" xsi:type="string">customer_max_login_failures_number</data> <data name="initialCustomer/dataset" xsi:type="string">default</data> <data name="incorrectPassword" xsi:type="string">incorrect password</data> diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml index b888ba1f778370d11e19ded0f8c40cfd543541ea..2c3809e27f2eff076ffd538d7aebcfa4fed04e7f 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml @@ -17,7 +17,7 @@ <constraint name="Magento\Store\Test\Constraint\AssertStoreNotOnFrontend" /> </variation> <variation name="DeleteStoreEntityTestVariation2"> - <data name="tag" xsi:type="string">severity:S2</data> + <data name="tag" xsi:type="string">severity:S2, stable:no</data> <data name="store/dataset" xsi:type="string">custom</data> <data name="createBackup" xsi:type="string">No</data> <constraint name="Magento\Store\Test\Constraint\AssertStoreSuccessDeleteMessage" /> diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.xml b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.xml index 16c0aeb358bb0fe5e7f0e18216300161c6dfbbf1..cfda1263ac19f8355370ad5cb507b44a8aa43f29 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Store\Test\TestCase\DeleteStoreGroupEntityTest" summary="Delete Store Group" ticketId="MAGETWO-27596"> <variation name="DeleteStoreGroupEntityTestVariation1"> - <data name="tag" xsi:type="string">severity:S3</data> + <data name="tag" xsi:type="string">severity:S3, stable:no</data> <data name="storeGroup/dataset" xsi:type="string">custom</data> <data name="createBackup" xsi:type="string">Yes</data> <constraint name="Magento\Store\Test\Constraint\AssertStoreGroupSuccessDeleteAndBackupMessages" /> @@ -16,7 +16,7 @@ <constraint name="Magento\Backup\Test\Constraint\AssertBackupInGrid" /> </variation> <variation name="DeleteStoreGroupEntityTestVariation2"> - <data name="tag" xsi:type="string">severity:S3</data> + <data name="tag" xsi:type="string">severity:S3, stable:no</data> <data name="storeGroup/dataset" xsi:type="string">custom</data> <data name="createBackup" xsi:type="string">No</data> <constraint name="Magento\Store\Test\Constraint\AssertStoreGroupSuccessDeleteMessage" /> diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php index 94e14b4a42317edaa2b1f151a3858c770a74fc68..f349131fe5848a5a6b1f44c696bf96969053b19e 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php @@ -39,6 +39,7 @@ class DeleteWebsiteEntityTest extends Injectable /* tags */ const MVP = 'yes'; const SEVERITY = 'S3'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ListProduct.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ListProduct.php new file mode 100644 index 0000000000000000000000000000000000000000..39c630a0aa2060f23e6ef87c2682e73169ffa777 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ListProduct.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\Block\Product; + +use Magento\Mtf\Client\Locator; +use Magento\Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Block\Product\ListProduct as CatalogListProduct; + +/** + * Product list block. + */ +class ListProduct extends CatalogListProduct +{ + /** + * @inheritdoc + */ + public function getProductItem(FixtureInterface $product) + { + $locator = sprintf($this->productItem, $product->getName()); + + return $this->blockFactory->create( + \Magento\Swatches\Test\Block\Product\ProductList\ProductItem::class, + ['element' => $this->_rootElement->find($locator, Locator::SELECTOR_XPATH)] + ); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ProductList/ProductItem.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ProductList/ProductItem.php new file mode 100755 index 0000000000000000000000000000000000000000..414d03bc687871490b551fcfb807f2958fd4e25e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ProductList/ProductItem.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\Block\Product\ProductList; + +use Magento\Mtf\Client\Locator; +use Magento\Catalog\Test\Block\Product\ProductList\ProductItem as CatalogProductItem; + +/** + * Product item block on frontend category view. + */ +class ProductItem extends CatalogProductItem +{ + /** + * Selector for the swatches of the product. + * + * @var string + */ + protected $swatchSelector = 'div[option-id="%s"]'; + + /** + * Fill product options on category page. + * + * @param \Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct $product + * @return void + */ + public function fillData(\Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct $product) + { + $checkoutData = $product->getCheckoutData(); + $options = $checkoutData['options']['configurable_options']; + $confAttrData = $product->getDataFieldConfig('configurable_attributes_data'); + $confAttrSource = $confAttrData['source']; + $attributes = $confAttrSource->getAttributes(); + + foreach ($options as $option) { + if (!isset($attributes[$option['title']])) { + continue; + } + $availableOptions = $attributes[$option['title']]->getOptions(); + $optionKey = str_replace('option_key_', '', $option['value']); + if (!isset($availableOptions[$optionKey])) { + continue; + } + $optionForSelect = $availableOptions[$optionKey]; + $this->clickOnSwatch($optionForSelect['id']); + } + } + + /** + * Click on swatch. + * + * @param $optionId + */ + private function clickOnSwatch($optionId) + { + $selector = sprintf($this->swatchSelector, $optionId); + $this->_rootElement->find($selector, Locator::SELECTOR_CSS)->click(); + } + + /** + * @inheritdoc + */ + public function clickAddToCart() + { + $this->_rootElement->hover(); + parent::clickAddToCart(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ViewWithSwatches.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ViewWithSwatches.php new file mode 100644 index 0000000000000000000000000000000000000000..c1405b4a807718edbb511569ac23d03fc2b52d43 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Block/Product/ViewWithSwatches.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\Block\Product; + +use Magento\Catalog\Test\Block\Product\View; +use Magento\Mtf\Fixture\InjectableFixture; + +/** + * Configurable product view block with swatch attributes on frontend product page + */ +class ViewWithSwatches extends View +{ + /** + * Selector for swatch attribute value + * + * @var string + */ + private $swatchAttributeSelector = '.swatch-attribute.%s .swatch-attribute-selected-option'; + + /** + * Get chosen options from the product view page. + * + * @param InjectableFixture $product + * @return array + */ + public function getSelectedSwatchOptions(InjectableFixture $product) + { + $checkoutData = $product->getCheckoutData(); + $availableAttributes = $product->getConfigurableAttributesData(); + $attributesData = $availableAttributes['attributes_data']; + $formData = []; + foreach ($checkoutData['options']['configurable_options'] as $item) { + $selector = sprintf($this->swatchAttributeSelector, $attributesData[$item['title']]['attribute_code']); + $this->waitForElementVisible($selector); + $selected = $this->_rootElement->find($selector)->getText(); + $formData[$item['title']] = $selected; + } + + return $formData; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Constraint/AssertSwatchConfigurableProductPage.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Constraint/AssertSwatchConfigurableProductPage.php new file mode 100644 index 0000000000000000000000000000000000000000..460a13ce49d704f30f513af5c8f3189c45f3ffc4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Constraint/AssertSwatchConfigurableProductPage.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\Constraint; + +use Magento\Catalog\Test\Constraint\AssertProductPage; +use Magento\Mtf\Fixture\FixtureInterface; +use Magento\Catalog\Test\Page\Product\CatalogProductView; +use Magento\Mtf\Client\BrowserInterface; + +/** + * Assert that product with swatches and regular dropdown redirect can't be add to cart from catalog catergory page. + */ +class AssertSwatchConfigurableProductPage extends AssertProductPage +{ + /** + * {@inheritdoc} + */ + public function processAssert( + BrowserInterface $browser, + CatalogProductView $catalogProductView, + FixtureInterface $product + ) { + $this->product = $product; + $this->productView = $catalogProductView->getProductViewWithSwatchesBlock(); + $this->objectManager->create( + \Magento\Swatches\Test\TestStep\AddProductToCartFromCatalogCategoryPageStep::class, + [ + 'product' => $product + ] + )->run(); + // we need this line for waiti until page will be fully loaded + $this->productView->getSelectedSwatchOptions($this->product); + $errors = $this->verify(); + \PHPUnit_Framework_Assert::assertEmpty( + $errors, + "\nFound the following errors:\n" . implode(" \n", $errors) + ); + } + + /** + * Verify product on product view page. + * + * @return array + */ + protected function verify() + { + $errors = parent::verify(); + $errors[] = $this->verifySwatches(); + + return array_filter($errors); + } + + /** + * Verify selected swatches on product view page. + * + * @return array + */ + protected function verifySwatches() + { + $actualData = $this->productView->getSelectedSwatchOptions($this->product); + $expectedData = $this->convertCheckoutData($this->product); + $this->verifyData($expectedData, $actualData); + } + + /** + * Get swatch attributes formatter to attributes comparison. + * + * @param FixtureInterface $product + * @return array + */ + public function convertCheckoutData(FixtureInterface $product) + { + $out = []; + $checkoutData = $product->getCheckoutData(); + $availableAttributes = $product->getConfigurableAttributesData(); + $attributesData = $availableAttributes['attributes_data']; + foreach ($checkoutData['options']['configurable_options'] as $item) { + $out[$item['title']] = $attributesData[$item['title']]['options'][$item['value']]['label']; + } + + return $out; + } + + /** + * Return string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Swatch attributes displayed as expected on product page'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/Cart/Item.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/Cart/Item.php new file mode 100644 index 0000000000000000000000000000000000000000..46c9b383ae8420c5210a3d4f71ac49b3513b1724 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/Cart/Item.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\Fixture\Cart; + +use Magento\ConfigurableProduct\Test\Fixture\Cart\Item as ConfigurableCart; + +/** + * @inheritdoc + */ +class Item extends ConfigurableCart +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/ConfigurableProduct.xml new file mode 100644 index 0000000000000000000000000000000000000000..dbc57a321a68238adff45355fd87a4e97028cde2 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/ConfigurableProduct.xml @@ -0,0 +1,16 @@ +<?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/fixture.xsd"> + <fixture + name="configurableProductSwatch" + module="Magento_Swatches" + class="Magento\Swatches\Test\Fixture\ConfigurableProduct" + extends="\Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct" + > + </fixture> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/SwatchProductAttribute.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/SwatchProductAttribute.xml new file mode 100644 index 0000000000000000000000000000000000000000..d96331b8159d50a60f6aa215d523d492aa5de7a4 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Fixture/SwatchProductAttribute.xml @@ -0,0 +1,16 @@ +<?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/fixture.xsd"> + <fixture name="swatchesProductAttribute" + module="Magento_Swatches" + handler_interface="Magento\Swatches\Test\Handler\SwatchProductAttribute\SwatchProductAttributeInterface" + repository_class="Magento\Swatches\Test\Repository\SwatchProductAttribute" + class="Magento\Swatches\Test\Fixture\SwatchesProductAttribute" + extends="\Magento\Catalog\Test\Fixture\CatalogProductAttribute"> + </fixture> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php new file mode 100644 index 0000000000000000000000000000000000000000..86de2d651da1ecf3d48fdb165de0b223a665f126 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/Curl.php @@ -0,0 +1,49 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\Handler\SwatchProductAttribute; + +use Magento\Catalog\Test\Handler\CatalogProductAttribute\Curl as CatalogProductAttributeCurl; +use Magento\Mtf\Config\DataInterface; +use Magento\Mtf\System\Event\EventManagerInterface; + +/** + * Curl handler for creating Swatch Attribute. + */ +class Curl extends CatalogProductAttributeCurl implements SwatchProductAttributeInterface +{ + /** + * Add mapping data related to swatches. + * + * @param DataInterface $configuration + * @param EventManagerInterface $eventManager + */ + public function __construct(DataInterface $configuration, EventManagerInterface $eventManager) + { + parent::__construct($configuration, $eventManager); + $this->mappingData['frontend_input'] = [ + 'Text Swatch' => 'swatch_text', + ]; + } + + /** + * Re-map options from default options structure to swatches structure, + * as swatches was initially created with name convention differ from other attributes. + * + * @param array $data + * @return array + */ + protected function changeStructureOfTheData(array $data) + { + $data = parent::changeStructureOfTheData($data); + $data['optiontext'] = $data['option']; + $data['swatchtext'] = [ + 'value' => $data['option']['value'] + ]; + unset($data['option']); + return $data; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/SwatchProductAttributeInterface.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/SwatchProductAttributeInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..41fdebdd5ce8b084eca0a40c58aeba580a7b3518 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Handler/SwatchProductAttribute/SwatchProductAttributeInterface.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\Handler\SwatchProductAttribute; + +use Magento\Mtf\Handler\HandlerInterface; + +/** + * Interface for swatch specific Curl calls + */ +interface SwatchProductAttributeInterface extends HandlerInterface +{ + // +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Category/CatalogCategoryView.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Category/CatalogCategoryView.xml new file mode 100644 index 0000000000000000000000000000000000000000..9cb5e4fbdf69756a5289555e15d568f577bbf21d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Category/CatalogCategoryView.xml @@ -0,0 +1,12 @@ +<?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/pages.xsd"> + <page name="CatalogCategoryView" area="Category" mca="catalog/category/view" module="Magento_Catalog"> + <block name="listSwatchesProductBlock" class="Magento\Swatches\Test\Block\Product\ListProduct" locator=".products.wrapper.grid" strategy="css selector"/> + </page> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Product/CatalogProductView.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Product/CatalogProductView.xml new file mode 100644 index 0000000000000000000000000000000000000000..315c6a02ee968e6bc93ec52bd5555d65be3f87d7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Page/Product/CatalogProductView.xml @@ -0,0 +1,12 @@ +<?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/pages.xsd"> + <page name="CatalogProductView" area="Product" mca="catalog/product/view"> + <block name="productViewWithSwatchesBlock" class="Magento\Swatches\Test\Block\Product\ViewWithSwatches" locator="#maincontent" strategy="css selector" /> + </page> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml new file mode 100644 index 0000000000000000000000000000000000000000..22e73572ead0d9081b3bdf15c78f75df12409a3c --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct.xml @@ -0,0 +1,83 @@ +<?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\ConfigurableProduct\Test\Repository\ConfigurableProduct"> + <dataset name="product_with_text_swatch"> + <field name="name" xsi:type="string">Test configurable product with color and size %isolation%</field> + <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">30</field> + <field name="status" xsi:type="string">Yes</field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="url_key" xsi:type="string">configurable-product-%isolation%</field> + <field name="configurable_attributes_data" xsi:type="array"> + <item name="dataset" xsi:type="string">text_swatch</item> + </field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="category_ids" xsi:type="array"> + <item name="dataset" xsi:type="string">default_subcategory</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="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">custom_attribute_set</item> + </field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">40</item> + <item name="dataset" xsi:type="string">price_40</item> + </field> + <field name="checkout_data" xsi:type="array"> + <item name="dataset" xsi:type="string">two_text_swatches</item> + </field> + </dataset> + <dataset name="product_with_text_swatch_and_size"> + <field name="name" xsi:type="string">Test configurable product with color and size %isolation%</field> + <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field> + <field name="product_has_weight" xsi:type="string">This item has weight</field> + <field name="weight" xsi:type="string">30</field> + <field name="status" xsi:type="string">Yes</field> + <field name="visibility" xsi:type="string">Catalog, Search</field> + <field name="tax_class_id" xsi:type="array"> + <item name="dataset" xsi:type="string">taxable_goods</item> + </field> + <field name="url_key" xsi:type="string">configurable-product-%isolation%</field> + <field name="configurable_attributes_data" xsi:type="array"> + <item name="dataset" xsi:type="string">text_swatch_with_dropdown</item> + </field> + <field name="quantity_and_stock_status" xsi:type="array"> + <item name="is_in_stock" xsi:type="string">In Stock</item> + </field> + <field name="category_ids" xsi:type="array"> + <item name="dataset" xsi:type="string">default_subcategory</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="attribute_set_id" xsi:type="array"> + <item name="dataset" xsi:type="string">custom_attribute_set</item> + </field> + <field name="price" xsi:type="array"> + <item name="value" xsi:type="string">40</item> + <item name="dataset" xsi:type="string">price_40</item> + </field> + <field name="checkout_data" xsi:type="array"> + <item name="dataset" xsi:type="string">swatches_with_dropdown</item> + </field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/CheckoutData.xml new file mode 100644 index 0000000000000000000000000000000000000000..9b369d5a536f0de9e41bb302910526dd8f5023fb --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/CheckoutData.xml @@ -0,0 +1,47 @@ +<?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\ConfigurableProduct\Test\Repository\ConfigurableProduct\CheckoutData"> + <dataset name="two_text_swatches"> + <field name="options" xsi:type="array"> + <item name="configurable_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 name="1" xsi:type="array"> + <item name="title" xsi:type="string">attribute_key_1</item> + <item name="value" xsi:type="string">option_key_2</item> + </item> + </item> + </field> + <field name="qty" xsi:type="string">1</field> + <field name="cartItem" xsi:type="array"> + <item name="price" xsi:type="string">42</item> + <item name="qty" xsi:type="string">1</item> + <item name="subtotal" xsi:type="string">47</item> + </field> + </dataset> + <dataset name="swatches_with_dropdown"> + <field name="options" xsi:type="array"> + <item name="configurable_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">42</item> + <item name="qty" xsi:type="string">1</item> + <item name="subtotal" xsi:type="string">47</item> + </field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml new file mode 100644 index 0000000000000000000000000000000000000000..492fda6b751c664bdfde231d813a866e24073f7b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/ConfigurableProduct/ConfigurableAttributesData.xml @@ -0,0 +1,151 @@ +<?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\ConfigurableProduct\Test\Repository\ConfigurableProduct\ConfigurableAttributesData"> + <dataset name="text_swatch"> + <field name="attributes_data" xsi:type="array"> + <item name="attribute_key_0" xsi:type="array"> + <item name="options" xsi:type="array"> + <item name="option_key_0" xsi:type="array"> + <item name="pricing_value" xsi:type="string">12.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + <item name="option_key_1" xsi:type="array"> + <item name="pricing_value" xsi:type="string">20.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + <item name="option_key_2" xsi:type="array"> + <item name="pricing_value" xsi:type="string">18.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + </item> + </item> + <item name="attribute_key_1" xsi:type="array"> + <item name="options" xsi:type="array"> + <item name="option_key_0" xsi:type="array"> + <item name="pricing_value" xsi:type="string">42.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + <item name="option_key_1" xsi:type="array"> + <item name="pricing_value" xsi:type="string">40.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + <item name="option_key_2" xsi:type="array"> + <item name="pricing_value" xsi:type="string">48.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + </item> + </item> + </field> + <field name="attributes" xsi:type="array"> + <item name="attribute_key_0" xsi:type="string">swatchesProductAttribute::attribute_type_text_swatch</item> + <item name="attribute_key_1" xsi:type="string">swatchesProductAttribute::attribute_type_text_swatch</item> + </field> + <field name="matrix" xsi:type="array"> + <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_0" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_1" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_2" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_0" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_1" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_2" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_0" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_1" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_2" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + </field> + </dataset> + <dataset name="text_swatch_with_dropdown"> + <field name="attributes_data" xsi:type="array"> + <item name="attribute_key_0" xsi:type="array"> + <item name="options" xsi:type="array"> + <item name="option_key_0" xsi:type="array"> + <item name="pricing_value" xsi:type="string">12.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + <item name="option_key_1" xsi:type="array"> + <item name="pricing_value" xsi:type="string">20.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + <item name="option_key_2" xsi:type="array"> + <item name="pricing_value" xsi:type="string">18.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + </item> + </item> + <item name="attribute_key_1" xsi:type="array"> + <item name="options" xsi:type="array"> + <item name="option_key_0" xsi:type="array"> + <item name="pricing_value" xsi:type="string">42.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + <item name="option_key_1" xsi:type="array"> + <item name="pricing_value" xsi:type="string">40.00</item> + <item name="include" xsi:type="string">Yes</item> + </item> + </item> + </item> + </field> + <field name="attributes" xsi:type="array"> + <item name="attribute_key_0" xsi:type="string">swatchesProductAttribute::attribute_type_text_swatch</item> + <item name="attribute_key_1" xsi:type="string">catalogProductAttribute::size</item> + </field> + <field name="matrix" xsi:type="array"> + <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_0" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_0 attribute_key_1:option_key_1" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_0" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_1 attribute_key_1:option_key_1" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_0" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + <item name="attribute_key_0:option_key_2 attribute_key_1:option_key_1" xsi:type="array"> + <item name="qty" xsi:type="string">10</item> + <item name="weight" xsi:type="string">1</item> + </item> + </field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/SwatchProductAttribute.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/SwatchProductAttribute.xml new file mode 100644 index 0000000000000000000000000000000000000000..fc92146861d1e89e5ef32666c67b8c63882d9691 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/Repository/SwatchProductAttribute.xml @@ -0,0 +1,35 @@ +<?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\Swatches\Test\Repository\SwatchProductAttribute"> + <dataset name="attribute_type_text_swatch"> + <field name="attribute_code" xsi:type="string">sw_color%isolation%</field> + <field name="frontend_input" xsi:type="string" >Text Swatch</field> + <field name="frontend_label" xsi:type="string" >Text Swatch</field> + <field name="options" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="is_default" xsi:type="string">No</item> + <item name="admin" xsi:type="string">R</item> + <item name="view" xsi:type="string">R</item> + </item> + <item name="1" xsi:type="array"> + <item name="is_default" xsi:type="string">No</item> + <item name="admin" xsi:type="string">G</item> + <item name="view" xsi:type="string">G</item> + </item> + <item name="2" xsi:type="array"> + <item name="is_default" xsi:type="string">No</item> + <item name="admin" xsi:type="string">B</item> + <item name="view" xsi:type="string">B</item> + </item> + </field> + <field name="is_global" xsi:type="string">Global</field> + <field name="used_in_product_listing" xsi:type="string">Yes</field> + </dataset> + </repository> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.php new file mode 100644 index 0000000000000000000000000000000000000000..60cc61f7f0f79319336d57d0d81289de6fe31cab --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\TestCase; + +use Magento\Mtf\TestCase\Scenario; + +/** + * Preconditions: + * 1. Configure text swatch attribute. + * 2. Create configurable product with this attribute + * 3. Open it on catalog page + * 4. Click on 'Add to Cart' button + * + * Steps: + * 1. Go to Frontend. + * 2. Open category page with created product + * 3. Click on 'Add to Cart' button + * 4. Perform asserts + * + * @group Configurable_Product + * @ZephyrId MAGETWO-59958 + */ +class AddConfigurableProductWithSwatchToShopingCartTest extends Scenario +{ + /** + * Runs add configurable product with swatches attributes test. + * + * @return void + */ + public function test() + { + $this->executeScenario(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..adf8d71395ccb9c4b714ad58887ec741391871a2 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/AddConfigurableProductWithSwatchToShopingCartTest.xml @@ -0,0 +1,16 @@ +<?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\Swatches\Test\TestCase\AddConfigurableProductWithSwatchToShopingCartTest" summary="Create text swatch attribute" ticketId="MAGETWO-47017"> + <variation name="AddConfigurableProductWithSwatchToShopingCartTest1"> + <data name="attributeTypeAction" xsi:type="string">addOptions</data> + <data name="product" xsi:type="string">configurableProductSwatch::product_with_text_swatch</data> + <constraint name="Magento\Checkout\Test\Constraint\AssertCartItemsOptions" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ac3016ade3f016b82a856677715db6c93736c1ef --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\TestCase; + +use Magento\Mtf\TestCase\Scenario; + +/** + * Preconditions: + * 1. Configure text swatch attribute. + * 2. Create configurable product with this attribute + * 3. Open it on catalog page + * 4. Click on 'Add to Cart' button + * + * Steps: + * 1. Go to Frontend. + * 2. Open category page with created product + * 3. Click on 'Add to Cart' button + * 4. Perform asserts + * + * @group Configurable_Product + * @ZephyrId TODO: MAGETWO-59979 + */ +class TryToAddConfigurableProductWithSwatchToShopingCartTest extends Scenario +{ + /** + * Runs add configurable product with swatches attributes test. + * + * @return void + */ + public function test() + { + $this->executeScenario(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..4cb7a3e01676f09c6c3e6b9ffcd3d85fb9abbe4a --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestCase/TryToAddConfigurableProductWithSwatchToShopingCartTest.xml @@ -0,0 +1,16 @@ +<?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\Swatches\Test\TestCase\TryToAddConfigurableProductWithSwatchToShopingCartTest" summary="Create text swatch attribute" ticketId="MAGETWO-47017"> + <variation name="TryToAddConfigurableProductWithSwatchToShopingCartTest1"> + <data name="attributeTypeAction" xsi:type="string">addOptions</data> + <data name="product" xsi:type="string">configurableProductSwatch::product_with_text_swatch_and_size</data> + <constraint name="Magento\Swatches\Test\Constraint\AssertSwatchConfigurableProductPage" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/TestStep/AddProductToCartFromCatalogCategoryPageStep.php b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestStep/AddProductToCartFromCatalogCategoryPageStep.php new file mode 100644 index 0000000000000000000000000000000000000000..e19f9d7b3c362ca61d5869ea409c20359b4b4ffb --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/TestStep/AddProductToCartFromCatalogCategoryPageStep.php @@ -0,0 +1,96 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Swatches\Test\TestStep; + +use Magento\Mtf\TestStep\TestStepInterface; +use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Swatches\Test\Block\Product\ProductList\ProductItem; +use Magento\Mtf\Fixture\InjectableFixture; +use Magento\Catalog\Test\Page\Category\CatalogCategoryView; +use Magento\Cms\Test\Page\CmsIndex; + +/** + * Add configurable product to cart. + */ +class AddProductToCartFromCatalogCategoryPageStep implements TestStepInterface +{ + /** + * Fixture of configurable product with swatches configuration. + * + * @var \Magento\Swatches\Test\Fixture\ConfigurableProduct + */ + private $product; + + /** + * Fixture factory for create/get fixtures. + * + * @var FixtureFactory + */ + private $fixtureFactory; + + /** + * Page of catalog category view. + * + * @var CatalogCategoryView + */ + private $categoryView; + + /** + * CMS index page. + * + * @var CmsIndex + */ + private $cmsIndex; + + /** + * @constructor + * @param FixtureFactory $fixtureFactory + * @param CmsIndex $cmsIndex + * @param InjectableFixture $product + * @param CatalogCategoryView $categoryView + */ + public function __construct( + FixtureFactory $fixtureFactory, + CmsIndex $cmsIndex, + CatalogCategoryView $categoryView, + InjectableFixture $product + ) { + $this->fixtureFactory = $fixtureFactory; + $this->cmsIndex = $cmsIndex; + $this->categoryView = $categoryView; + $this->product = $product; + } + + /** + * Update configurable product. + * + * @return array + */ + public function run() + { + $categoryName = $this->product->getCategoryIds()[0]; + $this->cmsIndex->open(); + $this->cmsIndex->getTopmenu()->selectCategoryByName($categoryName); + /** @var \Magento\Swatches\Test\Block\Product\ListProduct $productsList */ + $productsList = $this->categoryView->getListSwatchesProductBlock(); + /** @var ProductItem $productItemBlock */ + $productItemBlock = $productsList->getProductItem($this->product); + $productItemBlock->fillData($this->product); + $productItemBlock->clickAddToCart(); + $cart = [ + 'data' => [ + 'items' => [ + 'products' => [$this->product] + ] + ] + ]; + + return [ + 'cart' => $this->fixtureFactory->createByCode('cart', $cart) + ]; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/curl/di.xml new file mode 100644 index 0000000000000000000000000000000000000000..ac3ad40f804e1abac634c135228d89fca3a90876 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/curl/di.xml @@ -0,0 +1,10 @@ +<?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="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\Swatches\Test\Handler\SwatchProductAttribute\SwatchProductAttributeInterface" type="\Magento\Swatches\Test\Handler\SwatchProductAttribute\Curl" /> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/testcase.xml new file mode 100644 index 0000000000000000000000000000000000000000..f2e30c42a7a859e52ad129eda213aa8b1e597aad --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Swatches/Test/etc/testcase.xml @@ -0,0 +1,16 @@ +<?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/TestCase/etc/testcase.xsd"> + <scenario name="AddConfigurableProductWithSwatchToShopingCartTest" firstStep="createProduct"> + <step name="createProduct" module="Magento_Catalog" next="addProductToCartFromCatalogCategoryPage" /> + <step name="addProductToCartFromCatalogCategoryPage" module="Magento_Swatches" /> + </scenario> + <scenario name="TryToAddConfigurableProductWithSwatchToShopingCartTest" firstStep="createProduct"> + <step name="createProduct" module="Magento_Catalog" /> + </scenario> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/RemoveTaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/RemoveTaxRule.php index 31ca2396f07827735fa3f686facb412807bdf59e..3e69145b42b3416efb88b6557c780d83eae59a1c 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/RemoveTaxRule.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/RemoveTaxRule.php @@ -39,9 +39,9 @@ class RemoveTaxRule extends Curl public function persist(FixtureInterface $fixture = null) { $this->taxRuleGridUrl = $_ENV['app_backend_url'] . 'tax/rule/index/'; - $curl = $this->_getCurl($this->taxRuleGridUrl); + $curl = $this->getCurl($this->taxRuleGridUrl); $response = $curl->read(); - $this->_removeTaxRules($response); + $this->removeTaxRules($response); $curl->close(); return $response; } diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php index 9cfa401510bc17bd1e0651f7cb3a71370c46a2fe..55a6694571ac14f4bdb805f57d847db5db87fc62 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php @@ -28,6 +28,7 @@ class CreateTaxRuleEntityTest extends Injectable /* tags */ const MVP = 'yes'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; + const TO_MAINTAIN = 'yes'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml index 5d338af60555fbb68836d8abb8a53cf9c2d7ceae..7bbf6d29e7b9fb13c7df662f885c2a089f73f843 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml @@ -19,6 +19,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleForm" /> </variation> <variation name="CreateTaxRuleEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="taxRule/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRule/data/tax_rate/dataset/rate_0" xsi:type="string">US-CA-Rate_1</data> <data name="taxRule/data/tax_rate/dataset/rate_1" xsi:type="string">US-NY-Rate_1</data> @@ -47,6 +48,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleForm" /> </variation> <variation name="CreateTaxRuleEntityTestVariation4"> + <data name="tag" xsi:type="string">stable:no</data> <data name="taxRule/data/code" xsi:type="string">TaxIdentifier%isolation%</data> <data name="taxRule/data/tax_rate/dataset/rate_0" xsi:type="string">withZipRange</data> <data name="taxRule/data/tax_rate/dataset/rate_1" xsi:type="string">US-CA-Rate_1</data> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml index 9414b9a0172f173d18604ed5929c5617adce4341..cda7bf0665b01b8ace1ef863d84932ab44388c47 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Tax\Test\TestCase\TaxCalculationTest" summary="Apply Taxes for products" ticketId="MAGETWO-27809"> <variation name="TaxCalculationTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax equals store tax and catalog price including tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, row_cat_incl_ship_excl_after_disc_on_excl, display_excluding_including_tax</data> <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data> @@ -37,6 +38,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> </variation> <variation name="TaxCalculationTestVariation4"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax less than store tax and catalog price including tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, row_cat_incl_ship_excl_before_disc_on_incl, display_excluding_including_tax</data> <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data> @@ -66,6 +68,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> </variation> <variation name="TaxCalculationTestVariation5"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax less than store tax and catalog price including tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, unit_cat_incl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data> <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data> @@ -95,6 +98,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> </variation> <variation name="TaxCalculationTestVariation6"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax equals store tax and catalog price excluding tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, total_cat_excl_ship_incl_before_disc_on_incl, display_excluding_including_tax</data> <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data> @@ -124,6 +128,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> </variation> <variation name="TaxCalculationTestVariation9"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Simple product tier price with sales rule, customer tax greater than store tax and catalog price excluding tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, total_cat_excl_ship_incl_after_disc_on_incl, display_excluding_including_tax</data> <data name="product" xsi:type="string">catalogProductSimple::simple_with_tier_price_and_category</data> @@ -153,6 +158,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertOrderTaxOnBackendExcludingIncludingTax" /> </variation> <variation name="TaxCalculationTestVariation10"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Simple product special price with sales rule, customer tax greater than store tax and catalog price excluding tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods, unit_cat_excl_ship_incl_after_disc_on_excl, display_excluding_including_tax</data> <data name="product" xsi:type="string">catalogProductSimple::product_with_special_price_and_category</data> diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php index 9517ee063ce67cbf33e50ed44412d8e7253526e2..09debcf5f75eb3441b6b18bcab438ecda3f757a3 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php @@ -37,6 +37,7 @@ class TaxWithCrossBorderTest extends Injectable { /* tags */ const MVP = 'yes'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.xml index a485579634ed95e4027f2147088257ad6b256a52..58e7b2b038cc20cfb4ab079254f18edd6413bf9f 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.xml @@ -48,6 +48,7 @@ <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleIsApplied" /> </variation> <variation name="UpdateTaxRuleEntityTestVariation4"> + <data name="tag" xsi:type="string">stable:no</data> <data name="initialTaxRule/dataset" xsi:type="string">tax_rule_with_custom_tax_classes</data> <data name="address/data/country_id" xsi:type="string">United States</data> <data name="address/data/region_id" xsi:type="string">Idaho</data> diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php index 80df7e6f8c631722fb314525b2d6733e2ac605ad..c5968c8e936f8a5bead20016d9c70d699b8c1a0c 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php @@ -71,7 +71,7 @@ class DataGrid extends Grid * * @var string */ - protected $massActionToggleList = '//span[contains(@class, "action-menu-item") and .= "%s"]'; + protected $massActionToggleList = './/span[contains(@class, "action-menu-item") and .= "%s"]'; /** * Action button (located above the Grid). @@ -85,7 +85,7 @@ class DataGrid extends Grid * * @var string */ - protected $actionList = '//span[contains(@class, "action-menu-item") and .= "%s"]'; + protected $actionList = './/span[contains(@class, "action-menu-item") and .= "%s"]'; /** * Column header locator. @@ -104,6 +104,13 @@ class DataGrid extends Grid * @var string */ private $cellByHeader = "//td[count(//th[span[.='%s']][not(ancestor::*[@class='sticky-header'])]/preceding-sibling::th)+1]"; + + /** + * Admin data grid header selector. + * + * @var string + */ + private $gridHeader = './/div[@class="admin__data-grid-header"][(not(ancestor::*[@class="sticky-header"]) and not(contains(@style,"visibility: hidden"))) or (ancestor::*[@class="sticky-header" and not(contains(@style,"display: none"))])]'; // @codingStandardsIgnoreEnd /** @@ -165,7 +172,7 @@ class DataGrid extends Grid */ protected function waitFilterToLoad() { - $this->getTemplateBlock()->waitForElementNotVisible($this->loader); + $this->getTemplateBlock()->waitLoader(); $browser = $this->_rootElement; $selector = $this->filterButton . ', ' . $this->resetButton; $browser->waitUntil( @@ -322,12 +329,12 @@ class DataGrid extends Grid public function selectAction($action) { $actionType = is_array($action) ? key($action) : $action; - $this->_rootElement->find($this->actionButton)->click(); - $this->_rootElement + $this->getGridHeaderElement()->find($this->actionButton)->click(); + $this->getGridHeaderElement() ->find(sprintf($this->actionList, $actionType), Locator::SELECTOR_XPATH) ->click(); if (is_array($action)) { - $this->_rootElement + $this->getGridHeaderElement() ->find(sprintf($this->actionList, end($action)), Locator::SELECTOR_XPATH) ->click(); } @@ -463,4 +470,14 @@ class DataGrid extends Grid return $data; } + + /** + * Returns admin data grid header element. + * + * @return \Magento\Mtf\Client\ElementInterface + */ + private function getGridHeaderElement() + { + return $this->_rootElement->find($this->gridHeader, Locator::SELECTOR_XPATH); + } } diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php index 39a80b783a0a1cf2dcb36a91e8d140bf3e236b8c..4b923dd4344a93be0e2bf3491c30eecf823f76ba 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php @@ -28,6 +28,7 @@ use Magento\Ui\Test\Block\Adminhtml\DataGrid; class GridFilteringTest extends Injectable { /* tags */ + const STABLE = 'no'; const MVP = 'no'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php index c0049f0cc2fb39d22758a1ce3cae3fcc22bf9552..510d2d61c0acd2100b295ee1422015b1833d9c36 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php @@ -28,6 +28,7 @@ use Magento\Ui\Test\Block\Adminhtml\DataGrid; class GridFullTextSearchTest extends Injectable { /* tags */ + const STABLE = 'no'; const MVP = 'no'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php index 2003bb4b27770239a2b9c2b8d75dc1a9a178f02b..fdf10565117764fa85727d38a4d10c44e4047261 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php @@ -31,6 +31,7 @@ class CreateAdminUserEntityTest extends Injectable /* tags */ const MVP = 'no'; const TEST_TYPE = 'extended_acceptance_test'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Usps/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Usps/Test/Repository/ConfigData.xml index 85c6a6fd80eecc69cc945d96a908f40dcfb1a356..83b50205387d5da98401799e7486aba04368c355 100644 --- a/dev/tests/functional/tests/app/Magento/Usps/Test/Repository/ConfigData.xml +++ b/dev/tests/functional/tests/app/Magento/Usps/Test/Repository/ConfigData.xml @@ -54,7 +54,6 @@ <item name="value" xsi:type="number">1</item> </field> </dataset> - <dataset name="usps_rollback"> <field name="carriers/usps/active" xsi:type="array"> <item name="scope" xsi:type="string">carriers</item> @@ -63,5 +62,21 @@ <item name="value" xsi:type="number">0</item> </field> </dataset> + <dataset name="usps_container_sm_flat_rate_box"> + <field name="carriers/usps/container" xsi:type="array"> + <item name="scope" xsi:type="string">carriers</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">Small Flat-Rate Box</item> + <item name="value" xsi:type="string">SM FLAT RATE BOX</item> + </field> + </dataset> + <dataset name="usps_container_sm_flat_rate_box_rollback"> + <field name="carriers/usps/container" xsi:type="array"> + <item name="scope" xsi:type="string">carriers</item> + <item name="scope_id" xsi:type="number">1</item> + <item name="label" xsi:type="string">Variable</item> + <item name="value" xsi:type="string">VARIABLE</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml index 0bd219bab3bfff2103ea9f7a1ff2934ca8e1ad59..8081b485c27d5c0e803a051f9126bdf6599e6781 100644 --- a/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml +++ b/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml @@ -16,10 +16,10 @@ <data name="address/dataset" xsi:type="string">US_address_1</data> <data name="shippingAddress/dataset" xsi:type="string">US_address_1_without_email</data> <data name="shipping/shipping_service" xsi:type="string">United States Postal Service</data> - <data name="shipping/shipping_method" xsi:type="string">Priority Mail 1-Day</data> - <data name="cart/data/shipping_method" xsi:type="string">Priority Mail 1-Day</data> + <data name="shipping/shipping_method" xsi:type="string">Priority Mail 1-Day Small Flat Rate Box</data> + <data name="cart/data/shipping_method" xsi:type="string">Priority Mail 1-Day Small Flat Rate Box</data> <data name="payment/method" xsi:type="string">checkmo</data> - <data name="configData" xsi:type="string">checkmo, usps, shipping_origin_US_CA</data> + <data name="configData" xsi:type="string">checkmo, usps, shipping_origin_US_CA, usps_container_sm_flat_rate_box</data> <data name="tag" xsi:type="string">test_type:3rd_party_test, severity:S0</data> <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage"/> <constraint name="Magento\Checkout\Test\Constraint\AssertMinicartEmpty" /> diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.xml b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.xml index 381728cb375aef1595153431fa704812689be7cd..4860c6c93696c038b9de309a9ee068e09d65b284 100644 --- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.xml @@ -19,6 +19,7 @@ <constraint name="Magento\Variable\Test\Constraint\AssertCustomVariableInPage" /> </variation> <variation name="CreateCustomVariableEntityTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="customVariable/data/code" xsi:type="string">variableCode%isolation%</data> <data name="customVariable/data/name" xsi:type="string">variableName%isolation%</data> <data name="customVariable/data/html_value" xsi:type="string"><p>variableName%isolation%</p></data> diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.xml b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.xml index 7f2306c5154e78095979c1b64c7f171feacd722f..7234c455fcc223a6b373a04cd0f0672a2c40781e 100644 --- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Variable\Test\TestCase\DeleteCustomVariableEntityTest" summary="Delete Custom Variable" ticketId="MAGETWO-25535"> <variation name="DeleteCustomVariableEntityTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <constraint name="Magento\Variable\Test\Constraint\AssertCustomVariableSuccessDeleteMessage" /> <constraint name="Magento\Variable\Test\Constraint\AssertCustomVariableNotInGrid" /> <constraint name="Magento\Variable\Test\Constraint\AssertCustomVariableNotInCmsPageForm" /> diff --git a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml index 060d2fbc9a7e6f51113238ebf186930d864eec4c..247b22c86a1b207e686fd584b06b297aa4fa3668 100644 --- a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml +++ b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Weee\Test\TestCase\CreateTaxWithFptTest" summary="Apply FPT to Different Type Prices" ticketId="MAGETWO-29551"> <variation name="CreateTaxWithFptTestVariation1" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Check not taxed FPT display set to Excluding, Description and Including FPT on product with custom option catalog price Excluding Tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_excl</data> <data name="productData" xsi:type="string">with_custom_option_and_fpt</data> @@ -28,6 +29,7 @@ <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" /> </variation> <variation name="CreateTaxWithFptTestVariation2" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Check not taxed FPT display set to Including FPT and Description on product with custom option catalog price Excluding Tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_incl, display_including_tax</data> <data name="productData" xsi:type="string">with_custom_option_and_fpt</data> @@ -50,6 +52,7 @@ <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" /> </variation> <variation name="CreateTaxWithFptTestVariation3" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Check not taxed FPT display set to Excluding, Description and Including FPT on product with special price catalog price Excluding Tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_incl, display_including_tax</data> <data name="productData" xsi:type="string">with_special_price_and_fpt</data> @@ -72,6 +75,7 @@ <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" /> </variation> <variation name="CreateTaxWithFptTestVariation4" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test"> + <data name="tag" xsi:type="string">stable:no</data> <data name="description" xsi:type="string">Check not taxed FPT display set to Including FPT and Description on product with special price catalog price Excluding Tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_excl</data> <data name="productData" xsi:type="string">with_special_price_and_fpt</data> @@ -92,6 +96,7 @@ <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" /> </variation> <variation name="CreateTaxWithFptTestVariation5" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="description" xsi:type="string">Check taxed FPT display set to Excluding, Description and Including FPT on product with with custom option catalog price Excluding Tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_taxed_cat_excl_disc_on_excl</data> <data name="productData" xsi:type="string">with_custom_option_and_fpt</data> @@ -204,6 +209,7 @@ <constraint name="Magento\Weee\Test\Constraint\AssertFptApplied" /> </variation> <variation name="CreateTaxWithFptTestVariation11" firstConstraint="Magento\Weee\Test\Constraint\AssertFptApplied" method="test"> + <data name="issue" xsi:type="string">MAGETWO-44968: FPT Final price includes tax on custom option, when display is set to excluding tax</data> <data name="description" xsi:type="string">Check taxed FPT display set to Excluding, Description and Including FPT on product with with custom option and catalog price Including Tax</data> <data name="configData" xsi:type="string">shipping_tax_class_taxable_goods,tax_with_fpt_taxed_cat_incl_disc_on_excl</data> <data name="productData" xsi:type="string">with_custom_option_and_fpt</data> diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/WidgetGrid.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/WidgetGrid.php index 50a5657a4783088eabef74ea56aed23cd8592835..2a03872f4be6bce82a7764ec0358f83c654a5b0a 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/WidgetGrid.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/WidgetGrid.php @@ -7,12 +7,20 @@ namespace Magento\Widget\Test\Block\Adminhtml\Widget; use Magento\Backend\Test\Block\Widget\Grid as AbstractGrid; +use Magento\Mtf\Client\Locator; /** * Widget grid on the Widget Instance Index page. */ class WidgetGrid extends AbstractGrid { + /** + * Selector for not empty options at select element. + * + * @var string + */ + private $notEmptyOptionsSelector = 'option:not([value=""])'; + /** * Locator value for link in action column. * @@ -36,5 +44,28 @@ class WidgetGrid extends AbstractGrid 'title' => [ 'selector' => 'input[name="title"]', ], + 'theme_id' => [ + 'selector' => 'select[name="theme_id"]', + 'input' => 'select', + ], ]; + + /** + * Returns values of theme_id filter. + * + * @return array + */ + public function getThemeIdValues() + { + $values = []; + $themeFilter = $this->filters['theme_id']; + $strategy = empty($themeFilter['strategy']) ? Locator::SELECTOR_CSS : $themeFilter['strategy']; + $element = $this->_rootElement->find($themeFilter['selector'], $strategy, $themeFilter['input']); + $options = $element->getElements($this->notEmptyOptionsSelector); + foreach ($options as $option) { + $values[] = $option->getText(); + } + + return $values; + } } diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertThemeFilterValuesOnWidgetGrid.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertThemeFilterValuesOnWidgetGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..31ebfd87c252b6e4142263636eb00329ab8d72b7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertThemeFilterValuesOnWidgetGrid.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Widget\Test\Constraint; + +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Widget\Test\Fixture\Widget; +use Magento\Widget\Test\Page\Adminhtml\WidgetInstanceIndex; + +/** + * Assert theme filter contains all possible values from created widgets. + */ +class AssertThemeFilterValuesOnWidgetGrid extends AbstractConstraint +{ + /** + * Assert theme filter contains all possible values from created widgets. + * + * @param Widget[] $widgets + * @param WidgetInstanceIndex $widgetInstanceIndex + * @return void + */ + public function processAssert(array $widgets, WidgetInstanceIndex $widgetInstanceIndex) + { + $expectedValues = []; + foreach ($widgets as $widget) { + $expectedValues[] = $widget->getThemeId(); + } + $widgetInstanceIndex->open(); + $actualValues = $widgetInstanceIndex->getWidgetGrid()->getThemeIdValues(); + \PHPUnit_Framework_Assert::assertEmpty( + array_diff($expectedValues, $actualValues), + 'Widget grid theme filter doesn\'t contain all possible values from created widgets.' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Widget grid theme filter contains all possible values from created widgets.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetInGrid.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetInGrid.php index 5382d544a94b9f590a3475c915025c205e1453cd..2cc675f79fbd38a0f7654b40acc5d215be2a5191 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetInGrid.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetInGrid.php @@ -11,7 +11,7 @@ use Magento\Widget\Test\Page\Adminhtml\WidgetInstanceIndex; use Magento\Mtf\Constraint\AbstractConstraint; /** - * Class AssertWidgetInGrid + * Assert widget is present in widget grid. */ class AssertWidgetInGrid extends AbstractConstraint { @@ -20,7 +20,10 @@ class AssertWidgetInGrid extends AbstractConstraint /* end tags */ /** - * Assert widget availability in widget grid + * Assert widget availability in widget grid. + * Verifying such fields as: + * - title + * - theme_id * * @param Widget $widget * @param WidgetInstanceIndex $widgetInstanceIndex @@ -28,7 +31,7 @@ class AssertWidgetInGrid extends AbstractConstraint */ public function processAssert(Widget $widget, WidgetInstanceIndex $widgetInstanceIndex) { - $filter = ['title' => $widget->getTitle()]; + $filter = ['title' => $widget->getTitle(), 'theme_id' => $widget->getThemeId()]; $widgetInstanceIndex->open(); \PHPUnit_Framework_Assert::assertTrue( $widgetInstanceIndex->getWidgetGrid()->isRowVisible($filter), @@ -37,7 +40,7 @@ class AssertWidgetInGrid extends AbstractConstraint } /** - * Returns a string representation of the object + * Returns a string representation of the object. * * @return string */ diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetsInGrid.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetsInGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..bc61b3ef66f51585b0e21fc7dc1a64b7f04e57f7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetsInGrid.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Widget\Test\Constraint; + +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Widget\Test\Fixture\Widget; +use Magento\Widget\Test\Page\Adminhtml\WidgetInstanceIndex; + +/** + * Assert widgets are present in widget grid. + */ +class AssertWidgetsInGrid extends AbstractConstraint +{ + /** + * Assert widgets are present in widget grid. + * Verifying such fields as: + * - title + * - theme_id + * + * @param Widget[] $widgets + * @param WidgetInstanceIndex $widgetInstanceIndex + * @param AssertWidgetInGrid $assertWidgetInGrid + * @return void + */ + public function processAssert( + array $widgets, + WidgetInstanceIndex $widgetInstanceIndex, + AssertWidgetInGrid $assertWidgetInGrid + ) { + foreach ($widgets as $widget) { + $assertWidgetInGrid->processAssert($widget, $widgetInstanceIndex); + } + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Widgets are present in widget grid.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php index 4c9e61cdb873db0b32d3b77d9c16be3601537364..54520d0786a52732123a7fc0634d363f74d4b43d 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php @@ -27,6 +27,7 @@ class Curl extends AbstractCurl protected $mappingData = [ 'code' => [ 'CMS Page Link' => 'cms_page_link', + 'Recently Viewed Products' => 'recently_viewed', ], 'block' => [ 'Main Content Area' => 'content', diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Repository/Widget.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/Repository/Widget.xml index dc39ed7fa1259a02da5eadbc84c38e22f64c71aa..4a8972bfd8dbb3f5a80b7f6fc8a7e20c2f80e0fc 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Repository/Widget.xml +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Repository/Widget.xml @@ -25,5 +25,20 @@ <item name="dataset" xsi:type="string">cmsPageLink</item> </field> </dataset> + + <dataset name="recently_viewed_products_on_blank_theme"> + <field name="code" xsi:type="string">Recently Viewed Products</field> + <field name="title" xsi:type="string">Title_%isolation%</field> + <field name="theme_id" xsi:type="string">Magento Blank</field> + <field name="store_ids" xsi:type="array"> + <item name="dataset" xsi:type="string">all_store_views</item> + </field> + <field name="widget_instance" xsi:type="array"> + <item name="dataset" xsi:type="string">for_viewed_products</item> + </field> + <field name="parameters" xsi:type="array"> + <item name="dataset" xsi:type="string">recentlyViewedProducts</item> + </field> + </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php index 6358ac8821f26b621de3e83f7ef8380ffb7c3efc..cc02293ff8fdd98febf581beb87e8a00d7b128fb 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php @@ -48,7 +48,7 @@ class CreateWidgetEntityTest extends AbstractCreateWidgetEntityTest // Preconditions $this->caches = $caches; $this->adjustCacheSettings(); - + // Steps $this->widgetInstanceIndex->open(); $this->widgetInstanceIndex->getPageActionsBlock()->addNew(); diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml index f533e115253ed52100fa5c9a9d51f4aa2303ca6b..225759df91f179dbd911fca662c05476c4830a69 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml @@ -19,7 +19,7 @@ <constraint name="Magento\Widget\Test\Constraint\AssertWidgetOnFrontendInCatalog" /> </variation> <variation name="CreateWidgetEntityTestVariation2"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1, stable:no</data> <data name="widget/data/code" xsi:type="string">CMS Page Link</data> <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data> <data name="widget/data/title" xsi:type="string">Title_%isolation%</data> @@ -42,7 +42,7 @@ <constraint name="Magento\Widget\Test\Constraint\AssertWidgetRecentlyViewedProducts" /> </variation> <variation name="CreateWidgetEntityTestVariation4"> - <data name="tag" xsi:type="string">severity:S1</data> + <data name="tag" xsi:type="string">severity:S1, stable:no</data> <data name="widget/data/code" xsi:type="string">Recently Compared Products</data> <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data> <data name="widget/data/title" xsi:type="string">Title_%isolation%</data> @@ -53,7 +53,7 @@ <constraint name="Magento\Widget\Test\Constraint\AssertWidgetRecentlyComparedProducts" /> </variation> <variation name="CreateWidgetEntityTestVariation5"> - <data name="tag" xsi:type="string">severity:S1</data> + <data name="tag" xsi:type="string">severity:S1, stable:no</data> <data name="widget/data/code" xsi:type="string">Catalog Category Link</data> <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data> <data name="widget/data/title" xsi:type="string">Title_%isolation%</data> @@ -76,6 +76,7 @@ <constraint name="Magento\Widget\Test\Constraint\AssertWidgetProductLink" /> </variation> <variation name="CreateWidgetEntityTestVariation7" summary="Assert widget with disabled block_html cache type"> + <data name="issue" xsi:type="string">MAGETWO-58146: There is no cache invalidate popup after creating widget with disabled block_html cache type</data> <data name="tag" xsi:type="string">severity:S2</data> <data name="caches/block_html" xsi:type="string">Disabled</data> <data name="widget/data/code" xsi:type="string">CMS Static Block</data> @@ -91,6 +92,7 @@ <constraint name="Magento\Widget\Test\Constraint\AssertWidgetOnFrontendInCatalog" /> </variation> <variation name="CreateWidgetEntityTestVariation8" summary="Assert widget with invalidated block_html cache type"> + <data name="issue" xsi:type="string">MAGETWO-58146: There is no cache invalidate popup after creating widget with disabled block_html cache type</data> <data name="tag" xsi:type="string">severity:S3</data> <data name="caches/block_html" xsi:type="string">Invalidated</data> <data name="widget/data/code" xsi:type="string">Catalog Category Link</data> @@ -106,7 +108,7 @@ <constraint name="Magento\Widget\Test\Constraint\AssertWidgetAbsentOnFrontendHome" /> </variation> <variation name="CreateWidgetEntityTestVariation9" summary="Create Catalog New Products List type widget"> - <data name="tag" xsi:type="string">severity:S1</data> + <data name="tag" xsi:type="string">severity:S1, stable:no</data> <data name="widget/data/code" xsi:type="string">Catalog New Products List</data> <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data> <data name="widget/data/title" xsi:type="string">Title_%isolation%</data> diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5269c315f78fc23c55e6848ec2482f850cdf2c0e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Widget\Test\TestCase; + +use Magento\Mtf\Fixture\FixtureFactory; +use \Magento\Mtf\TestCase\Injectable; +use Magento\Widget\Test\Fixture\Widget; + +/** + * Steps: + * 1. Create widgets. + * 2. Perform all assertions. + * + * @group Widget + * @ZephyrId MAGETWO-60672 + */ +class CreateWidgetsEntityTest extends Injectable +{ + /* tags */ + const SEVERITY = 'S3'; + /* end tags */ + + /** + * Create multiple widgets. + * + * @param array $widgets + * @param FixtureFactory $fixtureFactory + * @return array + */ + public function test(array $widgets, FixtureFactory $fixtureFactory) + { + /** @var Widget[] $widgetInstances */ + $widgetInstances = []; + // Preconditions + foreach ($widgets as $widget) { + $widget = $fixtureFactory->createByCode('widget', ['dataset' => $widget]); + $widget->persist(); + $widgetInstances[] = $widget; + } + + return ['widgets' => $widgetInstances]; + } + + /** + * Delete all widgets. + * + * @return void + */ + public function tearDown() + { + $this->objectManager->create(\Magento\Widget\Test\TestStep\DeleteAllWidgetsStep::class)->run(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..484ea26cf5253a6524b77e299ccdc2532924d3e9 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetsEntityTest.xml @@ -0,0 +1,18 @@ +<?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\Widget\Test\TestCase\CreateWidgetsEntityTest" summary="Create Widget" ticketId="MAGETWO-60672"> + <variation name="CreateWidgetEntityTestWithDifferentThemes" summary="Widgets with different themes is presented in grid/filter"> + <data name="tag" xsi:type="string">severity:S3</data> + <data name="widgets/0" xsi:type="string">default</data> + <data name="widgets/1" xsi:type="string">recently_viewed_products_on_blank_theme</data> + <constraint name="Magento\Widget\Test\Constraint\AssertThemeFilterValuesOnWidgetGrid" /> + <constraint name="Magento\Widget\Test\Constraint\AssertWidgetsInGrid" /> + </variation> + </testCase> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml index 122a9659cf2b6be0706218e1f761870784179ea7..c1595838b4f63d51d1732857c7ccdd6d6ff8bec3 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml @@ -66,4 +66,14 @@ <argument name="severity" xsi:type="string">S1</argument> </arguments> </type> + <type name="Magento\Widget\Test\Constraint\AssertWidgetsInGrid"> + <arguments> + <argument name="severity" xsi:type="string">S3</argument> + </arguments> + </type> + <type name="Magento\Widget\Test\Constraint\AssertThemeFilterValuesOnWidgetGrid"> + <arguments> + <argument name="severity" xsi:type="string">S3</argument> + </arguments> + </type> </config> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php index 076739590e1f19b86fee7bc105221f51efda34cb..226faf7d9ce507dccfa830cc0f7053cf998eb53e 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Block/Customer/Wishlist/Items/Product.php @@ -123,14 +123,12 @@ class Product extends Form $viewDetails = $this->_rootElement->find($this->viewDetails); if ($viewDetails->isVisible()) { $this->_rootElement->find($this->footer, Locator::SELECTOR_XPATH)->click(); - $viewDetails->click(); + $viewDetails->hover(); $labels = $this->_rootElement->getElements($this->optionLabel); $values = $this->_rootElement->getElements($this->optionValue); $data = []; foreach ($labels as $key => $label) { - if (!$label->isVisible()) { - $viewDetails->click(); - } + $viewDetails->hover(); $data[] = [ 'title' => $label->getText(), 'value' => str_replace('$', '', $values[$key]->getText()), @@ -164,6 +162,18 @@ class Product extends Form $this->_rootElement->find($this->price)->hover(); } + /** + * Returns product price + * + * @param string $currency + * @return string + */ + public function getPrice($currency = '$') + { + $price = $this->_rootElement->find($this->price)->getText(); + return str_replace($currency, '', $price); + } + /** * Get Wish List data for the Product. * diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductPriceIsNotZero.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductPriceIsNotZero.php new file mode 100644 index 0000000000000000000000000000000000000000..24f6222dac09eb34cf3c3d6c5a063341b2acc2ef --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/Constraint/AssertProductPriceIsNotZero.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Wishlist\Test\Constraint; + +class AssertProductPriceIsNotZero extends \Magento\Mtf\Constraint\AbstractConstraint +{ + /** + * Assert that product price is not zero in default wishlist. + * + * @param \Magento\Cms\Test\Page\CmsIndex $cmsIndex + * @param \Magento\Customer\Test\Page\CustomerAccountIndex $customerAccountIndex + * @param \Magento\Wishlist\Test\Page\WishlistIndex $wishlistIndex + * @param \Magento\Mtf\Fixture\InjectableFixture $product + * + * @return void + */ + public function processAssert( + \Magento\Cms\Test\Page\CmsIndex $cmsIndex, + \Magento\Customer\Test\Page\CustomerAccountIndex $customerAccountIndex, + \Magento\Wishlist\Test\Page\WishlistIndex $wishlistIndex, + \Magento\Mtf\Fixture\InjectableFixture $product + ) { + $cmsIndex->getLinksBlock()->openLink('My Account'); + $customerAccountIndex->getAccountMenuBlock()->openMenuItem('My Wish List'); + $wishlistItem = $wishlistIndex->getWishlistBlock()->getProductItemsBlock()->getItemProduct($product); + + \PHPUnit_Framework_Assert::assertNotEquals( + '0.00', + $wishlistItem->getPrice(), + $product->getName() . ' has zero price on Wish List page.' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Product price is not zero in default Wish List.'; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php index 9959796828df23943db8fc3f6dfdce4b6387e1ac..bd922feee99d0315b5f7f16ee13b60eb101b626e 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php @@ -48,15 +48,16 @@ class AddProductToWishlistEntityTest extends AbstractWishlistTest * * @param Customer $customer * @param string $product + * @param bool $configure * @return array */ - public function test(Customer $customer, $product) + public function test(Customer $customer, $product, $configure = true) { $product = $this->createProducts($product)[0]; // Steps: $this->loginCustomer($customer); - $this->addToWishlist([$product], true); + $this->addToWishlist([$product], $configure); return ['product' => $product]; } diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.xml index 0557fa298ce985313593216b561b181175719a70..1a50facc1d67d756ea9ccfb051db7bb0a643c23b 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Wishlist\Test\TestCase\AddProductToWishlistEntityTest" summary="Add Product to Wishlist" ticketId="MAGETWO-29045"> <variation name="AddProductToWishlistEntityTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/0" xsi:type="string">catalogProductSimple::default</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertAddProductToWishlistSuccessMessage" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> @@ -38,16 +39,25 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInCustomerBackendWishlist" /> </variation> <variation name="AddProductToWishlistEntityTestVariation6"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertAddProductToWishlistSuccessMessage" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInCustomerBackendWishlist" /> </variation> <variation name="AddProductToWishlistEntityTestVariation7"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/0" xsi:type="string">bundleProduct::bundle_fixed_product</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertAddProductToWishlistSuccessMessage" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInCustomerBackendWishlist" /> </variation> + <variation name="AddProductToWishlistEntityTestVariation8"> + <data name="product/0" xsi:type="string">configurableProduct::default</data> + <data name="configure" xsi:type="boolean">false</data> + <constraint name="Magento\Wishlist\Test\Constraint\AssertAddProductToWishlistSuccessMessage" /> + <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> + <constraint name="Magento\Wishlist\Test\Constraint\AssertProductPriceIsNotZero" /> + </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php index cf16a045c3487ca9c8520a03ff4b47fc83ed84dd..6fec88a05de2885c57a61383497b06c353b0823a 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php @@ -28,6 +28,7 @@ class AddProductsToCartFromCustomerWishlistOnFrontendTest extends AbstractWishli { /* tags */ const MVP = 'no'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml index 7f89b52dff6185330d0058d664fff9ea5c987d70..ab33641cd04420a2eaa7b92df44312278a0ec57e 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Wishlist\Test\TestCase\AddProductsToCartFromCustomerWishlistOnFrontendTest" summary="Add Products from Wishlist to Cart" ticketId="MAGETWO-25268"> <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_100_dollar</data> <data name="qty" xsi:type="string">2</data> <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" /> @@ -20,6 +21,7 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" /> </variation> <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation3"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="products/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data> <data name="products/2" xsi:type="string">catalogProductSimple::default</data> @@ -41,18 +43,21 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" /> </variation> <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation6"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">configurableProduct::default</data> <data name="qty" xsi:type="string">3</data> <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" /> </variation> <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation7"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="products/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data> <data name="qty" xsi:type="string">2</data> <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" /> </variation> <variation name="AddProductsToCartFromCustomerWishlistOnFrontendTestVariation8"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="products/0" xsi:type="string">bundleProduct::bundle_fixed_product</data> <data name="qty" xsi:type="string">2</data> <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" /> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.xml index ea6e122badf8bdcda1d57dcd4900b13a83d73d3a..62654bff2b7a91c4831a28b8f59068dc1667de14 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Wishlist\Test\TestCase\ConfigureProductInCustomerWishlistOnBackendTest" summary="Configure Products in Customer Wishlist on Backend" ticketId="MAGETWO-29257"> <variation name="ConfigureProductInCustomerWishlistOnBackendTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductInCustomerWishlistOnBackendGrid" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php index 3738dd0631e82510715c1ef10f2c12dd5cc7c5d1..037de4cba7bcaa00d884e2f5d926b8bc977f7c14 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php @@ -29,6 +29,7 @@ class ConfigureProductInCustomerWishlistOnFrontendTest extends AbstractWishlistT { /* tags */ const MVP = 'no'; + const STABLE = 'no'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.xml index c9da4e6ea9b2e4c12b7f8643939f30d8bc97b638..8708ea3c8073f559d2d72c6fbe1129de5fac5017 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.xml @@ -8,26 +8,31 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Wishlist\Test\TestCase\ConfigureProductInCustomerWishlistOnFrontendTest" summary="Configure Products in Customer Wishlist on Frontend" ticketId="MAGETWO-29507"> <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> </variation> <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/0" xsi:type="string">configurableProduct::default</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> </variation> <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation3"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> </variation> <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation4"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/0" xsi:type="string">downloadableProduct::with_two_separately_links</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> </variation> <variation name="ConfigureProductInCustomerWishlistOnFrontendTestVariation5"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/0" xsi:type="string">groupedProduct::three_simple_products</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.xml index 4d410c03d6fe6df49f6a306108d20bc8a9005e06..f74039110ea4476db0b3b01a17a2968179bc7529 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Wishlist\Test\TestCase\DeleteProductsFromWishlistOnFrontendTest" summary="Delete Products from Wishlist" ticketId="MAGETWO-28874"> <variation name="DeleteProductsFromWishlistOnFrontendTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductSimple::product_100_dollar</data> <data name="products/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data> <data name="removedProductsIndex" xsi:type="array"> @@ -16,6 +17,7 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertProductsIsAbsentInWishlist" /> </variation> <variation name="DeleteProductsFromWishlistOnFrontendTestVariation2"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductVirtual::product_50_dollar</data> <data name="removedProductsIndex" xsi:type="array"> <item name="0" xsi:type="string">1</item> @@ -23,6 +25,7 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistIsEmpty" /> </variation> <variation name="DeleteProductsFromWishlistOnFrontendTestVariation3"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">catalogProductSimple::default</data> <data name="products/1" xsi:type="string">catalogProductVirtual::product_50_dollar</data> <data name="products/2" xsi:type="string">catalogProductSimple::default</data> @@ -57,6 +60,7 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistIsEmpty" /> </variation> <variation name="DeleteProductsFromWishlistOnFrontendTestVariation7"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">downloadableProduct::with_two_separately_links</data> <data name="removedProductsIndex" xsi:type="array"> <item name="0" xsi:type="string">1</item> @@ -64,6 +68,7 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertWishlistIsEmpty" /> </variation> <variation name="DeleteProductsFromWishlistOnFrontendTestVariation8"> + <data name="tag" xsi:type="string">stable:no</data> <data name="products/0" xsi:type="string">groupedProduct::three_simple_products</data> <data name="removedProductsIndex" xsi:type="array"> <item name="0" xsi:type="string">1</item> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.xml index 3706c8f8b3085bbafc35d4974cbdefb8daacddf9..999591d3344f939db0865c53ce5cbd6013a5e069 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Wishlist\Test\TestCase\MoveProductFromShoppingCartToWishlistTest" summary="Move Products from Shopping Cart to Wishlist" ticketId="MAGETWO-29545"> <variation name="MoveProductFromShoppingCartToWishlistTestVariation1"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/0" xsi:type="string">catalogProductSimple::default</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertMoveProductToWishlistSuccessMessage" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> @@ -20,6 +21,7 @@ <constraint name="Magento\Checkout\Test\Constraint\AssertCartIsEmpty" /> </variation> <variation name="MoveProductFromShoppingCartToWishlistTestVariation3"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/0" xsi:type="string">downloadableProduct::with_two_separately_links</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertMoveProductToWishlistSuccessMessage" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> @@ -35,6 +37,7 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> </variation> <variation name="MoveProductFromShoppingCartToWishlistTestVariation5"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/0" xsi:type="string">bundleProduct::bundle_dynamic_product</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertMoveProductToWishlistSuccessMessage" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> @@ -42,6 +45,7 @@ <constraint name="Magento\Wishlist\Test\Constraint\AssertProductDetailsInWishlist" /> </variation> <variation name="MoveProductFromShoppingCartToWishlistTestVariation6"> + <data name="tag" xsi:type="string">stable:no</data> <data name="product/0" xsi:type="string">bundleProduct::bundle_fixed_product</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertMoveProductToWishlistSuccessMessage" /> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductIsPresentInWishlist" /> diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.xml b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.xml index 82d6bf563ae627530781c47c6ad90b5824bfcdc3..5025cb97250d780a56d956e28a5641437494a425 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.xml +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Wishlist\Test\TestCase\ViewProductInCustomerWishlistOnBackendTest" summary="View Product in Customer Wishlist on Backend" ticketId="MAGETWO-29616"> <variation name="ViewProductInCustomerWishlistOnBackendTestVariation1"> + <data name="tag" xsi:type="string">to_maintain:yes</data> <data name="product/0" xsi:type="string">catalogProductSimple::with_two_custom_option</data> <constraint name="Magento\Wishlist\Test\Constraint\AssertProductInCustomerWishlistOnBackendGrid" /> </variation> diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml new file mode 100644 index 0000000000000000000000000000000000000000..df7b03a994df4d322b533162f04dd45c2108d650 --- /dev/null +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/basic_green.xml @@ -0,0 +1,29 @@ +<?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/TestRunner/etc/testRunner.xsd"> + <rule scope="testcase"> + <deny> + <tag group="stable" value="no" /> + <tag group="to_maintain" value="yes" /> + </deny> + </rule> + <rule scope="testsuite"> + <deny> + <module value="Magento_Setup" strict="1" /> + <module value="Magento_SampleData" strict="1" /> + </deny> + </rule> + <rule scope="variation"> + <deny> + <tag group="test_type" value="3rd_party_test" /> + <tag group="stable" value="no" /> + <tag group="to_maintain" value="yes" /> + </deny> + </rule> +</config> diff --git a/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/module.xml b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/module.xml new file mode 100644 index 0000000000000000000000000000000000000000..ce5ed9cb663a759edf057291f11ccc6a75fe6266 --- /dev/null +++ b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/module.xml @@ -0,0 +1,14 @@ +<?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="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_TestModuleDirectoryZipCodes" setup_version="0.0.1" active="true"> + <sequence> + <module name="Magento_Directory"/> + </sequence> + </module> +</config> diff --git a/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/zip_codes.xml b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/zip_codes.xml new file mode 100644 index 0000000000000000000000000000000000000000..d4f121c60daeb8c44f327f8149f0148051c252ff --- /dev/null +++ b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/etc/zip_codes.xml @@ -0,0 +1,20 @@ +<?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="urn:magento:module:Magento_Directory:etc/zip_codes.xsd"> + <zip countryCode="NL"> + <codes> + <code id="pattern_1" active="true" example="test1">^[0-9]{4}\s[a-zA-Z]{2}$</code> + <code id="pattern_2" active="true" example="test2">^[0-5]{4}[a-z]{2}$</code> + </codes> + </zip> + <zip countryCode="NL_NEW"> + <codes> + <code id="pattern_1" active="true" example="test1">^[0-2]{4}[A-Z]{2}$</code> + </codes> + </zip> +</config> diff --git a/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/registration.php b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/registration.php new file mode 100644 index 0000000000000000000000000000000000000000..2ed368ecf3b23a4bd4db86357f6cbbca0bfc55de --- /dev/null +++ b/dev/tests/integration/_files/Magento/TestModuleDirectoryZipCodes/registration.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\Component\ComponentRegistrar; + +$registrar = new ComponentRegistrar(); +if ($registrar->getPath(ComponentRegistrar::MODULE, 'Magento_TestModuleDirectoryZipCodes') === null) { + ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_TestModuleDirectoryZipCodes', __DIR__); +} diff --git a/dev/tests/integration/_files/Magento/TestModuleSample/composer.json b/dev/tests/integration/_files/Magento/TestModuleSample/composer.json index 4d6383045d27f2123e84146eae970ec74ae77797..3e8e5650b85a77f75c079ae0ad9211a8d4d0764a 100644 --- a/dev/tests/integration/_files/Magento/TestModuleSample/composer.json +++ b/dev/tests/integration/_files/Magento/TestModuleSample/composer.json @@ -2,7 +2,7 @@ "name": "magento/module-sample-test", "description": "test sample module", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "100.1.*", "magento/module-integration": "100.1.*" }, diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 9ab7db147d811d370a4c2609d5baf5ea35225680..d8b2189e9f0d267d24d86ea77c67e84b2e2f73c9 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -1431,4 +1431,113 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase $this->assertEquals(implode(',', [$multiselectOptions[1]->getValue(), $multiselectOptions[2]->getValue()]), $product2->getData('multiselect_attribute')); } + + /** + * @param array $row + * @param string|null $behavior + * @param bool $expectedResult + * @magentoAppArea adminhtml + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + * @magentoDataFixture Magento/Catalog/Model/ResourceModel/_files/product_simple.php + * @dataProvider validateRowDataProvider + */ + public function testValidateRow(array $row, $behavior, $expectedResult) + { + $this->_model->setParameters(['behavior' => $behavior, 'entity' => 'catalog_product']); + $this->assertSame($expectedResult, $this->_model->validateRow($row, 1)); + } + + /** + * @return array + */ + public function validateRowDataProvider() + { + return [ + [ + 'row' => ['sku' => 'simple products'], + 'behavior' => null, + 'expectedResult' => true, + ], + [ + 'row' => ['sku' => 'simple products absent'], + 'behavior' => null, + 'expectedResult' => false, + ], + [ + 'row' => [ + 'sku' => 'simple products absent', + 'name' => 'Test', + 'product_type' => 'simple', + '_attribute_set' => 'Default', + 'price' => 10.20, + ], + 'behavior' => null, + 'expectedResult' => true, + ], + [ + 'row' => ['sku' => 'simple products'], + 'behavior' => Import::BEHAVIOR_ADD_UPDATE, + 'expectedResult' => true, + ], + [ + 'row' => ['sku' => 'simple products absent'], + 'behavior' => Import::BEHAVIOR_ADD_UPDATE, + 'expectedResult' => false, + ], + [ + 'row' => [ + 'sku' => 'simple products absent', + 'name' => 'Test', + 'product_type' => 'simple', + '_attribute_set' => 'Default', + 'price' => 10.20, + ], + 'behavior' => Import::BEHAVIOR_ADD_UPDATE, + 'expectedResult' => true, + ], + [ + 'row' => ['sku' => 'simple products'], + 'behavior' => Import::BEHAVIOR_DELETE, + 'expectedResult' => true, + ], + [ + 'row' => ['sku' => 'simple products absent'], + 'behavior' => Import::BEHAVIOR_DELETE, + 'expectedResult' => false, + ], + [ + 'row' => ['sku' => 'simple products'], + 'behavior' => Import::BEHAVIOR_REPLACE, + 'expectedResult' => false, + ], + [ + 'row' => ['sku' => 'simple products absent'], + 'behavior' => Import::BEHAVIOR_REPLACE, + 'expectedResult' => false, + ], + [ + 'row' => [ + 'sku' => 'simple products absent', + 'name' => 'Test', + 'product_type' => 'simple', + '_attribute_set' => 'Default', + 'price' => 10.20, + ], + 'behavior' => Import::BEHAVIOR_REPLACE, + 'expectedResult' => false, + ], + [ + 'row' => [ + 'sku' => 'simple products', + 'name' => 'Test', + 'product_type' => 'simple', + '_attribute_set' => 'Default', + 'price' => 10.20, + ], + 'behavior' => Import::BEHAVIOR_REPLACE, + 'expectedResult' => true, + ], + ]; + } } diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a6031429c66023491e2c411748046e76ecbddf41 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php @@ -0,0 +1,39 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Checkout\Controller\Cart\Index; + +/** + * @magentoDbIsolation enabled + */ +class CouponPostTest extends \Magento\TestFramework\TestCase\AbstractController +{ + /** + * Test for \Magento\Checkout\Controller\Cart\CouponPost::execute() with simple product + * + * @magentoDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php + */ + public function testExecute() + { + /** @var $session \Magento\Checkout\Model\Session */ + $session = $this->_objectManager->create(\Magento\Checkout\Model\Session::class); + $quote = $session->getQuote(); + $quote->setData('trigger_recollect', 1)->setTotalsCollectedFlag(true); + $inputData = [ + 'remove' => 0, + 'coupon_code' => 'test' + ]; + $this->getRequest()->setPostValue($inputData); + $this->dispatch( + 'checkout/cart/couponPost/' + ); + + $this->assertSessionMessages( + $this->equalTo(['The coupon code "test" is not valid.']), + \Magento\Framework\Message\MessageInterface::TYPE_ERROR + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php index 34a484f749b7807a7096e22fc24c21b8b6e6c5dd..54a068dad5d0a26f1564d662eb962eca64527110 100644 --- a/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php +++ b/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php @@ -229,4 +229,51 @@ class CartTest extends \Magento\TestFramework\TestCase\AbstractController } return null; } + + /** + * Test for \Magento\Checkout\Controller\Cart::execute() with simple product + * + * @param string $area + * @param string $expectedPrice + * @magentoDataFixture Magento/Catalog/_files/products.php + * @magentoAppIsolation enabled + * @dataProvider addAddProductDataProvider + */ + public function testAddToCartSimpleProduct($area, $expectedPrice) + { + $formKey = $this->_objectManager->get(\Magento\Framework\Data\Form\FormKey::class); + $postData = [ + 'qty' => '1', + 'product' => '1', + 'custom_price' => 1, + 'form_key' => $formKey->getFormKey(), + 'isAjax' => 1 + ]; + \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea($area); + $this->getRequest()->setPostValue($postData); + + $quote = $this->_objectManager->create(\Magento\Checkout\Model\Cart::class); + /** @var \Magento\Checkout\Controller\Cart\Add $controller */ + $controller = $this->_objectManager->create(\Magento\Checkout\Controller\Cart\Add::class, [$quote]); + $controller->execute(); + + $this->assertContains(json_encode([]), $this->getResponse()->getBody()); + $items = $quote->getItems()->getItems(); + $this->assertTrue(is_array($items), 'Quote doesn\'t have any items'); + $this->assertCount(1, $items, 'Expected quote items not equal to 1'); + $item = reset($items); + $this->assertEquals(1, $item->getProductId(), 'Quote has more than one product'); + $this->assertEquals($expectedPrice, $item->getPrice(), 'Expected product price failed'); + } + + /** + * Data provider for testAddToCartSimpleProduct + */ + public function addAddProductDataProvider() + { + return [ + 'frontend' => ['frontend', 'expected_price' => 10], + 'adminhtml' => ['adminhtml', 'expected_price' => 1] + ]; + } } diff --git a/dev/tests/integration/testsuite/Magento/Config/Model/Config/Backend/BaseurlTest.php b/dev/tests/integration/testsuite/Magento/Config/Model/Config/Backend/BaseurlTest.php index 0ce30e5b2984120c7e325a151d96c0ef044affa6..5a2db8ccb22fa0484ab71c04f8a6bbc4cbc7b0e6 100644 --- a/dev/tests/integration/testsuite/Magento/Config/Model/Config/Backend/BaseurlTest.php +++ b/dev/tests/integration/testsuite/Magento/Config/Model/Config/Backend/BaseurlTest.php @@ -95,33 +95,44 @@ class BaseurlTest extends \PHPUnit_Framework_TestCase $unsecurePlaceholder = '{{unsecure_base_url}}'; $unsecureSuffix = '{{unsecure_base_url}}test/'; $unsecureWrongSuffix = '{{unsecure_base_url}}test'; + $unsecureWrongDomainName = 'http://example.com_test/'; $securePlaceholder = '{{secure_base_url}}'; $secureSuffix = '{{secure_base_url}}test/'; $secureWrongSuffix = '{{secure_base_url}}test'; + $secureWrongDomainName = 'https://example.com_test/'; return [ ['', 'not a valid URL'], ['', 'example.com'], ['', 'http://example.com'], ['', 'http://example.com/uri'], + ['', $unsecureWrongDomainName], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, ''], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, $baseSuffix], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, $unsecureSuffix], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, $unsecurePlaceholder], + [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_URL, $unsecureWrongDomainName], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL, ''], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL, $baseSuffix], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL, $unsecureWrongSuffix], + [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_LINK_URL, $unsecureWrongDomainName], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_MEDIA_URL, $unsecureWrongSuffix], + [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_MEDIA_URL, $unsecureWrongDomainName], [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_STATIC_URL, $unsecureWrongSuffix], + [\Magento\Store\Model\Store::XML_PATH_UNSECURE_BASE_STATIC_URL, $unsecureWrongDomainName], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, ''], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, $baseSuffix], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, $secureSuffix], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, $securePlaceholder], + [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_URL, $secureWrongDomainName], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL, ''], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL, $baseSuffix], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL, $secureWrongSuffix], + [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_LINK_URL, $secureWrongDomainName], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_MEDIA_URL, $secureWrongSuffix], + [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_MEDIA_URL, $secureWrongDomainName], [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_STATIC_URL, $secureWrongSuffix], + [\Magento\Store\Model\Store::XML_PATH_SECURE_BASE_STATIC_URL, $secureWrongDomainName], ]; } } diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/ConfigurableTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5db97cc36614924ae915b7b924b2c7a1f575e344 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/ConfigurableTest.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * @magentoAppArea adminhtml + */ +class ConfigurableTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + protected function setUp() + { + $this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class); + $this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + */ + public function testGetProductFinalPriceIfOneOfChildIsDisabled() + { + /** @var Collection $collection */ + $collection = Bootstrap::getObjectManager()->get(CollectionFactory::class) + ->create(); + $configurableProduct = $collection + ->addIdFilter([1]) + ->addMinimalPrice() + ->load() + ->getFirstItem(); + $this->assertEquals(10, $configurableProduct->getMinimalPrice()); + + $childProduct = $this->productRepository->getById(10, false, null, true); + $childProduct->setStatus(Status::STATUS_DISABLED); + // update in global scope + $currentStoreId = $this->storeManager->getStore()->getId(); + $this->storeManager->setCurrentStore(Store::ADMIN_CODE); + $this->productRepository->save($childProduct); + $this->storeManager->setCurrentStore($currentStoreId); + + /** @var Collection $collection */ + $collection = Bootstrap::getObjectManager()->get(CollectionFactory::class) + ->create(); + $configurableProduct = $collection + ->addIdFilter([1]) + ->addMinimalPrice() + ->load() + ->getFirstItem(); + $this->assertEquals(20, $configurableProduct->getMinimalPrice()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php index ff08056e4b18def3f520d2a5d9f2090b168d5ec8..0d8361b4751e38a96ae4dbb7aadb86510dad92dc 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php @@ -1,5 +1,7 @@ <?php /** + * Creates a simple product to be used for test cases. + * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -72,7 +74,8 @@ $product->setTypeId(Type::TYPE_SIMPLE) 'is_in_stock' => 1, ] )->setCanSaveCustomOptions(true) - ->setHasOptions(true); + ->setHasOptions(true) + ->setCustomAttribute('test_configurable', 42); $oldOptions = [ [ diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php index 1576ff90cb38ee4cd89b68766395fa0746d071d6..5f9b9e928b3178f3ae06a8d5a885022cc8e954cc 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php @@ -313,6 +313,8 @@ class IndexTest extends \Magento\TestFramework\TestCase\AbstractBackendControlle $this->assertEquals(2, count($addresses)); $updatedAddress = $this->addressRepository->getById(1); $this->assertEquals('update firstname', $updatedAddress->getFirstname()); + $this->assertTrue($updatedAddress->isDefaultBilling()); + $this->assertEquals($updatedAddress->getId(), $customer->getDefaultBilling()); $newAddress = $this->accountManagement->getDefaultShippingAddress($customerId); $this->assertEquals('new firstname', $newAddress->getFirstname()); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c44e320e64f4d0cfe1646f97642a2080e604ed74 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Section/LoadTest.php @@ -0,0 +1,19 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Customer\Controller\Section; + +class LoadTest extends \Magento\TestFramework\TestCase\AbstractController +{ + public function testLoadInvalidSection() + { + $expected = [ + 'message' => '"section<invalid" section source is not supported', + ]; + $this->dispatch('/customer/section/load/?sections=section<invalid&update_section_id=false&_=147066166394'); + self::assertEquals(json_encode($expected), $this->getResponse()->getBody()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/Config/ReaderTest.php b/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/Config/ReaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2b57fcb43a1a4326fc80dadcbc8211f6ed35b623 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/Config/ReaderTest.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Model\Country\Postcode\Config; + +class ReaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Directory\Model\Country\Postcode\Config\Reader + */ + private $reader; + + protected function setUp() + { + $this->reader = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Directory\Model\Country\Postcode\Config\Reader::class + ); + } + + public function testRead() + { + $result = $this->reader->read(); + + $this->assertArrayHasKey('NL', $result); + $this->assertArrayHasKey('pattern_1', $result['NL']); + $this->assertArrayHasKey('pattern_2', $result['NL']); + + $this->assertEquals('test1', $result['NL']['pattern_1']['example']); + $this->assertEquals('^[0-9]{4}\s[a-zA-Z]{2}$', $result['NL']['pattern_1']['pattern']); + + $this->assertEquals('test2', $result['NL']['pattern_2']['example']); + $this->assertEquals('^[0-5]{4}[a-z]{2}$', $result['NL']['pattern_2']['pattern']); + + $this->assertArrayHasKey('NL_NEW', $result); + $this->assertArrayHasKey('pattern_1', $result['NL_NEW']); + + $this->assertEquals('test1', $result['NL_NEW']['pattern_1']['example']); + $this->assertEquals('^[0-2]{4}[A-Z]{2}$', $result['NL_NEW']['pattern_1']['pattern']); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeManagementTest.php b/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeManagementTest.php new file mode 100644 index 0000000000000000000000000000000000000000..82d83938db148ace03cedf19a89cf098517a1d56 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeManagementTest.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Eav\Model; + +class AttributeManagementTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Eav\Api\AttributeManagementInterface + */ + private $model; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->model = $this->objectManager->create(\Magento\Eav\Api\AttributeManagementInterface::class); + } + + /** + * Verify that collection in service used correctly + */ + public function testGetList() + { + $productAttributeSetId = $this->getAttributeSetId( + \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE + ); + $productAttributes = $this->model->getAttributes( + \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE, + $productAttributeSetId + ); + // Verify that result contains only product attributes + $this->verifyAttributeSetIds($productAttributes, $productAttributeSetId); + + $categoryAttributeSetId = $this->getAttributeSetId( + \Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE + ); + $categoryAttributes = $this->model->getAttributes( + \Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE, + $categoryAttributeSetId + ); + // Verify that result contains only category attributes + $this->verifyAttributeSetIds($categoryAttributes, $categoryAttributeSetId); + } + + /** + * @param string $entityTypeCode + * @return int + */ + private function getAttributeSetId($entityTypeCode) + { + /** @var \Magento\Eav\Model\Config $eavConfig */ + $eavConfig = $this->objectManager->create(\Magento\Eav\Model\Config::class); + return $eavConfig->getEntityType($entityTypeCode)->getDefaultAttributeSetId(); + } + + /** + * @param array $items + * @param string $attributeSetId + * @return void + */ + private function verifyAttributeSetIds(array $items, $attributeSetId) + { + /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $item */ + foreach ($items as $item) { + $this->assertEquals($attributeSetId, $item->getAttributeSetId()); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php b/dev/tests/integration/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php index 8a566a0d4efe55e856716c095f5a3a7e14896af1..14118414859f0d9bced34e393bfb699f22251edf 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php @@ -12,6 +12,7 @@ namespace Magento\Framework\DB\Adapter\Pdo; use Magento\Framework\App\ResourceConnection; +use Zend_Db_Statement_Exception; class MysqlTest extends \PHPUnit_Framework_TestCase { @@ -32,6 +33,7 @@ class MysqlTest extends \PHPUnit_Framework_TestCase restore_error_handler(); } + /** * Test lost connection re-initializing * @@ -125,9 +127,9 @@ class MysqlTest extends \PHPUnit_Framework_TestCase protected function _getConnection() { if (is_null($this->_connection)) { - /** @var $coreResource \Magento\Framework\App\ResourceConnection */ + /** @var $coreResource ResourceConnection */ $coreResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->get(\Magento\Framework\App\ResourceConnection::class); + ->get(ResourceConnection::class); $this->_connection = $coreResource->getConnection(); } return $this->_connection; diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php index 9acfa6f1caab150b0a0db2d54e87358adf88cf5b..67a6e416973493887912e2e62674108b1694c315 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php @@ -414,6 +414,37 @@ class AdapterTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expectedRecordsCount, $queryResponse->count()); } + /** + * @magentoDataFixture Magento/Framework/Search/_files/product_configurable.php + * @magentoConfigFixture current_store catalog/search/engine mysql + */ + public function testAdvancedSearchCompositeProductWithOutOfStockOption() + { + /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ + $attribute = $this->objectManager->get(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) + ->loadByCode(\Magento\Catalog\Model\Product::ENTITY, 'test_configurable'); + /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection $selectOptions */ + $selectOptions = $this->objectManager + ->create(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection::class) + ->setAttributeFilter($attribute->getId()); + + $firstOption = $selectOptions->getFirstItem(); + $firstOptionId = $firstOption->getId(); + $this->requestBuilder->bind('test_configurable', $firstOptionId); + $this->requestBuilder->setRequestName('filter_out_of_stock_child'); + + $queryResponse = $this->executeQuery(); + $this->assertEquals(0, $queryResponse->count()); + + $secondOption = $selectOptions->getLastItem(); + $secondOptionId = $secondOption->getId(); + $this->requestBuilder->bind('test_configurable', $secondOptionId); + $this->requestBuilder->setRequestName('filter_out_of_stock_child'); + + $queryResponse = $this->executeQuery(); + $this->assertEquals(1, $queryResponse->count()); + } + public function dateDataProvider() { return [ diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute.php new file mode 100644 index 0000000000000000000000000000000000000000..030e0250c3ec7fed4747aed4e168413207c7daf7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Eav\Api\AttributeRepositoryInterface; + +$eavConfig = Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class); +$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable'); + +$eavConfig->clear(); + +/** @var $installer \Magento\Catalog\Setup\CategorySetup */ +$installer = Bootstrap::getObjectManager()->create(\Magento\Catalog\Setup\CategorySetup::class); + +if (!$attribute->getId()) { + + /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ + $attribute = Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class + ); + + /** @var AttributeRepositoryInterface $attributeRepository */ + $attributeRepository = Bootstrap::getObjectManager()->create(AttributeRepositoryInterface::class); + + $attribute->setData( + [ + 'attribute_code' => 'test_configurable', + 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), + 'is_global' => 1, + 'is_user_defined' => 1, + 'frontend_input' => 'select', + 'is_unique' => 0, + 'is_required' => 0, + 'is_searchable' => 1, + 'is_visible_in_advanced_search' => 1, + 'is_comparable' => 0, + 'is_filterable' => 1, + 'is_filterable_in_search' => 1, + 'is_used_for_promo_rules' => 0, + 'is_html_allowed_on_front' => 1, + 'is_visible_on_front' => 0, + 'used_in_product_listing' => 0, + 'used_for_sort_by' => 0, + 'frontend_label' => ['Test Configurable'], + 'backend_type' => 'int', + 'option' => [ + 'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']], + 'order' => ['option_0' => 1, 'option_1' => 2], + ], + ] + ); + + $attributeRepository->save($attribute); +} + +/* Assign attribute to attribute set */ +$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId()); +$eavConfig->clear(); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..bd18100f6d97b4b9b56c9743e8064e0723fdc6c8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/configurable_attribute_rollback.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); +$productCollection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\ResourceModel\Product\Collection::class); +foreach ($productCollection as $product) { + $product->delete(); +} + +$eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class); +$attribute = $eavConfig->getAttribute('catalog_product', 'test_configurable'); +if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute + && $attribute->getId() +) { + $attribute->delete(); +} +$eavConfig->clear(); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php new file mode 100644 index 0000000000000000000000000000000000000000..590f3c8041c6d819fafa14ef7ddc4d1f2ebccbeb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php @@ -0,0 +1,147 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\Product\Type; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Catalog\Setup\CategorySetup; +use Magento\ConfigurableProduct\Helper\Product\Options\Factory; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\Eav\Api\Data\AttributeOptionInterface; +use Magento\TestFramework\Helper\Bootstrap; + +\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize(); + +require __DIR__ . '/configurable_attribute.php'; + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = Bootstrap::getObjectManager() + ->create(ProductRepositoryInterface::class); + +/** @var $installer CategorySetup */ +$installer = Bootstrap::getObjectManager()->create(CategorySetup::class); + +/* Create simple products per each option value*/ +/** @var AttributeOptionInterface[] $options */ +$options = $attribute->getOptions(); + +$attributeValues = []; +$attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default'); +$associatedProductIds = []; +$productIds = [10, 20]; +array_shift($options); //remove the first option which is empty + +$isFirstOption = true; +foreach ($options as $option) { + /** @var $product Product */ + $product = Bootstrap::getObjectManager()->create(Product::class); + $productId = array_shift($productIds); + $product->setTypeId(Type::TYPE_SIMPLE) + ->setId($productId) + ->setAttributeSetId($attributeSetId) + ->setWebsiteIds([1]) + ->setName('Configurable Option' . $option->getLabel()) + ->setSku('simple_' . $productId) + ->setPrice($productId) + ->setTestConfigurable($option->getValue()) + ->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData( + [ + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 0, + 'is_in_stock' => (int)!$isFirstOption, + ] + ); + + $product = $productRepository->save($product); + + /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */ + $stockItem = Bootstrap::getObjectManager()->create(\Magento\CatalogInventory\Model\Stock\Item::class); + $stockItem->load($productId, 'product_id'); + + if (!$stockItem->getProductId()) { + $stockItem->setProductId($productId); + } + $stockItem->setUseConfigManageStock(1); + $stockItem->setQty(1000); + $stockItem->setIsQtyDecimal(0); + $stockItem->setIsInStock((int)!$isFirstOption); + $stockItem->save(); + + $attributeValues[] = [ + 'label' => 'test', + 'attribute_id' => $attribute->getId(), + 'value_index' => $option->getValue(), + ]; + $associatedProductIds[] = $product->getId(); + $isFirstOption = false; +} + +/** @var $product Product */ +$product = Bootstrap::getObjectManager()->create(Product::class); + +/** @var Factory $optionsFactory */ +$optionsFactory = Bootstrap::getObjectManager()->create(Factory::class); + +$configurableAttributesData = [ + [ + 'attribute_id' => $attribute->getId(), + 'code' => $attribute->getAttributeCode(), + 'label' => $attribute->getStoreLabel(), + 'position' => '0', + 'values' => $attributeValues, + ], +]; + +$configurableOptions = $optionsFactory->create($configurableAttributesData); + +$extensionConfigurableAttributes = $product->getExtensionAttributes(); +$extensionConfigurableAttributes->setConfigurableProductOptions($configurableOptions); +$extensionConfigurableAttributes->setConfigurableProductLinks($associatedProductIds); + +$product->setExtensionAttributes($extensionConfigurableAttributes); + +// Remove any previously created product with the same id. +/** @var \Magento\Framework\Registry $registry */ +$registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); +try { + $productToDelete = $productRepository->getById(1); + $productRepository->delete($productToDelete); + + /** @var \Magento\Quote\Model\ResourceModel\Quote\Item $itemResource */ + $itemResource = Bootstrap::getObjectManager()->get(\Magento\Quote\Model\ResourceModel\Quote\Item::class); + $itemResource->getConnection()->delete( + $itemResource->getMainTable(), + 'product_id = ' . $productToDelete->getId() + ); +} catch (\Exception $e) { + // Nothing to remove +} +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); + +$product->setTypeId(Configurable::TYPE_CODE) + ->setId(1) + ->setAttributeSetId($attributeSetId) + ->setWebsiteIds([1]) + ->setName('Configurable Product') + ->setSku('configurable') + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData(['use_config_manage_stock' => 1, 'is_in_stock' => 1]); + +$productRepository->save($product); +// +///** @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor $eavIndexer */ +//$eavIndexer = Bootstrap::getObjectManager() +// ->get(\Magento\Catalog\Model\Indexer\Product\Eav\Processor::class); +//$eavIndexer->reindexAll(); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_rollback.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..8ba4e3abe21cc14a75a66270d22ea262dffeb788 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_rollback.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Framework\Registry $registry */ +$registry = $objectManager->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +foreach (['simple_10', 'simple_20', 'configurable'] as $sku) { + try { + $product = $productRepository->get($sku, false, null, true); + + $stockStatus = $objectManager->create(\Magento\CatalogInventory\Model\Stock\Status::class); + $stockStatus->load($product->getEntityId(), 'product_id'); + $stockStatus->delete(); + + $productRepository->delete($product); + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + //Product already removed + } +} + +require __DIR__ . '/configurable_attribute_rollback.php'; + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml index 0cdfa11c3b6b5744abbd911e063553cd23039cc5..4cdc9a93e1f1f0ee093b8e0fd8e555a157fce851 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/requests.xml @@ -387,4 +387,24 @@ <from>0</from> <size>10</size> </request> + <request query="filter_out_of_stock_child" index="catalogsearch_fulltext"> + <dimensions> + <dimension name="scope" value="default"/> + </dimensions> + <queries> + <query xsi:type="boolQuery" name="filter_out_of_stock_child" boost="1"> + <queryReference clause="must" ref="test_configurable"/> + </query> + <query xsi:type="filteredQuery" name="test_configurable"> + <filterReference clause="must" ref="test_configurable_filter"/> + </query> + </queries> + <filters> + <filter xsi:type="termFilter" name="test_configurable_filter" field="test_configurable" value="$test_configurable$"/> + </filters> + <aggregations/> + <from>0</from> + <size>10</size> + </request> + </requests> diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml b/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml index f9f8f1ffba91a55536c9d2221b68dc85b702e7f0..19feb33748c840b6c87f506ffd450897e2ace286 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml @@ -593,7 +593,8 @@ <label>Express Checkout</label> <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model> <field id="business_account" translate="label comment tooltip" showInDefault="1" showInWebsite="1" sortOrder="5"> - <label>Email Associated with PayPal Merchant Account</label> + <label>Email Associated with PayPal Merchant Account (Optional)</label> + <frontend_class>not-required</frontend_class> <comment> <![CDATA[<a href="http://www.magentocommerce.com/paypal">Start accepting payments via PayPal!</a>]]> </comment> diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json index 222e5ff822b043185e44719804e0af75d8809c6e..a004d3a86b5b9d0c68ec096ab8beff48fa1e51c5 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/A/composer.json @@ -1,7 +1,7 @@ { "name": "magento/module-a", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "0.1", "magento/module-b": "0.1" }, diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json index 57944758267fd668f541b34586a8eb9f7acd9c98..0626cc6a84d055757c32d9192cc7f2682696912f 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/app/code/Magento/B/composer.json @@ -1,7 +1,7 @@ { "name": "magento/module-b", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "0.74.0-beta6", "magento/module-a": "0.1" }, diff --git a/dev/tests/integration/testsuite/Magento/Setup/Controller/UrlCheckTest.php b/dev/tests/integration/testsuite/Magento/Setup/Controller/UrlCheckTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6fe9ec2ee3ea13ef4b2b5881e4970f7aa99e9447 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Setup/Controller/UrlCheckTest.php @@ -0,0 +1,98 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Setup\Controller; + +use Magento\TestFramework\Helper\Bootstrap; +use Zend\Stdlib\RequestInterface as Request; +use Zend\View\Model\JsonModel; + +class UrlCheckTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var UrlCheck + */ + private $controller; + + protected function setUp() + { + $this->controller = Bootstrap::getObjectManager()->create(UrlCheck::class); + } + + /** + * @param array $requestContent + * @param bool $successUrl + * @param bool $successSecureUrl + * @return void + * @dataProvider indexActionDataProvider + */ + public function testIndexAction($requestContent, $successUrl, $successSecureUrl) + { + $requestMock = $this->getMockBuilder(Request::class) + ->getMockForAbstractClass(); + $requestMock->expects($this->once()) + ->method('getContent') + ->willReturn(json_encode($requestContent)); + + $requestProperty = new \ReflectionProperty(get_class($this->controller), 'request'); + $requestProperty->setAccessible(true); + $requestProperty->setValue($this->controller, $requestMock); + + $resultModel = new JsonModel(['successUrl' => $successUrl, 'successSecureUrl' => $successSecureUrl]); + + $this->assertEquals($resultModel, $this->controller->indexAction()); + } + + /** + * @return array + */ + public function indexActionDataProvider() + { + return [ + [ + 'requestContent' => [ + 'address' => [ + 'actual_base_url' => 'http://example.com/' + ], + 'https' => [ + 'text' => 'https://example.com/', + 'admin' => true, + 'front' => false + ], + ], + 'successUrl' => true, + 'successSecureUrl' => true + ], + [ + 'requestContent' => [ + 'address' => [ + 'actual_base_url' => 'http://example.com/folder/' + ], + 'https' => [ + 'text' => 'https://example.com/folder_name/', + 'admin' => false, + 'front' => true + ], + ], + 'successUrl' => true, + 'successSecureUrl' => true + ], + [ + 'requestContent' => [ + 'address' => [ + 'actual_base_url' => 'ftp://example.com/' + ], + 'https' => [ + 'text' => 'https://example.com_test/', + 'admin' => true, + 'front' => true + ], + ], + 'successUrl' => false, + 'successSecureUrl' => false + ], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8fac1c9b0e7031277e59c67d31c8bbff555910c0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php @@ -0,0 +1,135 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Webapi\Model; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Customer\Api\AccountManagementInterface; +use Magento\Framework\Exception\LocalizedException; + +class ServiceMetadataTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ServiceMetadata + */ + private $serviceMetadata; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->serviceMetadata = $objectManager->create(ServiceMetadata::class); + } + + public function testGetServiceMetadata() + { + $expected = [ + 'methods' => [ + 'activate' => [ + 'method' => 'activate', + 'inputRequired' => false, + 'isSecure' => false, + 'resources' => [ + 'Magento_Customer::manage' + ], + 'documentation' => 'Activate a customer account using a key that was sent in a confirmation email.', + 'interface' => [ + 'in' => [ + 'parameters' => [ + 'email' => [ + 'type' => 'string', + 'required' => true, + 'documentation' => null + ], + 'confirmationKey' => [ + 'type' => 'string', + 'required' => true, + 'documentation' => null + ] + ] + ], + 'out' => [ + 'parameters' => [ + 'result' => [ + 'type' => 'CustomerDataCustomerInterface', + 'required' => true, + 'documentation' => '' + ] + ], + 'throws' => [ + '\\' . LocalizedException::class + ] + ] + ] + ] + ], + 'class' => AccountManagementInterface::class, + 'description' => 'Interface for managing customers accounts.', + ]; + $actual = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1'); + $this->assertEquals(array_replace_recursive($actual, $expected), $actual); + } + + public function testGetRouteMetadata() + { + $expected = [ + 'methods' => [ + 'activate' => [ + 'method' => 'activate', + 'inputRequired' => false, + 'isSecure' => false, + 'resources' => [ + 'Magento_Customer::manage' + ], + 'documentation' => 'Activate a customer account using a key that was sent in a confirmation email.', + 'interface' => [ + 'in' => [ + 'parameters' => [ + 'email' => [ + 'type' => 'string', + 'required' => true, + 'documentation' => null + ], + 'confirmationKey' => [ + 'type' => 'string', + 'required' => true, + 'documentation' => null + ] + ] + ], + 'out' => [ + 'parameters' => [ + 'result' => [ + 'type' => 'CustomerDataCustomerInterface', + 'required' => true, + 'documentation' => '' + ] + ], + 'throws' => [ + '\\' . LocalizedException::class + ] + ] + ] + ] + ], + 'class' => AccountManagementInterface::class, + 'description' => 'Interface for managing customers accounts.', + 'routes' => [ + '/V1/customers/me/activate' => [ + 'PUT' => [ + 'method' => 'activateById', + 'parameters' => [ + 'customerId' => [ + 'force' => true, + 'value' => '%customer_id%' + ] + ] + ] + ] + ] + ]; + $actual = $this->serviceMetadata->getRouteMetadata('customerAccountManagementV1'); + $this->assertEquals(array_replace_recursive($actual, $expected), $actual); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ff1634c60782aee3de08203078f9592716de7803 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php @@ -0,0 +1,115 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Webapi\Model\Soap; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Customer\Api\AccountManagementInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Framework\Exception\LocalizedException; + +class ConfigTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Config + */ + private $soapConfig; + + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->soapConfig = $objectManager->create(Config::class); + } + + public function testGetRequestedSoapServices() + { + $expected = [ + 'customerAccountManagementV1' => [ + 'methods' => [ + 'activate' => [ + 'method' => 'activate', + 'inputRequired' => false, + 'isSecure' => false, + 'resources' => [ + 'Magento_Customer::manage' + ], + 'documentation' + => 'Activate a customer account using a key that was sent in a confirmation email.', + 'interface' => [ + 'in' => [ + 'parameters' => [ + 'email' => [ + 'type' => 'string', + 'required' => true, + 'documentation' => null + ], + 'confirmationKey' => [ + 'type' => 'string', + 'required' => true, + 'documentation' => null + ] + ] + ], + 'out' => [ + 'parameters' => [ + 'result' => [ + 'type' => 'CustomerDataCustomerInterface', + 'required' => true, + 'documentation' => null + ] + ], + 'throws' => [ + '\\' . LocalizedException::class + ] + ] + ] + ] + ], + 'class' => AccountManagementInterface::class, + 'description' => 'Interface for managing customers accounts.', + ] + ]; + $actual = $this->soapConfig->getRequestedSoapServices( + [ + 'customerAccountManagementV1', + 'NonExistentService' + ] + ); + $this->assertEquals(array_replace_recursive($actual, $expected), $actual); + } + + public function testGetServiceMethodInfo() + { + $expected = [ + 'class' => CustomerRepositoryInterface::class, + 'method' => 'getById', + 'isSecure' => false, + 'resources' => [ + 'Magento_Customer::customer', + 'self' + ], + ]; + $actual = $this->soapConfig->getServiceMethodInfo( + 'customerCustomerRepositoryV1GetById', + [ + 'customerCustomerRepositoryV1', + 'NonExistentService' + ] + ); + $this->assertEquals($expected, $actual); + } + + public function testGetSoapOperation() + { + $expected = 'customerAccountManagementV1Activate'; + $actual = $this->soapConfig + ->getSoapOperation( + AccountManagementInterface::class, + 'activate', + 'V1' + ); + $this->assertEquals($expected, $actual); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json b/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json index 920dc1289b0cfa00cd696b35fb495434830850f6..47f9eb415d7badb00345e5436e2c10bd64532c2f 100644 --- a/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json +++ b/dev/tests/integration/testsuite/Magento/Widget/_files/design/adminhtml/magento_basic/composer.json @@ -2,7 +2,7 @@ "name": "magento/admin-Magento_Catalog", "description": "N/A", "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "magento/framework": "0.1.0-alpha103" }, "type": "magento2-theme", diff --git a/dev/tests/js/JsTestDriver/run_js_tests.php b/dev/tests/js/JsTestDriver/run_js_tests.php index e6578c52b0699ee334c2f0ce9213ec5f78373330..448fd85869cd28dea34d7a00384838674f086c5a 100644 --- a/dev/tests/js/JsTestDriver/run_js_tests.php +++ b/dev/tests/js/JsTestDriver/run_js_tests.php @@ -30,6 +30,8 @@ if (isset($config['Browser'])) { } else { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $browser = 'C:\Program Files (x86)\Mozilla Firefox\firefox.exe'; + } elseif (PHP_OS === 'Darwin') { + $browser = '/Applications/Firefox.app/Contents/MacOS/firefox'; } else { $browser = exec('which firefox'); } @@ -139,29 +141,35 @@ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { kill -9 $LSOF fi - DISPLAY_NUM=99 - ps -ef | egrep "[X]vfb.*:$DISPLAY_NUM" - if [ $? -eq 0 ] ; then - pkill Xvfb + # Skip Xvfb setup for OS X since there browsers do not support headless display that way + if [ "$(uname)" != "Darwin" ]; then + DISPLAY_NUM=99 + ps -ef | egrep "[X]vfb.*:$DISPLAY_NUM" + if [ $? -eq 0 ] ; then + pkill Xvfb + fi + + XVFB=`which Xvfb` + if [ "$?" -eq 1 ]; + then + echo "Xvfb not found." + exit 1 + fi + + $XVFB :$DISPLAY_NUM -nolisten inet6 -ac & + PID_XVFB="$!" # take the process ID + export DISPLAY=:$DISPLAY_NUM # set display to use that of the Xvfb fi - - XVFB=`which Xvfb` - if [ "$?" -eq 1 ]; - then - echo "Xvfb not found." - exit 1 - fi - - $XVFB :$DISPLAY_NUM -nolisten inet6 -ac & - PID_XVFB="$!" # take the process ID - export DISPLAY=:$DISPLAY_NUM # set display to use that of the Xvfb + USER=`whoami` SUDO=`which sudo` # run the tests $SUDO -u $USER ' . $command . ' - kill -9 $PID_XVFB # shut down Xvfb (firefox will shut down cleanly by JsTestDriver) + if [ "$(uname)" != "Darwin" ]; then + kill -9 $PID_XVFB # shut down Xvfb (firefox will shut down cleanly by JsTestDriver) + fi echo "Done."'; fwrite($fh, $shellCommand . PHP_EOL); diff --git a/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php b/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php index b2d9c164fbd1bc57cf9f2497ff02d6fe6f6895e9..b2766ebd90d92e85072bd84c7c7939813d863bc8 100644 --- a/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php +++ b/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php @@ -56,8 +56,7 @@ class CopyPasteDetector implements ToolInterface, BlacklistInterface */ public function canRun() { - $vendorDir = require BP . '/app/etc/vendor_path.php'; - exec('php ' . BP . '/' . $vendorDir . '/bin/phpcpd --version', $output, $exitCode); + exec($this->getCommand() . ' --version', $output, $exitCode); return $exitCode === 0; } @@ -71,22 +70,37 @@ class CopyPasteDetector implements ToolInterface, BlacklistInterface */ public function run(array $whiteList) { - $blackListStr = ' '; + $blacklistedDirs = []; + $blacklistedFileNames = []; foreach ($this->blacklist as $file) { $file = escapeshellarg(trim($file)); if (!$file) { continue; } - $blackListStr .= '--exclude ' . $file . ' '; + $ext = pathinfo($file, PATHINFO_EXTENSION); + if ($ext != '') { + $blacklistedFileNames[] = $file; + } else { + $blacklistedDirs[] = '--exclude ' . $file . ' '; + } } - $vendorDir = require BP . '/app/etc/vendor_path.php'; - $command = 'php ' . BP . '/' . $vendorDir . '/bin/phpcpd' . ' --log-pmd ' . escapeshellarg( - $this->reportFile - ) . ' --names-exclude "*Test.php" --min-lines 13' . $blackListStr . ' ' . implode(' ', $whiteList); - + $command = $this->getCommand() . ' --log-pmd ' . escapeshellarg($this->reportFile) + . ' --names-exclude ' . join(',', $blacklistedFileNames) . ' --min-lines 13 ' . join(' ', $blacklistedDirs) + . ' ' . implode(' ', $whiteList); exec($command, $output, $exitCode); return !(bool)$exitCode; } + + /** + * Get PHPCPD command + * + * @return string + */ + private function getCommand() + { + $vendorDir = require BP . '/app/etc/vendor_path.php'; + return 'php ' . BP . '/' . $vendorDir . '/bin/phpcpd'; + } } diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/RequestConfigTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/RequestConfigTest.php index 52244463a535693746eddf8f4e0d07b05cf9de08..ff12618b399639fb8c4f56a422828cbb7c0c1e67 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/RequestConfigTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Search/RequestConfigTest.php @@ -100,7 +100,7 @@ Element 'filterReference': The attribute 'clause' is required but missing. Element 'filterReference': The attribute 'ref' is required but missing. Element 'filter': The attribute 'field' is required but missing. Element 'metric', attribute 'type': [facet 'enumeration'] " . - "The value 'sumasdasd' is not an element of the set {'sum', 'count', 'min', 'max'}. + "The value 'sumasdasd' is not an element of the set {'sum', 'count', 'min', 'max', 'avg'}. Element 'metric', attribute 'type': 'sumasdasd' is not a valid value of the local atomic type. Element 'bucket': Missing child element(s). Expected is one of ( metrics, ranges ). Element 'request': Missing child element(s). Expected is ( from )." diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php index 6b18eb2b71478463e39e815dec078478c4034a07..e5263713d71d7af374ea1f32c2d765d3639e56ce 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php @@ -64,7 +64,7 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase if ($regexp) { $matches = preg_grep( $regexp, - file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) + file($fileName) ); if (!empty($matches)) { foreach (array_keys($matches) as $line) { @@ -114,7 +114,8 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase if (strpos($path, $directory) === 0) { if (preg_match($fileExtensions, $path)) { foreach ($blackListFiles as $blackListFile) { - if (preg_match($blackListFile, $path)) { + $blackListFile = preg_quote($blackListFile, '#'); + if (preg_match('#' . $blackListFile . '#', $path)) { return false; } } @@ -158,10 +159,6 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase if (empty($functions)) { return ''; } - $regexArray = []; - foreach ($functions as $function) { - $regexArray[] = '\b' . $function . '\b\('; - } - return '/' . implode('|', $regexArray) . '/i'; + return '/(?<!function |[^\s])\b(' . join('|', $functions) . ')\s*\(/i'; } } diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php index d120a4543b9ddced597d330ab489de15c80cdb86..42b8e68e784111b96d43049ae27dc5ebc963ad40 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ return [ - '/Test\/Unit/', - '/lib\/internal\/Magento\/Framework\/DB\/Adapter\/Pdo\/Mysql\.php/', + 'Test/Unit', + 'lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php', + 'lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php', ]; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt index 2567475de6a035b2a369ac342c076ce1e5cad07d..e464d9713657f6341ccbf1f6d77986ebac08d979 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt @@ -1,4 +1,5 @@ +# "Component Type" "Component Name" "Path Pattern" module * / library * / setup -pub \ No newline at end of file +pub diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt index 56e0d51516c2632a28acd50ca2c3999e984720df..3afe3af79b14ff3177a0dc1c5ea9fe42e93b6331 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt @@ -196,4 +196,6 @@ Magento/Framework/Mview/Config/Data Magento/Framework/View/File/Collector/Override Magento/Framework/MessageQueue/Consumer/Config/ConsumerConfigItem Magento/Framework/MessageQueue/Publisher/Config/PublisherConfigItem -Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem \ No newline at end of file +Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem +IntegrationConfig.php +*Test.php diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php index c0316a435662ec4f85a42e5f65295e1f232b5c72..8075f9bddc318a81e8640f44c7e2081cd5aff161 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php @@ -13,10 +13,8 @@ return [ 'Magento_CatalogInventory', 'Magento_CatalogRule', 'Magento_CatalogSearch', - 'Magento_CatalogWidget', 'Magento_Checkout', 'Magento_CheckoutAgreements', - 'Magento_Cms', 'Magento_Config', 'Magento_ConfigurableProduct', 'Magento_CurrencySymbol', @@ -47,8 +45,6 @@ return [ 'Magento_Theme', 'Magento_Translation', 'Magento_Ui', - 'Magento_UrlRewrite', 'Magento_User', 'Magento_Weee', - 'Magento_Widget', ]; diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php index cfbeb4f54c9e29d2f7b320b57c51ae7a7b31a676..9af29ab2c458d8a8b09a73e570695d133bd7a123 100644 --- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php +++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php @@ -341,6 +341,9 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface /** * Creates a PDO object and connects to the database. * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + * * @return void * @throws \Zend_Db_Adapter_Exception */ @@ -371,6 +374,10 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface list($this->_config['host'], $this->_config['port']) = explode(':', $this->_config['host']); } + if (!isset($this->_config['driver_options'][\PDO::MYSQL_ATTR_MULTI_STATEMENTS])) { + $this->_config['driver_options'][\PDO::MYSQL_ATTR_MULTI_STATEMENTS] = false; + } + $this->logger->startTimer(); parent::_connect(); $this->logger->logStats(LoggerInterface::TYPE_CONNECT, ''); @@ -562,6 +569,7 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface * @throws \Zend_Db_Adapter_Exception To re-throw \PDOException. * @throws LocalizedException In case multiple queries are attempted at once, to protect from SQL injection * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @deprecated */ public function multiQuery($sql, $bind = []) { @@ -728,6 +736,8 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface * @return array * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) + + * @deprecated */ protected function _splitMultiQuery($sql) { diff --git a/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php b/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php index 10f1289b90c1841c7e5c9c014b3943132ab8e5f3..ad4746a36513c4dd028b1c81d27dbbcec70148eb 100644 --- a/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php +++ b/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php @@ -31,7 +31,7 @@ class MaliciousCode implements \Zend_Filter_Interface //js attributes '/(ondblclick|onclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onload|onunload|onerror)=[^<]*(?=\/*\>)/Uis', //tags - '/<\/?(script|meta|link|frame|iframe).*>/Uis', + '/<\/?(script|meta|link|frame|iframe|object).*>/Uis', //base64 usage '/src=[^<]*base64[^<]*(?=\/*\>)/Uis', ]; diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php index 512d8e89750bc24c666e58237668ad63f7e440b8..93de72e3c57c5610882aece936c9346be40dea64 100644 --- a/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php +++ b/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php @@ -89,6 +89,7 @@ class MaliciousCodeTest extends \PHPUnit_Framework_TestCase 'Tag is removed <link>SomeLink</link>', 'Tag is removed <frame>SomeFrame</frame>', 'Tag is removed <iframe>SomeIFrame</iframe>', + 'Tag is removed <object>SomeObject</object>', ], [ 'Tag is removed SomeScript', @@ -96,6 +97,7 @@ class MaliciousCodeTest extends \PHPUnit_Framework_TestCase 'Tag is removed SomeLink', 'Tag is removed SomeFrame', 'Tag is removed SomeIFrame', + 'Tag is removed SomeObject', ], ], 'Base64' => [ diff --git a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php index fb00e9f59c83097b13274e47e7b0a7a52634ecc2..181783c7b2115d8a216c681077e116e98344d15c 100644 --- a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php @@ -20,7 +20,15 @@ class Curl implements \Zend_Http_Client_Adapter_Interface * * @var array */ - protected $_config = []; + protected $_config = [ + 'protocols' => (CURLPROTO_HTTP + | CURLPROTO_HTTPS + | CURLPROTO_FTP + | CURLPROTO_FTPS + ), + 'verifypeer' => true, + 'verifyhost' => 2, + ]; /** * Curl handle @@ -41,7 +49,10 @@ class Curl implements \Zend_Http_Client_Adapter_Interface 'ssl_cert' => CURLOPT_SSLCERT, 'userpwd' => CURLOPT_USERPWD, 'useragent' => CURLOPT_USERAGENT, - 'referer' => CURLOPT_REFERER + 'referer' => CURLOPT_REFERER, + 'protocols' => CURLOPT_PROTOCOLS, + 'verifypeer' => CURLOPT_SSL_VERIFYPEER, + 'verifyhost' => CURLOPT_SSL_VERIFYHOST, ]; /** @@ -55,8 +66,6 @@ class Curl implements \Zend_Http_Client_Adapter_Interface * Apply current configuration array to transport resource * * @return \Magento\Framework\HTTP\Adapter\Curl - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ protected function _applyConfig() { @@ -65,22 +74,28 @@ class Curl implements \Zend_Http_Client_Adapter_Interface curl_setopt($this->_getResource(), $option, $value); } - if (empty($this->_config)) { - return $this; + // apply config options + foreach ($this->getDefaultConfig() as $option => $value) { + curl_setopt($this->_getResource(), $option, $value); } - $verifyPeer = isset($this->_config['verifypeer']) ? $this->_config['verifypeer'] : true; - curl_setopt($this->_getResource(), CURLOPT_SSL_VERIFYPEER, $verifyPeer); - - $verifyHost = isset($this->_config['verifyhost']) ? $this->_config['verifyhost'] : 2; - curl_setopt($this->_getResource(), CURLOPT_SSL_VERIFYHOST, $verifyHost); + return $this; + } - foreach ($this->_config as $param => $curlOption) { + /** + * Get default options + * + * @return array + */ + private function getDefaultConfig() + { + $config = []; + foreach (array_keys($this->_config) as $param) { if (array_key_exists($param, $this->_allowedParams)) { - curl_setopt($this->_getResource(), $this->_allowedParams[$param], $this->_config[$param]); + $config[$this->_allowedParams[$param]] = $this->_config[$param]; } } - return $this; + return $config; } /** @@ -116,7 +131,9 @@ class Curl implements \Zend_Http_Client_Adapter_Interface */ public function setConfig($config = []) { - $this->_config = $config; + foreach ($config as $key => $value) { + $this->_config[$key] = $value; + } return $this; } @@ -268,6 +285,13 @@ class Curl implements \Zend_Http_Client_Adapter_Interface $multihandle = curl_multi_init(); + // add default parameters + foreach ($this->getDefaultConfig() as $defaultOption => $defaultValue) { + if (!isset($options[$defaultOption])) { + $options[$defaultOption] = $defaultValue; + } + } + foreach ($urls as $key => $url) { $handles[$key] = curl_init(); curl_setopt($handles[$key], CURLOPT_URL, $url); diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php index 255be0a5596a622151e9e1091841d4f5ff8bf58b..37cd33d18683062ab48d16ae8aae2733def7a75e 100644 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Adapter/CurlTest.php @@ -10,10 +10,14 @@ use \Magento\Framework\HTTP\Adapter\Curl; class CurlTest extends \PHPUnit_Framework_TestCase { - /** @var Curl */ + /** + * @var Curl + */ protected $model; - /** @var \Closure */ + /** + * @var \Closure + */ public static $curlExectClosure; protected function setUp() @@ -42,4 +46,3 @@ class CurlTest extends \PHPUnit_Framework_TestCase ]; } } - diff --git a/lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php b/lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php index a3ed3b941844eec7497eb233d1c43e74045c45e1..779e8cf0a0e5ecf15b0fcb6da1e48b80a5bb3072 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php +++ b/lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php @@ -1,15 +1,15 @@ <?php /** - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\ObjectManager\Config; +use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManager\ConfigCacheInterface; use Magento\Framework\ObjectManager\RelationsInterface; -class Compiled implements \Magento\Framework\ObjectManager\ConfigInterface +class Compiled implements ConfigInterface { /** * @var array @@ -129,9 +129,15 @@ class Compiled implements \Magento\Framework\ObjectManager\ConfigInterface */ public function extend(array $configuration) { - $this->arguments = $configuration['arguments']; - $this->virtualTypes = $configuration['instanceTypes']; - $this->preferences = $configuration['preferences']; + $this->arguments = isset($configuration['arguments']) + ? array_replace($this->arguments, $configuration['arguments']) + : $this->arguments; + $this->virtualTypes = isset($configuration['instanceTypes']) + ? array_replace($this->virtualTypes, $configuration['instanceTypes']) + : $this->virtualTypes; + $this->preferences = isset($configuration['preferences']) + ? array_replace($this->preferences, $configuration['preferences']) + : $this->preferences; } /** diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php index 8ddb6255b9b862a37dea1aaefd742a4c03923d24..3d280f1224b8f3bb2e9082436fa7524308730387 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php @@ -71,6 +71,7 @@ class Adapter implements AdapterInterface /** * {@inheritdoc} + * @throws \LogicException */ public function query(RequestInterface $request) { diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php index 5860591eaf702494614ec89a90e816e159ffeb12..cf544eb126e1195096603979bd7378e08f44730d 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Aggregation/Builder/Metrics.php @@ -14,7 +14,7 @@ class Metrics * * @var string[] */ - private $mapMetrics = ['count', 'sum', 'min', 'max', 'avg']; + private $allowedMetrics = ['count', 'sum', 'min', 'max', 'avg']; /** * Build metrics for Select->columns @@ -30,7 +30,7 @@ class Metrics foreach ($metrics as $metric) { $metricType = $metric->getType(); - if (in_array($metricType, $this->mapMetrics)) { + if (in_array($metricType, $this->allowedMetrics, true)) { $selectAggregations[$metricType] = "$metricType(main_table.value)"; } } diff --git a/lib/internal/Magento/Framework/Search/etc/requests.xsd b/lib/internal/Magento/Framework/Search/etc/requests.xsd index f185699c5a5e890757850fa8985b2e0400c56c35..294232513b7d2ec1938e243423a3113e151fd0c0 100644 --- a/lib/internal/Magento/Framework/Search/etc/requests.xsd +++ b/lib/internal/Magento/Framework/Search/etc/requests.xsd @@ -263,6 +263,7 @@ <xs:enumeration value="count" /> <xs:enumeration value="min" /> <xs:enumeration value="max" /> + <xs:enumeration value="avg" /> </xs:restriction> </xs:simpleType> </xs:attribute> diff --git a/lib/internal/Magento/Framework/Serialize/README.md b/lib/internal/Magento/Framework/Serialize/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5af8fb7f71b6b174855cb39d004ea29cb6d518a3 --- /dev/null +++ b/lib/internal/Magento/Framework/Serialize/README.md @@ -0,0 +1,8 @@ +# Serialize + +**Serialize** library provides interface *SerializerInterface* and multiple implementations: + + * *Json* - default implementation. Uses PHP native json_encode/json_decode functions; + * *Serialize* - less secure than *Json*, but gives higher performance on big arrays. Uses PHP native serialize/unserialize functions, does not unserialize objects on PHP 7. + +Using *Serialize* implementation directly is discouraged, always use *SerializerInterface*, using *Serialize* implementation may lead to security vulnerabilities. \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/Json.php b/lib/internal/Magento/Framework/Serialize/Serializer/Json.php new file mode 100644 index 0000000000000000000000000000000000000000..9c5e55b194165849cddaeebc9d6f772375d7a66e --- /dev/null +++ b/lib/internal/Magento/Framework/Serialize/Serializer/Json.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Serialize\Serializer; + +use Magento\Framework\Serialize\SerializerInterface; + +/** + * Class for serializing data to json string and unserializing json string to data + */ +class Json implements SerializerInterface +{ + /** + * {@inheritDoc} + */ + public function serialize($data) + { + return json_encode($data); + } + + /** + * {@inheritDoc} + */ + public function unserialize($string) + { + return json_decode($string, true); + } +} diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php b/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php new file mode 100644 index 0000000000000000000000000000000000000000..3d2dc66e502ef478a868d04eac3bdc2e01bf8519 --- /dev/null +++ b/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php @@ -0,0 +1,45 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Serialize\Serializer; + +use Magento\Framework\Serialize\SerializerInterface; + +/** + * Less secure than Json implementation, but gives higher performance on big arrays. Does not unserialize objects on + * PHP 7. Using this implementation directly is discouraged as it may lead to security vulnerabilities, especially on + * older versions of PHP + */ +class Serialize implements SerializerInterface +{ + /** + * {@inheritDoc} + */ + public function serialize($data) + { + return serialize($data); + } + + /** + * {@inheritDoc} + */ + public function unserialize($string) + { + if ($this->getPhpVersion() >= 7) { + return unserialize($string, ['allowed_classes' => false]); + } + return unserialize($string); + } + + /** + * Return major PHP version + * + * @return int + */ + private function getPhpVersion() + { + return PHP_MAJOR_VERSION; + } +} diff --git a/lib/internal/Magento/Framework/Serialize/SerializerInterface.php b/lib/internal/Magento/Framework/Serialize/SerializerInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..f7a15b31a826e004541434a6ec6b4b30863ba9c3 --- /dev/null +++ b/lib/internal/Magento/Framework/Serialize/SerializerInterface.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Serialize; + +/** + * Interface for serializing + */ +interface SerializerInterface +{ + /** + * Serialize data into string + * + * @param string|int|float|bool|array|null $data + * @return string|bool + */ + public function serialize($data); + + /** + * Unserialize the given string + * + * @param string $string + * @return string|int|float|bool|array|null + */ + public function unserialize($string); +} diff --git a/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php new file mode 100644 index 0000000000000000000000000000000000000000..88e06d89e3763d36a1301b595942a513359ce076 --- /dev/null +++ b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Serialize\Test\Unit\Serializer; + +use Magento\Framework\DataObject; +use Magento\Framework\Serialize\Serializer\Json; + +class JsonTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Framework\Serialize\Serializer\Json + */ + private $json; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->json = $objectManager->getObject(Json::class); + } + + /** + * @param string|int|float|bool|array|null $value + * @param string $expected + * @dataProvider serializeDataProvider + */ + public function testSerialize($value, $expected) + { + $this->assertEquals( + $expected, + $this->json->serialize($value) + ); + } + + public function serializeDataProvider() + { + $dataObject = new DataObject(['something']); + return [ + ['', '""'], + ['string', '"string"'], + [null, 'null'], + [false, 'false'], + [['a' => 'b', 'd' => 123], '{"a":"b","d":123}'], + [123, '123'], + [10.56, '10.56'], + [$dataObject, '{}'], + ]; + } + + /** + * @param string $value + * @param string|int|float|bool|array|null $expected + * @dataProvider unserializeDataProvider + */ + public function testUnserialize($value, $expected) + { + $this->assertEquals( + $expected, + $this->json->unserialize($value) + ); + } + + public function unserializeDataProvider() + { + return [ + ['""', ''], + ['"string"', 'string'], + ['null', null], + ['false', false], + ['{"a":"b","d":123}', ['a' => 'b', 'd' => 123]], + ['123', 123], + ['10.56', 10.56], + ['{}', []], + ]; + } +} diff --git a/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..874647b5d705fc55e6b9328bab8450e1908a8921 --- /dev/null +++ b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Serialize\Test\Unit\Serializer; + +use Magento\Framework\Serialize\Serializer\Serialize; +use Magento\Framework\Serialize\Signer; +use Psr\Log\LoggerInterface; +use Magento\Framework\Serialize\InvalidSignatureException; + +class SerializeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Serialize + */ + private $serialize; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->serialize = $objectManager->getObject(Serialize::class); + } + + /** + * @param string|int|float|bool|array|null $value + * @param string $serializedValue + * @dataProvider serializeDataProvider + */ + public function testSerialize($value, $serializedValue) + { + $this->assertEquals($serializedValue, $this->serialize->serialize($value)); + } + + public function serializeDataProvider() + { + return [ + ['string', 's:6:"string";'], + ['', 's:0:"";'], + [10, 'i:10;'], + [10.5, 'd:10.5;'], + [null, 'N;'], + [false, 'b:0;'], + [['foo' => 'bar'], 'a:1:{s:3:"foo";s:3:"bar";}'], + ]; + } + + /** + * @param string $serializedValue + * @param string|int|float|bool|array|null $value + * @dataProvider unserializeDataProvider + */ + public function testUnserialize($serializedValue, $value) + { + $this->assertEquals($value, $this->serialize->unserialize($serializedValue)); + } + + public function unserializeDataProvider() + { + return [ + ['s:6:"string";', 'string'], + ['s:0:"";', ''], + ['i:10;', 10], + ['d:10.5;', 10.5], + ['N;', null], + ['b:0;', false], + ['a:1:{s:3:"foo";s:3:"bar";}', ['foo' => 'bar']], + ]; + } +} diff --git a/lib/internal/Magento/Framework/Session/SessionManager.php b/lib/internal/Magento/Framework/Session/SessionManager.php index e8013b024f4384e2c9b2261daed97a2ccbfb7f03..a517f1fd0b0b744cd44bad6b78ddd9c687a1fab5 100644 --- a/lib/internal/Magento/Framework/Session/SessionManager.php +++ b/lib/internal/Magento/Framework/Session/SessionManager.php @@ -298,6 +298,7 @@ class SessionManager implements SessionManagerInterface return; } + session_regenerate_id(true); session_destroy(); if ($options['send_expire_cookie']) { $this->expireSessionCookie(); diff --git a/lib/internal/Magento/Framework/Test/Unit/ObjectManager/Config/CompiledTest.php b/lib/internal/Magento/Framework/Test/Unit/ObjectManager/Config/CompiledTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3dd9f5065a1421ec822d4a81377ea81a5c3f8f52 --- /dev/null +++ b/lib/internal/Magento/Framework/Test/Unit/ObjectManager/Config/CompiledTest.php @@ -0,0 +1,91 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Test\Unit\ObjectManager\Config; + +use Magento\Framework\ObjectManager\Config\Compiled as CompiledConfig; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class CompiledTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; + + protected function setUp() + { + $this->objectManagerHelper = new ObjectManagerHelper($this); + } + + /** + * @param array $initialData + * @param array $configuration + * @param array $expectedArguments + * @param array $expectedVirtualTypes + * @param array $expectedPreferences + * + * @dataProvider extendDataProvider + */ + public function testExtend( + array $initialData, + array $configuration, + array $expectedArguments, + array $expectedVirtualTypes, + array $expectedPreferences + ) { + /** @var CompiledConfig $compiledConfig */ + $compiledConfig = $this->objectManagerHelper->getObject(CompiledConfig::class, ['data' => $initialData]); + $compiledConfig->extend($configuration); + + foreach ($expectedArguments as $type => $arguments) { + $this->assertEquals($arguments, $compiledConfig->getArguments($type)); + } + + $this->assertEquals($expectedVirtualTypes, $compiledConfig->getVirtualTypes()); + $this->assertEquals($expectedPreferences, $compiledConfig->getPreferences()); + } + + /** + * @return array + */ + public function extendDataProvider() + { + return [ + [ + 'initialData' => [ + 'arguments' => [ + 'type1' => serialize(['argument1_1' => 'argumentValue1_1', 'argument1_2' => 'argumentValue1_2']) + ], + 'instanceTypes' => [ + 'instanceType1' => 'instanceTypeValue1', 'instanceType2' => 'instanceTypeValue2' + ], + 'preferences' => ['preference1' => 'preferenceValue1', 'preference2' => 'preferenceValue2'] + ], + 'configuration' => [ + 'arguments' => [ + 'type1' => serialize(['argument1_1' => 'newArgumentValue1_1']), + 'type2' => serialize(['argument2_1' => 'newArgumentValue2_1']) + ], + 'instanceTypes' => [ + 'instanceType2' => 'newInstanceTypeValue2', 'instanceType3' => 'newInstanceTypeValue3' + ], + 'preferences' => ['preference1' => 'newPreferenceValue1'] + ], + 'expectedArguments' => [ + 'type1' => ['argument1_1' => 'newArgumentValue1_1'], + 'type2' => ['argument2_1' => 'newArgumentValue2_1'] + ], + 'expectedVirtualTypes' => [ + 'instanceType1' => 'instanceTypeValue1', 'instanceType2' => 'newInstanceTypeValue2', + 'instanceType3' => 'newInstanceTypeValue3' + ], + 'expectedPreferences' => [ + 'preference1' => 'newPreferenceValue1', 'preference2' => 'preferenceValue2' + ] + ] + ]; + } +} diff --git a/lib/internal/Magento/Framework/Validator/AllowedProtocols.php b/lib/internal/Magento/Framework/Validator/AllowedProtocols.php new file mode 100644 index 0000000000000000000000000000000000000000..3c7bbb3d997236aae0e7cc91994505af78620957 --- /dev/null +++ b/lib/internal/Magento/Framework/Validator/AllowedProtocols.php @@ -0,0 +1,59 @@ +<?php +/** + * Protocol validator + * + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Validator; + +use \Zend\Uri\Uri; + +/** + * Check is URI starts from allowed protocol + * + * Class AllowedProtocols + * @package Magento\Framework\Validator + */ +class AllowedProtocols extends AbstractValidator +{ + /** + * List of supported protocols + * + * @var array + */ + private $listOfProtocols = [ + 'http', + 'https', + ]; + + /** + * Constructor. + * @param array $listOfProtocols + */ + public function __construct($listOfProtocols = []) + { + if (count($listOfProtocols)) { + $this->listOfProtocols = $listOfProtocols; + } + } + + /** + * Validate URI + * + * @param string $value + * @return bool + */ + public function isValid($value) + { + $uri = new Uri($value); + $isValid = in_array( + strtolower($uri->getScheme()), + $this->listOfProtocols + ); + if (!$isValid) { + $this->_addMessages(["Protocol isn't allowed"]); + } + return $isValid; + } +} diff --git a/lib/internal/Magento/Framework/Validator/Test/Unit/UrlTest.php b/lib/internal/Magento/Framework/Validator/Test/Unit/UrlTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d66f84289424920d3d8aca1e5b39e76fa1ad1503 --- /dev/null +++ b/lib/internal/Magento/Framework/Validator/Test/Unit/UrlTest.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Validator\Test\Unit; + +use Magento\Framework\Validator\Url as UrlValidator; + +class UrlTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var UrlValidator + */ + private $validator; + + protected function setUp() + { + $this->validator = new UrlValidator(); + } + + /** + * @param array $allowedSchemes + * @param string $url + * @param bool $expectedResult + * @dataProvider isValidDataProvider + */ + public function testIsValid(array $allowedSchemes, $url, $expectedResult) + { + $this->assertSame($expectedResult, $this->validator->isValid($url, $allowedSchemes)); + } + + /** + * @return array + */ + public function isValidDataProvider() + { + return [ + [ + 'allowedSchemes' => [], + 'url' => 'http://example.com', + 'expectedResult' => true, + ], + [ + 'allowedSchemes' => ['http'], + 'url' => 'http://example.com', + 'expectedResult' => true, + ], + [ + 'allowedSchemes' => [], + 'url' => 'https://example.com', + 'expectedResult' => true, + ], + [ + 'allowedSchemes' => ['https'], + 'url' => 'https://example.com', + 'expectedResult' => true, + ], + [ + 'allowedSchemes' => [], + 'url' => 'http://example.com_test', + 'expectedResult' => false, + ], + [ + 'allowedSchemes' => [], + 'url' => 'ftp://example.com', + 'expectedResult' => true, + ], + [ + 'allowedSchemes' => ['ftp'], + 'url' => 'ftp://example.com', + 'expectedResult' => true, + ], + ]; + } +} diff --git a/lib/internal/Magento/Framework/Validator/Url.php b/lib/internal/Magento/Framework/Validator/Url.php new file mode 100644 index 0000000000000000000000000000000000000000..27262009b2d200bc354947208bfd075898a3ac0e --- /dev/null +++ b/lib/internal/Magento/Framework/Validator/Url.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Validator; + +/** + * Class Url validates URL and checks that it has allowed scheme + */ +class Url +{ + /** + * Validate URL and check that it has allowed scheme + * + * @param string $value + * @param array $allowedSchemes + * @return bool + */ + public function isValid($value, array $allowedSchemes = []) + { + $isValid = true; + + if (!filter_var($value, FILTER_VALIDATE_URL)) { + $isValid = false; + } + + if ($isValid && !empty($allowedSchemes)) { + $url = parse_url($value); + if (empty($url['scheme']) || !in_array($url['scheme'], $allowedSchemes)) { + $isValid = false; + } + } + + return $isValid; + } +} diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 98338ed4b099d202ce7d8e482b2bda9e3a675068..926d4cc54c140efb315921432b8afc5ebd237cf7 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -8,7 +8,7 @@ "AFL-3.0" ], "require": { - "php": "~5.6.0|7.0.2|7.0.4|~7.0.6", + "php": "~5.6.5|7.0.2|7.0.4|~7.0.6", "ext-spl": "*", "ext-dom": "*", "ext-simplexml": "*", diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js index 7b5100215200473f0610afaf27c922e4662cce8f..2c4ab52b896cb8fd8bf01974d7f39cfc8f11e4f4 100755 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js @@ -82,6 +82,7 @@ define([ } var settings = { + entity_encoding: 'raw', mode: (mode != undefined ? mode : 'none'), elements: this.id, theme: 'advanced', diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 3041a177185cf1dfa5bda6e233a2c58a0282d0de..eed9c676b4c90ce1a944d9e7c5ce88a815af08cf 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1441,17 +1441,19 @@ * Validate single element. * * @param {Element} element + * @param {Object} config * @returns {*} */ - $.validator.validateSingleElement = function (element) { + $.validator.validateSingleElement = function (element, config) { var errors = {}, valid = true, validateConfig = { errorElement: 'label', ignore: '.ignore-validate' }, - form, validator, classes; + form, validator, classes, elementValue; + $.extend(validateConfig, config); element = $(element).not(validateConfig.ignore); if (!element.length) { @@ -1475,7 +1477,11 @@ validator.toShow = validator.toHide = $([]); $.each(classes, $.proxy(function (i, className) { - if (this.methods[className] && !this.methods[className](element.val(), element.get(0))) { + elementValue = element.val(); + if (element.is(':checkbox') || element.is(':radio')) { + elementValue = element.is(':checked') || null; + } + if (this.methods[className] && !this.methods[className](elementValue, element.get(0))) { valid = false; errors[element.get(0).name] = this.messages[className]; validator.invalid[element.get(0).name] = true; diff --git a/setup/config/di.config.php b/setup/config/di.config.php index 804f18462065aa3af62cbba93d1fa5339b548f7e..b0dcb452ccd4030cf9736e6ab4a521199d1a899f 100644 --- a/setup/config/di.config.php +++ b/setup/config/di.config.php @@ -21,6 +21,7 @@ return [ \Magento\Setup\Controller\Environment::class, \Magento\Setup\Controller\DependencyCheck::class, \Magento\Setup\Controller\DatabaseCheck::class, + \Magento\Setup\Controller\UrlCheck::class, \Magento\Setup\Controller\ValidateAdminCredentials::class, \Magento\Setup\Controller\AddDatabase::class, \Magento\Setup\Controller\WebConfiguration::class, diff --git a/setup/pub/magento/setup/web-configuration.js b/setup/pub/magento/setup/web-configuration.js index 03a0fc7845dda90225d3be867f4bf9ddd1621f63..47458056b33b52f8913017a5f6f7c6317fd98347 100644 --- a/setup/pub/magento/setup/web-configuration.js +++ b/setup/pub/magento/setup/web-configuration.js @@ -5,7 +5,7 @@ 'use strict'; angular.module('web-configuration', ['ngStorage']) - .controller('webConfigurationController', ['$scope', '$state', '$localStorage', function ($scope, $state, $localStorage) { + .controller('webConfigurationController', ['$scope', '$state', '$localStorage', '$http', function ($scope, $state, $localStorage, $http) { $scope.config = { address: { base_url: '', @@ -119,4 +119,28 @@ angular.module('web-configuration', ['ngStorage']) $scope.webconfig.submitted = false; } }); + + // Validate URL + $scope.validateUrl = function () { + if (!$scope.webconfig.submitted) { + $http.post('index.php/url-check', $scope.config) + .success(function (data) { + $scope.validateUrl.result = data; + if ($scope.validateUrl.result.successUrl && $scope.validateUrl.result.successSecureUrl) { + $scope.nextState(); + } + if (!$scope.validateUrl.result.successUrl) { + $scope.webconfig.submitted = true; + $scope.webconfig.base_url.$setValidity('url', false); + } + if (!$scope.validateUrl.result.successSecureUrl) { + $scope.webconfig.submitted = true; + $scope.webconfig.https.$setValidity('url', false); + } + }) + .error(function (data) { + $scope.validateUrl.failed = data; + }); + } + }; }]); diff --git a/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php b/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php index 928fe1e3d4b8d32f7bc4656bf6c00ac500972234..f1098af2db00916e328f515a2a88696553603f78 100644 --- a/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php +++ b/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php @@ -16,11 +16,10 @@ use Magento\Setup\Model\StoreConfigurationDataMapper; use Magento\Setup\Model\ObjectManagerProvider; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Exception\LocalizedException; -use Magento\Store\Model\Store; -use Magento\Framework\Validator\Locale; -use Magento\Framework\Validator\Timezone; -use Magento\Framework\Validator\Currency; -use Magento\Framework\Url\Validator; +use Magento\Framework\Validator\Locale as LocaleValidator; +use Magento\Framework\Validator\Timezone as TimezoneValidator; +use Magento\Framework\Validator\Currency as CurrencyValidator; +use Magento\Framework\Validator\Url as UrlValidator; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -43,24 +42,57 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand * Object Manager * * @var ObjectManagerInterface + * @deprecated */ private $objectManager; + /** + * @var LocaleValidator + */ + private $localeValidator; + + /** + * @var TimezoneValidator + */ + private $timezoneValidator; + + /** + * @var CurrencyValidator + */ + private $currencyValidator; + + /** + * @var UrlValidator + */ + private $urlValidator; + /** * Inject dependencies * * @param InstallerFactory $installerFactory * @param DeploymentConfig $deploymentConfig * @param ObjectManagerProvider $objectManagerProvider + * @param LocaleValidator $localeValidator, + * @param TimezoneValidator $timezoneValidator, + * @param CurrencyValidator $currencyValidator, + * @param UrlValidator $urlValidator */ public function __construct( InstallerFactory $installerFactory, DeploymentConfig $deploymentConfig, - ObjectManagerProvider $objectManagerProvider + ObjectManagerProvider $objectManagerProvider, + LocaleValidator $localeValidator, + TimezoneValidator $timezoneValidator, + CurrencyValidator $currencyValidator, + UrlValidator $urlValidator ) { $this->installerFactory = $installerFactory; $this->deploymentConfig = $deploymentConfig; $this->objectManager = $objectManagerProvider->get(); + $this->localeValidator = $localeValidator; + $this->timezoneValidator = $timezoneValidator; + $this->currencyValidator = $currencyValidator; + $this->urlValidator = $urlValidator; parent::__construct(); } @@ -173,6 +205,7 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand public function validate(InputInterface $input) { $errors = []; + $errorMsg = ''; $options = $input->getOptions(); foreach ($options as $key => $value) { if (!$value) { @@ -180,99 +213,69 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand } switch ($key) { case StoreConfigurationDataMapper::KEY_BASE_URL: - /** @var Validator $url */ if (strcmp($value, '{{base_url}}') == 0) { break; } - $url = $this->objectManager->get(\Magento\Framework\Url\Validator::class); - if (!$url->isValid($value)) { - $errorMsgs = $url->getMessages(); - $errors[] = '<error>' . 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL - . '\': ' . $errorMsgs[Validator::INVALID_URL] .'</error>'; - } + $errorMsg = $this->validateUrl( + $value, + StoreConfigurationDataMapper::KEY_BASE_URL, + ['http', 'https'] + ); + break; case StoreConfigurationDataMapper::KEY_LANGUAGE: - /** @var Locale $lists */ - $lists = $this->objectManager->get(\Magento\Framework\Validator\Locale::class); - $errorMsg = $this->validateCodes($lists, $value, StoreConfigurationDataMapper::KEY_LANGUAGE); - if ($errorMsg !== '') { - $errors[] = $errorMsg; - } + $errorMsg = $this->validateCodes( + $this->localeValidator, + $value, + StoreConfigurationDataMapper::KEY_LANGUAGE + ); break; case StoreConfigurationDataMapper::KEY_TIMEZONE: - /** @var Timezone $lists */ - $lists = $this->objectManager->get(\Magento\Framework\Validator\Timezone::class); - $errorMsg = $this->validateCodes($lists, $value, StoreConfigurationDataMapper::KEY_TIMEZONE); - if ($errorMsg !== '') { - $errors[] = $errorMsg; - } + $errorMsg = $this->validateCodes( + $this->timezoneValidator, + $value, + StoreConfigurationDataMapper::KEY_TIMEZONE + ); break; case StoreConfigurationDataMapper::KEY_CURRENCY: - /** @var Currency $lists */ - $lists = $this->objectManager->get(\Magento\Framework\Validator\Currency::class); - $errorMsg = $this->validateCodes($lists, $value, StoreConfigurationDataMapper::KEY_CURRENCY); - if ($errorMsg !== '') { - $errors[] = $errorMsg; - } + $errorMsg = $this->validateCodes( + $this->currencyValidator, + $value, + StoreConfigurationDataMapper::KEY_CURRENCY + ); break; case StoreConfigurationDataMapper::KEY_USE_SEF_URL: $errorMsg = $this->validateBinaryValue($value, StoreConfigurationDataMapper::KEY_USE_SEF_URL); - if ($errorMsg !== '') { - $errors[] = $errorMsg; - } break; case StoreConfigurationDataMapper::KEY_IS_SECURE: $errorMsg = $this->validateBinaryValue($value, StoreConfigurationDataMapper::KEY_IS_SECURE); - if ($errorMsg !== '') { - $errors[] = $errorMsg; - } break; case StoreConfigurationDataMapper::KEY_BASE_URL_SECURE: - try { - /** @var Validator $url */ - $url = $this->objectManager->get(\Magento\Framework\Url\Validator::class); - $errorMsgs = ''; - if (!$url->isValid($value)) { - $errorMsgs = $url->getMessages(); - if (!empty($errorMsgs)) { - $errors[] = '<error>' . 'Command option \'' - . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE - . '\': ' . $errorMsgs[Validator::INVALID_URL] .'</error>'; - } - } - if (empty($errorMsgs) && strpos($value, 'https:') === false) { - throw new LocalizedException(new \Magento\Framework\Phrase("Invalid secure URL.")); - } - } catch (LocalizedException $e) { - $errors[] = '<error>' . 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE - . '\': ' . $e->getLogMessage() .'</error>'; - } + $errorMsg = $this->validateUrl( + $value, + StoreConfigurationDataMapper::KEY_BASE_URL_SECURE, + ['https'] + ); break; case StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN: $errorMsg = $this->validateBinaryValue($value, StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN); - if ($errorMsg !== '') { - $errors[] = $errorMsg; - } break; case StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY: $errorMsg = $this->validateBinaryValue( $value, StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY ); - if ($errorMsg !== '') { - $errors[] = $errorMsg; - } break; case StoreConfigurationDataMapper::KEY_JS_LOGGING: $errorMsg = $this->validateBinaryValue( $value, StoreConfigurationDataMapper::KEY_JS_LOGGING ); - if ($errorMsg !== '') { - $errors[] = $errorMsg; - } break; } + if ($errorMsg !== '') { + $errors[] = $errorMsg; + } } return $errors; } @@ -296,7 +299,7 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand /** * Validate codes for languages, currencies or timezones * - * @param Locale|Timezone|Currency $lists + * @param LocaleValidator|TimezoneValidator|CurrencyValidator $lists * @param string $code * @param string $type * @return string @@ -310,4 +313,31 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand } return $errorMsg; } + + /** + * Validate URL + * + * @param string $url + * @param string $option + * @param array $allowedSchemes + * @return string + */ + private function validateUrl($url, $option, array $allowedSchemes) + { + $errorMsg = ''; + + if (!$this->urlValidator->isValid($url, $allowedSchemes)) { + $errorTemplate = '<error>Command option \'%s\': Invalid URL \'%s\'.' + . ' Domain Name should contain only letters, digits and hyphen.' + . ' And you should use only following schemes: \'%s\'.</error>'; + $errorMsg = sprintf( + $errorTemplate, + $option, + $url, + implode(', ', $allowedSchemes) + ); + } + + return $errorMsg; + } } diff --git a/setup/src/Magento/Setup/Controller/UrlCheck.php b/setup/src/Magento/Setup/Controller/UrlCheck.php new file mode 100644 index 0000000000000000000000000000000000000000..08a0d50404c0a2e457a2646a30860d1f958f14d3 --- /dev/null +++ b/setup/src/Magento/Setup/Controller/UrlCheck.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Setup\Controller; + +use Zend\Mvc\Controller\AbstractActionController; +use Zend\View\Model\JsonModel; +use Zend\Json\Json; +use Magento\Framework\Validator\Url as UrlValidator; + +class UrlCheck extends AbstractActionController +{ + /** + * @var UrlValidator + */ + private $urlValidator; + + /** + * @param UrlValidator $urlValidator + */ + public function __construct(UrlValidator $urlValidator) + { + $this->urlValidator = $urlValidator; + } + + /** + * Validate URL + * + * @return JsonModel + */ + public function indexAction() + { + $params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY); + $result = ['successUrl' => false, 'successSecureUrl' => true]; + + $hasBaseUrl = isset($params['address']['actual_base_url']); + $hasSecureBaseUrl = isset($params['https']['text']); + $hasSecureAdminUrl = !empty($params['https']['admin']); + $hasSecureFrontUrl = !empty($params['https']['front']); + $schemes = ['http', 'https']; + + // Validating of Base URL + if ($hasBaseUrl && $this->urlValidator->isValid($params['address']['actual_base_url'], $schemes)) { + $result['successUrl'] = true; + } + + // Validating of Secure Base URL + if ($hasSecureAdminUrl || $hasSecureFrontUrl) { + if (!($hasSecureBaseUrl && $this->urlValidator->isValid($params['https']['text'], $schemes))) { + $result['successSecureUrl'] = false; + } + } + + return new JsonModel($result); + } +} diff --git a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php index 6a4b3a72b372c8ff611bcc7e535c99cbef4bb404..935f395a5e219f0546daf7967dbcc0726c695055 100644 --- a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php +++ b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php @@ -99,10 +99,10 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface } /** - * Check if user login + * Check if user logged-in and has permissions * * @param \Zend\Mvc\MvcEvent $event - * @return bool + * @return false|\Zend\Http\Response * @throws \Magento\Framework\Exception\LocalizedException */ public function authPreDispatch($event) @@ -115,6 +115,7 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface /** @var Application $application */ $application = $event->getApplication(); $serviceManager = $application->getServiceManager(); + if ($serviceManager->get(\Magento\Framework\App\DeploymentConfig::class)->isAvailable()) { /** @var \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider */ $objectManagerProvider = $serviceManager->get(\Magento\Setup\Model\ObjectManagerProvider::class); @@ -135,17 +136,26 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface 'appState' => $adminAppState ] ); - if (!$objectManager->get(\Magento\Backend\Model\Auth::class)->isLoggedIn()) { + /** @var \Magento\Backend\Model\Auth $auth */ + $authentication = $objectManager->get(\Magento\Backend\Model\Auth::class); + + if ( + !$authentication->isLoggedIn() || + !$adminSession->isAllowed('Magento_Backend::setup_wizard') + ) { $adminSession->destroy(); + /** @var \Zend\Http\Response $response */ $response = $event->getResponse(); $baseUrl = Http::getDistroBaseUrlPath($_SERVER); $response->getHeaders()->addHeaderLine('Location', $baseUrl . 'index.php/session/unlogin'); $response->setStatusCode(302); $event->stopPropagation(); + return $response; } } } + return false; } diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php index 6f5ab3a5a64c537751cc8964229e35869b06c8e5..c3494b389aa5ecb2a2ab2465b5d848627a5d8e7a 100644 --- a/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php @@ -11,8 +11,14 @@ use Symfony\Component\Console\Tester\CommandTester; use Magento\Setup\Model\Installer; use Magento\Framework\ObjectManagerInterface; use Magento\Setup\Model\StoreConfigurationDataMapper; -use Magento\Framework\Url\Validator; +use Magento\Framework\Validator\Url as UrlValidator; +use Magento\Framework\Validator\Locale as LocaleValidator; +use Magento\Framework\Validator\Timezone as TimezoneValidator; +use Magento\Framework\Validator\Currency as CurrencyValidator; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase { /** @@ -35,6 +41,26 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase */ private $objectManager; + /** + * @var LocaleValidator|\PHPUnit_Framework_MockObject_MockObject + */ + private $localeValidatorMock; + + /** + * @var TimezoneValidator|\PHPUnit_Framework_MockObject_MockObject + */ + private $timezoneValidatorMock; + + /** + * @var CurrencyValidator|\PHPUnit_Framework_MockObject_MockObject + */ + private $currencyValidatorMock; + + /** + * @var UrlValidator|\PHPUnit_Framework_MockObject_MockObject + */ + private $urlValidatorMock; + /** * @var InstallStoreConfigurationCommand */ @@ -42,6 +68,11 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase protected function setUp() { + $this->urlValidatorMock = $this->getMock(UrlValidator::class, [], [], '', false); + $this->localeValidatorMock = $this->getMock(LocaleValidator::class, [], [], '', false); + $this->timezoneValidatorMock = $this->getMock(TimezoneValidator::class, [], [], '', false); + $this->currencyValidatorMock = $this->getMock(CurrencyValidator::class, [], [], '', false); + $this->installerFactory = $this->getMock(\Magento\Setup\Model\InstallerFactory::class, [], [], '', false); $this->deploymentConfig = $this->getMock(\Magento\Framework\App\DeploymentConfig::class, [], [], '', false); $this->installer = $this->getMock(\Magento\Setup\Model\Installer::class, [], [], '', false); @@ -62,7 +93,11 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase $this->command = new InstallStoreConfigurationCommand( $this->installerFactory, $this->deploymentConfig, - $objectManagerProvider + $objectManagerProvider, + $this->localeValidatorMock, + $this->timezoneValidatorMock, + $this->currencyValidatorMock, + $this->urlValidatorMock ); } @@ -102,41 +137,11 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase */ public function testExecuteInvalidData(array $option, $error) { - $url= $this->getMock(\Magento\Framework\Url\Validator::class, [], [], '', false); - $url->expects($this->any())->method('isValid')->will($this->returnValue(false)); - if (!isset($option['--' . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE])) { - $url->expects($this->any())->method('getMessages')->will($this->returnValue([ - Validator::INVALID_URL => 'Invalid URL.' - ])); - } - $localeLists= $this->getMock(\Magento\Framework\Validator\Locale::class, [], [], '', false); - $localeLists->expects($this->any())->method('isValid')->will($this->returnValue(false)); - $timezoneLists= $this->getMock(\Magento\Framework\Validator\Timezone::class, [], [], '', false); - $timezoneLists->expects($this->any())->method('isValid')->will($this->returnValue(false)); - $currencyLists= $this->getMock(\Magento\Framework\Validator\Currency::class, [], [], '', false); - $currencyLists->expects($this->any())->method('isValid')->will($this->returnValue(false)); - - $returnValueMapOM = [ - [ - \Magento\Framework\Url\Validator::class, - $url - ], - [ - \Magento\Framework\Validator\Locale::class, - $localeLists - ], - [ - \Magento\Framework\Validator\Timezone::class, - $timezoneLists - ], - [ - \Magento\Framework\Validator\Currency::class, - $currencyLists - ], - ]; - $this->objectManager->expects($this->any()) - ->method('get') - ->will($this->returnValueMap($returnValueMapOM)); + $this->localeValidatorMock->expects($this->any())->method('isValid')->willReturn(false); + $this->timezoneValidatorMock->expects($this->any())->method('isValid')->willReturn(false); + $this->currencyValidatorMock->expects($this->any())->method('isValid')->willReturn(false); + $this->urlValidatorMock->expects($this->any())->method('isValid')->willReturn(false); + $this->deploymentConfig->expects($this->once()) ->method('isAvailable') ->will($this->returnValue(true)); @@ -144,7 +149,7 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase ->method('create'); $commandTester = new CommandTester($this->command); $commandTester->execute($option); - $this->assertEquals($error . PHP_EOL, $commandTester->getDisplay()); + $this->assertContains($error, $commandTester->getDisplay()); } /** @@ -155,48 +160,54 @@ class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase return [ [ ['--' . StoreConfigurationDataMapper::KEY_BASE_URL => 'sampleUrl'], - 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL . '\': Invalid URL.' + 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL . '\': Invalid URL \'sampleUrl\'.' + ], + [ + ['--' . StoreConfigurationDataMapper::KEY_BASE_URL => 'http://example.com_test'], + 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL + . '\': Invalid URL \'http://example.com_test\'.' ], [ ['--' . StoreConfigurationDataMapper::KEY_LANGUAGE => 'sampleLanguage'], 'Command option \'' . StoreConfigurationDataMapper::KEY_LANGUAGE - . '\': Invalid value. To see possible values, run command \'bin/magento info:language:list\'.' + . '\': Invalid value. To see possible values, run command \'bin/magento info:language:list\'.' ], [ ['--' . StoreConfigurationDataMapper::KEY_TIMEZONE => 'sampleTimezone'], 'Command option \'' . StoreConfigurationDataMapper::KEY_TIMEZONE - . '\': Invalid value. To see possible values, run command \'bin/magento info:timezone:list\'.' + . '\': Invalid value. To see possible values, run command \'bin/magento info:timezone:list\'.' ], [ ['--' . StoreConfigurationDataMapper::KEY_CURRENCY => 'sampleLanguage'], 'Command option \'' . StoreConfigurationDataMapper::KEY_CURRENCY - . '\': Invalid value. To see possible values, run command \'bin/magento info:currency:list\'.' + . '\': Invalid value. To see possible values, run command \'bin/magento info:currency:list\'.' ], [ ['--' . StoreConfigurationDataMapper::KEY_USE_SEF_URL => 'invalidValue'], 'Command option \'' . StoreConfigurationDataMapper::KEY_USE_SEF_URL - . '\': Invalid value. Possible values (0|1).' + . '\': Invalid value. Possible values (0|1).' ], [ ['--' . StoreConfigurationDataMapper::KEY_IS_SECURE => 'invalidValue'], 'Command option \'' . StoreConfigurationDataMapper::KEY_IS_SECURE - . '\': Invalid value. Possible values (0|1).' + . '\': Invalid value. Possible values (0|1).' ], [ ['--' . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE => 'http://www.sample.com'], 'Command option \'' . StoreConfigurationDataMapper::KEY_BASE_URL_SECURE - . '\': Invalid secure URL.' + . '\': Invalid URL \'http://www.sample.com\'.' ], [ ['--' . StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN => 'invalidValue'], 'Command option \'' . StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN - . '\': Invalid value. Possible values (0|1).' + . '\': Invalid value. Possible values (0|1).' ], [ ['--' . StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => 'invalidValue'], 'Command option \'' . StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY - . '\': Invalid value. Possible values (0|1).' + . '\': Invalid value. Possible values (0|1).' ], + ]; } } diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/UrlCheckTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/UrlCheckTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0b44887b586d5c69b6c56a1e19a4b9d68ae96bfe --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Controller/UrlCheckTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Setup\Test\Unit\Controller; + +use Magento\Setup\Controller\UrlCheck; +use Zend\Stdlib\RequestInterface; +use Zend\View\Model\JsonModel; +use Magento\Framework\Validator\Url as UrlValidator; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class UrlCheckTest extends \PHPUnit_Framework_TestCase +{ + /** + * @param array $requestJson + * @param array $expectedResult + * @dataProvider indexActionDataProvider + */ + public function testIndexAction($requestJson, $expectedResult) + { + /** @var ObjectManagerHelper $objectManagerHelper */ + $objectManagerHelper = new ObjectManagerHelper($this); + + $allowedSchemes = ['http', 'https']; + $returnMap = []; + if (isset($requestJson['address']['actual_base_url'])) { + $returnMap[] = [ + $requestJson['address']['actual_base_url'], + $allowedSchemes, + $expectedResult['successUrl'], + ]; + } + if (isset($requestJson['https']['text'])) { + $returnMap[] = [ + $requestJson['https']['text'], + $allowedSchemes, + $expectedResult['successSecureUrl'], + ]; + } + + /** @var UrlValidator|\PHPUnit_Framework_MockObject_MockObject $validator */ + $validator = $this->getMockBuilder(UrlValidator::class) + ->disableOriginalConstructor() + ->getMock(); + $validator->expects($this->any()) + ->method('isValid') + ->willReturnMap($returnMap); + + /** @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject $requestMock */ + $requestMock = $this->getMockBuilder(RequestInterface::class) + ->getMockForAbstractClass(); + $requestMock->expects($this->once()) + ->method('getContent') + ->willReturn(json_encode($requestJson)); + + $controller = $objectManagerHelper->getObject( + UrlCheck::class, + ['urlValidator' => $validator] + ); + $objectManagerHelper->setBackwardCompatibleProperty($controller, 'request', $requestMock); + + $this->assertEquals(new JsonModel($expectedResult), $controller->indexAction()); + } + + /** + * @return array + */ + public function indexActionDataProvider() + { + return [ + [ + 'requestJson' => [ + 'address' => [ + 'actual_base_url' => 'http://localhost' + ] + ], + 'expectedResult' => ['successUrl' => true, 'successSecureUrl' => true] + ], + [ + 'requestJson' => [ + 'address' => [ + 'actual_base_url' => 'http://localhost.com_test' + ] + ], + 'expectedResult' => ['successUrl' => false, 'successSecureUrl' => true] + ], + [ + 'requestJson' => [ + 'address' => [ + 'actual_base_url' => 'http://localhost.com_test' + ], + 'https' => [ + 'admin' => false, + 'front' => false, + 'text' => '' + ] + ], + 'expectedResult' => ['successUrl' => false, 'successSecureUrl' => true] + ], + [ + 'requestJson' => [ + 'address' => [ + 'actual_base_url' => 'http://localhost.com:8080' + ], + 'https' => [ + 'admin' => true, + 'front' => false, + 'text' => 'https://example.com.ua/' + ] + ], + 'expectedResult' => ['successUrl' => true, 'successSecureUrl' => true] + ], + [ + 'requestJson' => [ + 'address' => [ + 'actual_base_url' => 'http://localhost.com:8080/folder_name/' + ], + 'https' => [ + 'admin' => false, + 'front' => true, + 'text' => 'https://example.com.ua/' + ] + ], + 'expectedResult' => ['successUrl' => true, 'successSecureUrl' => true] + ], + [ + 'requestJson' => [ + 'address' => [ + 'actual_base_url' => 'http://localhost.com:8080/folder_name/' + ], + 'https' => [ + 'admin' => true, + 'front' => true, + 'text' => 'https://example.com.ua:8090/folder_name/' + ] + ], + 'expectedResult' => ['successUrl' => true, 'successSecureUrl' => true] + ], + ]; + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php b/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php index 558533afe92429582cbfa79e5fcd691b200ecef8..1ace3f452c4f917181c43a86744f2b4db39b9439 100644 --- a/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Setup\Test\Unit\Mvc\Bootstrap; use \Magento\Setup\Mvc\Bootstrap\InitParamListener; @@ -59,11 +58,11 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase ->withConsecutive( [ \Magento\Framework\App\Filesystem\DirectoryList::class, - $this->isInstanceOf(\Magento\Framework\App\Filesystem\DirectoryList::class) + $this->isInstanceOf(\Magento\Framework\App\Filesystem\DirectoryList::class), ], [ \Magento\Framework\Filesystem::class, - $this->isInstanceOf(\Magento\Framework\Filesystem::class) + $this->isInstanceOf(\Magento\Framework\Filesystem::class), ] ); $mvcApplication->expects($this->any())->method('getServiceManager')->willReturn($serviceManager); @@ -130,10 +129,10 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase $request->expects($this->any()) ->method('getContent') ->willReturn( - $cliParam ? ['install', '--magento-init-params=' . $cliParam ] : ['install'] + $cliParam ? ['install', '--magento-init-params=' . $cliParam] : ['install'] ); $mvcApplication->expects($this->any())->method('getConfig')->willReturn( - $zfAppConfig ? [InitParamListener::BOOTSTRAP_PARAM => $zfAppConfig]:[] + $zfAppConfig ? [InitParamListener::BOOTSTRAP_PARAM => $zfAppConfig] : [] ); $mvcApplication->expects($this->any())->method('getRequest')->willReturn($request); @@ -150,41 +149,55 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase 'mage_mode App' => [['MAGE_MODE' => 'developer'], [], '', ['MAGE_MODE' => 'developer']], 'mage_mode Env' => [[], ['MAGE_MODE' => 'developer'], '', ['MAGE_MODE' => 'developer']], 'mage_mode CLI' => [[], [], 'MAGE_MODE=developer', ['MAGE_MODE' => 'developer']], - 'one MAGE_DIRS CLI' => [[], [], 'MAGE_MODE=developer&MAGE_DIRS[base][path]=/var/www/magento2', - ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer']], + 'one MAGE_DIRS CLI' => [ + [], + [], + 'MAGE_MODE=developer&MAGE_DIRS[base][path]=/var/www/magento2', + ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer'], + ], 'two MAGE_DIRS CLI' => [ [], [], 'MAGE_MODE=developer&MAGE_DIRS[base][path]=/var/www/magento2&MAGE_DIRS[cache][path]=/tmp/cache', - ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2'], 'cache' => ['path' => '/tmp/cache']], - 'MAGE_MODE' => 'developer']], + [ + 'MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2'], 'cache' => ['path' => '/tmp/cache']], + 'MAGE_MODE' => 'developer', + ], + ], 'mage_mode only' => [[], [], 'MAGE_MODE=developer', ['MAGE_MODE' => 'developer']], 'MAGE_DIRS Env' => [ [], ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer'], '', - ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer']], + ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2']], 'MAGE_MODE' => 'developer'], + ], 'two MAGE_DIRS' => [ [], [], 'MAGE_MODE=developer&MAGE_DIRS[base][path]=/var/www/magento2&MAGE_DIRS[cache][path]=/tmp/cache', - ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2'], 'cache' => ['path' => '/tmp/cache']], - 'MAGE_MODE' => 'developer']], + [ + 'MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2'], 'cache' => ['path' => '/tmp/cache']], + 'MAGE_MODE' => 'developer', + ], + ], 'Env overwrites App' => [ ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/App']], 'MAGE_MODE' => 'developer'], ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']], 'MAGE_MODE' => 'developer'], '', - ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']], 'MAGE_MODE' => 'developer']], + ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']], 'MAGE_MODE' => 'developer'], + ], 'CLI overwrites Env' => [ ['MAGE_MODE' => 'developerApp'], ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']]], 'MAGE_DIRS[base][path]=/var/www/magento2/CLI', - ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/CLI']], 'MAGE_MODE' => 'developerApp']], + ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/CLI']], 'MAGE_MODE' => 'developerApp'], + ], 'CLI overwrites All' => [ ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/App']], 'MAGE_MODE' => 'production'], ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/Env']]], 'MAGE_DIRS[base][path]=/var/www/magento2/CLI', - ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/CLI']], 'MAGE_MODE' => 'production']], + ['MAGE_DIRS' => ['base' => ['path' => '/var/www/magento2/CLI']], 'MAGE_MODE' => 'production'], + ], ]; } @@ -226,6 +239,168 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase [$this->listener, 'onBootstrap'] )->willReturn($this->callbackHandler); $eventManager->expects($this->once())->method('getSharedManager')->willReturn($sharedManager); + return $eventManager; } + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testAuthPreDispatch() + { + $eventMock = $this->getMockBuilder(\Zend\Mvc\MvcEvent::class) + ->disableOriginalConstructor() + ->getMock(); + $routeMatchMock = $this->getMockBuilder(\Zend\Mvc\Router\Http\RouteMatch::class) + ->disableOriginalConstructor() + ->getMock(); + $applicationMock = $this->getMockBuilder(\Zend\Mvc\Application::class) + ->disableOriginalConstructor() + ->getMock(); + $serviceManagerMock = $this->getMockBuilder(\Zend\ServiceManager\ServiceManager::class) + ->disableOriginalConstructor() + ->getMock(); + $deploymentConfigMock = $this->getMockBuilder(\Magento\Framework\App\DeploymentConfig::class) + ->disableOriginalConstructor() + ->getMock(); + $deploymentConfigMock->expects($this->once()) + ->method('isAvailable') + ->willReturn(true); + $omProvider = $this->getMockBuilder(\Magento\Setup\Model\ObjectManagerProvider::class) + ->disableOriginalConstructor() + ->getMock(); + $objectManagerMock = $this->getMockForAbstractClass(\Magento\Framework\ObjectManagerInterface::class); + $adminAppStateMock = $this->getMockBuilder(\Magento\Framework\App\State::class) + ->disableOriginalConstructor() + ->getMock(); + $sessionConfigMock = $this->getMockBuilder(\Magento\Backend\Model\Session\AdminConfig::class) + ->disableOriginalConstructor() + ->getMock(); + $backendAppListMock = $this->getMockBuilder(\Magento\Backend\App\BackendAppList::class) + ->disableOriginalConstructor() + ->getMock(); + $backendAppMock = $this->getMockBuilder(\Magento\Backend\App\BackendApp::class) + ->disableOriginalConstructor() + ->getMock(); + $backendUrlFactoryMock = $this->getMockBuilder(\Magento\Backend\Model\UrlFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + $backendUrlMock = $this->getMockBuilder(\Magento\Backend\Model\Url::class) + ->disableOriginalConstructor() + ->getMock(); + $authenticationMock = $this->getMockBuilder(\Magento\Backend\Model\Auth::class) + ->disableOriginalConstructor() + ->getMock(); + $adminSessionMock = $this->getMockBuilder(\Magento\Backend\Model\Auth\Session::class) + ->disableOriginalConstructor() + ->getMock(); + $responseMock = $this->getMockBuilder(\Zend\Http\Response::class) + ->disableOriginalConstructor() + ->getMock(); + $headersMock = $this->getMockBuilder(\Zend\Http\Headers::class) + ->disableOriginalConstructor() + ->getMock(); + + $routeMatchMock->expects($this->once()) + ->method('getParam') + ->with('controller') + ->willReturn('testController'); + $eventMock->expects($this->once()) + ->method('getRouteMatch') + ->willReturn($routeMatchMock); + $eventMock->expects($this->once()) + ->method('getApplication') + ->willReturn($applicationMock); + $serviceManagerMock->expects($this->any()) + ->method('get') + ->willReturnMap( + [ + [ + \Magento\Framework\App\DeploymentConfig::class, + true, + $deploymentConfigMock, + ], + [ + \Magento\Setup\Model\ObjectManagerProvider::class, + true, + $omProvider, + ], + ] + ); + $objectManagerMock->expects($this->any()) + ->method('get') + ->willReturnMap( + [ + [ + \Magento\Framework\App\State::class, + $adminAppStateMock, + ], + [ + \Magento\Backend\Model\Session\AdminConfig::class, + $sessionConfigMock, + ], + [ + \Magento\Backend\App\BackendAppList::class, + $backendAppListMock, + ], + [ + \Magento\Backend\Model\UrlFactory::class, + $backendUrlFactoryMock, + ], + [ + \Magento\Backend\Model\Auth::class, + $authenticationMock, + ], + ] + ); + $objectManagerMock->expects($this->any()) + ->method('create') + ->willReturn($adminSessionMock); + $omProvider->expects($this->once()) + ->method('get') + ->willReturn($objectManagerMock); + $adminAppStateMock->expects($this->once()) + ->method('setAreaCode') + ->with(\Magento\Framework\App\Area::AREA_ADMINHTML); + $applicationMock->expects($this->once()) + ->method('getServiceManager') + ->willReturn($serviceManagerMock); + $backendAppMock->expects($this->once()) + ->method('getCookiePath') + ->willReturn(''); + $backendUrlFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($backendUrlMock); + $backendAppListMock->expects($this->once()) + ->method('getBackendApp') + ->willReturn($backendAppMock); + $authenticationMock->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(true); + $adminSessionMock->expects($this->once()) + ->method('isAllowed') + ->with('Magento_Backend::setup_wizard', null) + ->willReturn(false); + $adminSessionMock->expects($this->once()) + ->method('destroy'); + $eventMock->expects($this->once()) + ->method('getResponse') + ->willReturn($responseMock); + $responseMock->expects($this->once()) + ->method('getHeaders') + ->willReturn($headersMock); + $headersMock->expects($this->once()) + ->method('addHeaderLine'); + $responseMock->expects($this->once()) + ->method('setStatusCode') + ->with(302); + $eventMock->expects($this->once()) + ->method('stopPropagation'); + + $this->assertSame( + $this->listener->authPreDispatch($eventMock), + $responseMock + ); + } } diff --git a/setup/view/magento/setup/web-configuration.phtml b/setup/view/magento/setup/web-configuration.phtml index 35aa19484ed53f39bf37ae0e90e7b76c7f5efe87..ab2a00342b715b05f215d1d3e12010b0fc4993cc 100644 --- a/setup/view/magento/setup/web-configuration.phtml +++ b/setup/view/magento/setup/web-configuration.phtml @@ -30,7 +30,7 @@ $hints = [ <div class="nav-bar-outer-actions"> <div class="outer-actions-inner-wrap"> <div class="btn-wrap btn-wrap-triangle-right btn-wrap-next"> - <button type="button" class="btn btn-prime" ng-click="nextState()" dis>Next</button> + <button type="button" class="btn btn-prime" ng-click="validateUrl()" dis>Next</button> </div> <div class="btn-wrap btn-wrap-triangle-left btn-wrap-prev"> <button type="button" class="btn" ng-click="previousState()">Back</button> @@ -40,6 +40,13 @@ $hints = [ <h2 class="page-sub-title">{{$state.current.header}}</h2> +<div + class="message message-error" + ng-show="validateUrl.failed !== undefined" +> + <span class="message-text">{{validateUrl.failed}}</span> +</div> + <form name="webconfig" role="form"