diff --git a/.htaccess b/.htaccess index e7a6c2e218cb76bff2b480ccd8b5ddf97a47b25e..f824f0b7bbc59db5990b61922244909f84162738 100644 --- a/.htaccess +++ b/.htaccess @@ -203,76 +203,166 @@ RedirectMatch 403 /\.git <Files composer.json> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files composer.lock> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .gitignore> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .htaccess> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .htaccess.sample> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .php_cs.dist> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .travis.yml> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files CHANGELOG.md> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files CONTRIBUTING.md> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files COPYING.txt> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files Gruntfile.js> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files LICENSE.txt> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files LICENSE_AFL.txt> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files nginx.conf.sample> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files package.json> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files php.ini.sample> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files README.md> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files magento_umask> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> # For 404s and 403s that aren't handled by the application, show plain 404 response diff --git a/.htaccess.sample b/.htaccess.sample index 91a0372ef7f165feef4a41bc223c6bf8e73b70d0..f3a4474aec9492825323904d0df393b71945848f 100644 --- a/.htaccess.sample +++ b/.htaccess.sample @@ -180,76 +180,166 @@ RedirectMatch 403 /\.git <Files composer.json> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files composer.lock> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .gitignore> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .htaccess> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .htaccess.sample> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .php_cs.dist> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files .travis.yml> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files CHANGELOG.md> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files CONTRIBUTING.md> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files COPYING.txt> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files Gruntfile.js> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files LICENSE.txt> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files LICENSE_AFL.txt> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files nginx.conf.sample> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files package.json> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files php.ini.sample> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files README.md> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <Files magento_umask> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> # For 404s and 403s that aren't handled by the application, show plain 404 response diff --git a/CHANGELOG.md b/CHANGELOG.md index ef841ec0337f223ee17e95e6a08917ff5e479ca1..8270f8908a3c70f9235183c6667922dfab28a129 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,693 @@ +2.2.1 +============= +* GitHub issues: + * [#4248](https://github.com/magento/magento2/issues/4248) -- Validations not working on customer registration on DOB field. (fixed in [#11067](https://github.com/magento/magento2/pull/11067)) + * [#6350](https://github.com/magento/magento2/issues/6350) -- Frontend: Datepicker/calendar control does not use the store locale (fixed in [#11067](https://github.com/magento/magento2/pull/11067)) + * [#6858](https://github.com/magento/magento2/issues/6858) -- DatePicker date format does not reflect user's locale (fixed in [#11067](https://github.com/magento/magento2/pull/11067)) + * [#6831](https://github.com/magento/magento2/issues/6831) -- Magento 2.1.1 Invalid input date format 'Invalid date' (fixed in [#11067](https://github.com/magento/magento2/pull/11067)) + * [#9743](https://github.com/magento/magento2/issues/9743) -- Invalid date when customer validate with French locale (fixed in [#11067](https://github.com/magento/magento2/pull/11067)) + * [#6712](https://github.com/magento/magento2/issues/6712) -- Footer Links Widget CSS Issue (fixed in [#11063](https://github.com/magento/magento2/pull/11063)) + * [#9008](https://github.com/magento/magento2/issues/9008) -- Error Message Is Confusing When Code Base Is Behind Database Module Version (fixed in [#11064](https://github.com/magento/magento2/pull/11064)) + * [#9981](https://github.com/magento/magento2/issues/9981) -- M2 suggests running setup:upgrade if version number of module is higher than expected (fixed in [#11064](https://github.com/magento/magento2/pull/11064)) + * [#10824](https://github.com/magento/magento2/issues/10824) -- Cannot add new columns to item grid in admin sales_order_view layout (fixed in [#11076](https://github.com/magento/magento2/pull/11076)) + * [#10417](https://github.com/magento/magento2/issues/10417) -- Wysywig editor shows broken image icons (fixed in [#11048](https://github.com/magento/magento2/pull/11048)) + * [#10697](https://github.com/magento/magento2/issues/10697) -- Product Import: Additional data: Invalid URL key (fixed in [#11049](https://github.com/magento/magento2/pull/11049)) + * [#10474](https://github.com/magento/magento2/issues/10474) -- Error message in product review form not being translated (fixed in [#11069](https://github.com/magento/magento2/pull/11069)) + * [#9877](https://github.com/magento/magento2/issues/9877) -- getCacheTags for price issue (fixed in [#11154](https://github.com/magento/magento2/pull/11154)) + * [#10738](https://github.com/magento/magento2/issues/10738) -- Empty attribute label is displayed on product page when other language used. (fixed in [#11168](https://github.com/magento/magento2/pull/11168)) + * [#9900](https://github.com/magento/magento2/issues/9900) -- Cms module collections missing event prefix (fixed in [#11223](https://github.com/magento/magento2/pull/11223)) + * [#11044](https://github.com/magento/magento2/issues/11044) -- magento setup:upgrade prompts to run compilation, even in developer mode (fixed in [#11050](https://github.com/magento/magento2/pull/11050)) + * [#10775](https://github.com/magento/magento2/issues/10775) -- 404 Forbidden sounds not right (fixed in [#11134](https://github.com/magento/magento2/pull/11134)) + * [#11231](https://github.com/magento/magento2/issues/11231) -- Can't close mobile search bar once typed (fixed in [#11246](https://github.com/magento/magento2/pull/11246)) + * [#10317](https://github.com/magento/magento2/issues/10317) -- Region is being overridden when changing from a required-state country to one that is not required (fixed in [#11254](https://github.com/magento/magento2/pull/11254)) + * [#11089](https://github.com/magento/magento2/issues/11089) -- setup:config:set --key append instead of replace (fixed in [#11155](https://github.com/magento/magento2/pull/11155)) + * [#7582](https://github.com/magento/magento2/issues/7582) -- Payment methods in payments title in wrong language (fixed in [#11165](https://github.com/magento/magento2/pull/11165)) + * [#5105](https://github.com/magento/magento2/issues/5105) -- Error While send Invoice with Grouped Products (fixed in [#11297](https://github.com/magento/magento2/pull/11297)) + * [#11163](https://github.com/magento/magento2/issues/11163) -- Magento 2.2.0 Pages showing error: Data key is missing: code-entity (fixed in [#11205](https://github.com/magento/magento2/pull/11205)) + * [#11329](https://github.com/magento/magento2/issues/11329) -- Unable to proceed massaction "Update attributes" with required multiple select attribute (fixed in [#11349](https://github.com/magento/magento2/pull/11349)) + * [#8958](https://github.com/magento/magento2/issues/8958) -- Hint mistake in english language (fixed in [#11390](https://github.com/magento/magento2/pull/11390)) +* GitHub pull requests: + * [#11067](https://github.com/magento/magento2/pull/11067) -- Fix dob date validation on custom locale (by @joachimVT) + * [#11054](https://github.com/magento/magento2/pull/11054) -- Add dev:tests:run parameter to pass arguments to phpunit (by @schmengler) + * [#11056](https://github.com/magento/magento2/pull/11056) -- Do not disable maintenance mode after running a backup. (by @stevenvdp) + * [#11058](https://github.com/magento/magento2/pull/11058) -- Escape html before replace new line with break (by @Quinten) + * [#11063](https://github.com/magento/magento2/pull/11063) -- 6712 Remove additional margin for footer links widget; prevents layou… (by @fragdochkarl) + * [#11064](https://github.com/magento/magento2/pull/11064) -- Show different message if DB module version is higher than code modul… (by @schmengler) + * [#11076](https://github.com/magento/magento2/pull/11076) -- Backport to 2.2 of #10824: add name for order items grid default renderer block (by @gsomoza) + * [#11048](https://github.com/magento/magento2/pull/11048) -- Fix #10417 (by @PieterCappelle) + * [#11049](https://github.com/magento/magento2/pull/11049) -- Vague error message for invalid url_key for category (by @avdb) + * [#11069](https://github.com/magento/magento2/pull/11069) -- Error message in product review form not being translated (by @Echron) + * [#11127](https://github.com/magento/magento2/pull/11127) -- Add missing return statements in setters (by @niccifor) + * [#11138](https://github.com/magento/magento2/pull/11138) -- Added template as argument to the store address renderer to allow custom formatting (by @jokeputs) + * [#11147](https://github.com/magento/magento2/pull/11147) -- Fix the correct removal of the images and the removal of all images in the catalog (by @raumatbel) + * [#11154](https://github.com/magento/magento2/pull/11154) -- Issue #9877: Backport of: getCacheTags for price issue #10930 (by @denysbabenko) + * [#11160](https://github.com/magento/magento2/pull/11160) -- Ported Down changes from PR#10919 (by @strell) + * [#11200](https://github.com/magento/magento2/pull/11200) -- Delete CallExit function for After plugin logic execution 2.2-develop [BackPort] (by @osrecio) + * [#11168](https://github.com/magento/magento2/pull/11168) -- Fixed issue #10738: Don't display attribute label if defined as "none" in layout (by @maksek) + * [#11223](https://github.com/magento/magento2/pull/11223) -- Cms page/block eventprefix fix issue 9900 (by @convenient) + * [#11229](https://github.com/magento/magento2/pull/11229) -- Disable secret key validation on admin noroute to fix redirect loop (by @convenient) + * [#11050](https://github.com/magento/magento2/pull/11050) -- Only prompt for deploy command in production mode (by @schmengler) + * [#11134](https://github.com/magento/magento2/pull/11134) -- Fix 404 status header (by @Zifius) + * [#11084](https://github.com/magento/magento2/pull/11084) -- Fix in stripped min length validation when value has special characters (by @rubenRP) + * [#11246](https://github.com/magento/magento2/pull/11246) -- Can't close mobile search bar (by @crissanclick) + * [#11254](https://github.com/magento/magento2/pull/11254) -- Fix for #10317 Disable region list when switching to a region optional country. (by @romainruaud) + * [#11155](https://github.com/magento/magento2/pull/11155) -- Refactor ConfigGenerator to replace/set crypt key instead of append (by @renttek) + * [#11291](https://github.com/magento/magento2/pull/11291) -- Fix #9243 - Upgrade ZF components. Zend_Service (by @dverkade) + * [#11165](https://github.com/magento/magento2/pull/11165) -- #7582: use setStoreId after custom load method to give storeId precedence (by @bka) + * [#11297](https://github.com/magento/magento2/pull/11297) -- Fix for issue #5105 - Error While send Invoice with Grouped Products (by @michielgerritsen) + * [#11327](https://github.com/magento/magento2/pull/11327) -- Fix #10812: htaccess Options override (by @dverkade) + * [#11081](https://github.com/magento/magento2/pull/11081) -- Text updated. (by @RakeshJesadiya) + * [#11183](https://github.com/magento/magento2/pull/11183) -- FIX for #11166 Index Handling Fatal Error (by @larsroettig) + * [#11205](https://github.com/magento/magento2/pull/11205) -- Fixes #11163 missing data key code-entity in CMS page edit form (by @Tomasz-Silpion) + * [#11219](https://github.com/magento/magento2/pull/11219) -- Fix typo in sessionStorage polyfill (by @mszydlo) + * [#11249](https://github.com/magento/magento2/pull/11249) -- Add a payload extender to the default shipping-save-processor (Backport to 2.2) (by @navarr) + * [#11345](https://github.com/magento/magento2/pull/11345) -- Use US English spelling for "Optimization". (by @davidangel) + * [#11349](https://github.com/magento/magento2/pull/11349) -- Bug fix update attributes (by @manuelson) + * [#11390](https://github.com/magento/magento2/pull/11390) -- Fix typo in design rule hint message (by @jahvi) + +2.2.0 +============= +* GitHub issues: + * [#8287](https://github.com/magento/magento2/issues/8287) -- InputException while updating cart with Minimum order amount enabled (fixed in [#8474](https://github.com/magento/magento2/pull/8474)) + * [#8315](https://github.com/magento/magento2/issues/8315) -- Error with StdoTest (fixed in [#8487](https://github.com/magento/magento2/pull/8487)) + * [#5808](https://github.com/magento/magento2/issues/5808) -- [2.1.0] Problem on mobile when catalog gallery allowfullscreen is false (fixed in [#8434](https://github.com/magento/magento2/pull/8434)) + * [#8392](https://github.com/magento/magento2/issues/8392) -- Initial loading of the related-products sorting fails in Edge-Mode (fixed in [#8467](https://github.com/magento/magento2/pull/8467)) + * [#8076](https://github.com/magento/magento2/issues/8076) -- Currency Setup in admin throws in_array error when a single value is selected (fixed in [#8077](https://github.com/magento/magento2/pull/8077)) + * [#8277](https://github.com/magento/magento2/issues/8277) -- CatalogImportExport uploader can't handle HTTPS images (fixed in [#8278](https://github.com/magento/magento2/pull/8278)) + * [#7353](https://github.com/magento/magento2/issues/7353) -- Crosssells are never shown when using product/list/items.phtml template (fixed in [#8602](https://github.com/magento/magento2/pull/8602)) + * [#8632](https://github.com/magento/magento2/issues/8632) -- Location of wishlist.js file is incorrect (fixed in [#8633](https://github.com/magento/magento2/pull/8633)) + * [#6634](https://github.com/magento/magento2/issues/6634) -- Yes/No attribute value is not shown on a product details page (fixed in [#8623](https://github.com/magento/magento2/pull/8623)) + * [#8566](https://github.com/magento/magento2/issues/8566) -- Setting 'show_out_of_stock' to 'No' has no effect (fixed in [#8736](https://github.com/magento/magento2/pull/8736)) + * [#6706](https://github.com/magento/magento2/issues/6706) -- Notice undefined index when changes swatch attribute (fixed in [#6707](https://github.com/magento/magento2/pull/6707)) + * [#6855](https://github.com/magento/magento2/issues/6855) -- Create order via backend doesn't work after using NL translation for order-header (fixed in [#6856](https://github.com/magento/magento2/pull/6856)) + * [#8515](https://github.com/magento/magento2/issues/8515) -- Downloadable product is available for download even if order state is set canceled. (fixed in [#8917](https://github.com/magento/magento2/pull/8917)) + * [#8871](https://github.com/magento/magento2/issues/8871) -- Typo in Pull Request Template (fixed in [#8908](https://github.com/magento/magento2/pull/8908)) + * [#3791](https://github.com/magento/magento2/issues/3791) -- Error review when customer is not logged (fixed in [#9001](https://github.com/magento/magento2/pull/9001)) + * [#9017](https://github.com/magento/magento2/issues/9017) -- Duplicate call to $this->getLinkField(); (fixed in [#9057](https://github.com/magento/magento2/pull/9057)) + * [#7498](https://github.com/magento/magento2/issues/7498) -- Grammar Mistake: You don't subscribe to our newsletter. (fixed in [#9080](https://github.com/magento/magento2/pull/9080)) + * [#9078](https://github.com/magento/magento2/issues/9078) -- Does not translate "Track All Shipments" in My Account, view order (fixed in [#9095](https://github.com/magento/magento2/pull/9095)) + * [#5731](https://github.com/magento/magento2/issues/5731) -- FPT label not translatable in the totals on the cart page. (fixed in [#9204](https://github.com/magento/magento2/pull/9204)) + * [#5040](https://github.com/magento/magento2/issues/5040) -- Change 'select' to 'query' in AbstractSearchResult (fixed in [#5043](https://github.com/magento/magento2/pull/5043)) + * [#8761](https://github.com/magento/magento2/issues/8761) -- Popup-Modal not closing on Safari/Windows (fixed in [#8824](https://github.com/magento/magento2/pull/8824)) + * [#7549](https://github.com/magento/magento2/issues/7549) -- Google API Tracking code missing single quote after account number (fixed in [#9084](https://github.com/magento/magento2/pull/9084)) + * [#1146](https://github.com/magento/magento2/issues/1146) -- A few issues when you use /pub as DocumentRoot (fixed in [#9094](https://github.com/magento/magento2/pull/9094)) + * [#2802](https://github.com/magento/magento2/issues/2802) -- Sitemap generation in wrong folder when vhost is connected to pub folder (fixed in [#9094](https://github.com/magento/magento2/pull/9094)) + * [#9200](https://github.com/magento/magento2/issues/9200) -- Create new CLI command: Enable DB logging (fixed in [#9264](https://github.com/magento/magento2/pull/9264)) + * [#9199](https://github.com/magento/magento2/issues/9199) -- Create New CLI command: Generate Varnish VCL file (fixed in [#9286](https://github.com/magento/magento2/pull/9286)) + * [#6822](https://github.com/magento/magento2/issues/6822) -- CSS Minify Option Breaks inline SVG XML (fixed in [#9027](https://github.com/magento/magento2/pull/9027)) + * [#8552](https://github.com/magento/magento2/issues/8552) -- CSS Minifying not compatible with CSS3 calc() function (fixed in [#9027](https://github.com/magento/magento2/pull/9027)) + * [#9236](https://github.com/magento/magento2/issues/9236) -- Upgrade ZF components. Zend_Json (fixed in [#9262](https://github.com/magento/magento2/pull/9262) and [#9261](https://github.com/magento/magento2/pull/9261) and [#9344](https://github.com/magento/magento2/pull/9344) and [#9753](https://github.com/magento/magento2/pull/9753) and [#9754](https://github.com/magento/magento2/pull/9754)) + * [#7523](https://github.com/magento/magento2/issues/7523) -- Zend_Db_Statement_Exception after refreshing browser with empty category (fixed in [#9400](https://github.com/magento/magento2/pull/9400)) + * [#9237](https://github.com/magento/magento2/issues/9237) -- Upgrade ZF components. Zend_Log (fixed in [#9285](https://github.com/magento/magento2/pull/9285)) + * [#9518](https://github.com/magento/magento2/issues/9518) -- Chrome version 58 causes problems with selections in the tinymce editor (fixed in [#9540](https://github.com/magento/magento2/pull/9540)) + * [#9241](https://github.com/magento/magento2/issues/9241) -- Upgrade ZF components. Zend_Wildfire (fixed in [#9622](https://github.com/magento/magento2/pull/9622)) + * [#9239](https://github.com/magento/magento2/issues/9239) -- Upgrade ZF components. Zend_Controller (fixed in [#9622](https://github.com/magento/magento2/pull/9622)) + * [#6455](https://github.com/magento/magento2/issues/6455) -- Cookie Restriction Mode Overlay is cached by Varnish (fixed in [#9711](https://github.com/magento/magento2/pull/9711)) + * [#5596](https://github.com/magento/magento2/issues/5596) -- Google Universal Analytics does not track when Cookie Restriction is enabled (fixed in [#9713](https://github.com/magento/magento2/pull/9713)) + * [#6441](https://github.com/magento/magento2/issues/6441) -- Google Analytics Tracking Code cached by Varnish if Cookie Restriction Settings are active (fixed in [#9713](https://github.com/magento/magento2/pull/9713)) + * [#9242](https://github.com/magento/magento2/issues/9242) -- Upgrade ZF components. Zend_Session (fixed in [#9348](https://github.com/magento/magento2/pull/9348)) + * [#7279](https://github.com/magento/magento2/issues/7279) -- Bill-to Name and Ship-to Name trancated to 20 characters in backend (fixed in [#9654](https://github.com/magento/magento2/pull/9654)) + * [#6151](https://github.com/magento/magento2/issues/6151) -- Can't delete last item in cart if Minimum Order is Enable (fixed in [#9714](https://github.com/magento/magento2/pull/9714)) + * [#4272](https://github.com/magento/magento2/issues/4272) -- v2.0.4 Credit memos with adjustment fees cannot be fully refunded with a second credit memo (fixed in [#9715](https://github.com/magento/magento2/pull/9715)) + * [#6207](https://github.com/magento/magento2/issues/6207) -- Checkbox IDs for Terms and Conditions should be unique in Checkout (fixed in [#9717](https://github.com/magento/magento2/pull/9717)) + * [#7844](https://github.com/magento/magento2/issues/7844) -- Customer with unique attribute can't be saved (fixed in [#9712](https://github.com/magento/magento2/pull/9712)) + * [#6244](https://github.com/magento/magento2/issues/6244) -- Promo code label not used (fixed in [#9721](https://github.com/magento/magento2/pull/9721)) + * [#9771](https://github.com/magento/magento2/issues/9771) -- XML instruction referenceBlock does not allow template= or does it? (fixed in [#9772](https://github.com/magento/magento2/pull/9772)) + * [#8221](https://github.com/magento/magento2/issues/8221) -- Javascript "mixins" doesn't works if 'urlArgs' is in requirejs-config.js (fixed in [#9665](https://github.com/magento/magento2/pull/9665)) + * [#9278](https://github.com/magento/magento2/issues/9278) -- Create new CLI command: Enable Template Hints (fixed in [#9778](https://github.com/magento/magento2/pull/9778)) + * [#9819](https://github.com/magento/magento2/issues/9819) -- Authentication_lock settings cannot be edited in the Backend (fixed in [#9820](https://github.com/magento/magento2/pull/9820)) + * [#9216](https://github.com/magento/magento2/issues/9216) -- Coupon codes not showing in invoice print out (fixed in [#9780](https://github.com/magento/magento2/pull/9780)) + * [#9679](https://github.com/magento/magento2/issues/9679) -- Translation for layered navigation attribute option not working (fixed in [#9873](https://github.com/magento/magento2/pull/9873)) + * [#3060](https://github.com/magento/magento2/issues/3060) -- setup:static-content:deploy, setup:di:compile and deploy:mode:set will not return a non-zero exit code if any error occurs (fixed in [#7780](https://github.com/magento/magento2/pull/7780)) + * [#9421](https://github.com/magento/magento2/issues/9421) -- Inconsistent Gift Options checkbox labels (fixed in [#9525](https://github.com/magento/magento2/pull/9525)) + * [#9805](https://github.com/magento/magento2/issues/9805) -- Static tests in Windows fail due to file path mismatches (fixed in [#9902](https://github.com/magento/magento2/pull/9902)) + * [#9924](https://github.com/magento/magento2/issues/9924) -- Prefix and suffix are not prefilled in the quote shipping address (fixed in [#9925](https://github.com/magento/magento2/pull/9925)) + * [#4237](https://github.com/magento/magento2/issues/4237) -- Cron times in the database have a double timezone correction (fixed in [#9943](https://github.com/magento/magento2/pull/9943)) + * [#9426](https://github.com/magento/magento2/issues/9426) -- Incorrect order date in Orders grid (fixed in [#9941](https://github.com/magento/magento2/pull/9941)) + * [#3380](https://github.com/magento/magento2/issues/3380) -- Remove scheduled jobs after changing cron settings (fixed in [#9957](https://github.com/magento/magento2/pull/9957)) + * [#7504](https://github.com/magento/magento2/issues/7504) -- sitemap image URLs do not match with those on product pages (fixed in [#9082](https://github.com/magento/magento2/pull/9082)) + * [#8732](https://github.com/magento/magento2/issues/8732) -- The country drop-down list display incorrect after upgrade to 2.1.4 in Admin (fixed in [#9429](https://github.com/magento/magento2/pull/9429)) + * [#9680](https://github.com/magento/magento2/issues/9680) -- Adding product configurations uses sku based name (fixed in [#9681](https://github.com/magento/magento2/pull/9681)) + * [#10017](https://github.com/magento/magento2/issues/10017) -- Customer Backend: Confirmation Flag is being overwritten by save of the Customer (fixed in [#9681](https://github.com/magento/magento2/pull/9681)) + * [#2266](https://github.com/magento/magento2/issues/2266) -- Action column menu does not stay over the action column (fixed in [#10082](https://github.com/magento/magento2/pull/10082)) + * [#5381](https://github.com/magento/magento2/issues/5381) -- Cannot create a `etc/view.xml` file with an `images` tag with an attribute `module` other than `Magento_Catalog` (fixed in [#10052](https://github.com/magento/magento2/pull/10052)) + * [#6337](https://github.com/magento/magento2/issues/6337) -- Not able to translate page layout head titles (fixed in [#9992](https://github.com/magento/magento2/pull/9992)) + * [#3872](https://github.com/magento/magento2/issues/3872) -- Slash as category URL suffix gives 404 error on all category pages (fixed in [#10043](https://github.com/magento/magento2/pull/10043)) + * [#4660](https://github.com/magento/magento2/issues/4660) -- Multiple URLs causes duplicated content (fixed in [#10043](https://github.com/magento/magento2/pull/10043)) + * [#4876](https://github.com/magento/magento2/issues/4876) -- Product URL Suffix "/" results in 404 error (fixed in [#10043](https://github.com/magento/magento2/pull/10043)) + * [#8264](https://github.com/magento/magento2/issues/8264) -- Custom URL Rewrite where the request path ends with a forward slash is not matched (fixed in [#10043](https://github.com/magento/magento2/pull/10043)) + * [#6396](https://github.com/magento/magento2/issues/6396) -- Cart Price Rules: Category selection UI for Conditions do not come up. (fixed in [#10094](https://github.com/magento/magento2/pull/10094)) + * [#10124](https://github.com/magento/magento2/issues/10124) -- Wrong order of "width" x "height" when uploading image to admin under Content>Design Config (fixed in [#10126](https://github.com/magento/magento2/pull/10126)) + * [#6594](https://github.com/magento/magento2/issues/6594) -- Magento 2.1 EE: simplexml_load_string() error in custom widget (fixed in [#10151](https://github.com/magento/magento2/pull/10151)) + * [#10148](https://github.com/magento/magento2/issues/10148) -- Developer ACL incorrect (fixed in [#10149](https://github.com/magento/magento2/pull/10149)) + * [#9445](https://github.com/magento/magento2/issues/9445) -- Cart 860 does not contain item 1204 (fixed in [#10059](https://github.com/magento/magento2/pull/10059)) +* GitHub pull requests: + * [#4078](https://github.com/magento/magento2/pull/4078) -- Add logo folder to list of allowed resources (by @thaiphan) + * [#4355](https://github.com/magento/magento2/pull/4355) -- Enforce password and password-confirm as strings (by @nevvermind) + * [#4175](https://github.com/magento/magento2/pull/4175) -- PHP 7 (by @rafaelstz) + * [#4669](https://github.com/magento/magento2/pull/4669) -- Php 5.5 support was removed (by @fooman) + * [#4766](https://github.com/magento/magento2/pull/4766) -- The time has come for splat operator (by @orlangur) + * [#4867](https://github.com/magento/magento2/pull/4867) -- Fix commandExecutor interface mismatch (by @wexo-team) + * [#3705](https://github.com/magento/magento2/pull/3705) -- fix issue #3704 regarding integer attribute values being cast to decimal (by @digitalpianism) + * [#3750](https://github.com/magento/magento2/pull/3750) -- Add ability to show custom error message on Authorizenet place order (by @ytorbyk) + * [#3859](https://github.com/magento/magento2/pull/3859) -- Fixes _toHtml method of Checkout/Block/Cart/Link class (by @ddonnini) + * [#4017](https://github.com/magento/magento2/pull/4017) -- Add the $t to translate the message (by @mamzellejuu) + * [#4239](https://github.com/magento/magento2/pull/4239) -- Attribute Model specifiable in Propertymapper (by @liolemaire) + * [#4583](https://github.com/magento/magento2/pull/4583) -- Fix desktop spelling in lib/web/css #4557 (by @BenSpace48) + * [#2735](https://github.com/magento/magento2/pull/2735) -- Add database port to Magento Setup Model Installer (by @tkn98) + * [#4275](https://github.com/magento/magento2/pull/4275) -- Database port missing in Magento\TestFramework\Db\Mysql #3529 (by @gordonknoppe) + * [#4372](https://github.com/magento/magento2/pull/4372) -- Remove unused property + use ::class (by @nevvermind) + * [#2274](https://github.com/magento/magento2/pull/2274) -- TypeError: this.trigger is not a function (by @daim2k5) + * [#3050](https://github.com/magento/magento2/pull/3050) -- Replace PrototypeJS (by @srenon) + * [#3436](https://github.com/magento/magento2/pull/3436) -- Fix stripped-min-length check (by @avoelkl) + * [#3638](https://github.com/magento/magento2/pull/3638) -- Fix #3637 Add missing catalogsearch layout for swatches. (by @romainruaud) + * [#3633](https://github.com/magento/magento2/pull/3633) -- #768 - fix Missing acl.xml for the Magento_Checkout module (by @tzyganu) + * [#3708](https://github.com/magento/magento2/pull/3708) -- Add 'yyyy' to nomalizedDate method map for adminhtml i18n (by @Amakata) + * [#3973](https://github.com/magento/magento2/pull/3973) -- fix bug on newsletter subscription action when user use an existing email already subscribed (by @manfrinm) + * [#3932](https://github.com/magento/magento2/pull/3932) -- Update Date.php (by @Maddesto) + * [#3907](https://github.com/magento/magento2/pull/3907) -- Update Layout.php (by @Maddesto) + * [#4051](https://github.com/magento/magento2/pull/4051) -- Fix "minimum-length" option of the "validate-length" JS validation (by @adragus-inviqa) + * [#4269](https://github.com/magento/magento2/pull/4269) -- ConfigurableProduct validator, first check if array item exists (by @BlackIkeEagle) + * [#4496](https://github.com/magento/magento2/pull/4496) -- Access element through jQuery (by @sikker) + * [#4631](https://github.com/magento/magento2/pull/4631) -- Previous is spelt incorrectly (by @BenSpace48) + * [#4882](https://github.com/magento/magento2/pull/4882) -- Fix handling is_region_required key as optional (by @komsitr) + * [#5028](https://github.com/magento/magento2/pull/5028) -- Load jquery using requirejs to print page (by @Bartlomiejsz) + * [#1957](https://github.com/magento/magento2/pull/1957) -- Add required interface implementation (by @udovicic) + * [#2492](https://github.com/magento/magento2/pull/2492) -- No translation from "Orders and Returns" footer links (by @mageho) + * [#3749](https://github.com/magento/magento2/pull/3749) -- Stop screen loader on payment error (by @ytorbyk) + * [#4901](https://github.com/magento/magento2/pull/4901) -- Fix XML validation value type of post-code to "boolean" (by @adragus-inviqa) + * [#5066](https://github.com/magento/magento2/pull/5066) -- Add underscore as dependency to quote.js (by @Bartlomiejsz) + * [#5116](https://github.com/magento/magento2/pull/5116) -- Fixes invalid json objects in the order email templates. (by @hostep) + * [#5095](https://github.com/magento/magento2/pull/5095) -- Fix integration test expectation to match count of countries in the database (by @Vinai) + * [#5200](https://github.com/magento/magento2/pull/5200) -- Adminhtml sales view - Escape remoteIp (by @convenient) + * [#4294](https://github.com/magento/magento2/pull/4294) -- Static deploy flags (by @denisristic) + * [#3137](https://github.com/magento/magento2/pull/3137) -- Update nginx.conf.sample (by @thaiphan) + * [#3746](https://github.com/magento/magento2/pull/3746) -- Add HttpInterface methods and add up-casts for type safety (by @Vinai) + * [#4354](https://github.com/magento/magento2/pull/4354) -- Adds test for getDataUsingMethod using digits (by @fooman) + * [#4396](https://github.com/magento/magento2/pull/4396) -- Don't hardcode the Magento_Backend::admin index (by @annybs) + * [#4491](https://github.com/magento/magento2/pull/4491) -- Correction: variable naming for user roles & role id (by @MagePsycho) + * [#4519](https://github.com/magento/magento2/pull/4519) -- Create auth.json.sample (by @rafaelstz) + * [#3688](https://github.com/magento/magento2/pull/3688) -- added partial fix for issue #2617. (by @whizkid79) + * [#3770](https://github.com/magento/magento2/pull/3770) -- Bugfix: Unable to activate search form on phone (by @vovayatsyuk) + * [#4011](https://github.com/magento/magento2/pull/4011) -- Fixed post var name for update attributes (by @Corefix) + * [#2791](https://github.com/magento/magento2/pull/2791) -- Update Template.php (by @liam-wiltshire) + * [#5496](https://github.com/magento/magento2/pull/5496) -- Fixes #5495 (Mobile navigation submenus need two clicks to open) (by @ajpevers) + * [#5725](https://github.com/magento/magento2/pull/5725) -- Fix/translation in validation files (by @dvynograd) + * [#5915](https://github.com/magento/magento2/pull/5915) -- Added missing translation to range grid filter (by @maqlec) + * [#5884](https://github.com/magento/magento2/pull/5884) -- Use alias already defined in requirejs-config.js (by @kassner) + * [#4388](https://github.com/magento/magento2/pull/4388) -- Fixed column description for "website_id" column (by @ikk0) + * [#1628](https://github.com/magento/magento2/pull/1628) -- Add cache of configuration files list (by @otakarmare) + * [#4791](https://github.com/magento/magento2/pull/4791) -- Replace fabpot/php-cs-fixer with friendsofphp/php-cs-fixer (by @GordonLesti) + * [#5983](https://github.com/magento/magento2/pull/5983) -- Fix 'Track your order' i18n. (by @peec) + * [#1988](https://github.com/magento/magento2/pull/1988) -- Use inline elements for inline links (by @chicgeek) + * [#6283](https://github.com/magento/magento2/pull/6283) -- Update elements.xsd (by @aholovan) + * [#1935](https://github.com/magento/magento2/pull/1935) -- Added 'target' attribute to the allowed attributes array for link block (by @fcapua-summa) + * [#4733](https://github.com/magento/magento2/pull/4733) -- Escape Js Quote for layout updates (by @bchatard) + * [#4565](https://github.com/magento/magento2/pull/4565) -- Update Container.php (by @Maddesto) + * [#4845](https://github.com/magento/magento2/pull/4845) -- Set return code for SetModeCommand (by @mc388) + * [#2037](https://github.com/magento/magento2/pull/2037) -- Correct the error message when creating wrong object for block (by @hiephm) + * [#3779](https://github.com/magento/magento2/pull/3779) -- Add dispatching of view_block_abstract_to_html_after event (by @aleron75) + * [#5741](https://github.com/magento/magento2/pull/5741) -- Update AbstractTemplate.php (by @vivek201) + * [#5145](https://github.com/magento/magento2/pull/5145) -- \Magento\CatalogInventory\Model\Stock\Status->getStockId() to return correct value (by @fe-lix-) + * [#6009](https://github.com/magento/magento2/pull/6009) -- Update README.md (by @fooman) + * [#6280](https://github.com/magento/magento2/pull/6280) -- Fixed layout for customer authentication popup (by @rogyar) + * [#6549](https://github.com/magento/magento2/pull/6549) -- Remove obsolete comment in catalog_category_view.xml (by @pdanzinger) + * [#6804](https://github.com/magento/magento2/pull/6804) -- Fix nav not working in mobile (by @slackerzz) + * [#6801](https://github.com/magento/magento2/pull/6801) -- Fixed unclosed span tag in Review module (by @PingusPepan) + * [#5045](https://github.com/magento/magento2/pull/5045) -- Fix runner for JsTestDriver based tests on OS X (by @Vinai) + * [#4958](https://github.com/magento/magento2/pull/4958) -- block newsletter title (by @slackerzz) + * [#5548](https://github.com/magento/magento2/pull/5548) -- Fix error with the WYSIWYG and Greek characters (by @sakisplus) + * [#7256](https://github.com/magento/magento2/pull/7256) -- Fix incorrect table name during catalog product indexing (by @nagno) + * [#6972](https://github.com/magento/magento2/pull/6972) -- Fix issue #6968 since checkout success title is not displayed (by @AngelVazquezArroyo) + * [#4121](https://github.com/magento/magento2/pull/4121) -- Ensure composer.json exists (by @dank00) + * [#4134](https://github.com/magento/magento2/pull/4134) -- Added call to action to compile command error (by @sammarcus) + * [#6974](https://github.com/magento/magento2/pull/6974) -- Fixed calling non exists order address->getCountry to getCountryId (by @magexo) + * [#4088](https://github.com/magento/magento2/pull/4088) -- Fix newsletter queue subscribers adding performance (by @DariuszMaciejewski) + * [#6952](https://github.com/magento/magento2/pull/6952) -- Update AccountLock.php (by @klict) + * [#5465](https://github.com/magento/magento2/pull/5465) -- Fix Magento\Review\Model\ResourceModel\Rating\Option not instantiable in setup scripts (by @adragus-inviqa) + * [#7799](https://github.com/magento/magento2/pull/7799) -- Remove duplicate code from template file. (by @dverkade) + * [#7919](https://github.com/magento/magento2/pull/7919) -- Using Dynamic Protocol Concatination (by @brobie) + * [#7921](https://github.com/magento/magento2/pull/7921) -- Removed un-used static version rewrite rule in nginx.conf.sample (by @careys7) + * [#8019](https://github.com/magento/magento2/pull/8019) -- added fr_CH to allowed locales list (by @annapivniak) + * [#8082](https://github.com/magento/magento2/pull/8082) -- issue 8080: Cron configuration loading from DB doesn't work (by @ytorbyk) + * [#8062](https://github.com/magento/magento2/pull/8062) -- Fix theme source model used in widget grid (by @Zefiryn) + * [#8232](https://github.com/magento/magento2/pull/8232) -- Fix notice during DI compilation (by @qrz-io) + * [#8306](https://github.com/magento/magento2/pull/8306) -- Remove warning from setup/src/Magento/Setup/Module/I18n/Dictionary/Writer/Csv.php (by @dmanners) + * [#8185](https://github.com/magento/magento2/pull/8185) -- Fix #7461 using the simplest approach for now (by @lazyguru) + * [#8183](https://github.com/magento/magento2/pull/8183) -- [BUGFIX] Fixed the credit memo guest email (by @nickgraz) + * [#8161](https://github.com/magento/magento2/pull/8161) -- Return focus to search input after closing autocomplete dropdown (by @evktalo) + * [#8155](https://github.com/magento/magento2/pull/8155) -- Correct php doc (by @angelomaragna) + * [#8341](https://github.com/magento/magento2/pull/8341) -- Use better function for 'Continue Shopping' url (by @dmatthew) + * [#8336](https://github.com/magento/magento2/pull/8336) -- fixing time format on admin sales order grid (by @magexo) + * [#8327](https://github.com/magento/magento2/pull/8327) -- Change order of parameters passed to LogicException in AbstractTemplate.php (by @bery) + * [#8307](https://github.com/magento/magento2/pull/8307) -- Allow digits in communication class type definition (by @cmuench) + * [#8354](https://github.com/magento/magento2/pull/8354) -- Display correctly "Add" button label for the block class \Magento\Con… (by @diglin) + * [#8246](https://github.com/magento/magento2/pull/8246) -- Fixes #7723 - saving multi select field in UI component form (by @Zefiryn) + * [#8353](https://github.com/magento/magento2/pull/8353) -- Replace into the layout adminhtml_order_shipment_new.xml block alias … (by @diglin) + * [#8395](https://github.com/magento/magento2/pull/8395) -- Added "editPost" action for customer sections.xml (by @rossluk) + * [#8383](https://github.com/magento/magento2/pull/8383) -- Issue/8382 (by @PascalBrouwers) + * [#8151](https://github.com/magento/magento2/pull/8151) -- Remove "<2.7" constraint on symfony/console (by @nicolas-grekas) + * [#8416](https://github.com/magento/magento2/pull/8416) -- Use configured product attributes in wishlist item collection (by @schmengler) + * [#8414](https://github.com/magento/magento2/pull/8414) -- Replace toGMTString with toUTCString (by @schmengler) + * [#8419](https://github.com/magento/magento2/pull/8419) -- Use page result instead of rendering layout directly in controllers (by @schmengler) + * [#8331](https://github.com/magento/magento2/pull/8331) -- Remove Zend1 Json from Magento Captcha module (by @dmanners) + * [#8252](https://github.com/magento/magento2/pull/8252) -- Customer account edit form: additional info block visible (by @Sylvco) + * [#8405](https://github.com/magento/magento2/pull/8405) -- Remove the unused Ajax/Serializer.php class (by @dmanners) + * [#8402](https://github.com/magento/magento2/pull/8402) -- Remove Zend1 db from captcha module (by @dmanners) + * [#8463](https://github.com/magento/magento2/pull/8463) -- Remove outdated comment (by @evktalo) + * [#8456](https://github.com/magento/magento2/pull/8456) -- Specifically ask for the Json Serializer object Mage Braintree (by @dmanners) + * [#8446](https://github.com/magento/magento2/pull/8446) -- Fix "each()" function call on potentially invalid data (by @giacmir) + * [#5928](https://github.com/magento/magento2/pull/5928) -- prevent double shipping method selection (by @danslo) + * [#8217](https://github.com/magento/magento2/pull/8217) -- Update DataProvider.php (by @redelschaap) + * [#8413](https://github.com/magento/magento2/pull/8413) -- Load translations for area, fixes #8412 (by @fooman) + * [#8356](https://github.com/magento/magento2/pull/8356) -- Remove Zend1 captcha from Magento2 Captcha module (by @dmanners) + * [#8474](https://github.com/magento/magento2/pull/8474) -- Fix for https://github.com/magento/magento2/issues/8287 (by @ericrisler) + * [#8487](https://github.com/magento/magento2/pull/8487) -- Mark the STDO test as skipped (by @dmanners) + * [#3155](https://github.com/magento/magento2/pull/3155) -- Remove unused variables in unit test (by @fooman) + * [#6049](https://github.com/magento/magento2/pull/6049) -- Added typo correction for table name comment (by @atishgoswami) + * [#4370](https://github.com/magento/magento2/pull/4370) -- update Catalog Helper (by @barbarich-p) + * [#4106](https://github.com/magento/magento2/pull/4106) -- Adds support for purging varnish cache based on an X-Pool header (by @davidalger) + * [#7982](https://github.com/magento/magento2/pull/7982) -- Add bin/magento commands to list store/website data (by @convenient) + * [#8434](https://github.com/magento/magento2/pull/8434) -- Problem on mobile when catalog gallery allowfullscreen is false #5808 (by @Crossmotion) + * [#8417](https://github.com/magento/magento2/pull/8417) -- add anonymize ip option for google analytics (by @thomas-villagers) + * [#8498](https://github.com/magento/magento2/pull/8498) -- Product->save() shouldn't be called directly (by @stansm) + * [#8581](https://github.com/magento/magento2/pull/8581) -- Fixed overly bold icons in Firefox Mac (by @TandyCorp) + * [#8481](https://github.com/magento/magento2/pull/8481) -- Remove zend json checkout (by @dmanners) + * [#8518](https://github.com/magento/magento2/pull/8518) -- Change link text from "Report Bugs" to "Report a Bug" (by @Zifius) + * [#8514](https://github.com/magento/magento2/pull/8514) -- Add missing name attributes to catalog_product_view layout xml (by @andrewnoble) + * [#8505](https://github.com/magento/magento2/pull/8505) -- Update the Adminhtml image tree JSON (by @dmanners) + * [#8467](https://github.com/magento/magento2/pull/8467) -- Fix for magento/magento2#8392 (by @kirashet666) + * [#8617](https://github.com/magento/magento2/pull/8617) -- Remove Zend_Json from Customer module (by @dmanners) + * [#8609](https://github.com/magento/magento2/pull/8609) -- [PHP 7.1 Compatibility] Void became a reserved word (by @orlangur) + * [#8611](https://github.com/magento/magento2/pull/8611) -- Fix #8308: test setup/src/Magento/Setup/Test/Unit/Model/Cron/JobSetCacheTest.php crashes in debug mode (by @orlangur) + * [#8610](https://github.com/magento/magento2/pull/8610) -- Fix #8315: test setup/src/Magento/Setup/Test/Unit/Module/I18n/Dictionary/Writer/Csv/StdoTest.php crashes in debug mode (by @orlangur) + * [#7339](https://github.com/magento/magento2/pull/7339) -- Fix/xml parser issue (by @dvynograd) + * [#7345](https://github.com/magento/magento2/pull/7345) -- Fix typo (by @mpchadwick) + * [#7406](https://github.com/magento/magento2/pull/7406) -- MAGETWO-60448 (by @vasilii-b) + * [#8000](https://github.com/magento/magento2/pull/8000) -- Set static html fragments as cacheable (by @paveq) + * [#8077](https://github.com/magento/magento2/pull/8077) -- Type cast (by @deriknel) + * [#8278](https://github.com/magento/magento2/pull/8278) -- bug #8277 fixing bug with https downloading. (by @clementbeudot) + * [#8420](https://github.com/magento/magento2/pull/8420) -- Refactor contact module (by @schmengler) + * [#8519](https://github.com/magento/magento2/pull/8519) -- Make "is_required" and "is_visible" properties of telephone, company and fax attributes of addresses configurable (by @avstudnitz) + * [#8537](https://github.com/magento/magento2/pull/8537) -- Fixed missing echo statement in checkout cart coupon template (by @FrankRuis) + * [#8602](https://github.com/magento/magento2/pull/8602) -- Fixed crosssells count always null (by @koenner01) + * [#8593](https://github.com/magento/magento2/pull/8593) -- Fix #7371 (by @rossluk) + * [#8642](https://github.com/magento/magento2/pull/8642) -- Update Save.php (by @josefbehr) + * [#8633](https://github.com/magento/magento2/pull/8633) -- Fix #8632 (by @koenner01) + * [#8513](https://github.com/magento/magento2/pull/8513) -- Replace ext name spaces with dashes (as composer does when storing) (by @AydinHassan) + * [#8668](https://github.com/magento/magento2/pull/8668) -- Add correct return type in order service (by @cmuench) + * [#8677](https://github.com/magento/magento2/pull/8677) -- Fixed Doc Block for the dispatch method of the Rest Controller (by @vrann) + * [#3585](https://github.com/magento/magento2/pull/3585) -- Remove duplicate switchIsFilterable (by @GordonLesti) + * [#8132](https://github.com/magento/magento2/pull/8132) -- Fix incorrect schema definition for price (by @unfunco) + * [#2275](https://github.com/magento/magento2/pull/2275) -- Updated links to point to http://devdocs.magento.com/guides/v2.0 (by @wjarka) + * [#8683](https://github.com/magento/magento2/pull/8683) -- Fixed return type of OrderRepository::getList (by @clementbeudot) + * [#8682](https://github.com/magento/magento2/pull/8682) -- Remove unused argument (by @mfdj) + * [#2185](https://github.com/magento/magento2/pull/2185) -- unused variable (by @barbarich-p) + * [#7894](https://github.com/magento/magento2/pull/7894) -- Fix #7893 (by @andreaspenz) + * [#8623](https://github.com/magento/magento2/pull/8623) -- Fix check for boolean product attributes (by @TKlement) + * [#8678](https://github.com/magento/magento2/pull/8678) -- Fixed Issue #8425 (by @DavidLambauer) + * [#8711](https://github.com/magento/magento2/pull/8711) -- Remove Zend_Json from the persistent module remember me status observer (by @dmanners) + * [#8706](https://github.com/magento/magento2/pull/8706) -- Remove Zend_Json from the unit test in the CustomerImportExport module (by @dmanners) + * [#8723](https://github.com/magento/magento2/pull/8723) -- Add active class to search form wrapper for more theming flexibility (by @andrewkett) + * [#8768](https://github.com/magento/magento2/pull/8768) -- Fix issue #8709 (by @renatocason) + * [#8762](https://github.com/magento/magento2/pull/8762) -- Fix issue #2558 (by @renatocason) + * [#8759](https://github.com/magento/magento2/pull/8759) -- magento/magento2#8618: Apply coupon code button issue on Checkout (by @mcspronko) + * [#8776](https://github.com/magento/magento2/pull/8776) -- Range filter doesn't works with 0 values in admin #7103 (by @giacmir) + * [#7611](https://github.com/magento/magento2/pull/7611) -- Update catalog_rule_form.xml edit labels (by @fernandofauth) + * [#7650](https://github.com/magento/magento2/pull/7650) -- Add host header to varnish cache purge request (by @m0zziter) + * [#7914](https://github.com/magento/magento2/pull/7914) -- FPC JS - Fix for CORS issue (by @OZZlE) + * [#8013](https://github.com/magento/magento2/pull/8013) -- Update resets.html (by @ryantfowler) + * [#8041](https://github.com/magento/magento2/pull/8041) -- Fix USPS Priority Mail to Canada (by @jaywilliams) + * [#8014](https://github.com/magento/magento2/pull/8014) -- Update _resets.less (by @ryantfowler) + * [#8053](https://github.com/magento/magento2/pull/8053) -- Strict checking types during di compilation (by @michalderlatka) + * [#8048](https://github.com/magento/magento2/pull/8048) -- Consistent HTML tags and breaks (by @chickenland) + * [#8056](https://github.com/magento/magento2/pull/8056) -- update allowed container tags (by @steros) + * [#8158](https://github.com/magento/magento2/pull/8158) -- Fix OAuth request helper to support Authorization header value parsing with non-leading OAuth key (by @careys7) + * [#8589](https://github.com/magento/magento2/pull/8589) -- Set correct primary keys for temporary tables in product flat indexer (by @jarnooravainen) + * [#8736](https://github.com/magento/magento2/pull/8736) -- Update Stock.php (by @Corefix) + * [#8119](https://github.com/magento/magento2/pull/8119) -- Throw exception for invalid (missing) template in dev mode (by @convenient) + * [#8690](https://github.com/magento/magento2/pull/8690) -- Fix SALES_ORDER_TAX_ITEM_TAX_ID_ITEM_ID duplicates (by @mimarcel) + * [#8743](https://github.com/magento/magento2/pull/8743) -- Validate PHP classnames in di.xml files via schema (by @ktomk) + * [#8714](https://github.com/magento/magento2/pull/8714) -- Quote values in IN() predicate to avoid cast issues (by @xi-ao) + * [#8835](https://github.com/magento/magento2/pull/8835) -- Replace Zend_Json from the Magento Review module (by @dmanners) + * [#8832](https://github.com/magento/magento2/pull/8832) -- Replace Zend_Json from the Magento Quote module (by @dmanners) + * [#8839](https://github.com/magento/magento2/pull/8839) -- Rename to DataObjectTest (by @mfdj) + * [#2199](https://github.com/magento/magento2/pull/2199) -- Rename admin sidebar Products to Catalog #2060 (by @markoshust) + * [#5620](https://github.com/magento/magento2/pull/5620) -- Remove superfluous method call. (by @maksim-grib) + * [#6767](https://github.com/magento/magento2/pull/6767) -- Removed setting routerlist twice. (by @dverkade) + * [#6257](https://github.com/magento/magento2/pull/6257) -- Fix "none" is not meant to be translated in catalog_product_view layout file (by @azanelli) + * [#7645](https://github.com/magento/magento2/pull/7645) -- Storecode in url changed from default to all (by @bartlubbersen) + * [#7864](https://github.com/magento/magento2/pull/7864) -- Bugfix: Fix for not respected alternative headers in maintenance mode (by @cmuench) + * [#7794](https://github.com/magento/magento2/pull/7794) -- Check return value for getProduct() in getPrice(). (by @pbaylies) + * [#8052](https://github.com/magento/magento2/pull/8052) -- Update PurgeCache.php (by @bery) + * [#8130](https://github.com/magento/magento2/pull/8130) -- Update Options.php (by @redelschaap) + * [#8079](https://github.com/magento/magento2/pull/8079) -- FIX Backend mass delete Sql error (by @asubit) + * [#7234](https://github.com/magento/magento2/pull/7234) -- Lossless images optimalization (by @Igloczek) + * [#8685](https://github.com/magento/magento2/pull/8685) -- [PSR-2 Compliance] Fix #8612: Hundreds of PHPCS-based static tests violations in mainline (by @orlangur) + * [#7568](https://github.com/magento/magento2/pull/7568) -- Minor Update Mysql.php (by @WJdeBaas) + * [#7598](https://github.com/magento/magento2/pull/7598) -- Bugfix for _getProductCollection on a product page (by @evgk) + * [#8886](https://github.com/magento/magento2/pull/8886) -- Fix typo in app/code/Magento/Email/Test/Unit/Model/TemplateTest.php (by @orlangur) + * [#5029](https://github.com/magento/magento2/pull/5029) -- Add default swatch_image placeholder (by @Bartlomiejsz) + * [#6838](https://github.com/magento/magento2/pull/6838) -- Removed preference from di.xml (by @dverkade) + * [#7578](https://github.com/magento/magento2/pull/7578) -- Don't skip attribute options with a value of 0 from the layered navigation (by @dcabrejas) + * [#7615](https://github.com/magento/magento2/pull/7615) -- Fixes duplicate messages shown when adding items to cart (by @comdiler) + * [#7590](https://github.com/magento/magento2/pull/7590) -- Reset skippedRows array in clear method (by @ccasciotti) + * [#7701](https://github.com/magento/magento2/pull/7701) -- Allows you to have 0 as a option (by @Corefix) + * [#7748](https://github.com/magento/magento2/pull/7748) -- Remove _required class from ZIP field (by @dmitryshkolnikov) + * [#7743](https://github.com/magento/magento2/pull/7743) -- MAGETWO-61828: Text swatch "zero" not shown (by @oroskodias) + * [#8883](https://github.com/magento/magento2/pull/8883) -- Fix a typo (by @evgk) + * [#7541](https://github.com/magento/magento2/pull/7541) -- Added "Add / update" comment. Update was missing. (by @gastondisacco) + * [#8808](https://github.com/magento/magento2/pull/8808) -- Change link text from "Report a Bug" to "Report an Issue" (by @Zifius) + * [#8907](https://github.com/magento/magento2/pull/8907) -- Removed unused dependencys (by @ikrs) + * [#8910](https://github.com/magento/magento2/pull/8910) -- Prevent overwriting grunt config (by @Igloczek) + * [#7562](https://github.com/magento/magento2/pull/7562) -- Update AbstractCart.php (by @Corefix) + * [#8766](https://github.com/magento/magento2/pull/8766) -- fix $childrenWrapClass never used (by @slackerzz) + * [#8822](https://github.com/magento/magento2/pull/8822) -- Upgrade PHP CS Fixer to v2 (by @keradus) + * [#8901](https://github.com/magento/magento2/pull/8901) -- Update design_config_form.xml (by @WaPoNe) + * [#8896](https://github.com/magento/magento2/pull/8896) -- Fix all words without " (by @rafaelstz) + * [#8912](https://github.com/magento/magento2/pull/8912) -- magento/magento2#8590: M2.1.4 : ArrayBackend cannot save and Added country regions for Croatia (by @nkajic) + * [#8909](https://github.com/magento/magento2/pull/8909) -- magento/magento2#8863: Malta zipcode validation incomplete (by @mmacinko) + * [#2829](https://github.com/magento/magento2/pull/2829) -- Update final_price.phtml (by @liam-wiltshire) + * [#3869](https://github.com/magento/magento2/pull/3869) -- Optional PHP7.0 Socket Path (by @digimix) + * [#4854](https://github.com/magento/magento2/pull/4854) -- Fix admin menu bug (by @NikolasSumrak) + * [#6400](https://github.com/magento/magento2/pull/6400) -- Fix for Product Attribute's Conditions (by @NikolasSumrak) + * [#6677](https://github.com/magento/magento2/pull/6677) -- Update addCategoriesFilter to return $this (by @maciekpaprocki) + * [#6894](https://github.com/magento/magento2/pull/6894) -- Fixed phpseclib\Net\SFTP constants used in write() method (by @federivo) + * [#7117](https://github.com/magento/magento2/pull/7117) -- Add de_LU and fr_LU languages for Luxembourg (by @ajpevers) + * [#8915](https://github.com/magento/magento2/pull/8915) -- magento/magetno2#8676: I can not translate title attribute in xml fil… (by @DanijelPotocki) + * [#5446](https://github.com/magento/magento2/pull/5446) -- Fix Rest Api - GET /V1/configurable-products/{sku}/children not giving ID in response (by @k-andrew) + * [#6321](https://github.com/magento/magento2/pull/6321) -- Add missing return in resolveShippingRates (by @GordonLesti) + * [#6707](https://github.com/magento/magento2/pull/6707) -- Issue/6706 (by @PascalBrouwers) + * [#6794](https://github.com/magento/magento2/pull/6794) -- Move cache to instance of price box widget (by @JamesonNetworks) + * [#6856](https://github.com/magento/magento2/pull/6856) -- Issue/6855 (by @PascalBrouwers) + * [#6837](https://github.com/magento/magento2/pull/6837) -- Removed argument from di.xml (by @dverkade) + * [#6878](https://github.com/magento/magento2/pull/6878) -- Media attribute folder to be ignored (by @rafaelstz) + * [#6914](https://github.com/magento/magento2/pull/6914) -- Put the contants in the same docblock together (by @dverkade) + * [#6913](https://github.com/magento/magento2/pull/6913) -- Removed commented out line for ignoring coding standards (by @dverkade) + * [#7142](https://github.com/magento/magento2/pull/7142) -- [Framework][Translate] Changed translation order to allow language (by @JSchlarb) + * [#7352](https://github.com/magento/magento2/pull/7352) -- Product export duplicate rows for product with html special chars in data. Bugfix for #7350 (by @comdiler) + * [#8445](https://github.com/magento/magento2/pull/8445) -- Changed name of dispatched object in delete event (by @clementbeudot) + * [#8959](https://github.com/magento/magento2/pull/8959) -- Fixes #2461 (by @ajpevers) + * [#8950](https://github.com/magento/magento2/pull/8950) -- Remove deadcode (by @jipjop) + * [#3469](https://github.com/magento/magento2/pull/3469) -- respect depends declaration in system.xml for form element (by @phoenix-bjoern) + * [#5362](https://github.com/magento/magento2/pull/5362) -- Make CMS directive filtering error be more generic (by @erikhansen) + * [#6354](https://github.com/magento/magento2/pull/6354) -- Newsletter Email fix (by @inettman) + * [#6744](https://github.com/magento/magento2/pull/6744) -- add-product-image-label-bug (by @markpol) + * [#6773](https://github.com/magento/magento2/pull/6773) -- Allow to insert Persian characters for attributes! (by @sIiiS) + * [#6779](https://github.com/magento/magento2/pull/6779) -- Changed documentation of the cache variable (by @dverkade) + * [#6775](https://github.com/magento/magento2/pull/6775) -- Changed constructor to use interface instead of direct classname (by @dverkade) + * [#6971](https://github.com/magento/magento2/pull/6971) -- fix #6961 (by @razbakov) + * [#7097](https://github.com/magento/magento2/pull/7097) -- You -> Your (by @avitex) + * [#7414](https://github.com/magento/magento2/pull/7414) -- Fix typo (by @convenient) + * [#8005](https://github.com/magento/magento2/pull/8005) -- Prevent cross origin iframe content reading (by @Igloczek) + * [#8753](https://github.com/magento/magento2/pull/8753) -- Added Translation for required Data-Attribute (by @DavidLambauer) + * [#8778](https://github.com/magento/magento2/pull/8778) -- magento/magento2: #8765 (by @cavalier79) + * [#8914](https://github.com/magento/magento2/pull/8914) -- magento/magetno2#8529:Typo in error message "Table is not exists" (by @bvrbanec) + * [#2448](https://github.com/magento/magento2/pull/2448) -- Fix Inconsistency (by @srenon) + * [#2093](https://github.com/magento/magento2/pull/2093) -- Remove call to load() in getChildrenCategories method (by @davidalger) + * [#4179](https://github.com/magento/magento2/pull/4179) -- fix typo in Magento_Catalog toolbar less source (by @gil--) + * [#5078](https://github.com/magento/magento2/pull/5078) -- Rename $websiteId to $scopeId (by @flancer64) + * [#5207](https://github.com/magento/magento2/pull/5207) -- Table name fix - rule_customer to salesrule_customer (by @Bartlomiejsz) + * [#5858](https://github.com/magento/magento2/pull/5858) -- Save shipping discount in $total (by @flancer64) + * [#6811](https://github.com/magento/magento2/pull/6811) -- Unable to save subscription checkbox on Admin customer save (by @rich1990) + * [#6839](https://github.com/magento/magento2/pull/6839) -- Changed constructor to use an interface (by @dverkade) + * [#6912](https://github.com/magento/magento2/pull/6912) -- Changed module readme text (by @dverkade) + * [#7262](https://github.com/magento/magento2/pull/7262) -- Replace boolean cast to be able to disable frame, aspect ratio, trans… (by @joost-florijn-kega) + * [#7762](https://github.com/magento/magento2/pull/7762) -- change getId() to getPaymentId() (by @HirokazuNishi) + * [#8769](https://github.com/magento/magento2/pull/8769) -- magento/magento2#7860: Invalid comment for the method __order in Mage… (by @mcspronko) + * [#8917](https://github.com/magento/magento2/pull/8917) -- imagento/magento2#8515: Downloadable product is available for downloa… (by @nazarpadalka) + * [#8908](https://github.com/magento/magento2/pull/8908) -- magento/magento2#8871: Typo in Pull Request Template (by @tomislavsantek) + * [#8989](https://github.com/magento/magento2/pull/8989) -- Remove redundant check in if-condition (by @FabianLauer) + * [#8953](https://github.com/magento/magento2/pull/8953) -- Log level for caught exception (by @flancer64) + * [#8994](https://github.com/magento/magento2/pull/8994) -- Syntax fix (by @rafaelstz) + * [#1895](https://github.com/magento/magento2/pull/1895) -- Fix relative template references in individual Magento modules (by @davidalger) + * [#4224](https://github.com/magento/magento2/pull/4224) -- Update get.php (by @thaiphan) + * [#6567](https://github.com/magento/magento2/pull/6567) -- Always skip hidden files (by @quickshiftin) + * [#6989](https://github.com/magento/magento2/pull/6989) -- Allow extending config variables (by @adragus-inviqa) + * [#7218](https://github.com/magento/magento2/pull/7218) -- Set store id on block only when empty (by @dank00) + * [#7161](https://github.com/magento/magento2/pull/7161) -- Fix a bug resulting in incorrect offsets with dynamic row drag-n-drop functionality (by @navarr) + * [#7664](https://github.com/magento/magento2/pull/7664) -- Fix for "Stock Status" field not disappearing in admin when "Manage Stock" = No (by @comdiler) + * [#8812](https://github.com/magento/magento2/pull/8812) -- Fix count SQL on products sold collection (by @jameshalsall) + * [#8991](https://github.com/magento/magento2/pull/8991) -- Update AbstractModel.php (by @redelschaap) + * [#9001](https://github.com/magento/magento2/pull/9001) -- Fix #3791 (by @quienti) + * [#8998](https://github.com/magento/magento2/pull/8998) -- Fixed empty submenu group in backend menu (by @vovayatsyuk) + * [#8928](https://github.com/magento/magento2/pull/8928) -- Stop $this->validColumnNames array from growing and growing (by @jalogut) + * [#4149](https://github.com/magento/magento2/pull/4149) -- Fix wording of downloadable Products (by @bh-ref) + * [#4674](https://github.com/magento/magento2/pull/4674) -- Refactor repeating logic (by @nevvermind) + * [#4501](https://github.com/magento/magento2/pull/4501) -- Add Crowdin badge - official translations (by @piotrekkaminski) + * [#6243](https://github.com/magento/magento2/pull/6243) -- Set getConnection() as public method (by @flancer64) + * [#6250](https://github.com/magento/magento2/pull/6250) -- Return the same data on exit (by @flancer64) + * [#4844](https://github.com/magento/magento2/pull/4844) -- Fix typo (by @orlangur) + * [#4874](https://github.com/magento/magento2/pull/4874) -- Make NL zipcode pattern less strict (by @tdgroot) + * [#5400](https://github.com/magento/magento2/pull/5400) -- Privacy Policy translation (fixes Issue #2951) (by @MindConflicts) + * [#5671](https://github.com/magento/magento2/pull/5671) -- Fix small typo (by @adragus-inviqa) + * [#6132](https://github.com/magento/magento2/pull/6132) -- Remove an extra space while clearing indexed stock items. (by @nntoan) + * [#6840](https://github.com/magento/magento2/pull/6840) -- Removed unused variable $routerId (by @dverkade) + * [#6834](https://github.com/magento/magento2/pull/6834) -- Removed default values for title, meta description, better labels. (by @paales) + * [#7124](https://github.com/magento/magento2/pull/7124) -- Code documentation corrections (by @evktalo) + * [#7294](https://github.com/magento/magento2/pull/7294) -- Let less continue compilation if file is empty (by @timo-schmid) + * [#8648](https://github.com/magento/magento2/pull/8648) -- Remove the copyright year from file headers (by @jameshalsall) + * [#4897](https://github.com/magento/magento2/pull/4897) -- Schedule generation was broken (by @ajpevers) + * [#5503](https://github.com/magento/magento2/pull/5503) -- ACL titles are swapped (by @yireo) + * [#7344](https://github.com/magento/magento2/pull/7344) -- Fix checking active carrier against store (by @torreytsui) + * [#7221](https://github.com/magento/magento2/pull/7221) -- Typo fix (by @gastondisacco) + * [#8982](https://github.com/magento/magento2/pull/8982) -- Move blank theme dependencies out of Magento_Theme requirejs-config (by @mikeoloughlin) + * [#8930](https://github.com/magento/magento2/pull/8930) -- Improved check when CategoryProcessor attempts to create a new category (by @ccasciotti) + * [#8923](https://github.com/magento/magento2/pull/8923) -- Check of null result value in swatch-renderer.js (by @aholovan) + * [#9013](https://github.com/magento/magento2/pull/9013) -- Added JS Jasmine tests to Travis CI (by @Igloczek) + * [#9039](https://github.com/magento/magento2/pull/9039) -- Translation in adminhtml Import form (by @Nolwennig) + * [#9034](https://github.com/magento/magento2/pull/9034) -- Invalidate and refresh customer data sections on HTTP DELETE requests (by @Vinai) + * [#6322](https://github.com/magento/magento2/pull/6322) -- Admin product edit block getHeader is not used (by @kassner) + * [#7045](https://github.com/magento/magento2/pull/7045) -- In case something wrong with underlying products (by @Will-I4M) + * [#8568](https://github.com/magento/magento2/pull/8568) -- Fix quote's outdated shipping address overwriting PayPal Express shipping address (by @torreytsui) + * [#9057](https://github.com/magento/magento2/pull/9057) -- remove duplicate method call (#9017) (by @will-b) + * [#9080](https://github.com/magento/magento2/pull/9080) -- Fix grammar mistakes with subscriptions - fixes #7498 (by @sambolek) + * [#9076](https://github.com/magento/magento2/pull/9076) -- Fix typo (by @PieterCappelle) + * [#9061](https://github.com/magento/magento2/pull/9061) -- Empty resolvedScopeCodes when config cache is cleaned (by @andreas-wickberg-vaimo) + * [#9044](https://github.com/magento/magento2/pull/9044) -- Remove superfluous character in class (by @tkn98) + * [#9095](https://github.com/magento/magento2/pull/9095) -- Added translation to label argument xml. (by @mrkhoa99) + * [#9108](https://github.com/magento/magento2/pull/9108) -- Redundant expression */1 in crontab.xml (by @giacmir) + * [#9170](https://github.com/magento/magento2/pull/9170) -- Corrected class name in documentation. (by @dfelton) + * [#6778](https://github.com/magento/magento2/pull/6778) -- Changed locator class name for ObjectManager (by @dverkade) + * [#7556](https://github.com/magento/magento2/pull/7556) -- Fix merging nested in view.xml (by @torreytsui) + * [#8903](https://github.com/magento/magento2/pull/8903) -- Include Reply-To name in contact form email header (by @josephmcdermott) + * [#9140](https://github.com/magento/magento2/pull/9140) -- remove duplicate calls to initObjectManager in bootstrap class (by @sivajik34) + * [#9133](https://github.com/magento/magento2/pull/9133) -- Favicon folder added on gitignore (by @rafaelstz) + * [#9204](https://github.com/magento/magento2/pull/9204) -- FPT label not translatable in the totals on the cart page. (by @okorshenko) + * [#5043](https://github.com/magento/magento2/pull/5043) -- Change 'select' to 'query' in props (by @flancer64) + * [#5367](https://github.com/magento/magento2/pull/5367) -- Change pub/.htaccess MAGE_MODE comment (by @erikhansen) + * [#5742](https://github.com/magento/magento2/pull/5742) -- Collection walk method bug fix when specific callback function (by @jalogut) + * [#6385](https://github.com/magento/magento2/pull/6385) -- Replace EE License Placeholder text with filename (by @navarr) + * [#6443](https://github.com/magento/magento2/pull/6443) -- Refactor Option ResourceModel to allow price supporting types to be intercepted (by @navarr) + * [#6772](https://github.com/magento/magento2/pull/6772) -- Changed constructor to use an interface (by @dverkade) + * [#6910](https://github.com/magento/magento2/pull/6910) -- Good practice, license in readme file (by @rafaelstz) + * [#7506](https://github.com/magento/magento2/pull/7506) -- Add configurations for change email templates (by @kassner) + * [#7464](https://github.com/magento/magento2/pull/7464) -- Is Allowed Guest Checkout (by @hungvt) + * [#7900](https://github.com/magento/magento2/pull/7900) -- Setting proper resource name (by @ddattee) + * [#8462](https://github.com/magento/magento2/pull/8462) -- Fix product option files not copying to order dir. (by @evktalo) + * [#8824](https://github.com/magento/magento2/pull/8824) -- Popup-Modal not closing on Safari/Windows (by @Hansschouten) + * [#9062](https://github.com/magento/magento2/pull/9062) -- Upgrade JS dependencies (by @Igloczek) + * [#9084](https://github.com/magento/magento2/pull/9084) -- Fix Google Analytics typo in printing Account Number, fixes #7549 (by @sambolek) + * [#9112](https://github.com/magento/magento2/pull/9112) -- Fix attribute label on product page at different store views (by @tufahu) + * [#9103](https://github.com/magento/magento2/pull/9103) -- Cli info di (by @springerin) + * [#9165](https://github.com/magento/magento2/pull/9165) -- Improved text of exception message in case of error in module's composer.json (by @vovayatsyuk) + * [#9131](https://github.com/magento/magento2/pull/9131) -- Fix to allow Zend_Db_Expr as column default (by @scottsb) + * [#9221](https://github.com/magento/magento2/pull/9221) -- Avoid: Undefined index: value in app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php on line 157 in Ajax return (by @mhauri) + * [#9215](https://github.com/magento/magento2/pull/9215) -- Remove unused and invalid method (by @adragus-inviqa) + * [#9210](https://github.com/magento/magento2/pull/9210) -- Do not di:compile tests/ folder (by @kassner) + * [#5325](https://github.com/magento/magento2/pull/5325) -- update url guide to v2.0 (by @sIiiS) + * [#6452](https://github.com/magento/magento2/pull/6452) -- Fix Login Popup broken on iPad portrait (by @ihor-sviziev) + * [#9234](https://github.com/magento/magento2/pull/9234) -- Fix indentation in pub/.htaccess file (by @erikhansen) + * [#6266](https://github.com/magento/magento2/pull/6266) -- Change commit to rollBack on fail (by @flancer64) + * [#6792](https://github.com/magento/magento2/pull/6792) -- Make a hardcoded value in Customizable Options interceptable (by @navarr) + * [#9094](https://github.com/magento/magento2/pull/9094) -- Issue #2802, #1146: Fixing sitemap generation folder (by @JosephMaxwell) + * [#9124](https://github.com/magento/magento2/pull/9124) -- Solve issues with API (by @paales) + * [#9247](https://github.com/magento/magento2/pull/9247) -- Fixed layout handle for cms page (by @simpleadm) + * [#9257](https://github.com/magento/magento2/pull/9257) -- Fixed coding standard violations in the Framework\Message namespace (by @dverkade) + * [#9254](https://github.com/magento/magento2/pull/9254) -- Fixed coding standard violations in the Framework\Encryption namespace (by @dverkade) + * [#9253](https://github.com/magento/magento2/pull/9253) -- Fixed coding standard violations in the Framework\Event namespace (by @dverkade) + * [#9250](https://github.com/magento/magento2/pull/9250) -- Fixed coding standard violations in the Framework\Archive namespace (by @dverkade) + * [#9264](https://github.com/magento/magento2/pull/9264) -- Enable/Disable DB query logging commands (by @federivo) + * [#9260](https://github.com/magento/magento2/pull/9260) -- Fixed coding standard violations in Framework\HTTP namespace: (by @dverkade) + * [#9258](https://github.com/magento/magento2/pull/9258) -- Fixed coding standard violations in the Framework\Filesystem namespace (by @dverkade) + * [#9286](https://github.com/magento/magento2/pull/9286) -- [WIP] Varnish Vcl generator command (by @piotrkwiecinski) + * [#9282](https://github.com/magento/magento2/pull/9282) -- Fixed coding standard violations in the Framework\Filter namespace (by @dverkade) + * [#9281](https://github.com/magento/magento2/pull/9281) -- Fixed coding standard violations in Framework\Image namespace (by @dverkade) + * [#9298](https://github.com/magento/magento2/pull/9298) -- Remove php-5.6 environment from travis.yml (by @4quaternion) + * [#4816](https://github.com/magento/magento2/pull/4816) -- Fixed issue with grouped product name column renderer. It (by @wbyrnetx) + * [#5147](https://github.com/magento/magento2/pull/5147) -- Change value-assignment to a setValue call (by @wexo-team) + * [#5411](https://github.com/magento/magento2/pull/5411) -- #5236 fixes "The configuration parameter "componentType" is a required for "advanced_pricing_button" component" (by @Protazy21) + * [#7148](https://github.com/magento/magento2/pull/7148) -- Fix issue 7075 (by @rmsundar1) + * [#9027](https://github.com/magento/magento2/pull/9027) -- Make CSS minifying compatible with calc() CSS function (by @sambolek) + * [#9262](https://github.com/magento/magento2/pull/9262) -- Remove zend json from theme (by @dmanners) + * [#9261](https://github.com/magento/magento2/pull/9261) -- Remove zend json from weee (by @dmanners) + * [#9302](https://github.com/magento/magento2/pull/9302) -- Fixed coding standard violations in the Framework\Module namespace (by @dverkade) + * [#9299](https://github.com/magento/magento2/pull/9299) -- Improved check for attribute codes in "additional_attributes" field (by @ccasciotti) + * [#9293](https://github.com/magento/magento2/pull/9293) -- Deprecate unused navigation-menu.js file in blank theme (by @mikeoloughlin) + * [#9308](https://github.com/magento/magento2/pull/9308) -- Remove unnecessary FQCN in ObserverInterface (by @jameshalsall) + * [#9304](https://github.com/magento/magento2/pull/9304) -- Fixed coding standard violations in all Factory classes located in app/code (by @dverkade) + * [#9303](https://github.com/magento/magento2/pull/9303) -- Fixed coding standard violations in the Framework namespace (by @dverkade) + * [#9318](https://github.com/magento/magento2/pull/9318) -- Fixed coding standard violations in the Framework\Backup namespace (by @dverkade) + * [#9321](https://github.com/magento/magento2/pull/9321) -- Fixed coding standard violations in the Framework\Autoload, Framework\Session & Framework\Webapi namespaces (by @dverkade) + * [#9320](https://github.com/magento/magento2/pull/9320) -- Fixed coding standard violations in the Framework\Cache namespace (by @dverkade) + * [#9319](https://github.com/magento/magento2/pull/9319) -- Fixed coding standard violations in the Framework\Api namespace (by @dverkade) + * [#9334](https://github.com/magento/magento2/pull/9334) -- Fixed coding standard violations in the Framework\Controller, Framework\CSS, Framework\Phrase and Framework\Pricing namespace (by @dverkade) + * [#9330](https://github.com/magento/magento2/pull/9330) -- Fixed coding standard violations in the Framework\Data namespace (by @dverkade) + * [#9329](https://github.com/magento/magento2/pull/9329) -- Fixed coding standard violations in the Framework\Stdlib namespace (by @dverkade) + * [#9328](https://github.com/magento/magento2/pull/9328) -- Fixed coding standard violations in the Framework\Config namespace (by @dverkade) + * [#5372](https://github.com/magento/magento2/pull/5372) -- Fix filesystem permission issues (by @BlackIkeEagle) + * [#9129](https://github.com/magento/magento2/pull/9129) -- Product Wizard: Use result type Layout instead of page layout (by @klein0r) + * [#9352](https://github.com/magento/magento2/pull/9352) -- Fixed coding standard violations in the Framework\File namespace (by @dverkade) + * [#9351](https://github.com/magento/magento2/pull/9351) -- Fixed coding standard violations in the Framework\Locale namespace (by @dverkade) + * [#9350](https://github.com/magento/magento2/pull/9350) -- Fixed coding standard violations in the Framework\App namespace (by @dverkade) + * [#9355](https://github.com/magento/magento2/pull/9355) -- Fixed coding standard violations in the Framework\Test namespace (by @dverkade) + * [#9354](https://github.com/magento/magento2/pull/9354) -- Fixed coding standard violations in the Framework\Translate namespace (by @dverkade) + * [#9353](https://github.com/magento/magento2/pull/9353) -- Fixed coding standard violations in the Framework\DB namespace (by @dverkade) + * [#8955](https://github.com/magento/magento2/pull/8955) -- Remove context aggregation validation (see Issue #6114) (by @Vinai) + * [#9343](https://github.com/magento/magento2/pull/9343) -- Add logging to contact us form (by @JamesonNetworks) + * [#9414](https://github.com/magento/magento2/pull/9414) -- Use loadPlayer requirejs mapping (by @ntoombs19) + * [#9400](https://github.com/magento/magento2/pull/9400) -- Fix addIdFilter method (by @adrian-martinez-interactiv4) + * [#9363](https://github.com/magento/magento2/pull/9363) -- Add ability to inject exception code in LocalizedException (by @adragus-inviqa) + * [#9446](https://github.com/magento/magento2/pull/9446) -- Fix data deletion using the multiple delete command (by @Kenboy) + * [#9539](https://github.com/magento/magento2/pull/9539) -- fix for "Class Magento\Framework\Console\CLI not found" in case sensitive scenarios (by @EObukhovsky) + * [#9514](https://github.com/magento/magento2/pull/9514) -- Fix breadcrumbs extra space (by @VincentMarmiesse) + * [#8409](https://github.com/magento/magento2/pull/8409) -- Allow X-Forwarded-For to have multiple values (by @kassner) + * [#9093](https://github.com/magento/magento2/pull/9093) -- JS Static tests added to CI (ESLint + JSCS) (by @Igloczek) + * [#9091](https://github.com/magento/magento2/pull/9091) -- ESLint errors fix (by @Igloczek) + * [#9285](https://github.com/magento/magento2/pull/9285) -- Replace Zend_Log with Psr\Log\LoggerInterface (by @tdgroot) + * [#9380](https://github.com/magento/magento2/pull/9380) -- Removed unnecessary code and namespaces from import validators (by @ccasciotti) + * [#9540](https://github.com/magento/magento2/pull/9540) -- Removed workaround for old Webkit bug in the TinyMCE editor for selec… (by @hostep) + * [#9549](https://github.com/magento/magento2/pull/9549) -- Selects correct stores value option (by @Corefix) + * [#9574](https://github.com/magento/magento2/pull/9574) -- no need to create customer once u got the quote object (by @sivajik34) + * [#9618](https://github.com/magento/magento2/pull/9618) -- Flip the property assignments for _logger and _fetchStrategy in __wakeup (by @cykirsch) + * [#9617](https://github.com/magento/magento2/pull/9617) -- Exclude unnecessarily duplicated Travis CI build jobs (by @Igloczek) + * [#9622](https://github.com/magento/magento2/pull/9622) -- Zend_Wildfire deprecated, Firephp outdated, magento/magento2#9239 and magento/magento2#9241 (by @SolsWebdesign) + * [#9625](https://github.com/magento/magento2/pull/9625) -- Remove unused plugin (by @elzekool) + * [#9637](https://github.com/magento/magento2/pull/9637) -- Change "wan't" to "want" (by @Leland) + * [#7020](https://github.com/magento/magento2/pull/7020) -- Fixes #7006, sales_order_status_label does not support version control (by @ajpevers) + * [#7456](https://github.com/magento/magento2/pull/7456) -- Remove unused entity_id foreign key (by @mattjbarlow) + * [#7755](https://github.com/magento/magento2/pull/7755) -- Remove redundant check and return early (by @AydinHassan) + * [#9657](https://github.com/magento/magento2/pull/9657) -- Fixes Typo (by @riconeitzel) + * [#4903](https://github.com/magento/magento2/pull/4903) -- Fix undefined offset notice when no order states are set (by @adragus-inviqa) + * [#6344](https://github.com/magento/magento2/pull/6344) -- Zend instead of regex in getGetterReturnType (by @flancer64) + * [#9686](https://github.com/magento/magento2/pull/9686) -- Update scripts.js (by @redelschaap) + * [#9701](https://github.com/magento/magento2/pull/9701) -- Add missing payment info template for PDF generation (by @cmuench) + * [#9697](https://github.com/magento/magento2/pull/9697) -- Configure Travis CI to run functional tests (by @okolesnyk) + * [#9711](https://github.com/magento/magento2/pull/9711) -- Cookie Restriction Mode Overlay should not be cached by Varnish #6455 (by @bka) + * [#9713](https://github.com/magento/magento2/pull/9713) -- stringify cookie value to fix Google Analyitcs Tracking and Cookie Overlay #5596 (by @bka) + * [#6503](https://github.com/magento/magento2/pull/6503) -- Remove breadcrumbs for multistore homepage (by @PingusPepan) + * [#7330](https://github.com/magento/magento2/pull/7330) -- Fix Framework\Data\Collection::each() method (by @Vinai) + * [#8484](https://github.com/magento/magento2/pull/8484) -- Fix swatch-renderer.js product id and isProductViewExist (by @mimarcel) + * [#9348](https://github.com/magento/magento2/pull/9348) -- Replace framework's Zend_Session interface usage with SessionHandlerInterface (by @tdgroot) + * [#9654](https://github.com/magento/magento2/pull/9654) -- magento/magento2#7279 bill-to name and ship-to name truncated to 20 chars (by @SolsWebdesign) + * [#9627](https://github.com/magento/magento2/pull/9627) -- Fix coding standard in Magento AdminNotification module (by @dverkade) + * [#9714](https://github.com/magento/magento2/pull/9714) -- Can't delete last item in cart if Minimum Order is Enable #6151 (by @storbahn) + * [#9717](https://github.com/magento/magento2/pull/9717) -- use payment method name to make checkbox of agreements more unique #6207 (by @bka) + * [#9715](https://github.com/magento/magento2/pull/9715) -- #4272: v2.0.4 Credit memos with adjustment fees cannot be fully refunded with a second credit memo (by @mcspronko) + * [#9344](https://github.com/magento/magento2/pull/9344) -- Explace the direct usage of Zend_Json with a call to the Json Help class (by @dmanners) + * [#9475](https://github.com/magento/magento2/pull/9475) -- Update select.js (by @redelschaap) + * [#9600](https://github.com/magento/magento2/pull/9600) -- Do not hardcode product link types (by @kassner) + * [#9712](https://github.com/magento/magento2/pull/9712) -- Customer with unique attribute can't be saved #7844 (by @storbahn) + * [#9723](https://github.com/magento/magento2/pull/9723) -- Patch to allow multiple filter_url_params to function (by @southerncomputer) + * [#9721](https://github.com/magento/magento2/pull/9721) -- [BUGFIX][6244] Fix Issue with code label display in cart checkout. (by @diglin) + * [#9753](https://github.com/magento/magento2/pull/9753) -- Replace Zend_Json in the configurable product block test (by @dmanners) + * [#9777](https://github.com/magento/magento2/pull/9777) -- Fix for #5897: getIdentities relies on uninitialized collection (by @kassner) + * [#9772](https://github.com/magento/magento2/pull/9772) -- Allow for referenceBlock to include template argument (by @jissereitsma) + * [#9797](https://github.com/magento/magento2/pull/9797) -- Adding logo in media folder (by @rafaelstz) + * [#9409](https://github.com/magento/magento2/pull/9409) -- Add a name to the Composite\Fieldset\Options block directive (by @navarr) + * [#9665](https://github.com/magento/magento2/pull/9665) -- Fix for javascript "mixins" when 'urlArgs' is set in requirejs - issue 8221 (by @thelettuce) + * [#9835](https://github.com/magento/magento2/pull/9835) -- Fixes Mage.Cookies poor performance (by @wujashek) + * [#9430](https://github.com/magento/magento2/pull/9430) -- Fix wrong store id filter (by @mimarcel) + * [#9670](https://github.com/magento/magento2/pull/9670) -- Allow injection of Magento\Catalog\Model\View\Asset\ImageFactory (by @rolftimmermans) + * [#9778](https://github.com/magento/magento2/pull/9778) -- new CLI command: Enable Template Hints (by @miguelbalparda) + * [#9820](https://github.com/magento/magento2/pull/9820) -- [oauth] Fixes #9819 (by @EliasKotlyar) + * [#9859](https://github.com/magento/magento2/pull/9859) -- Removed unused $_customerSession property (by @edenreich) + * [#4450](https://github.com/magento/magento2/pull/4450) -- Add ability to use tree-massactions ("sub-menus") on Sales > Orders grid (by @ikk0) + * [#9368](https://github.com/magento/magento2/pull/9368) -- Redis sess: fix path for persistent_identifier & compression_threshold (by @LukeHandle) + * [#9690](https://github.com/magento/magento2/pull/9690) -- Add froogaloop library as a dependency to load-player module (by @ntoombs19) + * [#9813](https://github.com/magento/magento2/pull/9813) -- Use static:: to support late static bindings in Invoice and Creditmemo (by @jokeputs) + * [#9780](https://github.com/magento/magento2/pull/9780) -- Coupon codes not showing in invoice print out #9216 (by @naouibelgacem) + * [#9872](https://github.com/magento/magento2/pull/9872) -- Fixed issue causing static test failure to report success on Travis (by @davidalger) + * [#9890](https://github.com/magento/magento2/pull/9890) -- Improved error logging when trying to save a product (by @woutersamaey) + * [#9892](https://github.com/magento/magento2/pull/9892) -- Added .DS_Store to .gitignore for Mac users (by @woutersamaey) + * [#9873](https://github.com/magento/magento2/pull/9873) -- Fixes layered navigation options being cached using the wrong store id. (by @hostep) + * [#7405](https://github.com/magento/magento2/pull/7405) -- Update Curl.php (by @redelschaap) + * [#7780](https://github.com/magento/magento2/pull/7780) -- setup:di:compile returns exit code 0 if errors are found (by @pivulic) + * [#9157](https://github.com/magento/magento2/pull/9157) -- Return array of blocks as items instead of array of arrays (by @tkotosz) + * [#9810](https://github.com/magento/magento2/pull/9810) -- Fix bug linked product position not updated if product link already exists (by @jalogut) + * [#9824](https://github.com/magento/magento2/pull/9824) -- Email to a Friend feature (by @WaPoNe) + * [#9823](https://github.com/magento/magento2/pull/9823) -- Return array of pages as items instead of array of arrays (by @tkotosz) + * [#9922](https://github.com/magento/magento2/pull/9922) -- Fixes small backwards incompatibility issue created in MAGETWO-69728 (by @hostep) + * [#4891](https://github.com/magento/magento2/pull/4891) -- Remove faulty index subscription (by @ajpevers) + * [#7758](https://github.com/magento/magento2/pull/7758) -- Throw exception when attribute doesn't exitst (by @AydinHassan) + * [#8879](https://github.com/magento/magento2/pull/8879) -- add middle name to checkout address html templates #8878 (by @ajpevers) + * [#9251](https://github.com/magento/magento2/pull/9251) -- Fixed coding standard violations in the Framework\Validator namespace (by @dverkade) + * [#9525](https://github.com/magento/magento2/pull/9525) -- Fixed the Inconsistent Gift Options checkbox labels #9421 (by @vpiyappan) + * [#9905](https://github.com/magento/magento2/pull/9905) -- Fix composer validation (by @barbazul) + * [#9932](https://github.com/magento/magento2/pull/9932) -- Fix typo in comment (by @avoelkl) + * [#9306](https://github.com/magento/magento2/pull/9306) -- Fix PaymentTokenFactory interface to have the "Interface" at the end of the name. (by @dverkade) + * [#9391](https://github.com/magento/magento2/pull/9391) -- Fix depends per group in system.xml (by @osrecio) + * [#9902](https://github.com/magento/magento2/pull/9902) -- Fix static integrity classes tests in Windows (by @barbazul) + * [#9915](https://github.com/magento/magento2/pull/9915) -- suggestion from #9338: add some command/option to the deploy command to refresh the version (by @ajpevers) + * [#9925](https://github.com/magento/magento2/pull/9925) -- Fix #9924, prefill prefix and suffix in checkout shipping address (by @ajpevers) + * [#9941](https://github.com/magento/magento2/pull/9941) -- By default, show times in admin grids in the store timezone. (by @ajpevers) + * [#9943](https://github.com/magento/magento2/pull/9943) -- Cron uses the wrong timestamp method (by @ajpevers) + * [#9964](https://github.com/magento/magento2/pull/9964) -- Add target attribute to Magento_Ui grid (by @thelettuce) + * [#9973](https://github.com/magento/magento2/pull/9973) -- Fixed coding standard violations in the Magento\Wishlist namespace (by @dverkade) + * [#9974](https://github.com/magento/magento2/pull/9974) -- Fixed coding standard violations in the Magento\Backend namespace (by @dverkade) + * [#9975](https://github.com/magento/magento2/pull/9975) -- Fixed coding standard violations in the Magento\Cms namespace (by @dverkade) + * [#9978](https://github.com/magento/magento2/pull/9978) -- Fixed coding standard violations in the Magento\Authorization Magento\Backup Magento\Captcha Magento\CurrencySymbol and Magento\Dhl namespace (by @dverkade) + * [#8965](https://github.com/magento/magento2/pull/8965) -- Reduce calls to SplFileInfo::realpath() in the Magento\Setup\Module\Di\Code\Reader\ClassesScanner class (by @kschroeder) + * [#9996](https://github.com/magento/magento2/pull/9996) -- Ubuntu Trusty 14.04 images update (by @miguelbalparda) + * [#8784](https://github.com/magento/magento2/pull/8784) -- magento/magento2: #8616 (by @cavalier79) + * [#9939](https://github.com/magento/magento2/pull/9939) -- Retrieve taxes from the correct object (by @fooman) + * [#9957](https://github.com/magento/magento2/pull/9957) -- Instantly apply configuration changes in the cron schedule (by @ajpevers) + * [#9994](https://github.com/magento/magento2/pull/9994) -- Fix mini-cart not emptied for logged out users checking out with PayPal Express (by @driskell) + * [#9082](https://github.com/magento/magento2/pull/9082) -- Get sitemap product images from image cache, if available (by @sambolek) + * [#9786](https://github.com/magento/magento2/pull/9786) -- [#7291] Change the default contact form email template to HTML (by @VincentMarmiesse) + * [#9361](https://github.com/magento/magento2/pull/9361) -- Fixed coding standard violations in the Framework\Model namespace (by @dverkade) + * [#9359](https://github.com/magento/magento2/pull/9359) -- Fixed coding standard violations in the Framework\Interception namespace (by @dverkade) + * [#9358](https://github.com/magento/magento2/pull/9358) -- Fixed coding standard violations in the Framework\Code namespace (by @dverkade) + * [#9429](https://github.com/magento/magento2/pull/9429) -- Fix not detecting current store using store code in url using $storeResolver->getCurrentStoreId() (by @mimarcel) + * [#9362](https://github.com/magento/magento2/pull/9362) -- Fixed coding standard violations in the Framework\ObjectManager namespace (by @dverkade) + * [#9970](https://github.com/magento/magento2/pull/9970) -- Added public methods to make Sitemap model plugin friendly (by @7ochem) + * [#7729](https://github.com/magento/magento2/pull/7729) -- Allow USPS Shipping Methods Without ExtraServices (by @jaywilliams) + * [#9314](https://github.com/magento/magento2/pull/9314) -- Support null value for custom attributes. (by @meng-tian) + * [#10033](https://github.com/magento/magento2/pull/10033) -- Fix for file category image uploader (by @Bartlomiejsz) + * [#10047](https://github.com/magento/magento2/pull/10047) -- Include attribute code in error message (by @lazyguru) + * [#10056](https://github.com/magento/magento2/pull/10056) -- Translate password field placeholder in Checkout (by @mimarcel) + * [#7139](https://github.com/magento/magento2/pull/7139) -- Stickyjs improvements (by @vovayatsyuk) + * [#9681](https://github.com/magento/magento2/pull/9681) -- Issue 9680: Use parent name for variations (by @PascalBrouwers) + * [#10031](https://github.com/magento/magento2/pull/10031) -- Allow option disabling for optgroup binding (by @Bart-art) + * [#10060](https://github.com/magento/magento2/pull/10060) -- Adding escapeHtml to Newsletter phtml (by @rafaelstz) + * [#10062](https://github.com/magento/magento2/pull/10062) -- Fix formatting for USPS Carrier (by @ihor-sviziev) + * [#9672](https://github.com/magento/magento2/pull/9672) -- Revert minimum stability to stable, tasks #4359 (by @ktomk) + * [#9986](https://github.com/magento/magento2/pull/9986) -- Improved type hints and declarations for \Magento\Quote\Model\Quote\Address\Total (by @schmengler) + * [#10082](https://github.com/magento/magento2/pull/10082) -- M2 2266 (by @tzyganu) + * [#10086](https://github.com/magento/magento2/pull/10086) -- Fix condition for autoloader function definitions (by @miromichalicka) + * [#9611](https://github.com/magento/magento2/pull/9611) -- Admin Grid Mass action Select / Unselect All issue #9610 (by @minesh0111) + * [#9726](https://github.com/magento/magento2/pull/9726) -- Remove wrong '_setup' replace when getting DB connection (2) (by @jalogut) + * [#9754](https://github.com/magento/magento2/pull/9754) -- Remove zend json from form elements (by @dmanners) + * [#9992](https://github.com/magento/magento2/pull/9992) -- Make page title in layout files translatable (by @ajpevers) + * [#10052](https://github.com/magento/magento2/pull/10052) -- M2 5381 (by @tzyganu) + * [#1563](https://github.com/magento/magento2/pull/1563) -- Convert long form tags with echo to use short-echo tags (by @davidalger) + * [#4147](https://github.com/magento/magento2/pull/4147) -- Add filename paramenter log (by @fcapua-summa) + * [#10043](https://github.com/magento/magento2/pull/10043) -- Fix trailing slash used in url rewrites (by @ihor-sviziev) + * [#10106](https://github.com/magento/magento2/pull/10106) -- Return URL in getThumbnailUrl instead of nothing (by @samgranger) + * [#3889](https://github.com/magento/magento2/pull/3889) -- Add missing dependencies of magento/framework (by @GordonLesti) + * [#10114](https://github.com/magento/magento2/pull/10114) -- Add missing dependencies of magento/framework (by @okorshenko) + * [#7174](https://github.com/magento/magento2/pull/7174) -- Type hint for \DateTimeInterface instead of \DateTime (by @jameshalsall) + * [#9189](https://github.com/magento/magento2/pull/9189) -- Avoid duplicate ltrim function on not complied mode. (by @sivajik34) + * [#10094](https://github.com/magento/magento2/pull/10094) -- Fix for isoneof condition in catalogrule (by @duckchip) + * [#10105](https://github.com/magento/magento2/pull/10105) -- Add referrerPolicy to Vimeo Video iframe to allow domain-restricted videos (by @davefarthing) + * [#10126](https://github.com/magento/magento2/pull/10126) -- Fix width & height mapping during image upload (by @ihor-sviziev) + * [#10140](https://github.com/magento/magento2/pull/10140) -- Update attribute vat_id frontend_label to make it translatable (by @JeroenVanLeusden) + * [#10149](https://github.com/magento/magento2/pull/10149) -- Fix wrong ACL for Developer Section (by @PascalBrouwers) + * [#10151](https://github.com/magento/magento2/pull/10151) -- Fix Widget saving non-XML entities to layout_update (by @tdgroot) + * [#9588](https://github.com/magento/magento2/pull/9588) -- Support controller src_type for head links (by @kassner) + * [#9904](https://github.com/magento/magento2/pull/9904) -- Fixed pointless exception in logs every time a category with image is saved (by @woutersamaey) + * [#10059](https://github.com/magento/magento2/pull/10059) -- Fix fetching quote item by id (by @mladenilic) + 2.1.0 ============= To get detailed information about changes in Magento 2.1.0, please visit [Magento Community Edition (CE) Release Notes](http://devdocs.magento.com/guides/v2.1/release-notes/ReleaseNotes2.1.0CE.html "Magento Community Edition (CE) Release Notes") diff --git a/app/.htaccess b/app/.htaccess index 93169e4eb44ffa5e6251f3532bb1902854703f07..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/app/.htaccess +++ b/app/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/app/code/Magento/AdvancedPricingImportExport/composer.json b/app/code/Magento/AdvancedPricingImportExport/composer.json index ec54cfd1e5e622b7aca158de63bf06322058d2d0..79e6e2d36873678a9ff20ea2dcc47e0328445186 100644 --- a/app/code/Magento/AdvancedPricingImportExport/composer.json +++ b/app/code/Magento/AdvancedPricingImportExport/composer.json @@ -13,7 +13,7 @@ "magento/framework": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Analytics/composer.json b/app/code/Magento/Analytics/composer.json index edc3443e487b6067499a45ba930f0d7382c24b32..b17bb10cb411263cbb6ac6e6295878ec22c1780d 100644 --- a/app/code/Magento/Analytics/composer.json +++ b/app/code/Magento/Analytics/composer.json @@ -10,7 +10,7 @@ "magento/framework": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0-dev", + "version": "100.2.0", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json index 036f0b4d54a465fcc0efb6bf543385e6d2e51ba6..3d8cfa49cd1fa01776cb4b12f0c66e00b489acf1 100644 --- a/app/code/Magento/Backend/composer.json +++ b/app/code/Magento/Backend/composer.json @@ -24,7 +24,7 @@ "magento/module-theme": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Braintree/Block/Form.php b/app/code/Magento/Braintree/Block/Form.php index f6cf62f5a21317170f9558b33ba37d2bb93abcb3..8a727ae87262fab411b093c1be2cbed77feb3302 100644 --- a/app/code/Magento/Braintree/Block/Form.php +++ b/app/code/Magento/Braintree/Block/Form.php @@ -9,7 +9,6 @@ use Magento\Backend\Model\Session\Quote; use Magento\Braintree\Gateway\Config\Config as GatewayConfig; use Magento\Braintree\Model\Adminhtml\Source\CcType; use Magento\Braintree\Model\Ui\ConfigProvider; -use Magento\Framework\App\ObjectManager; use Magento\Framework\View\Element\Template\Context; use Magento\Payment\Block\Form\Cc; use Magento\Payment\Helper\Data; @@ -21,7 +20,6 @@ use Magento\Vault\Model\VaultPaymentInterface; */ class Form extends Cc { - /** * @var Quote */ @@ -48,6 +46,7 @@ class Form extends Cc * @param Quote $sessionQuote * @param GatewayConfig $gatewayConfig * @param CcType $ccType + * @param Data $paymentDataHelper * @param array $data */ public function __construct( @@ -56,12 +55,14 @@ class Form extends Cc Quote $sessionQuote, GatewayConfig $gatewayConfig, CcType $ccType, + Data $paymentDataHelper, array $data = [] ) { parent::__construct($context, $paymentConfig, $data); $this->sessionQuote = $sessionQuote; $this->gatewayConfig = $gatewayConfig; $this->ccType = $ccType; + $this->paymentDataHelper = $paymentDataHelper; } /** @@ -81,7 +82,7 @@ class Form extends Cc */ public function useCvv() { - return $this->gatewayConfig->isCvvEnabled(); + return $this->gatewayConfig->isCvvEnabled($this->sessionQuote->getStoreId()); } /** @@ -90,9 +91,8 @@ class Form extends Cc */ public function isVaultEnabled() { - $storeId = $this->_storeManager->getStore()->getId(); $vaultPayment = $this->getVaultPayment(); - return $vaultPayment->isActive($storeId); + return $vaultPayment->isActive($this->sessionQuote->getStoreId()); } /** @@ -102,7 +102,10 @@ class Form extends Cc private function getConfiguredCardTypes() { $types = $this->ccType->getCcTypeLabelMap(); - $configCardTypes = array_fill_keys($this->gatewayConfig->getAvailableCardTypes(), ''); + $configCardTypes = array_fill_keys( + $this->gatewayConfig->getAvailableCardTypes($this->sessionQuote->getStoreId()), + '' + ); return array_intersect_key($types, $configCardTypes); } @@ -116,7 +119,11 @@ class Form extends Cc private function filterCardTypesForCountry(array $configCardTypes, $countryId) { $filtered = $configCardTypes; - $countryCardTypes = $this->gatewayConfig->getCountryAvailableCardTypes($countryId); + $countryCardTypes = $this->gatewayConfig->getCountryAvailableCardTypes( + $countryId, + $this->sessionQuote->getStoreId() + ); + // filter card types only if specific card types are set for country if (!empty($countryCardTypes)) { $availableTypes = array_fill_keys($countryCardTypes, ''); @@ -131,19 +138,6 @@ class Form extends Cc */ private function getVaultPayment() { - return $this->getPaymentDataHelper()->getMethodInstance(ConfigProvider::CC_VAULT_CODE); - } - - /** - * Get payment data helper instance - * @return Data - * @deprecated 100.1.0 - */ - private function getPaymentDataHelper() - { - if ($this->paymentDataHelper === null) { - $this->paymentDataHelper = ObjectManager::getInstance()->get(Data::class); - } - return $this->paymentDataHelper; + return $this->paymentDataHelper->getMethodInstance(ConfigProvider::CC_VAULT_CODE); } } diff --git a/app/code/Magento/Braintree/Block/Payment.php b/app/code/Magento/Braintree/Block/Payment.php index 8e05856d9b57a540ad1a4b39300490af03fe89c9..1ba2f862e2fe567662f12f7fd43b2c4492c69a2a 100644 --- a/app/code/Magento/Braintree/Block/Payment.php +++ b/app/code/Magento/Braintree/Block/Payment.php @@ -48,6 +48,10 @@ class Payment extends Template $payment = $this->config->getConfig()['payment']; $config = $payment[$this->getCode()]; $config['code'] = $this->getCode(); + $config['clientTokenUrl'] = $this->_urlBuilder->getUrl( + 'braintree/payment/getClientToken', + ['_secure' => true] + ); return json_encode($config, JSON_UNESCAPED_SLASHES); } diff --git a/app/code/Magento/Braintree/Controller/Adminhtml/Payment/GetClientToken.php b/app/code/Magento/Braintree/Controller/Adminhtml/Payment/GetClientToken.php new file mode 100644 index 0000000000000000000000000000000000000000..af0f1d75665d51f1d01ea38bb85fff38b95c3fb3 --- /dev/null +++ b/app/code/Magento/Braintree/Controller/Adminhtml/Payment/GetClientToken.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Braintree\Controller\Adminhtml\Payment; + +use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; +use Magento\Backend\Model\Session\Quote; +use Magento\Braintree\Gateway\Config\Config; +use Magento\Braintree\Gateway\Request\PaymentDataBuilder; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; +use Magento\Framework\Controller\ResultFactory; + +class GetClientToken extends Action +{ + const ADMIN_RESOURCE = 'Magento_Braintree::get_client_token'; + + /** + * @var Config + */ + private $config; + + /** + * @var BraintreeAdapterFactory + */ + private $adapterFactory; + + /** + * @var Quote + */ + private $quoteSession; + + /** + * @param Context $context + * @param Config $config + * @param BraintreeAdapterFactory $adapterFactory + * @param Quote $quoteSession + */ + public function __construct( + Context $context, + Config $config, + BraintreeAdapterFactory $adapterFactory, + Quote $quoteSession + ) { + parent::__construct($context); + $this->config = $config; + $this->adapterFactory = $adapterFactory; + $this->quoteSession = $quoteSession; + } + + /** + * @inheritdoc + */ + public function execute() + { + $params = []; + $response = $this->resultFactory->create(ResultFactory::TYPE_JSON); + + $storeId = $this->quoteSession->getStoreId(); + $merchantAccountId = $this->config->getMerchantAccountId($storeId); + if (!empty($merchantAccountId)) { + $params[PaymentDataBuilder::MERCHANT_ACCOUNT_ID] = $merchantAccountId; + } + + $clientToken = $this->adapterFactory->create($storeId) + ->generate($params); + $response->setData(['clientToken' => $clientToken]); + + return $response; + } +} diff --git a/app/code/Magento/Braintree/Controller/Payment/GetNonce.php b/app/code/Magento/Braintree/Controller/Payment/GetNonce.php index aecde869ca196f48d112ac55608f3cb77a93ad87..f8b152ded1556a8648949a9f7bf26fed3f689751 100644 --- a/app/code/Magento/Braintree/Controller/Payment/GetNonce.php +++ b/app/code/Magento/Braintree/Controller/Payment/GetNonce.php @@ -62,7 +62,10 @@ class GetNonce extends Action try { $publicHash = $this->getRequest()->getParam('public_hash'); $customerId = $this->session->getCustomerId(); - $result = $this->command->execute(['public_hash' => $publicHash, 'customer_id' => $customerId])->get(); + $result = $this->command->execute( + ['public_hash' => $publicHash, 'customer_id' => $customerId, 'store_id' => $this->session->getStoreId()] + ) + ->get(); $response->setData(['paymentMethodNonce' => $result['paymentMethodNonce']]); } catch (\Exception $e) { $this->logger->critical($e); diff --git a/app/code/Magento/Braintree/Gateway/Command/CaptureStrategyCommand.php b/app/code/Magento/Braintree/Gateway/Command/CaptureStrategyCommand.php index f972eecf9f92d9ae62f27da769e8ff5689e4dba4..c8359f69bc47daf7fd900223680a552ddf9ac1a2 100644 --- a/app/code/Magento/Braintree/Gateway/Command/CaptureStrategyCommand.php +++ b/app/code/Magento/Braintree/Gateway/Command/CaptureStrategyCommand.php @@ -6,18 +6,19 @@ namespace Magento\Braintree\Gateway\Command; use Braintree\Transaction; -use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Gateway\SubjectReader; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Braintree\Model\Adapter\BraintreeSearchAdapter; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Payment\Gateway\Command; use Magento\Payment\Gateway\Command\CommandPoolInterface; use Magento\Payment\Gateway\CommandInterface; +use Magento\Payment\Gateway\Data\OrderAdapterInterface; use Magento\Payment\Gateway\Helper\ContextHelper; -use Magento\Braintree\Gateway\Helper\SubjectReader; use Magento\Sales\Api\Data\OrderPaymentInterface; -use Magento\Sales\Api\TransactionRepositoryInterface; use Magento\Sales\Api\Data\TransactionInterface; +use Magento\Sales\Api\TransactionRepositoryInterface; +use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; /** * Class CaptureStrategyCommand @@ -66,9 +67,9 @@ class CaptureStrategyCommand implements CommandInterface private $subjectReader; /** - * @var BraintreeAdapter + * @var BraintreeAdapterFactory */ - private $braintreeAdapter; + private $braintreeAdapterFactory; /** * @var BraintreeSearchAdapter @@ -83,7 +84,7 @@ class CaptureStrategyCommand implements CommandInterface * @param FilterBuilder $filterBuilder * @param SearchCriteriaBuilder $searchCriteriaBuilder * @param SubjectReader $subjectReader - * @param BraintreeAdapter $braintreeAdapter + * @param BraintreeAdapterFactory $braintreeAdapterFactory, * @param BraintreeSearchAdapter $braintreeSearchAdapter */ public function __construct( @@ -92,7 +93,7 @@ class CaptureStrategyCommand implements CommandInterface FilterBuilder $filterBuilder, SearchCriteriaBuilder $searchCriteriaBuilder, SubjectReader $subjectReader, - BraintreeAdapter $braintreeAdapter, + BraintreeAdapterFactory $braintreeAdapterFactory, BraintreeSearchAdapter $braintreeSearchAdapter ) { $this->commandPool = $commandPool; @@ -100,7 +101,7 @@ class CaptureStrategyCommand implements CommandInterface $this->filterBuilder = $filterBuilder; $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->subjectReader = $subjectReader; - $this->braintreeAdapter = $braintreeAdapter; + $this->braintreeAdapterFactory = $braintreeAdapterFactory; $this->braintreeSearchAdapter = $braintreeSearchAdapter; } @@ -112,29 +113,29 @@ class CaptureStrategyCommand implements CommandInterface /** @var \Magento\Payment\Gateway\Data\PaymentDataObjectInterface $paymentDO */ $paymentDO = $this->subjectReader->readPayment($commandSubject); - /** @var \Magento\Sales\Api\Data\OrderPaymentInterface $paymentInfo */ - $paymentInfo = $paymentDO->getPayment(); - ContextHelper::assertOrderPayment($paymentInfo); - - $command = $this->getCommand($paymentInfo); + $command = $this->getCommand($paymentDO); $this->commandPool->get($command)->execute($commandSubject); } /** - * Get execution command name - * @param OrderPaymentInterface $payment + * Gets command name. + * + * @param PaymentDataObjectInterface $paymentDO * @return string */ - private function getCommand(OrderPaymentInterface $payment) + private function getCommand(PaymentDataObjectInterface $paymentDO) { - // if auth transaction is not exists execute authorize&capture command + $payment = $paymentDO->getPayment(); + ContextHelper::assertOrderPayment($payment); + + // if auth transaction does not exist then execute authorize&capture command $existsCapture = $this->isExistsCaptureTransaction($payment); if (!$payment->getAuthorizationTransaction() && !$existsCapture) { return self::SALE; } // do capture for authorization transaction - if (!$existsCapture && !$this->isExpiredAuthorization($payment)) { + if (!$existsCapture && !$this->isExpiredAuthorization($payment, $paymentDO->getOrder())) { return self::CAPTURE; } @@ -143,12 +144,16 @@ class CaptureStrategyCommand implements CommandInterface } /** + * Checks if authorization transaction does not expired yet. + * * @param OrderPaymentInterface $payment - * @return boolean + * @param OrderAdapterInterface $orderAdapter + * @return bool */ - private function isExpiredAuthorization(OrderPaymentInterface $payment) + private function isExpiredAuthorization(OrderPaymentInterface $payment, OrderAdapterInterface $orderAdapter) { - $collection = $this->braintreeAdapter->search( + $adapter = $this->braintreeAdapterFactory->create($orderAdapter->getStoreId()); + $collection = $adapter->search( [ $this->braintreeSearchAdapter->id()->is($payment->getLastTransId()), $this->braintreeSearchAdapter->status()->is(Transaction::AUTHORIZATION_EXPIRED) diff --git a/app/code/Magento/Braintree/Gateway/Command/GetPaymentNonceCommand.php b/app/code/Magento/Braintree/Gateway/Command/GetPaymentNonceCommand.php index 91c9f6c14bb5dd953ba0e36696a7bbc17a8f453b..64e38d2999676c5a96aee1887315271396d6922f 100644 --- a/app/code/Magento/Braintree/Gateway/Command/GetPaymentNonceCommand.php +++ b/app/code/Magento/Braintree/Gateway/Command/GetPaymentNonceCommand.php @@ -7,10 +7,9 @@ namespace Magento\Braintree\Gateway\Command; use Exception; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Validator\PaymentNonceResponseValidator; -use Magento\Braintree\Model\Adapter\BraintreeAdapter; -use Magento\Payment\Gateway\Command; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Payment\Gateway\Command\Result\ArrayResultFactory; use Magento\Payment\Gateway\CommandInterface; use Magento\Vault\Api\PaymentTokenManagementInterface; @@ -27,9 +26,9 @@ class GetPaymentNonceCommand implements CommandInterface private $tokenManagement; /** - * @var BraintreeAdapter + * @var BraintreeAdapterFactory */ - private $adapter; + private $adapterFactory; /** * @var ArrayResultFactory @@ -48,20 +47,20 @@ class GetPaymentNonceCommand implements CommandInterface /** * @param PaymentTokenManagementInterface $tokenManagement - * @param BraintreeAdapter $adapter + * @param BraintreeAdapterFactory $adapterFactory * @param ArrayResultFactory $resultFactory * @param SubjectReader $subjectReader * @param PaymentNonceResponseValidator $responseValidator */ public function __construct( PaymentTokenManagementInterface $tokenManagement, - BraintreeAdapter $adapter, + BraintreeAdapterFactory $adapterFactory, ArrayResultFactory $resultFactory, SubjectReader $subjectReader, PaymentNonceResponseValidator $responseValidator ) { $this->tokenManagement = $tokenManagement; - $this->adapter = $adapter; + $this->adapterFactory = $adapterFactory; $this->resultFactory = $resultFactory; $this->subjectReader = $subjectReader; $this->responseValidator = $responseValidator; @@ -80,7 +79,9 @@ class GetPaymentNonceCommand implements CommandInterface throw new Exception('No available payment tokens'); } - $data = $this->adapter->createNonce($paymentToken->getGatewayToken()); + $storeId = $this->subjectReader->readStoreId($commandSubject); + $data = $this->adapterFactory->create($storeId) + ->createNonce($paymentToken->getGatewayToken()); $result = $this->responseValidator->validate(['response' => ['object' => $data]]); if (!$result->isValid()) { diff --git a/app/code/Magento/Braintree/Gateway/Config/CanVoidHandler.php b/app/code/Magento/Braintree/Gateway/Config/CanVoidHandler.php index 9dd52dc91afb937263cfe90aed6c0995fe78078a..0466216bdb7d2e525db5570adf375247b974cdf2 100644 --- a/app/code/Magento/Braintree/Gateway/Config/CanVoidHandler.php +++ b/app/code/Magento/Braintree/Gateway/Config/CanVoidHandler.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Gateway\Config; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Config\ValueHandlerInterface; use Magento\Sales\Model\Order\Payment; diff --git a/app/code/Magento/Braintree/Gateway/Config/Config.php b/app/code/Magento/Braintree/Gateway/Config/Config.php index 7badd2b87ac3461d75881d331cefe3d24aa78380..01bb32fbb1a7e5dbbe4b5a6bca65c22e73478ab4 100644 --- a/app/code/Magento/Braintree/Gateway/Config/Config.php +++ b/app/code/Magento/Braintree/Gateway/Config/Config.php @@ -68,11 +68,12 @@ class Config extends \Magento\Payment\Gateway\Config\Config /** * Return the country specific card type config * + * @param int|null $storeId * @return array */ - public function getCountrySpecificCardTypeConfig() + public function getCountrySpecificCardTypeConfig($storeId = null) { - $countryCardTypes = $this->getValue(self::KEY_COUNTRY_CREDIT_CARD); + $countryCardTypes = $this->getValue(self::KEY_COUNTRY_CREDIT_CARD, $storeId); if (!$countryCardTypes) { return []; } @@ -83,11 +84,12 @@ class Config extends \Magento\Payment\Gateway\Config\Config /** * Retrieve available credit card types * + * @param int|null $storeId * @return array */ - public function getAvailableCardTypes() + public function getAvailableCardTypes($storeId = null) { - $ccTypes = $this->getValue(self::KEY_CC_TYPES); + $ccTypes = $this->getValue(self::KEY_CC_TYPES, $storeId); return !empty($ccTypes) ? explode(',', $ccTypes) : []; } @@ -108,79 +110,111 @@ class Config extends \Magento\Payment\Gateway\Config\Config } /** - * Get list of card types available for country + * Gets list of card types available for country. + * * @param string $country + * @param int|null $storeId * @return array */ - public function getCountryAvailableCardTypes($country) + public function getCountryAvailableCardTypes($country, $storeId = null) { - $types = $this->getCountrySpecificCardTypeConfig(); + $types = $this->getCountrySpecificCardTypeConfig($storeId); return (!empty($types[$country])) ? $types[$country] : []; } /** - * Check if cvv field is enabled - * @return boolean + * Checks if cvv field is enabled. + * + * @param int|null $storeId + * @return bool */ - public function isCvvEnabled() + public function isCvvEnabled($storeId = null) { - return (bool) $this->getValue(self::KEY_USE_CVV); + return (bool) $this->getValue(self::KEY_USE_CVV, $storeId); } /** - * Check if 3d secure verification enabled + * Checks if 3d secure verification enabled. + * + * @param int|null $storeId * @return bool */ - public function isVerify3DSecure() + public function isVerify3DSecure($storeId = null) { - return (bool) $this->getValue(self::KEY_VERIFY_3DSECURE); + return (bool) $this->getValue(self::KEY_VERIFY_3DSECURE, $storeId); } /** - * Get threshold amount for 3d secure + * Gets threshold amount for 3d secure. + * + * @param int|null $storeId * @return float */ - public function getThresholdAmount() + public function getThresholdAmount($storeId = null) { - return (double) $this->getValue(self::KEY_THRESHOLD_AMOUNT); + return (double) $this->getValue(self::KEY_THRESHOLD_AMOUNT, $storeId); } /** - * Get list of specific countries for 3d secure + * Gets list of specific countries for 3d secure. + * + * @param int|null $storeId * @return array */ - public function get3DSecureSpecificCountries() + public function get3DSecureSpecificCountries($storeId = null) { - if ((int) $this->getValue(self::KEY_VERIFY_ALLOW_SPECIFIC) == self::VALUE_3DSECURE_ALL) { + if ((int) $this->getValue(self::KEY_VERIFY_ALLOW_SPECIFIC, $storeId) == self::VALUE_3DSECURE_ALL) { return []; } - return explode(',', $this->getValue(self::KEY_VERIFY_SPECIFIC)); + return explode(',', $this->getValue(self::KEY_VERIFY_SPECIFIC, $storeId)); + } + + /** + * Gets value of configured environment. + * Possible values: production or sandbox. + * + * @param int|null $storeId + * @return string + */ + public function getEnvironment($storeId = null) + { + return $this->getValue(Config::KEY_ENVIRONMENT, $storeId); } /** + * Gets Kount merchant ID. + * + * @param int|null $storeId * @return string + * @internal param null $storeId */ - public function getEnvironment() + public function getKountMerchantId($storeId = null) { - return $this->getValue(Config::KEY_ENVIRONMENT); + return $this->getValue(Config::KEY_KOUNT_MERCHANT_ID, $storeId); } /** + * Gets merchant ID. + * + * @param int|null $storeId * @return string */ - public function getKountMerchantId() + public function getMerchantId($storeId = null) { - return $this->getValue(Config::KEY_KOUNT_MERCHANT_ID); + return $this->getValue(Config::KEY_MERCHANT_ID, $storeId); } /** + * Gets Merchant account ID. + * + * @param int|null $storeId * @return string */ - public function getMerchantId() + public function getMerchantAccountId($storeId = null) { - return $this->getValue(Config::KEY_MERCHANT_ID); + return $this->getValue(self::KEY_MERCHANT_ACCOUNT_ID, $storeId); } /** @@ -192,45 +226,42 @@ class Config extends \Magento\Payment\Gateway\Config\Config } /** + * Checks if fraud protection is enabled. + * + * @param int|null $storeId * @return bool */ - public function hasFraudProtection() + public function hasFraudProtection($storeId = null) { - return (bool) $this->getValue(Config::FRAUD_PROTECTION); + return (bool) $this->getValue(Config::FRAUD_PROTECTION, $storeId); } /** - * Get Payment configuration status + * Gets Payment configuration status. + * + * @param int|null $storeId * @return bool */ - public function isActive() + public function isActive($storeId = null) { - return (bool) $this->getValue(self::KEY_ACTIVE); + return (bool) $this->getValue(self::KEY_ACTIVE, $storeId); } /** - * Get list of configured dynamic descriptors + * Gets list of configured dynamic descriptors. + * + * @param int|null $storeId * @return array */ - public function getDynamicDescriptors() + public function getDynamicDescriptors($storeId = null) { $values = []; foreach (self::$dynamicDescriptorKeys as $key) { - $value = $this->getValue('descriptor_' . $key); + $value = $this->getValue('descriptor_' . $key, $storeId); if (!empty($value)) { $values[$key] = $value; } } return $values; } - - /** - * Get Merchant account ID - * - * @return string - */ - public function getMerchantAccountId() - { - return $this->getValue(self::KEY_MERCHANT_ACCOUNT_ID); - } } diff --git a/app/code/Magento/Braintree/Gateway/Http/Client/AbstractTransaction.php b/app/code/Magento/Braintree/Gateway/Http/Client/AbstractTransaction.php index caeaaa7fe45a2c087a7a30aa4f0f83451f8a210b..ef35152bf7e95280819a28c0bec860925f88078a 100644 --- a/app/code/Magento/Braintree/Gateway/Http/Client/AbstractTransaction.php +++ b/app/code/Magento/Braintree/Gateway/Http/Client/AbstractTransaction.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Http\Client; -use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Payment\Gateway\Http\ClientException; use Magento\Payment\Gateway\Http\ClientInterface; use Magento\Payment\Gateway\Http\TransferInterface; @@ -29,22 +29,22 @@ abstract class AbstractTransaction implements ClientInterface protected $customLogger; /** - * @var BraintreeAdapter + * @var BraintreeAdapterFactory */ - protected $adapter; + protected $adapterFactory; /** * Constructor * * @param LoggerInterface $logger * @param Logger $customLogger - * @param BraintreeAdapter $transaction + * @param BraintreeAdapterFactory $adapterFactory */ - public function __construct(LoggerInterface $logger, Logger $customLogger, BraintreeAdapter $adapter) + public function __construct(LoggerInterface $logger, Logger $customLogger, BraintreeAdapterFactory $adapterFactory) { $this->logger = $logger; $this->customLogger = $customLogger; - $this->adapter = $adapter; + $this->adapterFactory = $adapterFactory; } /** diff --git a/app/code/Magento/Braintree/Gateway/Http/Client/TransactionRefund.php b/app/code/Magento/Braintree/Gateway/Http/Client/TransactionRefund.php index 180344ab7263ffcf06174366fef738cec0af97af..4c3f1e179d37803d94c7d5eff3cf86b11db12f73 100644 --- a/app/code/Magento/Braintree/Gateway/Http/Client/TransactionRefund.php +++ b/app/code/Magento/Braintree/Gateway/Http/Client/TransactionRefund.php @@ -16,9 +16,11 @@ class TransactionRefund extends AbstractTransaction */ protected function process(array $data) { - return $this->adapter->refund( - $data['transaction_id'], - $data[PaymentDataBuilder::AMOUNT] - ); + $storeId = $data['store_id'] ?? null; + // sending store id and other additional keys are restricted by Braintree API + unset($data['store_id']); + + return $this->adapterFactory->create($storeId) + ->refund($data['transaction_id'], $data[PaymentDataBuilder::AMOUNT]); } } diff --git a/app/code/Magento/Braintree/Gateway/Http/Client/TransactionSale.php b/app/code/Magento/Braintree/Gateway/Http/Client/TransactionSale.php index 81c79e522907dd88c0a30877684933c3a1af6749..529045b5b18f5c1cf11bbd73574b4bbe12aa9e39 100644 --- a/app/code/Magento/Braintree/Gateway/Http/Client/TransactionSale.php +++ b/app/code/Magento/Braintree/Gateway/Http/Client/TransactionSale.php @@ -15,6 +15,11 @@ class TransactionSale extends AbstractTransaction */ protected function process(array $data) { - return $this->adapter->sale($data); + $storeId = $data['store_id'] ?? null; + // sending store id and other additional keys are restricted by Braintree API + unset($data['store_id']); + + return $this->adapterFactory->create($storeId) + ->sale($data); } } diff --git a/app/code/Magento/Braintree/Gateway/Http/Client/TransactionSubmitForSettlement.php b/app/code/Magento/Braintree/Gateway/Http/Client/TransactionSubmitForSettlement.php index 0df5799b54b831faedb51a1e9d6404c27faf0124..16ebd7a7a00c5b2f353458b5a31f954b9996f30d 100644 --- a/app/code/Magento/Braintree/Gateway/Http/Client/TransactionSubmitForSettlement.php +++ b/app/code/Magento/Braintree/Gateway/Http/Client/TransactionSubmitForSettlement.php @@ -18,9 +18,11 @@ class TransactionSubmitForSettlement extends AbstractTransaction */ protected function process(array $data) { - return $this->adapter->submitForSettlement( - $data[CaptureDataBuilder::TRANSACTION_ID], - $data[PaymentDataBuilder::AMOUNT] - ); + $storeId = $data['store_id'] ?? null; + // sending store id and other additional keys are restricted by Braintree API + unset($data['store_id']); + + return $this->adapterFactory->create($storeId) + ->submitForSettlement($data[CaptureDataBuilder::TRANSACTION_ID], $data[PaymentDataBuilder::AMOUNT]); } } diff --git a/app/code/Magento/Braintree/Gateway/Http/Client/TransactionVoid.php b/app/code/Magento/Braintree/Gateway/Http/Client/TransactionVoid.php index a774065365b47ba2692e9c4b89f1fd88391bfa07..133c7f0f4062ed6485746c829058bf9fd5583927 100644 --- a/app/code/Magento/Braintree/Gateway/Http/Client/TransactionVoid.php +++ b/app/code/Magento/Braintree/Gateway/Http/Client/TransactionVoid.php @@ -14,6 +14,11 @@ class TransactionVoid extends AbstractTransaction */ protected function process(array $data) { - return $this->adapter->void($data['transaction_id']); + $storeId = $data['store_id'] ?? null; + // sending store id and other additional keys are restricted by Braintree API + unset($data['store_id']); + + return $this->adapterFactory->create($storeId) + ->void($data['transaction_id']); } } diff --git a/app/code/Magento/Braintree/Gateway/Request/AddressDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/AddressDataBuilder.php index 9ff65149894f81b96d145a8a4ef2d786ce0ab1ca..f7d3aae823e566511da45da7b6b8706f19faaa0d 100644 --- a/app/code/Magento/Braintree/Gateway/Request/AddressDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/AddressDataBuilder.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Request; use Magento\Payment\Gateway\Request\BuilderInterface; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; /** * Class AddressDataBuilder diff --git a/app/code/Magento/Braintree/Gateway/Request/CaptureDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/CaptureDataBuilder.php index c6588cfaca05fbb325ff65bf59b29d2b82aa5ed0..6f3a262d7efb41463d272ee15e248c39c99958f5 100644 --- a/app/code/Magento/Braintree/Gateway/Request/CaptureDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/CaptureDataBuilder.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Request; use Magento\Framework\Exception\LocalizedException; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Helper\Formatter; diff --git a/app/code/Magento/Braintree/Gateway/Request/CustomerDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/CustomerDataBuilder.php index 6b03f418c2545e67f1e120e448fc0e0c70d2b02a..6b3403bcd15c1b925b7ea15f78ce643c4218286f 100644 --- a/app/code/Magento/Braintree/Gateway/Request/CustomerDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/CustomerDataBuilder.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Request; use Magento\Payment\Gateway\Request\BuilderInterface; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; /** * Class CustomerDataBuilder diff --git a/app/code/Magento/Braintree/Gateway/Request/DescriptorDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/DescriptorDataBuilder.php index 3794058c2be8cdd035d0e55b758f2ed3132cc14f..aac603bfb621a138e7bf574d6d3fb410aab62687 100644 --- a/app/code/Magento/Braintree/Gateway/Request/DescriptorDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/DescriptorDataBuilder.php @@ -5,6 +5,7 @@ */ namespace Magento\Braintree\Gateway\Request; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Braintree\Gateway\Config\Config; @@ -24,21 +25,29 @@ class DescriptorDataBuilder implements BuilderInterface private $config; /** - * DescriptorDataBuilder constructor. + * @var SubjectReader + */ + private $subjectReader; + + /** * @param Config $config + * @param SubjectReader $subjectReader */ - public function __construct(Config $config) + public function __construct(Config $config, SubjectReader $subjectReader) { $this->config = $config; + $this->subjectReader = $subjectReader; } /** * @inheritdoc - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function build(array $buildSubject) { - $values = $this->config->getDynamicDescriptors(); + $paymentDO = $this->subjectReader->readPayment($buildSubject); + $order = $paymentDO->getOrder(); + + $values = $this->config->getDynamicDescriptors($order->getStoreId()); return !empty($values) ? [self::$descriptorKey => $values] : []; } } diff --git a/app/code/Magento/Braintree/Gateway/Request/KountPaymentDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/KountPaymentDataBuilder.php index 7eebbca1d42901c660e439cde43c5973655b6e63..8538667778504da29601f8ebb7fab87565bcb0a6 100644 --- a/app/code/Magento/Braintree/Gateway/Request/KountPaymentDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/KountPaymentDataBuilder.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Request; use Magento\Braintree\Gateway\Config\Config; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Observer\DataAssignObserver; use Magento\Payment\Gateway\Request\BuilderInterface; @@ -48,10 +48,12 @@ class KountPaymentDataBuilder implements BuilderInterface public function build(array $buildSubject) { $result = []; - if (!$this->config->hasFraudProtection()) { + $paymentDO = $this->subjectReader->readPayment($buildSubject); + $order = $paymentDO->getOrder(); + + if (!$this->config->hasFraudProtection($order->getStoreId())) { return $result; } - $paymentDO = $this->subjectReader->readPayment($buildSubject); $payment = $paymentDO->getPayment(); $data = $payment->getAdditionalInformation(); diff --git a/app/code/Magento/Braintree/Gateway/Request/PayPal/DeviceDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/PayPal/DeviceDataBuilder.php index cea0f8f1291bbd2fc0747a22c538a9c0c58197f2..7d0d9dad0db065ce163302037d48d40d36b2d03a 100644 --- a/app/code/Magento/Braintree/Gateway/Request/PayPal/DeviceDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/PayPal/DeviceDataBuilder.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Gateway\Request\PayPal; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Observer\DataAssignObserver; use Magento\Payment\Gateway\Request\BuilderInterface; diff --git a/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php index 6f76c3415c31a9371bec6fa214488691c1a890c5..a035c84b4cafd5e01d64039f3df85c8010580a82 100644 --- a/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/PayPal/VaultDataBuilder.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Gateway\Request\PayPal; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Vault\Model\Ui\VaultConfigProvider; diff --git a/app/code/Magento/Braintree/Gateway/Request/PaymentDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/PaymentDataBuilder.php index a3341c3fc18736fc1ce0cdb890f6751cda93c93e..85a0c644513983c797f554a149d4040b7c14fd56 100644 --- a/app/code/Magento/Braintree/Gateway/Request/PaymentDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/PaymentDataBuilder.php @@ -7,7 +7,7 @@ namespace Magento\Braintree\Gateway\Request; use Magento\Braintree\Gateway\Config\Config; use Magento\Braintree\Observer\DataAssignObserver; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Helper\Formatter; @@ -87,7 +87,7 @@ class PaymentDataBuilder implements BuilderInterface self::ORDER_ID => $order->getOrderIncrementId() ]; - $merchantAccountId = $this->config->getMerchantAccountId(); + $merchantAccountId = $this->config->getMerchantAccountId($order->getStoreId()); if (!empty($merchantAccountId)) { $result[self::MERCHANT_ACCOUNT_ID] = $merchantAccountId; } diff --git a/app/code/Magento/Braintree/Gateway/Request/RefundDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/RefundDataBuilder.php index 82de8e84cbfea6f60852f03b3f86f74439db4d64..1c25646311160a14232ad20eed2537e8959d35dd 100644 --- a/app/code/Magento/Braintree/Gateway/Request/RefundDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/RefundDataBuilder.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Gateway\Request; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Helper\Formatter; use Magento\Sales\Api\Data\TransactionInterface; diff --git a/app/code/Magento/Braintree/Gateway/Request/StoreConfigBuilder.php b/app/code/Magento/Braintree/Gateway/Request/StoreConfigBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..014df33690fa0034f6f32077c4aeaf23881ec5f2 --- /dev/null +++ b/app/code/Magento/Braintree/Gateway/Request/StoreConfigBuilder.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Braintree\Gateway\Request; + +use Magento\Payment\Gateway\Request\BuilderInterface; +use Magento\Braintree\Gateway\SubjectReader; + +/** + * This builder is used for correct store resolving and used only to retrieve correct store ID. + * The data from this build won't be send to Braintree Gateway. + */ +class StoreConfigBuilder implements BuilderInterface +{ + /** + * @var SubjectReader + */ + private $subjectReader; + + /** + * @param SubjectReader $subjectReader + */ + public function __construct(SubjectReader $subjectReader) + { + $this->subjectReader = $subjectReader; + } + + /** + * @inheritdoc + */ + public function build(array $buildSubject) + { + $paymentDO = $this->subjectReader->readPayment($buildSubject); + $order = $paymentDO->getOrder(); + + return [ + 'store_id' => $order->getStoreId() + ]; + } +} diff --git a/app/code/Magento/Braintree/Gateway/Request/ThreeDSecureDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/ThreeDSecureDataBuilder.php index c366a67701521e017cb6405d9b23283149b25347..520aa584577537c282165431a77a16c5d60830fa 100644 --- a/app/code/Magento/Braintree/Gateway/Request/ThreeDSecureDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/ThreeDSecureDataBuilder.php @@ -7,7 +7,7 @@ namespace Magento\Braintree\Gateway\Request; use Magento\Braintree\Gateway\Config\Config; use Magento\Payment\Gateway\Data\OrderAdapterInterface; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Helper\Formatter; @@ -64,12 +64,15 @@ class ThreeDSecureDataBuilder implements BuilderInterface */ private function is3DSecureEnabled(OrderAdapterInterface $order, $amount) { - if (!$this->config->isVerify3DSecure() || $amount < $this->config->getThresholdAmount()) { + $storeId = $order->getStoreId(); + if (!$this->config->isVerify3DSecure($storeId) + || $amount < $this->config->getThresholdAmount($storeId) + ) { return false; } $billingAddress = $order->getBillingAddress(); - $specificCounties = $this->config->get3DSecureSpecificCountries(); + $specificCounties = $this->config->get3DSecureSpecificCountries($storeId); if (!empty($specificCounties) && !in_array($billingAddress->getCountryId(), $specificCounties)) { return false; } diff --git a/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php index 7182f87e082d137d6201d71682bf10ea6c56a36c..4280663178efb95801c49c5e6f76514fc884b899 100644 --- a/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/VaultCaptureDataBuilder.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Gateway\Request; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Helper\Formatter; diff --git a/app/code/Magento/Braintree/Gateway/Request/VoidDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/VoidDataBuilder.php index 2328ea10f78c74ce08d457272d23ed37bfd6078c..0bbda28cd344b4fec14e0cea8190429866034105 100644 --- a/app/code/Magento/Braintree/Gateway/Request/VoidDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/VoidDataBuilder.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Gateway\Request; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Sales\Model\Order\Payment; diff --git a/app/code/Magento/Braintree/Gateway/Response/CardDetailsHandler.php b/app/code/Magento/Braintree/Gateway/Response/CardDetailsHandler.php index 2715da5d3c4196f7971d73d33a9b7fecd9b74eab..e89e604867baaa28bff08dc2ac72cd7df44ef811 100644 --- a/app/code/Magento/Braintree/Gateway/Response/CardDetailsHandler.php +++ b/app/code/Magento/Braintree/Gateway/Response/CardDetailsHandler.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Response; use Magento\Braintree\Gateway\Config\Config; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Helper\ContextHelper; use Magento\Payment\Gateway\Response\HandlerInterface; use Magento\Sales\Api\Data\OrderPaymentInterface; diff --git a/app/code/Magento/Braintree/Gateway/Response/PayPal/VaultDetailsHandler.php b/app/code/Magento/Braintree/Gateway/Response/PayPal/VaultDetailsHandler.php index 766b385851ab811cf9008c5e205ad51a278453a6..f527e9051935b7fc8d258d6ada419516856930d9 100644 --- a/app/code/Magento/Braintree/Gateway/Response/PayPal/VaultDetailsHandler.php +++ b/app/code/Magento/Braintree/Gateway/Response/PayPal/VaultDetailsHandler.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Response\PayPal; use Braintree\Transaction; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Framework\Intl\DateTimeFactory; use Magento\Payment\Gateway\Response\HandlerInterface; use Magento\Payment\Model\InfoInterface; diff --git a/app/code/Magento/Braintree/Gateway/Response/PayPalDetailsHandler.php b/app/code/Magento/Braintree/Gateway/Response/PayPalDetailsHandler.php index 83d7e44a6b612a91ccc0678dfa91bb887b69cfb4..97bb312af4bd49ab5a6740eb3b8aaa28b06dfaea 100644 --- a/app/code/Magento/Braintree/Gateway/Response/PayPalDetailsHandler.php +++ b/app/code/Magento/Braintree/Gateway/Response/PayPalDetailsHandler.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Response; use Magento\Payment\Gateway\Response\HandlerInterface; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Sales\Api\Data\OrderPaymentInterface; /** diff --git a/app/code/Magento/Braintree/Gateway/Response/PaymentDetailsHandler.php b/app/code/Magento/Braintree/Gateway/Response/PaymentDetailsHandler.php index 3941640aaeeb115b2820fcec04f7b3940192037a..6e509fae35fec28b5313f5fc1d8c656d7ce0965f 100644 --- a/app/code/Magento/Braintree/Gateway/Response/PaymentDetailsHandler.php +++ b/app/code/Magento/Braintree/Gateway/Response/PaymentDetailsHandler.php @@ -8,7 +8,7 @@ namespace Magento\Braintree\Gateway\Response; use Braintree\Transaction; use Magento\Braintree\Observer\DataAssignObserver; use Magento\Payment\Gateway\Helper\ContextHelper; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Response\HandlerInterface; use Magento\Sales\Api\Data\OrderPaymentInterface; diff --git a/app/code/Magento/Braintree/Gateway/Response/RiskDataHandler.php b/app/code/Magento/Braintree/Gateway/Response/RiskDataHandler.php index 95660e10b394cfbe4fee83f72ee1dc7544b0fa62..d4976ff18e0ee6f9229e70b2f95a774dc649b61c 100644 --- a/app/code/Magento/Braintree/Gateway/Response/RiskDataHandler.php +++ b/app/code/Magento/Braintree/Gateway/Response/RiskDataHandler.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Gateway\Response; use Magento\Payment\Gateway\Helper\ContextHelper; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Response\HandlerInterface; /** diff --git a/app/code/Magento/Braintree/Gateway/Response/ThreeDSecureDetailsHandler.php b/app/code/Magento/Braintree/Gateway/Response/ThreeDSecureDetailsHandler.php index 93f37cb561feb4bf418c7c17419a97541d7a320b..8d61660f03ce5d69264c693be589975940a17b35 100644 --- a/app/code/Magento/Braintree/Gateway/Response/ThreeDSecureDetailsHandler.php +++ b/app/code/Magento/Braintree/Gateway/Response/ThreeDSecureDetailsHandler.php @@ -7,7 +7,7 @@ namespace Magento\Braintree\Gateway\Response; use Braintree\Transaction; use Magento\Payment\Gateway\Helper\ContextHelper; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Response\HandlerInterface; use Magento\Sales\Api\Data\OrderPaymentInterface; diff --git a/app/code/Magento/Braintree/Gateway/Response/TransactionIdHandler.php b/app/code/Magento/Braintree/Gateway/Response/TransactionIdHandler.php index 7dd79143736e5827e9b8b789a155587d4a895c78..18888bdcf3d4a2f9d36b034c0a95ca975c238c21 100644 --- a/app/code/Magento/Braintree/Gateway/Response/TransactionIdHandler.php +++ b/app/code/Magento/Braintree/Gateway/Response/TransactionIdHandler.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Gateway\Response; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Response\HandlerInterface; use Magento\Sales\Model\Order\Payment; diff --git a/app/code/Magento/Braintree/Gateway/Response/VaultDetailsHandler.php b/app/code/Magento/Braintree/Gateway/Response/VaultDetailsHandler.php index a8332b9409f78f3a33d089d90499afb10462be4c..89bf7f14692b0567a7cd227a98bea5d9a293581d 100644 --- a/app/code/Magento/Braintree/Gateway/Response/VaultDetailsHandler.php +++ b/app/code/Magento/Braintree/Gateway/Response/VaultDetailsHandler.php @@ -7,7 +7,7 @@ namespace Magento\Braintree\Gateway\Response; use Braintree\Transaction; use Magento\Braintree\Gateway\Config\Config; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Response\HandlerInterface; use Magento\Payment\Model\InfoInterface; use Magento\Sales\Api\Data\OrderPaymentExtensionInterface; diff --git a/app/code/Magento/Braintree/Gateway/Helper/SubjectReader.php b/app/code/Magento/Braintree/Gateway/SubjectReader.php similarity index 92% rename from app/code/Magento/Braintree/Gateway/Helper/SubjectReader.php rename to app/code/Magento/Braintree/Gateway/SubjectReader.php index e98597655190f891c65412befaf18acd4ad16dac..d5dc43a4c5e340fe7675788d9cd5a9117bf7c5d8 100644 --- a/app/code/Magento/Braintree/Gateway/Helper/SubjectReader.php +++ b/app/code/Magento/Braintree/Gateway/SubjectReader.php @@ -3,13 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Braintree\Gateway\Helper; +namespace Magento\Braintree\Gateway; use Braintree\Transaction; -use Magento\Quote\Model\Quote; +use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Payment\Gateway\Helper; use Magento\Vault\Api\Data\PaymentTokenInterface; -use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; /** * Class SubjectReader @@ -119,4 +118,15 @@ class SubjectReader return $transaction->paypal; } + + /** + * Reads store's ID, otherwise returns null. + * + * @param array $subject + * @return int|null + */ + public function readStoreId(array $subject) + { + return $subject['store_id'] ?? null; + } } diff --git a/app/code/Magento/Braintree/Gateway/Validator/GeneralResponseValidator.php b/app/code/Magento/Braintree/Gateway/Validator/GeneralResponseValidator.php index a70bc2d02e0e5443ee7ce69242cfafaf91e75e21..8028bace0cf242d373e329f0a90fbdf9a1fb2bc9 100644 --- a/app/code/Magento/Braintree/Gateway/Validator/GeneralResponseValidator.php +++ b/app/code/Magento/Braintree/Gateway/Validator/GeneralResponseValidator.php @@ -8,7 +8,7 @@ namespace Magento\Braintree\Gateway\Validator; use Braintree\Result\Error; use Braintree\Result\Successful; use Magento\Payment\Gateway\Validator\AbstractValidator; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Validator\ResultInterfaceFactory; class GeneralResponseValidator extends AbstractValidator diff --git a/app/code/Magento/Braintree/Model/Adapter/BraintreeAdapter.php b/app/code/Magento/Braintree/Model/Adapter/BraintreeAdapter.php index 71f3828ebe9d4cef4fa9871fa6fc9161ff9edb22..d11be39a9bb490c871a5fbe4c0e31b01b197e2f8 100644 --- a/app/code/Magento/Braintree/Model/Adapter/BraintreeAdapter.php +++ b/app/code/Magento/Braintree/Model/Adapter/BraintreeAdapter.php @@ -15,29 +15,40 @@ use Magento\Braintree\Model\Adminhtml\Source\Environment; /** * Class BraintreeAdapter + * Use \Magento\Braintree\Model\Adapter\BraintreeAdapterFactory to create new instance of adapter. * @codeCoverageIgnore */ class BraintreeAdapter { - /** * @var Config */ private $config; /** - * @param Config $config + * @param string $merchantId + * @param string $publicKey + * @param string $privateKey + * @param string $environment */ - public function __construct(Config $config) + public function __construct($merchantId, $publicKey, $privateKey, $environment) { - $this->config = $config; - $this->initCredentials(); + $this->merchantId($merchantId); + $this->publicKey($publicKey); + $this->privateKey($privateKey); + + if ($environment == Environment::ENVIRONMENT_PRODUCTION) { + $this->environment(Environment::ENVIRONMENT_PRODUCTION); + } else { + $this->environment(Environment::ENVIRONMENT_SANDBOX); + } } /** * Initializes credentials. * * @return void + * @deprecated is not used anymore */ protected function initCredentials() { diff --git a/app/code/Magento/Braintree/Model/Adapter/BraintreeAdapterFactory.php b/app/code/Magento/Braintree/Model/Adapter/BraintreeAdapterFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..890f1a1021eda8cbc05656d5e507fb7772bb302a --- /dev/null +++ b/app/code/Magento/Braintree/Model/Adapter/BraintreeAdapterFactory.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Braintree\Model\Adapter; + +use Magento\Braintree\Gateway\Config\Config; +use Magento\Framework\ObjectManagerInterface; + +/** + * This factory is preferable to use for Braintree adapter instance creation. + */ +class BraintreeAdapterFactory +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var Config + */ + private $config; + + /** + * @param ObjectManagerInterface $objectManager + * @param Config $config + */ + public function __construct(ObjectManagerInterface $objectManager, Config $config) + { + $this->config = $config; + $this->objectManager = $objectManager; + } + + /** + * Creates instance of Braintree Adapter. + * + * @param int $storeId if null is provided as an argument, then current scope will be resolved + * by \Magento\Framework\App\Config\ScopeCodeResolver (useful for most cases) but for adminhtml area the store + * should be provided as the argument for correct config settings loading. + * @return BraintreeAdapter + */ + public function create($storeId = null) + { + return $this->objectManager->create( + BraintreeAdapter::class, + [ + 'merchantId' => $this->config->getMerchantId($storeId), + 'publicKey' => $this->config->getValue(Config::KEY_PUBLIC_KEY, $storeId), + 'privateKey' => $this->config->getValue(Config::KEY_PRIVATE_KEY, $storeId), + 'environment' => $this->config->getEnvironment($storeId) + ] + ); + } +} diff --git a/app/code/Magento/Braintree/Model/Report/TransactionsCollection.php b/app/code/Magento/Braintree/Model/Report/TransactionsCollection.php index edac6e35338498742f446bf560e97aeb5326a3e9..a237b64bf58ee4e4edc0506bb7eea75c99f0b1ad 100644 --- a/app/code/Magento/Braintree/Model/Report/TransactionsCollection.php +++ b/app/code/Magento/Braintree/Model/Report/TransactionsCollection.php @@ -5,7 +5,8 @@ */ namespace Magento\Braintree\Model\Report; -use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; +use Magento\Braintree\Model\Report\Row\TransactionMap; use Magento\Framework\Api\Search\SearchResultInterface; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Data\Collection; @@ -26,7 +27,7 @@ class TransactionsCollection extends Collection implements SearchResultInterface * * @var string */ - protected $_itemObjectClass = \Magento\Braintree\Model\Report\Row\TransactionMap::class; + protected $_itemObjectClass = TransactionMap::class; /** * @var array @@ -39,9 +40,9 @@ class TransactionsCollection extends Collection implements SearchResultInterface private $filterMapper; /** - * @var BraintreeAdapter + * @var BraintreeAdapterFactory */ - private $braintreeAdapter; + private $braintreeAdapterFactory; /** * @var \Braintree\ResourceCollection | null @@ -50,17 +51,17 @@ class TransactionsCollection extends Collection implements SearchResultInterface /** * @param EntityFactoryInterface $entityFactory - * @param BraintreeAdapter $braintreeAdapter + * @param BraintreeAdapterFactory $braintreeAdapterFactory * @param FilterMapper $filterMapper */ public function __construct( EntityFactoryInterface $entityFactory, - BraintreeAdapter $braintreeAdapter, + BraintreeAdapterFactory $braintreeAdapterFactory, FilterMapper $filterMapper ) { parent::__construct($entityFactory); $this->filterMapper = $filterMapper; - $this->braintreeAdapter = $braintreeAdapter; + $this->braintreeAdapterFactory = $braintreeAdapterFactory; } /** @@ -110,7 +111,8 @@ class TransactionsCollection extends Collection implements SearchResultInterface // Fetch all transaction IDs in order to filter if (empty($this->collection)) { $filters = $this->getFilters(); - $this->collection = $this->braintreeAdapter->search($filters); + $this->collection = $this->braintreeAdapterFactory->create() + ->search($filters); } return $this->collection; diff --git a/app/code/Magento/Braintree/Model/Ui/ConfigProvider.php b/app/code/Magento/Braintree/Model/Ui/ConfigProvider.php index c420195446270e49b3a75e6707a15a0a4835a9c8..6ab69923760ce6c7770102184aff40c58b4a323f 100644 --- a/app/code/Magento/Braintree/Model/Ui/ConfigProvider.php +++ b/app/code/Magento/Braintree/Model/Ui/ConfigProvider.php @@ -5,10 +5,11 @@ */ namespace Magento\Braintree\Model\Ui; +use Magento\Braintree\Gateway\Config\Config; use Magento\Braintree\Gateway\Request\PaymentDataBuilder; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Checkout\Model\ConfigProviderInterface; -use Magento\Braintree\Gateway\Config\Config; -use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Framework\Session\SessionManagerInterface; /** * Class ConfigProvider @@ -25,27 +26,35 @@ class ConfigProvider implements ConfigProviderInterface private $config; /** - * @var BraintreeAdapter + * @var BraintreeAdapterFactory */ - private $adapter; + private $adapterFactory; /** * @var string */ private $clientToken = ''; + /** + * @var SessionManagerInterface + */ + private $session; + /** * Constructor * * @param Config $config - * @param BraintreeAdapter $adapter + * @param BraintreeAdapterFactory $adapterFactory + * @param SessionManagerInterface $session */ public function __construct( Config $config, - BraintreeAdapter $adapter + BraintreeAdapterFactory $adapterFactory, + SessionManagerInterface $session ) { $this->config = $config; - $this->adapter = $adapter; + $this->adapterFactory = $adapterFactory; + $this->session = $session; } /** @@ -55,26 +64,27 @@ class ConfigProvider implements ConfigProviderInterface */ public function getConfig() { + $storeId = $this->session->getStoreId(); return [ 'payment' => [ self::CODE => [ - 'isActive' => $this->config->isActive(), + 'isActive' => $this->config->isActive($storeId), 'clientToken' => $this->getClientToken(), 'ccTypesMapper' => $this->config->getCctypesMapper(), 'sdkUrl' => $this->config->getSdkUrl(), - 'countrySpecificCardTypes' => $this->config->getCountrySpecificCardTypeConfig(), - 'availableCardTypes' => $this->config->getAvailableCardTypes(), - 'useCvv' => $this->config->isCvvEnabled(), - 'environment' => $this->config->getEnvironment(), - 'kountMerchantId' => $this->config->getKountMerchantId(), - 'hasFraudProtection' => $this->config->hasFraudProtection(), - 'merchantId' => $this->config->getMerchantId(), + 'countrySpecificCardTypes' => $this->config->getCountrySpecificCardTypeConfig($storeId), + 'availableCardTypes' => $this->config->getAvailableCardTypes($storeId), + 'useCvv' => $this->config->isCvvEnabled($storeId), + 'environment' => $this->config->getEnvironment($storeId), + 'kountMerchantId' => $this->config->getKountMerchantId($storeId), + 'hasFraudProtection' => $this->config->hasFraudProtection($storeId), + 'merchantId' => $this->config->getMerchantId($storeId), 'ccVaultCode' => self::CC_VAULT_CODE ], Config::CODE_3DSECURE => [ - 'enabled' => $this->config->isVerify3DSecure(), - 'thresholdAmount' => $this->config->getThresholdAmount(), - 'specificCountries' => $this->config->get3DSecureSpecificCountries() + 'enabled' => $this->config->isVerify3DSecure($storeId), + 'thresholdAmount' => $this->config->getThresholdAmount($storeId), + 'specificCountries' => $this->config->get3DSecureSpecificCountries($storeId) ], ] ]; @@ -89,12 +99,14 @@ class ConfigProvider implements ConfigProviderInterface if (empty($this->clientToken)) { $params = []; - $merchantAccountId = $this->config->getMerchantAccountId(); + $storeId = $this->session->getStoreId(); + $merchantAccountId = $this->config->getMerchantAccountId($storeId); if (!empty($merchantAccountId)) { $params[PaymentDataBuilder::MERCHANT_ACCOUNT_ID] = $merchantAccountId; } - $this->clientToken = $this->adapter->generate($params); + $this->clientToken = $this->adapterFactory->create($storeId) + ->generate($params); } return $this->clientToken; diff --git a/app/code/Magento/Braintree/Test/Unit/Block/FormTest.php b/app/code/Magento/Braintree/Test/Unit/Block/FormTest.php index 5b28e6d8aedcdd8979d23a2ac21d8f1e4992b06c..9d363c77f2b0557f15b406be6391161b2226ad56 100644 --- a/app/code/Magento/Braintree/Test/Unit/Block/FormTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Block/FormTest.php @@ -13,8 +13,6 @@ use Magento\Braintree\Model\Ui\ConfigProvider; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Payment\Helper\Data; use Magento\Payment\Model\Config; -use Magento\Store\Api\Data\StoreInterface; -use Magento\Store\Model\StoreManagerInterface; use Magento\Vault\Model\VaultPaymentInterface; use PHPUnit_Framework_MockObject_MockObject as MockObject; @@ -57,11 +55,6 @@ class FormTest extends \PHPUnit\Framework\TestCase */ private $ccType; - /** - * @var StoreManagerInterface|MockObject - */ - private $storeManager; - /** * @var Data|MockObject */ @@ -72,8 +65,7 @@ class FormTest extends \PHPUnit\Framework\TestCase $this->initCcTypeMock(); $this->initSessionQuoteMock(); $this->initGatewayConfigMock(); - - $this->storeManager = $this->getMockForAbstractClass(StoreManagerInterface::class); + $this->paymentDataHelper = $this->getMockBuilder(Data::class) ->disableOriginalConstructor() ->setMethods(['getMethodInstance']) @@ -84,15 +76,13 @@ class FormTest extends \PHPUnit\Framework\TestCase 'paymentConfig' => $managerHelper->getObject(Config::class), 'sessionQuote' => $this->sessionQuote, 'gatewayConfig' => $this->gatewayConfig, - 'ccType' => $this->ccType, - 'storeManager' => $this->storeManager + 'ccType' => $this->ccType ]); $managerHelper->setBackwardCompatibleProperty($this->block, 'paymentDataHelper', $this->paymentDataHelper); } /** - * @covers \Magento\Braintree\Block\Form::getCcAvailableTypes * @param string $countryId * @param array $availableTypes * @param array $expected @@ -100,21 +90,18 @@ class FormTest extends \PHPUnit\Framework\TestCase */ public function testGetCcAvailableTypes($countryId, array $availableTypes, array $expected) { - $this->sessionQuote->expects(static::once()) - ->method('getCountryId') + $this->sessionQuote->method('getCountryId') ->willReturn($countryId); - $this->gatewayConfig->expects(static::once()) - ->method('getAvailableCardTypes') + $this->gatewayConfig->method('getAvailableCardTypes') ->willReturn(self::$configCardTypes); - $this->gatewayConfig->expects(static::once()) - ->method('getCountryAvailableCardTypes') + $this->gatewayConfig->method('getCountryAvailableCardTypes') ->with($countryId) ->willReturn($availableTypes); $result = $this->block->getCcAvailableTypes(); - static::assertEquals($expected, array_values($result)); + self::assertEquals($expected, array_values($result)); } /** @@ -131,33 +118,20 @@ class FormTest extends \PHPUnit\Framework\TestCase ]; } - /** - * @covers \Magento\Braintree\Block\Form::isVaultEnabled - */ public function testIsVaultEnabled() { $storeId = 1; - $store = $this->getMockForAbstractClass(StoreInterface::class); - $this->storeManager->expects(static::once()) - ->method('getStore') - ->willReturn($store); - - $store->expects(static::once()) - ->method('getId') - ->willReturn($storeId); $vaultPayment = $this->getMockForAbstractClass(VaultPaymentInterface::class); - $this->paymentDataHelper->expects(static::once()) - ->method('getMethodInstance') + $this->paymentDataHelper->method('getMethodInstance') ->with(ConfigProvider::CC_VAULT_CODE) ->willReturn($vaultPayment); - $vaultPayment->expects(static::once()) - ->method('isActive') - ->with($storeId) + $vaultPayment->method('isActive') + ->with(self::equalTo($storeId)) ->willReturn(true); - static::assertTrue($this->block->isVaultEnabled()); + self::assertTrue($this->block->isVaultEnabled()); } /** @@ -170,8 +144,7 @@ class FormTest extends \PHPUnit\Framework\TestCase ->setMethods(['getCcTypeLabelMap']) ->getMock(); - $this->ccType->expects(static::any()) - ->method('getCcTypeLabelMap') + $this->ccType->method('getCcTypeLabelMap') ->willReturn(self::$baseCardTypes); } @@ -182,15 +155,15 @@ class FormTest extends \PHPUnit\Framework\TestCase { $this->sessionQuote = $this->getMockBuilder(Quote::class) ->disableOriginalConstructor() - ->setMethods(['getQuote', 'getBillingAddress', 'getCountryId', '__wakeup']) + ->setMethods(['getQuote', 'getBillingAddress', 'getCountryId', 'getStoreId']) ->getMock(); - $this->sessionQuote->expects(static::any()) - ->method('getQuote') + $this->sessionQuote->method('getQuote') ->willReturnSelf(); - $this->sessionQuote->expects(static::any()) - ->method('getBillingAddress') + $this->sessionQuote->method('getBillingAddress') ->willReturnSelf(); + $this->sessionQuote->method('getStoreId') + ->willReturn(1); } /** diff --git a/app/code/Magento/Braintree/Test/Unit/Controller/Payment/GetNonceTest.php b/app/code/Magento/Braintree/Test/Unit/Controller/Payment/GetNonceTest.php index e78e54f011d44d68bf3a99fd929ae483dea688a3..723897491da63db8b07b58c49c371b9697385c43 100644 --- a/app/code/Magento/Braintree/Test/Unit/Controller/Payment/GetNonceTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Controller/Payment/GetNonceTest.php @@ -16,6 +16,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\Webapi\Exception; use Magento\Payment\Gateway\Command\ResultInterface as CommandResultInterface; use Psr\Log\LoggerInterface; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class GetNonceTest @@ -30,37 +31,37 @@ class GetNonceTest extends \PHPUnit\Framework\TestCase private $action; /** - * @var GetPaymentNonceCommand|\PHPUnit_Framework_MockObject_MockObject + * @var GetPaymentNonceCommand|MockObject */ private $command; /** - * @var Session|\PHPUnit_Framework_MockObject_MockObject + * @var Session|MockObject */ private $session; /** - * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var LoggerInterface|MockObject */ private $logger; /** - * @var ResultFactory|\PHPUnit_Framework_MockObject_MockObject + * @var ResultFactory|MockObject */ private $resultFactory; /** - * @var ResultInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ResultInterface|MockObject */ private $result; /** - * @var Http|\PHPUnit_Framework_MockObject_MockObject + * @var Http|MockObject */ private $request; /** - * @var CommandResultInterface|\PHPUnit_Framework_MockObject_MockObject + * @var CommandResultInterface|MockObject */ private $commandResult; @@ -84,7 +85,7 @@ class GetNonceTest extends \PHPUnit\Framework\TestCase $this->session = $this->getMockBuilder(Session::class) ->disableOriginalConstructor() - ->setMethods(['getCustomerId']) + ->setMethods(['getCustomerId', 'getStoreId']) ->getMock(); $this->logger = $this->createMock(LoggerInterface::class); @@ -92,11 +93,9 @@ class GetNonceTest extends \PHPUnit\Framework\TestCase $context = $this->getMockBuilder(Context::class) ->disableOriginalConstructor() ->getMock(); - $context->expects(static::any()) - ->method('getRequest') + $context->method('getRequest') ->willReturn($this->request); - $context->expects(static::any()) - ->method('getResultFactory') + $context->method('getResultFactory') ->willReturn($this->resultFactory); $managerHelper = new ObjectManager($this); @@ -108,81 +107,68 @@ class GetNonceTest extends \PHPUnit\Framework\TestCase ]); } - /** - * @covers \Magento\Braintree\Controller\Payment\GetNonce::execute - */ public function testExecuteWithException() { - $this->request->expects(static::once()) - ->method('getParam') + $this->request->method('getParam') ->with('public_hash') ->willReturn(null); - $this->session->expects(static::once()) - ->method('getCustomerId') + $this->session->method('getCustomerId') + ->willReturn(null); + $this->session->method('getStoreId') ->willReturn(null); $exception = new \Exception('The "publicHash" field does not exists'); - $this->command->expects(static::once()) - ->method('execute') + $this->command->method('execute') ->willThrowException($exception); - $this->logger->expects(static::once()) - ->method('critical') + $this->logger->method('critical') ->with($exception); - $this->result->expects(static::once()) - ->method('setHttpResponseCode') + $this->result->method('setHttpResponseCode') ->with(Exception::HTTP_BAD_REQUEST); - $this->result->expects(static::once()) - ->method('setData') + $this->result->method('setData') ->with(['message' => 'Sorry, but something went wrong']); $this->action->execute(); } - /** - * @covers \Magento\Braintree\Controller\Payment\GetNonce::execute - */ public function testExecute() { $customerId = 1; $publicHash = '65b7bae0dcb690d93'; $nonce = 'f1hc45'; - $this->request->expects(static::once()) - ->method('getParam') + $this->request->method('getParam') ->with('public_hash') ->willReturn($publicHash); - $this->session->expects(static::once()) - ->method('getCustomerId') + $this->session->method('getCustomerId') ->willReturn($customerId); + $this->session->method('getStoreId') + ->willReturn(null); - $this->commandResult->expects(static::once()) - ->method('get') + $this->commandResult->method('get') ->willReturn([ 'paymentMethodNonce' => $nonce ]); - $this->command->expects(static::once()) - ->method('execute') + $this->command->method('execute') ->willReturn($this->commandResult); - $this->result->expects(static::once()) - ->method('setData') + $this->result->method('setData') ->with(['paymentMethodNonce' => $nonce]); - $this->logger->expects(static::never()) + $this->logger->expects(self::never()) ->method('critical'); - $this->result->expects(static::never()) + $this->result->expects(self::never()) ->method('setHttpResponseCode'); $this->action->execute(); } /** - * Create mock for result factory object + * Creates mock for result factory object */ private function initResultFactoryMock() { @@ -195,8 +181,7 @@ class GetNonceTest extends \PHPUnit\Framework\TestCase ->setMethods(['create']) ->getMock(); - $this->resultFactory->expects(static::once()) - ->method('create') + $this->resultFactory->method('create') ->willReturn($this->result); } } diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php index 56ea1f97fa165e27c993735990796e17bffda64b..52e17c4ff5d557d3162dc6d40255675d95b46969 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php @@ -6,23 +6,22 @@ namespace Magento\Braintree\Test\Unit\Gateway\Command; use Braintree\IsNode; -use Braintree\MultipleValueNode; -use Braintree\TextNode; use Magento\Braintree\Gateway\Command\CaptureStrategyCommand; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; +use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; +use Magento\Braintree\Model\Adapter\BraintreeSearchAdapter; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\Search\SearchCriteria; use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Payment\Gateway\Command; use Magento\Payment\Gateway\Command\CommandPoolInterface; use Magento\Payment\Gateway\Command\GatewayCommand; +use Magento\Payment\Gateway\Data\OrderAdapterInterface; use Magento\Payment\Gateway\Data\PaymentDataObject; use Magento\Sales\Api\TransactionRepositoryInterface; use Magento\Sales\Model\Order\Payment; -use Magento\Sales\Model\Order\Payment\Transaction; use Magento\Sales\Model\ResourceModel\Order\Payment\Transaction\CollectionFactory; -use Magento\Braintree\Model\Adapter\BraintreeAdapter; -use Magento\Braintree\Model\Adapter\BraintreeSearchAdapter; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class CaptureStrategyCommandTest @@ -37,42 +36,42 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase private $strategyCommand; /** - * @var CommandPoolInterface|\PHPUnit_Framework_MockObject_MockObject + * @var CommandPoolInterface|MockObject */ private $commandPool; /** - * @var TransactionRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var TransactionRepositoryInterface|MockObject */ private $transactionRepository; /** - * @var FilterBuilder|\PHPUnit_Framework_MockObject_MockObject + * @var FilterBuilder|MockObject */ private $filterBuilder; /** - * @var SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject + * @var SearchCriteriaBuilder|MockObject */ private $searchCriteriaBuilder; /** - * @var Payment|\PHPUnit_Framework_MockObject_MockObject + * @var Payment|MockObject */ private $payment; /** - * @var GatewayCommand|\PHPUnit_Framework_MockObject_MockObject + * @var GatewayCommand|MockObject */ private $command; /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + * @var SubjectReader|MockObject */ - private $subjectReaderMock; + private $subjectReader; /** - * @var BraintreeAdapter|\PHPUnit_Framework_MockObject_MockObject + * @var BraintreeAdapter|MockObject */ private $braintreeAdapter; @@ -88,7 +87,7 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase ->setMethods(['get', '__wakeup']) ->getMock(); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + $this->subjectReader = $this->getMockBuilder(SubjectReader::class) ->disableOriginalConstructor() ->getMock(); @@ -100,6 +99,13 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase $this->braintreeAdapter = $this->getMockBuilder(BraintreeAdapter::class) ->disableOriginalConstructor() ->getMock(); + /** @var BraintreeAdapterFactory|MockObject $adapterFactory */ + $adapterFactory = $this->getMockBuilder(BraintreeAdapterFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $adapterFactory->method('create') + ->willReturn($this->braintreeAdapter); + $this->braintreeSearchAdapter = new BraintreeSearchAdapter(); $this->strategyCommand = new CaptureStrategyCommand( @@ -107,86 +113,68 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase $this->transactionRepository, $this->filterBuilder, $this->searchCriteriaBuilder, - $this->subjectReaderMock, - $this->braintreeAdapter, + $this->subjectReader, + $adapterFactory, $this->braintreeSearchAdapter ); } - /** - * @covers \Magento\Braintree\Gateway\Command\CaptureStrategyCommand::execute - */ public function testSaleExecute() { $paymentData = $this->getPaymentDataObjectMock(); $subject['payment'] = $paymentData; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') + $this->subjectReader->method('readPayment') ->with($subject) ->willReturn($paymentData); - $this->payment->expects(static::once()) - ->method('getAuthorizationTransaction') + $this->payment->method('getAuthorizationTransaction') ->willReturn(false); - $this->payment->expects(static::once()) - ->method('getId') + $this->payment->method('getId') ->willReturn(1); $this->buildSearchCriteria(); - $this->transactionRepository->expects(static::once()) - ->method('getTotalCount') + $this->transactionRepository->method('getTotalCount') ->willReturn(0); - $this->commandPool->expects(static::once()) - ->method('get') + $this->commandPool->method('get') ->with(CaptureStrategyCommand::SALE) ->willReturn($this->command); $this->strategyCommand->execute($subject); } - /** - * @covers \Magento\Braintree\Gateway\Command\CaptureStrategyCommand::execute - */ public function testCaptureExecute() { $paymentData = $this->getPaymentDataObjectMock(); $subject['payment'] = $paymentData; $lastTransId = 'txnds'; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') + $this->subjectReader->method('readPayment') ->with($subject) ->willReturn($paymentData); - $this->payment->expects(static::once()) - ->method('getAuthorizationTransaction') + $this->payment->method('getAuthorizationTransaction') ->willReturn(true); - $this->payment->expects(static::once()) - ->method('getLastTransId') + $this->payment->method('getLastTransId') ->willReturn($lastTransId); - $this->payment->expects(static::once()) - ->method('getId') + $this->payment->method('getId') ->willReturn(1); $this->buildSearchCriteria(); - $this->transactionRepository->expects(static::once()) - ->method('getTotalCount') + $this->transactionRepository->method('getTotalCount') ->willReturn(0); // authorization transaction was not expired $collection = $this->getNotExpiredExpectedCollection($lastTransId); - $collection->expects(static::once()) - ->method('maximumCount') + $collection->method('maximumCount') ->willReturn(0); - $this->commandPool->expects(static::once()) - ->method('get') + $this->commandPool->method('get') ->with(CaptureStrategyCommand::CAPTURE) ->willReturn($this->command); @@ -195,7 +183,7 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase /** * @param string $lastTransactionId - * @return \Braintree\ResourceCollection|\PHPUnit_Framework_MockObject_MockObject + * @return \Braintree\ResourceCollection|MockObject */ private function getNotExpiredExpectedCollection($lastTransactionId) { @@ -208,10 +196,9 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase ->disableOriginalConstructor() ->getMock(); - $this->braintreeAdapter->expects(static::once()) - ->method('search') + $this->braintreeAdapter->method('search') ->with( - static::callback( + self::callback( function (array $filters) use ($isExpectations) { foreach ($filters as $filter) { /** @var IsNode $filter */ @@ -233,80 +220,62 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase return $collection; } - /** - * @covers \Magento\Braintree\Gateway\Command\CaptureStrategyCommand::execute - */ public function testExpiredAuthorizationPerformVaultCaptureExecute() { $paymentData = $this->getPaymentDataObjectMock(); $subject['payment'] = $paymentData; $lastTransId = 'txnds'; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') + $this->subjectReader->method('readPayment') ->with($subject) ->willReturn($paymentData); - $this->payment->expects(static::once()) - ->method('getAuthorizationTransaction') + $this->payment->method('getAuthorizationTransaction') ->willReturn(true); - $this->payment->expects(static::once()) - ->method('getLastTransId') + $this->payment->method('getLastTransId') ->willReturn($lastTransId); - $this->payment->expects(static::once()) - ->method('getId') + $this->payment->method('getId') ->willReturn(1); $this->buildSearchCriteria(); - $this->transactionRepository->expects(static::once()) - ->method('getTotalCount') + $this->transactionRepository->method('getTotalCount') ->willReturn(0); // authorization transaction was expired $collection = $this->getNotExpiredExpectedCollection($lastTransId); - $collection->expects(static::once()) - ->method('maximumCount') + $collection->method('maximumCount') ->willReturn(1); - $this->commandPool->expects(static::once()) - ->method('get') + $this->commandPool->method('get') ->with(CaptureStrategyCommand::VAULT_CAPTURE) ->willReturn($this->command); $this->strategyCommand->execute($subject); } - /** - * @covers \Magento\Braintree\Gateway\Command\CaptureStrategyCommand::execute - */ public function testVaultCaptureExecute() { $paymentData = $this->getPaymentDataObjectMock(); $subject['payment'] = $paymentData; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') + $this->subjectReader->method('readPayment') ->with($subject) ->willReturn($paymentData); - $this->payment->expects(static::once()) - ->method('getAuthorizationTransaction') + $this->payment->method('getAuthorizationTransaction') ->willReturn(true); - $this->payment->expects(static::once()) - ->method('getId') + $this->payment->method('getId') ->willReturn(1); $this->buildSearchCriteria(); - $this->transactionRepository->expects(static::once()) - ->method('getTotalCount') + $this->transactionRepository->method('getTotalCount') ->willReturn(1); - $this->commandPool->expects(static::once()) - ->method('get') + $this->commandPool->method('get') ->with(CaptureStrategyCommand::VAULT_CAPTURE) ->willReturn($this->command); @@ -314,8 +283,8 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase } /** - * Create mock for payment data object and order payment - * @return \PHPUnit_Framework_MockObject_MockObject + * Creates mock for payment data object and order payment + * @return MockObject */ private function getPaymentDataObjectMock() { @@ -324,19 +293,25 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase ->getMock(); $mock = $this->getMockBuilder(PaymentDataObject::class) - ->setMethods(['getPayment']) + ->setMethods(['getPayment', 'getOrder']) ->disableOriginalConstructor() ->getMock(); - $mock->expects(static::once()) - ->method('getPayment') + $mock->method('getPayment') ->willReturn($this->payment); + $order = $this->getMockBuilder(OrderAdapterInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $mock->method('getOrder') + ->willReturn($order); + return $mock; } /** - * Create mock for gateway command object + * Creates mock for gateway command object */ private function initCommandMock() { @@ -345,13 +320,12 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase ->setMethods(['execute']) ->getMock(); - $this->command->expects(static::once()) - ->method('execute') + $this->command->method('execute') ->willReturn([]); } /** - * Create mock for filter object + * Creates mock for filter object */ private function initFilterBuilderMock() { @@ -362,27 +336,25 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase } /** - * Build search criteria + * Builds search criteria */ private function buildSearchCriteria() { - $this->filterBuilder->expects(static::exactly(2)) + $this->filterBuilder->expects(self::exactly(2)) ->method('setField') ->willReturnSelf(); - $this->filterBuilder->expects(static::exactly(2)) + $this->filterBuilder->expects(self::exactly(2)) ->method('setValue') ->willReturnSelf(); $searchCriteria = new SearchCriteria(); - $this->searchCriteriaBuilder->expects(static::exactly(2)) + $this->searchCriteriaBuilder->expects(self::exactly(2)) ->method('addFilters') ->willReturnSelf(); - $this->searchCriteriaBuilder->expects(static::once()) - ->method('create') + $this->searchCriteriaBuilder->method('create') ->willReturn($searchCriteria); - $this->transactionRepository->expects(static::once()) - ->method('getList') + $this->transactionRepository->method('getList') ->with($searchCriteria) ->willReturnSelf(); } diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Command/GetPaymentNonceCommandTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Command/GetPaymentNonceCommandTest.php index 333f29eb29136633763b0b7d38a8a4350663b1c2..1b06fc0d21a2702d9942ec74773b490ee8a5e6a9 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Command/GetPaymentNonceCommandTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Command/GetPaymentNonceCommandTest.php @@ -6,15 +6,16 @@ namespace Magento\Braintree\Test\Unit\Gateway\Command; use Magento\Braintree\Gateway\Command\GetPaymentNonceCommand; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Validator\PaymentNonceResponseValidator; use Magento\Braintree\Model\Adapter\BraintreeAdapter; -use Magento\Payment\Gateway\Command; -use Magento\Payment\Gateway\Command\Result\ArrayResultFactory; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Payment\Gateway\Command\Result\ArrayResult; +use Magento\Payment\Gateway\Command\Result\ArrayResultFactory; use Magento\Payment\Gateway\Validator\ResultInterface; use Magento\Vault\Model\PaymentToken; use Magento\Vault\Model\PaymentTokenManagement; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class GetPaymentNonceCommandTest @@ -29,37 +30,37 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase private $command; /** - * @var BraintreeAdapter|\PHPUnit_Framework_MockObject_MockObject + * @var BraintreeAdapter|MockObject */ private $adapter; /** - * @var PaymentTokenManagement|\PHPUnit_Framework_MockObject_MockObject + * @var PaymentTokenManagement|MockObject */ private $tokenManagement; /** - * @var PaymentToken|\PHPUnit_Framework_MockObject_MockObject + * @var PaymentToken|MockObject */ private $paymentToken; /** - * @var ArrayResultFactory|\PHPUnit_Framework_MockObject_MockObject + * @var ArrayResultFactory|MockObject */ private $resultFactory; /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + * @var SubjectReader|MockObject */ private $subjectReader; /** - * @var PaymentNonceResponseValidator|\PHPUnit_Framework_MockObject_MockObject + * @var PaymentNonceResponseValidator|MockObject */ private $responseValidator; /** - * @var ResultInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ResultInterface|MockObject */ private $validationResult; @@ -79,6 +80,12 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase ->disableOriginalConstructor() ->setMethods(['createNonce']) ->getMock(); + /** @var BraintreeAdapterFactory|MockObject $adapterFactory */ + $adapterFactory = $this->getMockBuilder(BraintreeAdapterFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $adapterFactory->method('create') + ->willReturn($this->adapter); $this->resultFactory = $this->getMockBuilder(ArrayResultFactory::class) ->disableOriginalConstructor() @@ -101,7 +108,7 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase $this->command = new GetPaymentNonceCommand( $this->tokenManagement, - $this->adapter, + $adapterFactory, $this->resultFactory, $this->subjectReader, $this->responseValidator @@ -109,7 +116,6 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase } /** - * @covers \Magento\Braintree\Gateway\Command\GetPaymentNonceCommand::execute * @expectedException \InvalidArgumentException * @expectedExceptionMessage The "publicHash" field does not exists */ @@ -117,18 +123,16 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase { $exception = new \InvalidArgumentException('The "publicHash" field does not exists'); - $this->subjectReader->expects(static::once()) - ->method('readPublicHash') + $this->subjectReader->method('readPublicHash') ->willThrowException($exception); - $this->subjectReader->expects(static::never()) + $this->subjectReader->expects(self::never()) ->method('readCustomerId'); $this->command->execute([]); } /** - * @covers \Magento\Braintree\Gateway\Command\GetPaymentNonceCommand::execute * @expectedException \InvalidArgumentException * @expectedExceptionMessage The "customerId" field does not exists */ @@ -136,23 +140,20 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase { $publicHash = '3wv2m24d2er3'; - $this->subjectReader->expects(static::once()) - ->method('readPublicHash') + $this->subjectReader->method('readPublicHash') ->willReturn($publicHash); $exception = new \InvalidArgumentException('The "customerId" field does not exists'); - $this->subjectReader->expects(static::once()) - ->method('readCustomerId') + $this->subjectReader->method('readCustomerId') ->willThrowException($exception); - $this->tokenManagement->expects(static::never()) + $this->tokenManagement->expects(self::never()) ->method('getByPublicHash'); $this->command->execute(['publicHash' => $publicHash]); } /** - * @covers \Magento\Braintree\Gateway\Command\GetPaymentNonceCommand::execute * @expectedException \Exception * @expectedExceptionMessage No available payment tokens */ @@ -161,27 +162,23 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase $publicHash = '3wv2m24d2er3'; $customerId = 1; - $this->subjectReader->expects(static::once()) - ->method('readPublicHash') + $this->subjectReader->method('readPublicHash') ->willReturn($publicHash); - $this->subjectReader->expects(static::once()) - ->method('readCustomerId') + $this->subjectReader->method('readCustomerId') ->willReturn($customerId); $exception = new \Exception('No available payment tokens'); - $this->tokenManagement->expects(static::once()) - ->method('getByPublicHash') + $this->tokenManagement->method('getByPublicHash') ->willThrowException($exception); - $this->paymentToken->expects(static::never()) + $this->paymentToken->expects(self::never()) ->method('getGatewayToken'); $this->command->execute(['publicHash' => $publicHash, 'customerId' => $customerId]); } /** - * @covers \Magento\Braintree\Gateway\Command\GetPaymentNonceCommand::execute * @expectedException \Exception * @expectedExceptionMessage Payment method nonce can't be retrieved. */ @@ -191,52 +188,41 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase $customerId = 1; $token = 'jd2vnq'; - $this->subjectReader->expects(static::once()) - ->method('readPublicHash') + $this->subjectReader->method('readPublicHash') ->willReturn($publicHash); - $this->subjectReader->expects(static::once()) - ->method('readCustomerId') + $this->subjectReader->method('readCustomerId') ->willReturn($customerId); - $this->tokenManagement->expects(static::once()) - ->method('getByPublicHash') + $this->tokenManagement->method('getByPublicHash') ->with($publicHash, $customerId) ->willReturn($this->paymentToken); - $this->paymentToken->expects(static::once()) - ->method('getGatewayToken') + $this->paymentToken->method('getGatewayToken') ->willReturn($token); $obj = new \stdClass(); $obj->success = false; - $this->adapter->expects(static::once()) - ->method('createNonce') + $this->adapter->method('createNonce') ->with($token) ->willReturn($obj); - $this->responseValidator->expects(static::once()) - ->method('validate') + $this->responseValidator->method('validate') ->with(['response' => ['object' => $obj]]) ->willReturn($this->validationResult); - $this->validationResult->expects(static::once()) - ->method('isValid') + $this->validationResult->method('isValid') ->willReturn(false); - $this->validationResult->expects(static::once()) - ->method('getFailsDescription') + $this->validationResult->method('getFailsDescription') ->willReturn(['Payment method nonce can\'t be retrieved.']); - $this->resultFactory->expects(static::never()) + $this->resultFactory->expects(self::never()) ->method('create'); $this->command->execute(['publicHash' => $publicHash, 'customerId' => $customerId]); } - /** - * @covers \Magento\Braintree\Gateway\Command\GetPaymentNonceCommand::execute - */ public function testExecute() { $publicHash = '3wv2m24d2er3'; @@ -244,57 +230,48 @@ class GetPaymentNonceCommandTest extends \PHPUnit\Framework\TestCase $token = 'jd2vnq'; $nonce = 's1dj23'; - $this->subjectReader->expects(static::once()) - ->method('readPublicHash') + $this->subjectReader->method('readPublicHash') ->willReturn($publicHash); - $this->subjectReader->expects(static::once()) - ->method('readCustomerId') + $this->subjectReader->method('readCustomerId') ->willReturn($customerId); - $this->tokenManagement->expects(static::once()) - ->method('getByPublicHash') + $this->tokenManagement->method('getByPublicHash') ->with($publicHash, $customerId) ->willReturn($this->paymentToken); - $this->paymentToken->expects(static::once()) - ->method('getGatewayToken') + $this->paymentToken->method('getGatewayToken') ->willReturn($token); $obj = new \stdClass(); $obj->success = true; $obj->paymentMethodNonce = new \stdClass(); $obj->paymentMethodNonce->nonce = $nonce; - $this->adapter->expects(static::once()) - ->method('createNonce') + $this->adapter->method('createNonce') ->with($token) ->willReturn($obj); - $this->responseValidator->expects(static::once()) - ->method('validate') + $this->responseValidator->method('validate') ->with(['response' => ['object' => $obj]]) ->willReturn($this->validationResult); - $this->validationResult->expects(static::once()) - ->method('isValid') + $this->validationResult->method('isValid') ->willReturn(true); - $this->validationResult->expects(static::never()) + $this->validationResult->expects(self::never()) ->method('getFailsDescription'); $expected = $this->getMockBuilder(ArrayResult::class) ->disableOriginalConstructor() ->setMethods(['get']) ->getMock(); - $expected->expects(static::once()) - ->method('get') + $expected->method('get') ->willReturn(['paymentMethodNonce' => $nonce]); - $this->resultFactory->expects(static::once()) - ->method('create') + $this->resultFactory->method('create') ->willReturn($expected); $actual = $this->command->execute(['publicHash' => $publicHash, 'customerId' => $customerId]); - static::assertEquals($expected, $actual); - static::assertEquals($nonce, $actual->get()['paymentMethodNonce']); + self::assertEquals($expected, $actual); + self::assertEquals($nonce, $actual->get()['paymentMethodNonce']); } } diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Config/CanVoidHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Config/CanVoidHandlerTest.php index 793700ab1971f221274de7c1fe3c59024c91482b..bb258f27455a486b7893de49e09b29cb01834452 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Config/CanVoidHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Config/CanVoidHandlerTest.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Test\Unit\Gateway\Config; use Magento\Braintree\Gateway\Config\CanVoidHandler; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Payment\Model\InfoInterface; use Magento\Sales\Model\Order\Payment; diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Helper/SubjectReaderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Helper/SubjectReaderTest.php index b2207563b8b0fe0fbcf9d3f85b42441395c38a0f..21b8a13be6bed53c01ae02fff4b7eaa7f91ad6d1 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Helper/SubjectReaderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Helper/SubjectReaderTest.php @@ -7,7 +7,7 @@ namespace Magento\Braintree\Test\Unit\Gateway\Helper; use Braintree\Transaction; use InvalidArgumentException; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; /** * Class SubjectReaderTest @@ -25,7 +25,7 @@ class SubjectReaderTest extends \PHPUnit\Framework\TestCase } /** - * @covers \Magento\Braintree\Gateway\Helper\SubjectReader::readCustomerId + * @covers \Magento\Braintree\Gateway\SubjectReader::readCustomerId * @expectedException InvalidArgumentException * @expectedExceptionMessage The "customerId" field does not exists */ @@ -35,7 +35,7 @@ class SubjectReaderTest extends \PHPUnit\Framework\TestCase } /** - * @covers \Magento\Braintree\Gateway\Helper\SubjectReader::readCustomerId + * @covers \Magento\Braintree\Gateway\SubjectReader::readCustomerId */ public function testReadCustomerId() { @@ -44,7 +44,7 @@ class SubjectReaderTest extends \PHPUnit\Framework\TestCase } /** - * @covers \Magento\Braintree\Gateway\Helper\SubjectReader::readPublicHash + * @covers \Magento\Braintree\Gateway\SubjectReader::readPublicHash * @expectedException InvalidArgumentException * @expectedExceptionMessage The "public_hash" field does not exists */ @@ -54,7 +54,7 @@ class SubjectReaderTest extends \PHPUnit\Framework\TestCase } /** - * @covers \Magento\Braintree\Gateway\Helper\SubjectReader::readPublicHash + * @covers \Magento\Braintree\Gateway\SubjectReader::readPublicHash */ public function testReadPublicHash() { @@ -63,7 +63,7 @@ class SubjectReaderTest extends \PHPUnit\Framework\TestCase } /** - * @covers \Magento\Braintree\Gateway\Helper\SubjectReader::readPayPal + * @covers \Magento\Braintree\Gateway\SubjectReader::readPayPal * @expectedException \InvalidArgumentException * @expectedExceptionMessage Transaction has't paypal attribute */ @@ -76,7 +76,7 @@ class SubjectReaderTest extends \PHPUnit\Framework\TestCase } /** - * @covers \Magento\Braintree\Gateway\Helper\SubjectReader::readPayPal + * @covers \Magento\Braintree\Gateway\SubjectReader::readPayPal */ public function testReadPayPal() { diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Http/Client/TransactionSaleTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Http/Client/TransactionSaleTest.php index 5cbcfef8b6b9e3ee5a89ccc93c9fe14f0e25a126..48889f1efd2e512574b2a3992c98a909b5cdd929 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Http/Client/TransactionSaleTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Http/Client/TransactionSaleTest.php @@ -7,8 +7,10 @@ namespace Magento\Braintree\Test\Unit\Gateway\Http\Client; use Magento\Braintree\Gateway\Http\Client\TransactionSale; use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Payment\Gateway\Http\TransferInterface; use Magento\Payment\Model\Method\Logger; +use PHPUnit_Framework_MockObject_MockObject as MockObject; use Psr\Log\LoggerInterface; /** @@ -22,35 +24,41 @@ class TransactionSaleTest extends \PHPUnit\Framework\TestCase private $model; /** - * @var Logger|\PHPUnit_Framework_MockObject_MockObject + * @var Logger|MockObject */ - private $loggerMock; + private $logger; /** - * @var BraintreeAdapter|\PHPUnit_Framework_MockObject_MockObject + * @var BraintreeAdapter|MockObject */ private $adapter; /** - * Set up - * - * @return void + * @inheritdoc */ protected function setUp() { - $criticalLoggerMock = $this->getMockForAbstractClass(LoggerInterface::class); - $this->loggerMock = $this->getMockBuilder(Logger::class) + /** @var LoggerInterface|MockObject $criticalLogger */ + $criticalLogger = $this->getMockForAbstractClass(LoggerInterface::class); + $this->logger = $this->getMockBuilder(Logger::class) ->disableOriginalConstructor() ->getMock(); + $this->adapter = $this->getMockBuilder(BraintreeAdapter::class) ->disableOriginalConstructor() ->getMock(); + /** @var BraintreeAdapterFactory|MockObject $adapterFactory */ + $adapterFactory = $this->getMockBuilder(BraintreeAdapterFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $adapterFactory->method('create') + ->willReturn($this->adapter); - $this->model = new TransactionSale($criticalLoggerMock, $this->loggerMock, $this->adapter); + $this->model = new TransactionSale($criticalLogger, $this->logger, $adapterFactory); } /** - * Run test placeRequest method (exception) + * Runs test placeRequest method (exception) * * @return void * @@ -59,8 +67,7 @@ class TransactionSaleTest extends \PHPUnit\Framework\TestCase */ public function testPlaceRequestException() { - $this->loggerMock->expects($this->once()) - ->method('debug') + $this->logger->method('debug') ->with( [ 'request' => $this->getTransferData(), @@ -69,11 +76,10 @@ class TransactionSaleTest extends \PHPUnit\Framework\TestCase ] ); - $this->adapter->expects($this->once()) - ->method('sale') + $this->adapter->method('sale') ->willThrowException(new \Exception('Test messages')); - /** @var TransferInterface|\PHPUnit_Framework_MockObject_MockObject $transferObjectMock */ + /** @var TransferInterface|MockObject $transferObjectMock */ $transferObjectMock = $this->getTransferObjectMock(); $this->model->placeRequest($transferObjectMock); @@ -87,14 +93,11 @@ class TransactionSaleTest extends \PHPUnit\Framework\TestCase public function testPlaceRequestSuccess() { $response = $this->getResponseObject(); - $this->adapter->expects($this->once()) - ->method('sale') + $this->adapter->method('sale') ->with($this->getTransferData()) - ->willReturn($response) - ; + ->willReturn($response); - $this->loggerMock->expects($this->once()) - ->method('debug') + $this->logger->method('debug') ->with( [ 'request' => $this->getTransferData(), @@ -110,19 +113,22 @@ class TransactionSaleTest extends \PHPUnit\Framework\TestCase } /** - * @return TransferInterface|\PHPUnit_Framework_MockObject_MockObject + * Creates mock object for TransferInterface. + * + * @return TransferInterface|MockObject */ private function getTransferObjectMock() { $transferObjectMock = $this->createMock(TransferInterface::class); - $transferObjectMock->expects($this->once()) - ->method('getBody') + $transferObjectMock->method('getBody') ->willReturn($this->getTransferData()); return $transferObjectMock; } /** + * Creates stub for a response. + * * @return \stdClass */ private function getResponseObject() @@ -134,6 +140,8 @@ class TransactionSaleTest extends \PHPUnit\Framework\TestCase } /** + * Creates stub request data. + * * @return array */ private function getTransferData() diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Http/Client/TransactionSubmitForSettlementTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Http/Client/TransactionSubmitForSettlementTest.php index 86113c34ba218d05d3e561ffbc3514b833f4ea81..09b0efc58f3fbba82d25e87552cd3beba23c6af6 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Http/Client/TransactionSubmitForSettlementTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Http/Client/TransactionSubmitForSettlementTest.php @@ -8,8 +8,10 @@ namespace Magento\Braintree\Test\Unit\Gateway\Http\Client; use Braintree\Result\Successful; use Magento\Braintree\Gateway\Http\Client\TransactionSubmitForSettlement; use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Payment\Gateway\Http\TransferInterface; use Magento\Payment\Model\Method\Logger; +use PHPUnit_Framework_MockObject_MockObject as MockObject; use Psr\Log\LoggerInterface; /** @@ -23,76 +25,79 @@ class TransactionSubmitForSettlementTest extends \PHPUnit\Framework\TestCase private $client; /** - * @var Logger|\PHPUnit_Framework_MockObject_MockObject + * @var Logger|MockObject */ private $logger; /** - * @var BraintreeAdapter|\PHPUnit_Framework_MockObject_MockObject + * @var BraintreeAdapter|MockObject */ private $adapter; protected function setUp() { - $criticalLoggerMock = $this->getMockForAbstractClass(LoggerInterface::class); + /** @var LoggerInterface|MockObject $criticalLogger */ + $criticalLogger = $this->getMockForAbstractClass(LoggerInterface::class); $this->logger = $this->getMockBuilder(Logger::class) ->disableOriginalConstructor() ->setMethods(['debug']) ->getMock(); + $this->adapter = $this->getMockBuilder(BraintreeAdapter::class) ->disableOriginalConstructor() ->setMethods(['submitForSettlement']) ->getMock(); + /** @var BraintreeAdapterFactory|MockObject $adapterFactory */ + $adapterFactory = $this->getMockBuilder(BraintreeAdapterFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $adapterFactory->method('create') + ->willReturn($this->adapter); $this->client = new TransactionSubmitForSettlement( - $criticalLoggerMock, + $criticalLogger, $this->logger, - $this->adapter + $adapterFactory ); } /** - * @covers \Magento\Braintree\Gateway\Http\Client\TransactionSubmitForSettlement::placeRequest * @expectedException \Magento\Payment\Gateway\Http\ClientException * @expectedExceptionMessage Transaction has been declined */ public function testPlaceRequestWithException() { $exception = new \Exception('Transaction has been declined'); - $this->adapter->expects(static::once()) - ->method('submitForSettlement') + $this->adapter->method('submitForSettlement') ->willThrowException($exception); - /** @var TransferInterface|\PHPUnit_Framework_MockObject_MockObject $transferObjectMock */ - $transferObjectMock = $this->getTransferObjectMock(); - $this->client->placeRequest($transferObjectMock); + /** @var TransferInterface|MockObject $transferObject */ + $transferObject = $this->getTransferObjectMock(); + $this->client->placeRequest($transferObject); } - /** - * @covers \Magento\Braintree\Gateway\Http\Client\TransactionSubmitForSettlement::process - */ public function testPlaceRequest() { $data = new Successful(['success'], [true]); - $this->adapter->expects(static::once()) - ->method('submitForSettlement') + $this->adapter->method('submitForSettlement') ->willReturn($data); - /** @var TransferInterface|\PHPUnit_Framework_MockObject_MockObject $transferObjectMock */ - $transferObjectMock = $this->getTransferObjectMock(); - $response = $this->client->placeRequest($transferObjectMock); + /** @var TransferInterface|MockObject $transferObject */ + $transferObject = $this->getTransferObjectMock(); + $response = $this->client->placeRequest($transferObject); static::assertTrue(is_object($response['object'])); static::assertEquals(['object' => $data], $response); } /** - * @return TransferInterface|\PHPUnit_Framework_MockObject_MockObject + * Creates mock for TransferInterface + * + * @return TransferInterface|MockObject */ private function getTransferObjectMock() { $mock = $this->createMock(TransferInterface::class); - $mock->expects($this->once()) - ->method('getBody') + $mock->method('getBody') ->willReturn([ 'transaction_id' => 'vb4c6b', 'amount' => 124.00 diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/AddressDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/AddressDataBuilderTest.php index 3f05aed45da6057b3a81998306caef97582e8954..702b3254e3085d694b63d5321efa41bb357a60d6 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/AddressDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/AddressDataBuilderTest.php @@ -5,11 +5,12 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Request; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\AddressDataBuilder; -use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; -use Magento\Payment\Gateway\Data\OrderAdapterInterface; use Magento\Payment\Gateway\Data\AddressAdapterInterface; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Payment\Gateway\Data\OrderAdapterInterface; +use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class AddressDataBuilderTest @@ -17,34 +18,26 @@ use Magento\Braintree\Gateway\Helper\SubjectReader; class AddressDataBuilderTest extends \PHPUnit\Framework\TestCase { /** - * @var PaymentDataObjectInterface|\PHPUnit_Framework_MockObject_MockObject + * @var PaymentDataObjectInterface|MockObject */ - private $paymentDOMock; + private $paymentDO; /** - * @var OrderAdapterInterface|\PHPUnit_Framework_MockObject_MockObject + * @var OrderAdapterInterface|MockObject */ - private $orderMock; + private $order; /** * @var AddressDataBuilder */ private $builder; - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReaderMock; - protected function setUp() { - $this->paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->orderMock = $this->createMock(OrderAdapterInterface::class); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); + $this->order = $this->createMock(OrderAdapterInterface::class); - $this->builder = new AddressDataBuilder($this->subjectReaderMock); + $this->builder = new AddressDataBuilder(new SubjectReader()); } /** @@ -56,37 +49,24 @@ class AddressDataBuilderTest extends \PHPUnit\Framework\TestCase 'payment' => null, ]; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - $this->builder->build($buildSubject); } public function testBuildNoAddresses() { - $this->paymentDOMock->expects(static::once()) - ->method('getOrder') - ->willReturn($this->orderMock); + $this->paymentDO->method('getOrder') + ->willReturn($this->order); - $this->orderMock->expects(static::once()) - ->method('getShippingAddress') + $this->order->method('getShippingAddress') ->willReturn(null); - $this->orderMock->expects(static::once()) - ->method('getBillingAddress') + $this->order->method('getBillingAddress') ->willReturn(null); $buildSubject = [ - 'payment' => $this->paymentDOMock, + 'payment' => $this->paymentDO, ]; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDOMock); - - static::assertEquals([], $this->builder->build($buildSubject)); + self::assertEquals([], $this->builder->build($buildSubject)); } /** @@ -97,28 +77,20 @@ class AddressDataBuilderTest extends \PHPUnit\Framework\TestCase */ public function testBuild($addressData, $expectedResult) { - $addressMock = $this->getAddressMock($addressData); + $address = $this->getAddressMock($addressData); - $this->paymentDOMock->expects(static::once()) - ->method('getOrder') - ->willReturn($this->orderMock); + $this->paymentDO->method('getOrder') + ->willReturn($this->order); - $this->orderMock->expects(static::once()) - ->method('getShippingAddress') - ->willReturn($addressMock); - $this->orderMock->expects(static::once()) - ->method('getBillingAddress') - ->willReturn($addressMock); + $this->order->method('getShippingAddress') + ->willReturn($address); + $this->order->method('getBillingAddress') + ->willReturn($address); $buildSubject = [ - 'payment' => $this->paymentDOMock, + 'payment' => $this->paymentDO, ]; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDOMock); - self::assertEquals($expectedResult, $this->builder->build($buildSubject)); } @@ -171,37 +143,37 @@ class AddressDataBuilderTest extends \PHPUnit\Framework\TestCase /** * @param array $addressData - * @return AddressAdapterInterface|\PHPUnit_Framework_MockObject_MockObject + * @return AddressAdapterInterface|MockObject */ private function getAddressMock($addressData) { $addressMock = $this->createMock(AddressAdapterInterface::class); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getFirstname') ->willReturn($addressData['first_name']); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getLastname') ->willReturn($addressData['last_name']); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getCompany') ->willReturn($addressData['company']); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getStreetLine1') ->willReturn($addressData['street_1']); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getStreetLine2') ->willReturn($addressData['street_2']); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getCity') ->willReturn($addressData['city']); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getRegionCode') ->willReturn($addressData['region_code']); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getPostcode') ->willReturn($addressData['post_code']); - $addressMock->expects(static::exactly(2)) + $addressMock->expects(self::exactly(2)) ->method('getCountryId') ->willReturn($addressData['country_id']); diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php index 9799b6f18c639aa7cc14ed879d78d90999ef1fcf..b42b1162b3d70c1d1bd4edd4d392a56b1915ded6 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php @@ -8,7 +8,8 @@ namespace Magento\Braintree\Test\Unit\Gateway\Request; use Magento\Braintree\Gateway\Request\CaptureDataBuilder; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Sales\Model\Order\Payment; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class CaptureDataBuilderTest @@ -21,35 +22,26 @@ class CaptureDataBuilderTest extends \PHPUnit\Framework\TestCase private $builder; /** - * @var Payment|\PHPUnit_Framework_MockObject_MockObject + * @var Payment|MockObject */ private $payment; /** - * @var \Magento\Sales\Model\Order\Payment|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sales\Model\Order\Payment|MockObject */ private $paymentDO; - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReaderMock; - protected function setUp() { $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); $this->payment = $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() ->getMock(); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - $this->builder = new CaptureDataBuilder($this->subjectReaderMock); + $this->builder = new CaptureDataBuilder(new SubjectReader()); } /** - * @covers \Magento\Braintree\Gateway\Request\CaptureDataBuilder::build * @expectedException \Magento\Framework\Exception\LocalizedException * @expectedExceptionMessage No authorization transaction to proceed capture. */ @@ -61,25 +53,15 @@ class CaptureDataBuilderTest extends \PHPUnit\Framework\TestCase 'amount' => $amount ]; - $this->payment->expects(static::once()) - ->method('getCcTransId') + $this->payment->method('getCcTransId') ->willReturn(''); - $this->paymentDO->expects(static::once()) - ->method('getPayment') + $this->paymentDO->method('getPayment') ->willReturn($this->payment); - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDO); - $this->builder->build($buildSubject); } - /** - * @covers \Magento\Braintree\Gateway\Request\CaptureDataBuilder::build - */ public function testBuild() { $transactionId = 'b3b99d'; @@ -95,23 +77,12 @@ class CaptureDataBuilderTest extends \PHPUnit\Framework\TestCase 'amount' => $amount ]; - $this->payment->expects(static::once()) - ->method('getCcTransId') + $this->payment->method('getCcTransId') ->willReturn($transactionId); - $this->paymentDO->expects(static::once()) - ->method('getPayment') + $this->paymentDO->method('getPayment') ->willReturn($this->payment); - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDO); - $this->subjectReaderMock->expects(self::once()) - ->method('readAmount') - ->with($buildSubject) - ->willReturn($amount); - - static::assertEquals($expected, $this->builder->build($buildSubject)); + self::assertEquals($expected, $this->builder->build($buildSubject)); } } diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/CustomerDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/CustomerDataBuilderTest.php index 0f25b26fd2fa31d755816d192f12fe28bc0b7642..9b5cee30940df990c1363a0bc8c11d316443870d 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/CustomerDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/CustomerDataBuilderTest.php @@ -5,46 +5,36 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Request; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\CustomerDataBuilder; -use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; -use Magento\Payment\Gateway\Data\OrderAdapterInterface; use Magento\Payment\Gateway\Data\AddressAdapterInterface; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Payment\Gateway\Data\OrderAdapterInterface; +use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; +use PHPUnit_Framework_MockObject_MockObject as MockObject; -/** - * Class CustomerDataBuilderTest - */ class CustomerDataBuilderTest extends \PHPUnit\Framework\TestCase { /** - * @var PaymentDataObjectInterface|\PHPUnit_Framework_MockObject_MockObject + * @var PaymentDataObjectInterface|MockObject */ - private $paymentDOMock; + private $paymentDO; /** - * @var OrderAdapterInterface|\PHPUnit_Framework_MockObject_MockObject + * @var OrderAdapterInterface|MockObject */ - private $orderMock; + private $order; /** * @var CustomerDataBuilder */ private $builder; - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReaderMock; - protected function setUp() { - $this->paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->orderMock = $this->createMock(OrderAdapterInterface::class); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); + $this->order = $this->createMock(OrderAdapterInterface::class); - $this->builder = new CustomerDataBuilder($this->subjectReaderMock); + $this->builder = new CustomerDataBuilder(new SubjectReader()); } /** @@ -56,11 +46,6 @@ class CustomerDataBuilderTest extends \PHPUnit\Framework\TestCase 'payment' => null, ]; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - $this->builder->build($buildSubject); } @@ -74,22 +59,15 @@ class CustomerDataBuilderTest extends \PHPUnit\Framework\TestCase { $billingMock = $this->getBillingMock($billingData); - $this->paymentDOMock->expects(static::once()) - ->method('getOrder') - ->willReturn($this->orderMock); - $this->orderMock->expects(static::once()) - ->method('getBillingAddress') + $this->paymentDO->method('getOrder') + ->willReturn($this->order); + $this->order->method('getBillingAddress') ->willReturn($billingMock); $buildSubject = [ - 'payment' => $this->paymentDOMock, + 'payment' => $this->paymentDO, ]; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDOMock); - self::assertEquals($expectedResult, $this->builder->build($buildSubject)); } @@ -122,28 +100,23 @@ class CustomerDataBuilderTest extends \PHPUnit\Framework\TestCase /** * @param array $billingData - * @return AddressAdapterInterface|\PHPUnit_Framework_MockObject_MockObject + * @return AddressAdapterInterface|MockObject */ private function getBillingMock($billingData) { - $addressMock = $this->createMock(AddressAdapterInterface::class); + $address = $this->createMock(AddressAdapterInterface::class); - $addressMock->expects(static::once()) - ->method('getFirstname') + $address->method('getFirstname') ->willReturn($billingData['first_name']); - $addressMock->expects(static::once()) - ->method('getLastname') + $address->method('getLastname') ->willReturn($billingData['last_name']); - $addressMock->expects(static::once()) - ->method('getCompany') + $address->method('getCompany') ->willReturn($billingData['company']); - $addressMock->expects(static::once()) - ->method('getTelephone') + $address->method('getTelephone') ->willReturn($billingData['phone']); - $addressMock->expects(static::once()) - ->method('getEmail') + $address->method('getEmail') ->willReturn($billingData['email']); - return $addressMock; + return $address; } } diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/DescriptorDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/DescriptorDataBuilderTest.php index 761d88b636ed73733fed97b32a608c63eb27c6b6..eda9121236045e6fd25aca51d862bf368aa051f3 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/DescriptorDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/DescriptorDataBuilderTest.php @@ -6,12 +6,12 @@ namespace Magento\Braintree\Test\Unit\Gateway\Request; use Magento\Braintree\Gateway\Config\Config; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\DescriptorDataBuilder; +use Magento\Payment\Gateway\Data\OrderAdapterInterface; +use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use PHPUnit_Framework_MockObject_MockObject as MockObject; -/** - * Class DescriptorDataBuilderTest - */ class DescriptorDataBuilderTest extends \PHPUnit\Framework\TestCase { /** @@ -31,22 +31,25 @@ class DescriptorDataBuilderTest extends \PHPUnit\Framework\TestCase ->setMethods(['getDynamicDescriptors']) ->getMock(); - $this->builder = new DescriptorDataBuilder($this->config); + $this->builder = new DescriptorDataBuilder($this->config, new SubjectReader()); } /** - * @covers \Magento\Braintree\Gateway\Request\DescriptorDataBuilder::build * @param array $descriptors * @param array $expected * @dataProvider buildDataProvider */ public function testBuild(array $descriptors, array $expected) { - $this->config->expects(static::once()) - ->method('getDynamicDescriptors') + $paymentDO = $this->createMock(PaymentDataObjectInterface::class); + $order = $this->createMock(OrderAdapterInterface::class); + $paymentDO->method('getOrder') + ->willReturn($order); + + $this->config->method('getDynamicDescriptors') ->willReturn($descriptors); - $actual = $this->builder->build([]); + $actual = $this->builder->build(['payment' => $paymentDO]); static::assertEquals($expected, $actual); } diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/KountPaymentDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/KountPaymentDataBuilderTest.php index ee0907a1ddbbbb888f0161c72d378ba38b9baf5e..3737089ed175e6ad01ad559a4c26cabc26ddc5d1 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/KountPaymentDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/KountPaymentDataBuilderTest.php @@ -5,12 +5,14 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Request; +use Magento\Payment\Gateway\Data\OrderAdapterInterface; use Magento\Sales\Model\Order\Payment; use Magento\Braintree\Gateway\Config\Config; use Magento\Braintree\Observer\DataAssignObserver; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Braintree\Gateway\Request\KountPaymentDataBuilder; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class KountPaymentDataBuilderTest @@ -27,39 +29,31 @@ class KountPaymentDataBuilderTest extends \PHPUnit\Framework\TestCase private $builder; /** - * @var Config|\PHPUnit_Framework_MockObject_MockObject + * @var Config|MockObject */ - private $configMock; + private $config; /** - * @var Payment|\PHPUnit_Framework_MockObject_MockObject + * @var Payment|MockObject */ - private $paymentMock; + private $payment; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $paymentDO; - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReaderMock; - protected function setUp() { $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); - $this->configMock = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->getMock(); - $this->paymentMock = $this->getMockBuilder(Payment::class) + $this->config = $this->getMockBuilder(Config::class) ->disableOriginalConstructor() ->getMock(); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + $this->payment = $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() ->getMock(); - $this->builder = new KountPaymentDataBuilder($this->configMock, $this->subjectReaderMock); + $this->builder = new KountPaymentDataBuilder($this->config, new SubjectReader()); } /** @@ -69,15 +63,9 @@ class KountPaymentDataBuilderTest extends \PHPUnit\Framework\TestCase { $buildSubject = []; - $this->configMock->expects(static::once()) - ->method('hasFraudProtection') + $this->config->method('hasFraudProtection') ->willReturn(true); - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - $this->builder->build($buildSubject); } @@ -91,26 +79,23 @@ class KountPaymentDataBuilderTest extends \PHPUnit\Framework\TestCase KountPaymentDataBuilder::DEVICE_DATA => self::DEVICE_DATA, ]; + $order = $this->createMock(OrderAdapterInterface::class); + $this->paymentDO->method('getOrder') + ->willReturn($order); + $buildSubject = ['payment' => $this->paymentDO]; - $this->paymentMock->expects(static::exactly(count($additionalData))) + $this->payment->expects(self::exactly(count($additionalData))) ->method('getAdditionalInformation') ->willReturn($additionalData); - $this->configMock->expects(static::once()) - ->method('hasFraudProtection') + $this->config->method('hasFraudProtection') ->willReturn(true); - $this->paymentDO->expects(static::once()) - ->method('getPayment') - ->willReturn($this->paymentMock); - - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDO); + $this->paymentDO->method('getPayment') + ->willReturn($this->payment); - static::assertEquals( + self::assertEquals( $expectedResult, $this->builder->build($buildSubject) ); diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PayPal/DeviceDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PayPal/DeviceDataBuilderTest.php index fba65354d60959814cc2700ee8788c2afb4b332d..b363f2bcac673036452d92d4319a29f8683c65e6 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PayPal/DeviceDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PayPal/DeviceDataBuilderTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Request\PayPal; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\PayPal\DeviceDataBuilder; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Payment\Model\InfoInterface; @@ -16,15 +16,10 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject; */ class DeviceDataBuilderTest extends \PHPUnit\Framework\TestCase { - /** - * @var SubjectReader|MockObject - */ - private $subjectReader; - /** * @var PaymentDataObjectInterface|MockObject */ - private $paymentDataObject; + private $paymentDO; /** * @var InfoInterface|MockObject @@ -38,16 +33,10 @@ class DeviceDataBuilderTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->setMethods(['readPayment']) - ->getMock(); - - $this->paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - + $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); $this->paymentInfo = $this->createMock(InfoInterface::class); - $this->builder = new DeviceDataBuilder($this->subjectReader); + $this->builder = new DeviceDataBuilder(new SubjectReader()); } /** @@ -59,24 +48,17 @@ class DeviceDataBuilderTest extends \PHPUnit\Framework\TestCase public function testBuild(array $paymentData, array $expected) { $subject = [ - 'payment' => $this->paymentDataObject + 'payment' => $this->paymentDO ]; - $this->subjectReader->expects(static::once()) - ->method('readPayment') - ->with($subject) - ->willReturn($this->paymentDataObject); - - $this->paymentDataObject->expects(static::once()) - ->method('getPayment') + $this->paymentDO->method('getPayment') ->willReturn($this->paymentInfo); - $this->paymentInfo->expects(static::once()) - ->method('getAdditionalInformation') + $this->paymentInfo->method('getAdditionalInformation') ->willReturn($paymentData); $actual = $this->builder->build($subject); - static::assertEquals($expected, $actual); + self::assertEquals($expected, $actual); } /** diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PayPal/VaultDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PayPal/VaultDataBuilderTest.php index 8e83254727bf795c20a2bd49ab864e4a60f46991..10a96734b849aa79df526554609a1705153426d7 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PayPal/VaultDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PayPal/VaultDataBuilderTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Request\PayPal; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\PayPal\VaultDataBuilder; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Payment\Model\InfoInterface; @@ -17,15 +17,10 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject; */ class VaultDataBuilderTest extends \PHPUnit\Framework\TestCase { - /** - * @var SubjectReader|MockObject - */ - private $subjectReader; - /** * @var PaymentDataObjectInterface|MockObject */ - private $paymentDataObject; + private $paymentDO; /** * @var InfoInterface|MockObject @@ -39,16 +34,11 @@ class VaultDataBuilderTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); $this->paymentInfo = $this->createMock(InfoInterface::class); - $this->subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->setMethods(['readPayment']) - ->getMock(); - - $this->builder = new VaultDataBuilder($this->subjectReader); + $this->builder = new VaultDataBuilder(new SubjectReader()); } /** @@ -60,24 +50,17 @@ class VaultDataBuilderTest extends \PHPUnit\Framework\TestCase public function testBuild(array $additionalInfo, array $expected) { $subject = [ - 'payment' => $this->paymentDataObject + 'payment' => $this->paymentDO ]; - $this->subjectReader->expects(static::once()) - ->method('readPayment') - ->with($subject) - ->willReturn($this->paymentDataObject); - - $this->paymentDataObject->expects(static::once()) - ->method('getPayment') + $this->paymentDO->method('getPayment') ->willReturn($this->paymentInfo); - $this->paymentInfo->expects(static::once()) - ->method('getAdditionalInformation') + $this->paymentInfo->method('getAdditionalInformation') ->willReturn($additionalInfo); $actual = $this->builder->build($subject); - static::assertEquals($expected, $actual); + self::assertEquals($expected, $actual); } /** diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php index 12c613b8f216bbaf7e69d91739cecdd92894a37e..16f11559f73cc311c687da2b2ecc171658ec6883 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php @@ -6,12 +6,13 @@ namespace Magento\Braintree\Test\Unit\Gateway\Request; use Magento\Braintree\Gateway\Config\Config; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\PaymentDataBuilder; use Magento\Braintree\Observer\DataAssignObserver; use Magento\Payment\Gateway\Data\OrderAdapterInterface; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Sales\Model\Order\Payment; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class PaymentDataBuilderTest @@ -29,45 +30,37 @@ class PaymentDataBuilderTest extends \PHPUnit\Framework\TestCase private $builder; /** - * @var Config|\PHPUnit_Framework_MockObject_MockObject + * @var Config|MockObject */ - private $configMock; + private $config; /** - * @var Payment|\PHPUnit_Framework_MockObject_MockObject + * @var Payment|MockObject */ - private $paymentMock; + private $payment; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $paymentDO; /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + * @var OrderAdapterInterface|MockObject */ - private $subjectReaderMock; - - /** - * @var OrderAdapterInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $orderMock; + private $order; protected function setUp() { $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); - $this->configMock = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->getMock(); - $this->paymentMock = $this->getMockBuilder(Payment::class) + $this->config = $this->getMockBuilder(Config::class) ->disableOriginalConstructor() ->getMock(); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + $this->payment = $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() ->getMock(); - $this->orderMock = $this->createMock(OrderAdapterInterface::class); + $this->order = $this->createMock(OrderAdapterInterface::class); - $this->builder = new PaymentDataBuilder($this->configMock, $this->subjectReaderMock); + $this->builder = new PaymentDataBuilder($this->config, new SubjectReader()); } /** @@ -77,11 +70,6 @@ class PaymentDataBuilderTest extends \PHPUnit\Framework\TestCase { $buildSubject = []; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - $this->builder->build($buildSubject); } @@ -95,15 +83,6 @@ class PaymentDataBuilderTest extends \PHPUnit\Framework\TestCase 'amount' => null ]; - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDO); - $this->subjectReaderMock->expects(self::once()) - ->method('readAmount') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - $this->builder->build($buildSubject); } @@ -128,36 +107,23 @@ class PaymentDataBuilderTest extends \PHPUnit\Framework\TestCase 'amount' => 10.00 ]; - $this->paymentMock->expects(static::exactly(count($additionalData))) + $this->payment->expects(self::exactly(count($additionalData))) ->method('getAdditionalInformation') ->willReturnMap($additionalData); - $this->configMock->expects(static::once()) - ->method('getMerchantAccountId') + $this->config->method('getMerchantAccountId') ->willReturn(self::MERCHANT_ACCOUNT_ID); - $this->paymentDO->expects(static::once()) - ->method('getPayment') - ->willReturn($this->paymentMock); - - $this->paymentDO->expects(static::once()) - ->method('getOrder') - ->willReturn($this->orderMock); - - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDO); - $this->subjectReaderMock->expects(self::once()) - ->method('readAmount') - ->with($buildSubject) - ->willReturn(10.00); - - $this->orderMock->expects(static::once()) - ->method('getOrderIncrementId') + $this->paymentDO->method('getPayment') + ->willReturn($this->payment); + + $this->paymentDO->method('getOrder') + ->willReturn($this->order); + + $this->order->method('getOrderIncrementId') ->willReturn('000000101'); - static::assertEquals( + self::assertEquals( $expectedResult, $this->builder->build($buildSubject) ); diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/RefundDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/RefundDataBuilderTest.php index 5aa383d095a1e34481cdf5d4876ae675b5104131..ff4b2f4545fa66b908b341fb4e0159cdf88cd907 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/RefundDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/RefundDataBuilderTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Request; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\PaymentDataBuilder; use Magento\Braintree\Gateway\Request\RefundDataBuilder; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; @@ -14,11 +14,6 @@ use Magento\Sales\Model\Order\Payment; class RefundDataBuilderTest extends \PHPUnit\Framework\TestCase { - /** - * @var SubjectReader | \PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReader; - /** * @var RefundDataBuilder */ @@ -26,41 +21,25 @@ class RefundDataBuilderTest extends \PHPUnit\Framework\TestCase public function setUp() { - $this->subjectReader = $this->getMockBuilder( - SubjectReader::class - )->disableOriginalConstructor() - ->getMock(); - - $this->dataBuilder = new RefundDataBuilder($this->subjectReader); + $this->dataBuilder = new RefundDataBuilder(new SubjectReader()); } public function testBuild() { $paymentDO = $this->createMock(PaymentDataObjectInterface::class); - $paymentModel = $this->getMockBuilder( - Payment::class - )->disableOriginalConstructor() + $paymentModel = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() ->getMock(); $buildSubject = ['payment' => $paymentDO, 'amount' => 12.358]; $transactionId = 'xsd7n'; - $this->subjectReader->expects(static::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($paymentDO); - $paymentDO->expects(static::once()) - ->method('getPayment') + $paymentDO->method('getPayment') ->willReturn($paymentModel); - $paymentModel->expects(static::once()) - ->method('getParentTransactionId') + $paymentModel->method('getParentTransactionId') ->willReturn($transactionId); - $this->subjectReader->expects(static::once()) - ->method('readAmount') - ->with($buildSubject) - ->willReturn($buildSubject['amount']); - static::assertEquals( + self::assertEquals( [ 'transaction_id' => $transactionId, PaymentDataBuilder::AMOUNT => '12.36' @@ -72,30 +51,19 @@ class RefundDataBuilderTest extends \PHPUnit\Framework\TestCase public function testBuildNullAmount() { $paymentDO = $this->createMock(PaymentDataObjectInterface::class); - $paymentModel = $this->getMockBuilder( - Payment::class - )->disableOriginalConstructor() + $paymentModel = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() ->getMock(); $buildSubject = ['payment' => $paymentDO]; $transactionId = 'xsd7n'; - $this->subjectReader->expects(static::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($paymentDO); - $paymentDO->expects(static::once()) - ->method('getPayment') + $paymentDO->method('getPayment') ->willReturn($paymentModel); - $paymentModel->expects(static::once()) - ->method('getParentTransactionId') + $paymentModel->method('getParentTransactionId') ->willReturn($transactionId); - $this->subjectReader->expects(static::once()) - ->method('readAmount') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - static::assertEquals( + self::assertEquals( [ 'transaction_id' => $transactionId, PaymentDataBuilder::AMOUNT => null @@ -107,31 +75,20 @@ class RefundDataBuilderTest extends \PHPUnit\Framework\TestCase public function testBuildCutOffLegacyTransactionIdPostfix() { $paymentDO = $this->createMock(PaymentDataObjectInterface::class); - $paymentModel = $this->getMockBuilder( - Payment::class - )->disableOriginalConstructor() + $paymentModel = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() ->getMock(); $buildSubject = ['payment' => $paymentDO]; $legacyTxnId = 'xsd7n-' . TransactionInterface::TYPE_CAPTURE; $transactionId = 'xsd7n'; - $this->subjectReader->expects(static::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($paymentDO); - $paymentDO->expects(static::once()) - ->method('getPayment') + $paymentDO->method('getPayment') ->willReturn($paymentModel); - $paymentModel->expects(static::once()) - ->method('getParentTransactionId') + $paymentModel->method('getParentTransactionId') ->willReturn($legacyTxnId); - $this->subjectReader->expects(static::once()) - ->method('readAmount') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - static::assertEquals( + self::assertEquals( [ 'transaction_id' => $transactionId, PaymentDataBuilder::AMOUNT => null diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/SettlementDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/SettlementDataBuilderTest.php index 2f8f9542437495a30ebc886fa9a9040730af36c2..beccad6e9a045de1f18d1fb714e26c4e0293f3c3 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/SettlementDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/SettlementDataBuilderTest.php @@ -11,7 +11,7 @@ class SettlementDataBuilderTest extends \PHPUnit\Framework\TestCase { public function testBuild() { - $this->assertEquals( + self::assertEquals( [ 'options' => [ SettlementDataBuilder::SUBMIT_FOR_SETTLEMENT => true diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/ThreeDSecureDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/ThreeDSecureDataBuilderTest.php index c28ac0c3ac3722aa75ed33703a6fd9262900cc30..e2bcc2c3b39679f039748ca07821a70ecf8d0e05 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/ThreeDSecureDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/ThreeDSecureDataBuilderTest.php @@ -6,68 +6,63 @@ namespace Magento\Braintree\Test\Unit\Gateway\Request; use Magento\Braintree\Gateway\Config\Config; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\ThreeDSecureDataBuilder; -use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; -use Magento\Payment\Gateway\Data\Order\OrderAdapter; use Magento\Payment\Gateway\Data\Order\AddressAdapter; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Payment\Gateway\Data\Order\OrderAdapter; +use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class ThreeDSecureDataBuilderTest */ class ThreeDSecureDataBuilderTest extends \PHPUnit\Framework\TestCase { + /** + * @var int + */ + private static $storeId = 1; + /** * @var ThreeDSecureDataBuilder */ private $builder; /** - * @var Config|\PHPUnit_Framework_MockObject_MockObject + * @var Config|MockObject */ - private $configMock; + private $config; /** - * @var PaymentDataObjectInterface|\PHPUnit_Framework_MockObject_MockObject + * @var PaymentDataObjectInterface|MockObject */ private $paymentDO; /** - * @var OrderAdapter|\PHPUnit_Framework_MockObject_MockObject + * @var OrderAdapter|MockObject */ private $order; /** - * @var \Magento\Payment\Gateway\Data\Order\AddressAdapter|\PHPUnit_Framework_MockObject_MockObject + * @var AddressAdapter|MockObject */ private $billingAddress; - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReaderMock; - protected function setUp() { $this->initOrderMock(); $this->paymentDO = $this->getMockBuilder(PaymentDataObjectInterface::class) ->disableOriginalConstructor() - ->setMethods(['getOrder', 'getPayment']) ->getMock(); - $this->paymentDO->expects(static::once()) - ->method('getOrder') + $this->paymentDO->method('getOrder') ->willReturn($this->order); - $this->configMock = $this->getMockBuilder(Config::class) - ->setMethods(['isVerify3DSecure', 'getThresholdAmount', 'get3DSecureSpecificCountries']) - ->disableOriginalConstructor() - ->getMock(); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + $this->config = $this->getMockBuilder(Config::class) ->disableOriginalConstructor() ->getMock(); - $this->builder = new ThreeDSecureDataBuilder($this->configMock, $this->subjectReaderMock); + $this->builder = new ThreeDSecureDataBuilder($this->config, new SubjectReader()); } /** @@ -76,7 +71,6 @@ class ThreeDSecureDataBuilderTest extends \PHPUnit\Framework\TestCase * @param string $countryId * @param array $countries * @param array $expected - * @covers \Magento\Braintree\Gateway\Request\ThreeDSecureDataBuilder::build * @dataProvider buildDataProvider */ public function testBuild($verify, $thresholdAmount, $countryId, array $countries, array $expected) @@ -86,37 +80,28 @@ class ThreeDSecureDataBuilderTest extends \PHPUnit\Framework\TestCase 'amount' => 25 ]; - $this->configMock->expects(static::once()) - ->method('isVerify3DSecure') + $this->config->method('isVerify3DSecure') + ->with(self::equalTo(self::$storeId)) ->willReturn($verify); - $this->configMock->expects(static::any()) - ->method('getThresholdAmount') + $this->config->method('getThresholdAmount') + ->with(self::equalTo(self::$storeId)) ->willReturn($thresholdAmount); - $this->configMock->expects(static::any()) - ->method('get3DSecureSpecificCountries') + $this->config->method('get3DSecureSpecificCountries') + ->with(self::equalTo(self::$storeId)) ->willReturn($countries); - $this->billingAddress->expects(static::any()) - ->method('getCountryId') + $this->billingAddress->method('getCountryId') ->willReturn($countryId); - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDO); - $this->subjectReaderMock->expects(self::once()) - ->method('readAmount') - ->with($buildSubject) - ->willReturn(25); - $result = $this->builder->build($buildSubject); - static::assertEquals($expected, $result); + self::assertEquals($expected, $result); } /** - * Get list of variations for build test + * Gets list of variations to build request data. + * * @return array */ public function buildDataProvider() @@ -144,22 +129,21 @@ class ThreeDSecureDataBuilderTest extends \PHPUnit\Framework\TestCase } /** - * Create mock object for order adapter + * Creates mock object for order adapter. */ private function initOrderMock() { $this->billingAddress = $this->getMockBuilder(AddressAdapter::class) ->disableOriginalConstructor() - ->setMethods(['getCountryId']) ->getMock(); $this->order = $this->getMockBuilder(OrderAdapter::class) ->disableOriginalConstructor() - ->setMethods(['getBillingAddress']) ->getMock(); - $this->order->expects(static::any()) - ->method('getBillingAddress') + $this->order->method('getBillingAddress') ->willReturn($this->billingAddress); + $this->order->method('getStoreId') + ->willReturn(self::$storeId); } } diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php index df11938ddba7047728c710be96f1ca0488b5b794..5af050002eb2debeefe73426f2638d450c5626d4 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php @@ -5,12 +5,13 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Request; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Request\VaultCaptureDataBuilder; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Sales\Api\Data\OrderPaymentExtension; use Magento\Sales\Model\Order\Payment; use Magento\Vault\Model\PaymentToken; +use PHPUnit_Framework_MockObject_MockObject as MockObject; class VaultCaptureDataBuilderTest extends \PHPUnit\Framework\TestCase { @@ -20,35 +21,25 @@ class VaultCaptureDataBuilderTest extends \PHPUnit\Framework\TestCase private $builder; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var PaymentDataObjectInterface|MockObject */ private $paymentDO; /** - * @var Payment|\PHPUnit_Framework_MockObject_MockObject + * @var Payment|MockObject */ private $payment; - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReader; - public function setUp() { $this->paymentDO = $this->createMock(PaymentDataObjectInterface::class); $this->payment = $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() ->getMock(); - $this->paymentDO->expects(static::once()) - ->method('getPayment') + $this->paymentDO->method('getPayment') ->willReturn($this->payment); - $this->subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->builder = new VaultCaptureDataBuilder($this->subjectReader); + $this->builder = new VaultCaptureDataBuilder(new SubjectReader()); } /** @@ -68,15 +59,6 @@ class VaultCaptureDataBuilderTest extends \PHPUnit\Framework\TestCase 'paymentMethodToken' => $token ]; - $this->subjectReader->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDO); - $this->subjectReader->expects(self::once()) - ->method('readAmount') - ->with($buildSubject) - ->willReturn($amount); - $paymentExtension = $this->getMockBuilder(OrderPaymentExtension::class) ->setMethods(['getVaultPaymentToken']) ->disableOriginalConstructor() @@ -86,18 +68,15 @@ class VaultCaptureDataBuilderTest extends \PHPUnit\Framework\TestCase ->disableOriginalConstructor() ->getMock(); - $paymentExtension->expects(static::once()) - ->method('getVaultPaymentToken') + $paymentExtension->method('getVaultPaymentToken') ->willReturn($paymentToken); - $this->payment->expects(static::once()) - ->method('getExtensionAttributes') + $this->payment->method('getExtensionAttributes') ->willReturn($paymentExtension); - $paymentToken->expects(static::once()) - ->method('getGatewayToken') + $paymentToken->method('getGatewayToken') ->willReturn($token); $result = $this->builder->build($buildSubject); - static::assertEquals($expected, $result); + self::assertEquals($expected, $result); } } diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultDataBuilderTest.php index 08b5526daeb04ef64cea6cbcf24f7749fd0be0a5..c4bd047a06bb8b64e5f007ea948780dcb89be79a 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultDataBuilderTest.php @@ -20,7 +20,7 @@ class VaultDataBuilderTest extends \PHPUnit\Framework\TestCase $buildSubject = []; $builder = new VaultDataBuilder(); - static::assertEquals( + self::assertEquals( $expectedResult, $builder->build($buildSubject) ); diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/CardDetailsHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/CardDetailsHandlerTest.php index 87e8e4e413c1bcc5ff1dda38f6598b54dc44950a..525b474040ea4ddb3fa37cf10deea03630251e98 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/CardDetailsHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/CardDetailsHandlerTest.php @@ -11,7 +11,7 @@ use Magento\Braintree\Gateway\Response\CardDetailsHandler; use Magento\Payment\Gateway\Data\PaymentDataObject; use Magento\Sales\Model\Order\Payment; use Magento\Braintree\Gateway\Config\Config; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; /** * Class CardDetailsHandlerTest diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PayPal/VaultDetailsHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PayPal/VaultDetailsHandlerTest.php index fdf3dc941bd776217d6830f4be92ac7ba49a21a6..0a3a9f2918a2181d124581eb118db2502cb59252 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PayPal/VaultDetailsHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PayPal/VaultDetailsHandlerTest.php @@ -7,7 +7,7 @@ namespace Magento\Braintree\Test\Unit\Gateway\Response\PayPal; use Braintree\Transaction; use Braintree\Transaction\PayPalDetails; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Response\PayPal\VaultDetailsHandler; use Magento\Framework\Intl\DateTimeFactory; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PayPalDetailsHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PayPalDetailsHandlerTest.php index f1420ee895e5b7cb76e471c04a8690fd88af7f47..341135b6c03d0fa09ba472743d37ebd56bdd5f06 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PayPalDetailsHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PayPalDetailsHandlerTest.php @@ -10,7 +10,7 @@ use Magento\Braintree\Gateway\Response\PayPalDetailsHandler; use Magento\Payment\Gateway\Data\PaymentDataObject; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Payment; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use PHPUnit_Framework_MockObject_MockObject as MockObject; /** diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PaymentDetailsHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PaymentDetailsHandlerTest.php index d90caa84b447b110d0d43f02a7e7a7161c9c0a8e..f941b8d7245d13ed0115256938ef62e06616e01e 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PaymentDetailsHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/PaymentDetailsHandlerTest.php @@ -10,7 +10,7 @@ use Magento\Braintree\Gateway\Response\PaymentDetailsHandler; use Magento\Payment\Gateway\Data\PaymentDataObject; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Payment; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use PHPUnit_Framework_MockObject_MockObject as MockObject; /** diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/RiskDataHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/RiskDataHandlerTest.php index 2365c396c2f4a99934a807b6752ec278f2e4613a..374925b7339c0216537982b10b4a524e918fe2a2 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/RiskDataHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/RiskDataHandlerTest.php @@ -6,7 +6,7 @@ namespace Magento\Braintree\Test\Unit\Gateway\Response; use Braintree\Transaction; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Response\RiskDataHandler; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Sales\Model\Order\Payment; diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/ThreeDSecureDetailsHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/ThreeDSecureDetailsHandlerTest.php index 9ca9ca6aa07ae67217b5e76a167abda31dfaf464..6cffc00a89c418de24acb69bd1f7009560b333d7 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/ThreeDSecureDetailsHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/ThreeDSecureDetailsHandlerTest.php @@ -10,7 +10,7 @@ use Magento\Braintree\Gateway\Response\ThreeDSecureDetailsHandler; use Magento\Payment\Gateway\Data\PaymentDataObject; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Payment; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use PHPUnit_Framework_MockObject_MockObject as MockObject; /** diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/TransactionIdHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/TransactionIdHandlerTest.php index 3a2d2f7073573f8bb942479940a27cb1f848bddf..6cbca707242f18790ba3ea25bb43e63d9984ca38 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/TransactionIdHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/TransactionIdHandlerTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Response; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Response\TransactionIdHandler; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Sales\Model\Order\Payment; diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/VaultDetailsHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/VaultDetailsHandlerTest.php index fb8f507bf1214260735ec49831ad28f4485e5ed7..568593273c58cbd29fe11975137bacadf4d000f1 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/VaultDetailsHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/VaultDetailsHandlerTest.php @@ -8,7 +8,7 @@ namespace Magento\Braintree\Test\Unit\Gateway\Response; use Braintree\Transaction; use Braintree\Transaction\CreditCardDetails; use Magento\Braintree\Gateway\Config\Config; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Response\VaultDetailsHandler; use Magento\Framework\DataObject; use Magento\Payment\Gateway\Data\PaymentDataObject; diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/VoidHandlerTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/VoidHandlerTest.php index 398349a9692b7c6f81498775271a3056771e91a8..a541b0115fe63c5c741a7369d090e51c83675c48 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Response/VoidHandlerTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Response/VoidHandlerTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Braintree\Test\Unit\Gateway\Response; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use Magento\Braintree\Gateway\Response\VoidHandler; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; use Magento\Sales\Model\Order\Payment; diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php index 1a9e547e9063600caa7f50646fb8e8f411da5d05..c8a46da504fef158a4a3d56137dc7d6debb3cc9f 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php @@ -10,7 +10,7 @@ use Magento\Framework\Phrase; use Magento\Payment\Gateway\Validator\ResultInterface; use Magento\Payment\Gateway\Validator\ResultInterfaceFactory; use Magento\Braintree\Gateway\Validator\GeneralResponseValidator; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; class GeneralResponseValidatorTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/PaymentNonceResponseValidatorTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/PaymentNonceResponseValidatorTest.php index 294226b1656ecbfdd96b79576be1157fbf1d5ae5..03363b5463d78dd8f4774da5d8c54e96a68e65d5 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/PaymentNonceResponseValidatorTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/PaymentNonceResponseValidatorTest.php @@ -9,7 +9,7 @@ use Braintree\Transaction; use Magento\Braintree\Gateway\Validator\PaymentNonceResponseValidator; use Magento\Payment\Gateway\Validator\ResultInterface; use Magento\Payment\Gateway\Validator\ResultInterfaceFactory; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; /** * Class PaymentNonceResponseValidatorTest diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/ResponseValidatorTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/ResponseValidatorTest.php index aeb9b4a83077c3a1d73d70d116a84286a2ff1bea..4bd446079f9a70243944215ad450fede859cb59e 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/ResponseValidatorTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Validator/ResponseValidatorTest.php @@ -10,7 +10,7 @@ use Magento\Framework\Phrase; use Magento\Payment\Gateway\Validator\ResultInterface; use Magento\Payment\Gateway\Validator\ResultInterfaceFactory; use Magento\Braintree\Gateway\Validator\ResponseValidator; -use Magento\Braintree\Gateway\Helper\SubjectReader; +use Magento\Braintree\Gateway\SubjectReader; use PHPUnit_Framework_MockObject_MockObject as MockObject; use Braintree\Result\Error; use Braintree\Result\Successful; diff --git a/app/code/Magento/Braintree/Test/Unit/Model/Report/TransactionsCollectionTest.php b/app/code/Magento/Braintree/Test/Unit/Model/Report/TransactionsCollectionTest.php index e43e67c18744f27308ff006c685b179508f97560..5fcb6a89244b5e4286855ec79a466113f557df99 100644 --- a/app/code/Magento/Braintree/Test/Unit/Model/Report/TransactionsCollectionTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Model/Report/TransactionsCollectionTest.php @@ -6,10 +6,12 @@ namespace Magento\Braintree\Test\Unit\Model\Report; use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Braintree\Model\Report\FilterMapper; use Magento\Braintree\Model\Report\TransactionsCollection; use Magento\Framework\Api\Search\DocumentInterface; use Magento\Framework\Data\Collection\EntityFactoryInterface; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class TransactionsCollectionTest @@ -19,48 +21,58 @@ use Magento\Framework\Data\Collection\EntityFactoryInterface; class TransactionsCollectionTest extends \PHPUnit\Framework\TestCase { /** - * @var BraintreeAdapter|\PHPUnit_Framework_MockObject_MockObject + * @var BraintreeAdapter|MockObject */ - private $braintreeAdapterMock; + private $braintreeAdapter; /** - * @var EntityFactoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var BraintreeAdapterFactory|MockObject */ - private $entityFactoryMock; + private $adapterFactory; /** - * @var FilterMapper|\PHPUnit_Framework_MockObject_MockObject + * @var EntityFactoryInterface|MockObject */ - private $filterMapperMock; + private $entityFactory; /** - * @var DocumentInterface|\PHPUnit_Framework_MockObject_MockObject + * @var FilterMapper|MockObject */ - private $transactionMapMock; + private $filterMapper; + + /** + * @var DocumentInterface|MockObject + */ + private $transactionMap; /** * Setup */ protected function setUp() { - $this->transactionMapMock = $this->getMockBuilder(DocumentInterface::class) + $this->transactionMap = $this->getMockBuilder(DocumentInterface::class) ->disableOriginalConstructor() ->getMock(); - $this->entityFactoryMock = $this->getMockBuilder(EntityFactoryInterface::class) + $this->entityFactory = $this->getMockBuilder(EntityFactoryInterface::class) ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); - $this->filterMapperMock = $this->getMockBuilder(FilterMapper::class) + $this->filterMapper = $this->getMockBuilder(FilterMapper::class) ->setMethods(['getFilter']) ->disableOriginalConstructor() ->getMock(); - $this->braintreeAdapterMock = $this->getMockBuilder(BraintreeAdapter::class) + $this->braintreeAdapter = $this->getMockBuilder(BraintreeAdapter::class) ->setMethods(['search']) ->disableOriginalConstructor() ->getMock(); + $this->adapterFactory = $this->getMockBuilder(BraintreeAdapterFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->adapterFactory->method('create') + ->willReturn($this->braintreeAdapter); } /** @@ -68,28 +80,26 @@ class TransactionsCollectionTest extends \PHPUnit\Framework\TestCase */ public function testGetItems() { - $this->filterMapperMock->expects($this->once()) - ->method('getFilter') + $this->filterMapper->method('getFilter') ->willReturn(new BraintreeSearchNodeStub()); - $this->braintreeAdapterMock->expects($this->once()) - ->method('search') + $this->braintreeAdapter->method('search') ->willReturn(['transaction1', 'transaction2']); - $this->entityFactoryMock->expects($this->exactly(2)) + $this->entityFactory->expects(self::exactly(2)) ->method('create') - ->willReturn($this->transactionMapMock); + ->willReturn($this->transactionMap); $collection = new TransactionsCollection( - $this->entityFactoryMock, - $this->braintreeAdapterMock, - $this->filterMapperMock + $this->entityFactory, + $this->adapterFactory, + $this->filterMapper ); $collection->addFieldToFilter('orderId', ['like' => '0']); $items = $collection->getItems(); - $this->assertEquals(2, count($items)); - $this->assertInstanceOf(DocumentInterface::class, $items[1]); + self::assertEquals(2, count($items)); + self::assertInstanceOf(DocumentInterface::class, $items[1]); } /** @@ -97,27 +107,25 @@ class TransactionsCollectionTest extends \PHPUnit\Framework\TestCase */ public function testGetItemsEmptyCollection() { - $this->filterMapperMock->expects($this->once()) - ->method('getFilter') + $this->filterMapper->method('getFilter') ->willReturn(new BraintreeSearchNodeStub()); - $this->braintreeAdapterMock->expects($this->once()) - ->method('search') + $this->braintreeAdapter->method('search') ->willReturn(null); - $this->entityFactoryMock->expects($this->never()) + $this->entityFactory->expects(self::never()) ->method('create') - ->willReturn($this->transactionMapMock); + ->willReturn($this->transactionMap); $collection = new TransactionsCollection( - $this->entityFactoryMock, - $this->braintreeAdapterMock, - $this->filterMapperMock + $this->entityFactory, + $this->adapterFactory, + $this->filterMapper ); $collection->addFieldToFilter('orderId', ['like' => '0']); $items = $collection->getItems(); - $this->assertEquals(0, count($items)); + self::assertEquals(0, count($items)); } /** @@ -127,29 +135,27 @@ class TransactionsCollectionTest extends \PHPUnit\Framework\TestCase { $transations = range(1, TransactionsCollection::TRANSACTION_MAXIMUM_COUNT + 10); - $this->filterMapperMock->expects($this->once()) - ->method('getFilter') + $this->filterMapper->method('getFilter') ->willReturn(new BraintreeSearchNodeStub()); - $this->braintreeAdapterMock->expects($this->once()) - ->method('search') + $this->braintreeAdapter->method('search') ->willReturn($transations); - $this->entityFactoryMock->expects($this->exactly(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT)) + $this->entityFactory->expects(self::exactly(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT)) ->method('create') - ->willReturn($this->transactionMapMock); + ->willReturn($this->transactionMap); $collection = new TransactionsCollection( - $this->entityFactoryMock, - $this->braintreeAdapterMock, - $this->filterMapperMock + $this->entityFactory, + $this->adapterFactory, + $this->filterMapper ); $collection->setPageSize(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT); $collection->addFieldToFilter('orderId', ['like' => '0']); $items = $collection->getItems(); - $this->assertEquals(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT, count($items)); - $this->assertInstanceOf(DocumentInterface::class, $items[1]); + self::assertEquals(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT, count($items)); + self::assertInstanceOf(DocumentInterface::class, $items[1]); } /** @@ -159,29 +165,27 @@ class TransactionsCollectionTest extends \PHPUnit\Framework\TestCase { $transations = range(1, TransactionsCollection::TRANSACTION_MAXIMUM_COUNT + 10); - $this->filterMapperMock->expects($this->once()) - ->method('getFilter') + $this->filterMapper->method('getFilter') ->willReturn(new BraintreeSearchNodeStub()); - $this->braintreeAdapterMock->expects($this->once()) - ->method('search') + $this->braintreeAdapter->method('search') ->willReturn($transations); - $this->entityFactoryMock->expects($this->exactly(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT)) + $this->entityFactory->expects(self::exactly(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT)) ->method('create') - ->willReturn($this->transactionMapMock); + ->willReturn($this->transactionMap); $collection = new TransactionsCollection( - $this->entityFactoryMock, - $this->braintreeAdapterMock, - $this->filterMapperMock + $this->entityFactory, + $this->adapterFactory, + $this->filterMapper ); $collection->setPageSize(null); $collection->addFieldToFilter('orderId', ['like' => '0']); $items = $collection->getItems(); - $this->assertEquals(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT, count($items)); - $this->assertInstanceOf(DocumentInterface::class, $items[1]); + self::assertEquals(TransactionsCollection::TRANSACTION_MAXIMUM_COUNT, count($items)); + self::assertInstanceOf(DocumentInterface::class, $items[1]); } /** @@ -191,18 +195,18 @@ class TransactionsCollectionTest extends \PHPUnit\Framework\TestCase */ public function testAddToFilter($field, $condition, $filterMapperCall, $expectedCondition) { - $this->filterMapperMock->expects(static::exactly($filterMapperCall)) + $this->filterMapper->expects(self::exactly($filterMapperCall)) ->method('getFilter') ->with($field, $expectedCondition) ->willReturn(new BraintreeSearchNodeStub()); $collection = new TransactionsCollection( - $this->entityFactoryMock, - $this->braintreeAdapterMock, - $this->filterMapperMock + $this->entityFactory, + $this->adapterFactory, + $this->filterMapper ); - static::assertInstanceOf( + self::assertInstanceOf( TransactionsCollection::class, $collection->addFieldToFilter($field, $condition) ); diff --git a/app/code/Magento/Braintree/Test/Unit/Model/Ui/ConfigProviderTest.php b/app/code/Magento/Braintree/Test/Unit/Model/Ui/ConfigProviderTest.php index 6c85ae68eb7aff9c72550fb58860750e3a25a0ae..dca22c26c11da360360b8abfd37e285ee9c34452 100644 --- a/app/code/Magento/Braintree/Test/Unit/Model/Ui/ConfigProviderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Model/Ui/ConfigProviderTest.php @@ -7,7 +7,9 @@ namespace Magento\Braintree\Test\Unit\Model\Ui; use Magento\Braintree\Gateway\Config\Config; use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; use Magento\Braintree\Model\Ui\ConfigProvider; +use Magento\Customer\Model\Session; use PHPUnit_Framework_MockObject_MockObject as MockObject; /** @@ -31,6 +33,11 @@ class ConfigProviderTest extends \PHPUnit\Framework\TestCase */ private $braintreeAdapter; + /** + * @var Session|MockObject + */ + private $session; + /** * @var ConfigProvider */ @@ -45,10 +52,24 @@ class ConfigProviderTest extends \PHPUnit\Framework\TestCase $this->braintreeAdapter = $this->getMockBuilder(BraintreeAdapter::class) ->disableOriginalConstructor() ->getMock(); + /** @var BraintreeAdapterFactory|MockObject $adapterFactory */ + $adapterFactory = $this->getMockBuilder(BraintreeAdapterFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $adapterFactory->method('create') + ->willReturn($this->braintreeAdapter); + + $this->session = $this->getMockBuilder(Session::class) + ->disableOriginalConstructor() + ->setMethods(['getStoreId']) + ->getMock(); + $this->session->method('getStoreId') + ->willReturn(null); $this->configProvider = new ConfigProvider( $this->config, - $this->braintreeAdapter + $adapterFactory, + $this->session ); } @@ -61,35 +82,30 @@ class ConfigProviderTest extends \PHPUnit\Framework\TestCase */ public function testGetConfig($config, $expected) { - $this->braintreeAdapter->expects(static::once()) - ->method('generate') + $this->braintreeAdapter->method('generate') ->willReturn(self::CLIENT_TOKEN); foreach ($config as $method => $value) { - $this->config->expects(static::once()) - ->method($method) + $this->config->method($method) ->willReturn($value); } - static::assertEquals($expected, $this->configProvider->getConfig()); + self::assertEquals($expected, $this->configProvider->getConfig()); } /** - * @covers \Magento\Braintree\Model\Ui\ConfigProvider::getClientToken * @dataProvider getClientTokenDataProvider */ public function testGetClientToken($merchantAccountId, $params) { - $this->config->expects(static::once()) - ->method('getMerchantAccountId') + $this->config->method('getMerchantAccountId') ->willReturn($merchantAccountId); - $this->braintreeAdapter->expects(static::once()) - ->method('generate') + $this->braintreeAdapter->method('generate') ->with($params) ->willReturn(self::CLIENT_TOKEN); - static::assertEquals(self::CLIENT_TOKEN, $this->configProvider->getClientToken()); + self::assertEquals(self::CLIENT_TOKEN, $this->configProvider->getClientToken()); } /** diff --git a/app/code/Magento/Braintree/composer.json b/app/code/Magento/Braintree/composer.json index 64d2e1950825fc305c7a5b9d142f4e84f18ab6c5..0248a62ccfbb2476f07dcec730edada1ed38374d 100644 --- a/app/code/Magento/Braintree/composer.json +++ b/app/code/Magento/Braintree/composer.json @@ -25,7 +25,7 @@ "magento/module-theme": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "proprietary" ], diff --git a/app/code/Magento/Braintree/etc/adminhtml/di.xml b/app/code/Magento/Braintree/etc/adminhtml/di.xml index d0469ded83b67bebd4c875c1bedd3a223647ba0b..90fc927ed4f8026e6ee86fe22ec523a6eb3f69bf 100644 --- a/app/code/Magento/Braintree/etc/adminhtml/di.xml +++ b/app/code/Magento/Braintree/etc/adminhtml/di.xml @@ -28,6 +28,7 @@ <item name="address" xsi:type="string">Magento\Braintree\Gateway\Request\AddressDataBuilder</item> <item name="vault" xsi:type="string">Magento\Braintree\Gateway\Request\VaultDataBuilder</item> <item name="dynamic_descriptor" xsi:type="string">Magento\Braintree\Gateway\Request\DescriptorDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> </argument> </arguments> </virtualType> @@ -39,6 +40,7 @@ <item name="channel" xsi:type="string">Magento\Braintree\Gateway\Request\ChannelDataBuilder</item> <item name="address" xsi:type="string">Magento\Braintree\Gateway\Request\AddressDataBuilder</item> <item name="dynamic_descriptor" xsi:type="string">Magento\Braintree\Gateway\Request\DescriptorDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> </argument> </arguments> </virtualType> @@ -57,4 +59,9 @@ <argument name="session" xsi:type="object">Magento\Backend\Model\Session\Quote</argument> </arguments> </type> + <type name="Magento\Braintree\Model\Ui\ConfigProvider"> + <arguments> + <argument name="session" xsi:type="object">Magento\Backend\Model\Session\Quote</argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Braintree/etc/di.xml b/app/code/Magento/Braintree/etc/di.xml index 2a451e132eab0e5e69efdc656826327a8109c2c1..86c291181575437012da6db8ef0b2601eddd66bd 100644 --- a/app/code/Magento/Braintree/etc/di.xml +++ b/app/code/Magento/Braintree/etc/di.xml @@ -214,6 +214,7 @@ <item name="3dsecure" xsi:type="string">Magento\Braintree\Gateway\Request\ThreeDSecureDataBuilder</item> <item name="device_data" xsi:type="string">Magento\Braintree\Gateway\Request\KountPaymentDataBuilder</item> <item name="dynamic_descriptor" xsi:type="string">Magento\Braintree\Gateway\Request\DescriptorDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> </argument> </arguments> </virtualType> @@ -245,6 +246,7 @@ <arguments> <argument name="builders" xsi:type="array"> <item name="capture" xsi:type="string">Magento\Braintree\Gateway\Request\CaptureDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> </argument> </arguments> </virtualType> @@ -268,6 +270,7 @@ <item name="3dsecure" xsi:type="string">Magento\Braintree\Gateway\Request\ThreeDSecureDataBuilder</item> <item name="device_data" xsi:type="string">Magento\Braintree\Gateway\Request\KountPaymentDataBuilder</item> <item name="dynamic_descriptor" xsi:type="string">Magento\Braintree\Gateway\Request\DescriptorDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> </argument> </arguments> </virtualType> @@ -300,6 +303,7 @@ <argument name="builders" xsi:type="array"> <item name="vault_capture" xsi:type="string">Magento\Braintree\Gateway\Request\VaultCaptureDataBuilder</item> <item name="settlement" xsi:type="string">Magento\Braintree\Gateway\Request\SettlementDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> </argument> </arguments> </virtualType> @@ -321,6 +325,7 @@ <item name="vault" xsi:type="string">Magento\Braintree\Gateway\Request\PayPal\VaultDataBuilder</item> <item name="device_data" xsi:type="string">Magento\Braintree\Gateway\Request\PayPal\DeviceDataBuilder</item> <item name="dynamic_descriptor" xsi:type="string">Magento\Braintree\Gateway\Request\DescriptorDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> </argument> </arguments> </virtualType> @@ -353,6 +358,7 @@ <item name="channel" xsi:type="string">Magento\Braintree\Gateway\Request\ChannelDataBuilder</item> <item name="address" xsi:type="string">Magento\Braintree\Gateway\Request\AddressDataBuilder</item> <item name="dynamic_descriptor" xsi:type="string">Magento\Braintree\Gateway\Request\DescriptorDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> </argument> </arguments> </virtualType> @@ -463,23 +469,41 @@ <virtualType name="BraintreeVoidCommand" type="Magento\Payment\Gateway\Command\GatewayCommand"> <arguments> <argument name="client" xsi:type="object">Magento\Braintree\Gateway\Http\Client\TransactionVoid</argument> - <argument name="requestBuilder" xsi:type="object">Magento\Braintree\Gateway\Request\VoidDataBuilder</argument> + <argument name="requestBuilder" xsi:type="object">BraintreeVoidRequestBuilder</argument> <argument name="handler" xsi:type="object">Magento\Braintree\Gateway\Response\VoidHandler</argument> <argument name="validator" xsi:type="object">Magento\Braintree\Gateway\Validator\GeneralResponseValidator</argument> <argument name="transferFactory" xsi:type="object">Magento\Braintree\Gateway\Http\TransferFactory</argument> </arguments> </virtualType> + <virtualType name="BraintreeVoidRequestBuilder" type="Magento\Payment\Gateway\Request\BuilderComposite"> + <arguments> + <argument name="builders" xsi:type="array"> + <item name="void" xsi:type="string">Magento\Braintree\Gateway\Request\VoidDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> + </argument> + </arguments> + </virtualType> + <!-- END Void Command --> <!-- Refund Command --> <virtualType name="BraintreeRefundCommand" type="Magento\Payment\Gateway\Command\GatewayCommand"> <arguments> <argument name="client" xsi:type="object">Magento\Braintree\Gateway\Http\Client\TransactionRefund</argument> - <argument name="requestBuilder" xsi:type="object">Magento\Braintree\Gateway\Request\RefundDataBuilder</argument> + <argument name="requestBuilder" xsi:type="object">BraintreeRefundBuilder</argument> <argument name="validator" xsi:type="object">Magento\Braintree\Gateway\Validator\GeneralResponseValidator</argument> <argument name="handler" xsi:type="object">Magento\Braintree\Gateway\Response\RefundHandler</argument> <argument name="transferFactory" xsi:type="object">Magento\Braintree\Gateway\Http\TransferFactory</argument> </arguments> </virtualType> + <virtualType name="BraintreeRefundBuilder" type="Magento\Payment\Gateway\Request\BuilderComposite"> + <arguments> + <argument name="builders" xsi:type="array"> + <item name="refund" xsi:type="string">Magento\Braintree\Gateway\Request\RefundDataBuilder</item> + <item name="store" xsi:type="string">Magento\Braintree\Gateway\Request\StoreConfigBuilder</item> + </argument> + </arguments> + </virtualType> + <!-- END Refund Command --> <!-- Braintree validators infrastructure --> <virtualType name="BraintreeCountryValidator" type="Magento\Payment\Gateway\Validator\CountryValidator"> @@ -494,7 +518,7 @@ </argument> </arguments> </virtualType> - <!-- Braintree validators infrastructure --> + <!-- END Braintree validators infrastructure --> <!-- Braintree PayPal validators --> <virtualType name="BraintreePayPalCountryValidator" type="Magento\Payment\Gateway\Validator\CountryValidator"> diff --git a/app/code/Magento/Braintree/view/adminhtml/web/js/braintree.js b/app/code/Magento/Braintree/view/adminhtml/web/js/braintree.js index 8324cfe463bdb78d7caf8eb88e4a61f2a91c3965..5e1e85e6a3c481aabcb5f6cf15536b0cd64c3ae9 100644 --- a/app/code/Magento/Braintree/view/adminhtml/web/js/braintree.js +++ b/app/code/Magento/Braintree/view/adminhtml/web/js/braintree.js @@ -116,7 +116,7 @@ define([ }, /** - * Setup Braintree SDK + * Retrieves client token and setup Braintree SDK */ initBraintree: function () { var self = this; @@ -124,35 +124,14 @@ define([ try { $('body').trigger('processStart'); - self.braintree.setup(self.clientToken, 'custom', { - id: self.selector, - hostedFields: self.getHostedFields(), - - /** - * Triggered when sdk was loaded - */ - onReady: function () { - $('body').trigger('processStop'); - }, + $.getJSON(self.clientTokenUrl).done(function (response) { + self.clientToken = response.clientToken; + self._initBraintree(); + }).fail(function (response) { + var failed = JSON.parse(response.responseText); - /** - * Callback for success response - * @param {Object} response - */ - onPaymentMethodReceived: function (response) { - if (self.validateCardType()) { - self.setPaymentDetails(response.nonce); - self.placeOrder(); - } - }, - - /** - * Error callback - * @param {Object} response - */ - onError: function (response) { - self.error(response.message); - } + $('body').trigger('processStop'); + self.error(failed.message); }); } catch (e) { $('body').trigger('processStop'); @@ -160,6 +139,44 @@ define([ } }, + /** + * Setup Braintree SDK + */ + _initBraintree: function () { + var self = this; + + self.braintree.setup(self.clientToken, 'custom', { + id: self.selector, + hostedFields: self.getHostedFields(), + + /** + * Triggered when sdk was loaded + */ + onReady: function () { + $('body').trigger('processStop'); + }, + + /** + * Callback for success response + * @param {Object} response + */ + onPaymentMethodReceived: function (response) { + if (self.validateCardType()) { + self.setPaymentDetails(response.nonce); + self.placeOrder(); + } + }, + + /** + * Error callback + * @param {Object} response + */ + onError: function (response) { + self.error(response.message); + } + }); + }, + /** * Get hosted fields configuration * @returns {Object} diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json index 39b5fe1b1a6d5c009b4cdd58b2b587842f57862f..0983d4c6b5946787f9937567f6654840d6ddd9b1 100644 --- a/app/code/Magento/Bundle/composer.json +++ b/app/code/Magento/Bundle/composer.json @@ -25,7 +25,7 @@ "magento/module-bundle-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php index ae0c3554c0d32547fd0f2cc540405eb8dd04f7cb..e61acc2aa09e5cb8fe15ff601d241886f397a438 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php @@ -52,7 +52,6 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio * @param \Magento\Framework\Indexer\BatchSizeManagementInterface|null $batchSizeManagement * @param \Magento\Framework\Indexer\BatchProviderInterface|null $batchProvider * @param \Magento\Framework\EntityManager\MetadataPool|null $metadataPool - * @param \Magento\Indexer\Model\Indexer\StateFactory|null $stateFactory * @param int|null $batchRowsCount * @param ActiveTableSwitcher|null $activeTableSwitcher */ @@ -87,6 +86,20 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio $this->activeTableSwitcher = $activeTableSwitcher ?: $objectManager->get(ActiveTableSwitcher::class); } + /** + * Clear the table we'll be writing de-normalized data into + * to prevent archived data getting in the way of actual data. + * + * @return void + */ + private function clearCurrentTable() + { + $this->connection->delete( + $this->activeTableSwitcher + ->getAdditionalTableName($this->getMainTable()) + ); + } + /** * Refresh entities index * @@ -94,6 +107,7 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio */ public function execute() { + $this->clearCurrentTable(); $this->reindex(); $this->activeTableSwitcher->switchTable($this->connection, [$this->getMainTable()]); return $this; @@ -103,6 +117,7 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio * Return select for remove unnecessary data * * @return \Magento\Framework\DB\Select + * @deprecated 102.0.1 Not needed anymore. */ protected function getSelectUnnecessaryData() { @@ -127,12 +142,15 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio * Remove unnecessary data * * @return void + * + * @deprecated 102.0.1 Not needed anymore. */ protected function removeUnnecessaryData() { - $this->connection->query( - $this->connection->deleteFromSelect($this->getSelectUnnecessaryData(), $this->getMainTable()) - ); + //Called for backwards compatibility. + $this->getSelectUnnecessaryData(); + //This method is useless, + //left it here just in case somebody's using it in child classes. } /** 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 05dd94dbe6e578c8c87fde185549dada98b48fc8..fbe0d4b550fa671288001e27e4c1d95956430859 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php @@ -179,6 +179,11 @@ class FlatTableBuilder $columnComment = isset($fieldProp['comment']) ? $fieldProp['comment'] : $fieldName; + if ($fieldName == 'created_at') { + $columnDefinition['nullable'] = true; + $columnDefinition['default'] = null; + } + $table->addColumn($fieldName, $fieldProp['type'], $columnLength, $columnDefinition, $columnComment); } diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json index 5cdf62cdb34052e7142875300b8078087c555ad1..10b408c5458780245fde6ab32a77cccd2618be8c 100644 --- a/app/code/Magento/Catalog/composer.json +++ b/app/code/Magento/Catalog/composer.json @@ -34,7 +34,7 @@ "magento/module-catalog-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "102.0.0", + "version": "102.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogAnalytics/composer.json b/app/code/Magento/CatalogAnalytics/composer.json index 6cda52197f80a0ccb9fd5d7f4fc61c7ac0013f1c..7c622f6fbfa078366f811755a051ed1e07693e95 100644 --- a/app/code/Magento/CatalogAnalytics/composer.json +++ b/app/code/Magento/CatalogAnalytics/composer.json @@ -7,7 +7,7 @@ "magento/module-catalog": "101.1.*" }, "type": "magento2-module", - "version": "100.2.0-dev", + "version": "100.2.0", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index 5ef316b2c065c975a463a82f0eadee00310292dd..2b70f65d1f830a79111c129ebf5726e322865a77 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -16,7 +16,7 @@ "ext-ctype": "*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index 142ae98422e873e23fe60f4e44ef3e10cdc3a67b..79f86612d41bd21df75993308cc734d9aae0169c 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -13,7 +13,7 @@ "magento/module-ui": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json index 8bee82f6fe34be92d89c006ecf44081152e9c9bf..845bdeff31f427dbf74f8ecd0882de2794f15063 100644 --- a/app/code/Magento/CatalogRule/composer.json +++ b/app/code/Magento/CatalogRule/composer.json @@ -17,7 +17,7 @@ "magento/module-catalog-rule-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "101.0.0", + "version": "101.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index 8cdf797e1ca4cbd4d339ffbd00a971934b8b2e74..13be21e3248f248c064ad877fa80deb1add36ab1 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -15,7 +15,7 @@ "magento/framework": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index f11467e9f8d1f9d2d4c4a54a7a5b15094cce36c7..344562864384fc0dde8a70554416dcb058092ffc 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -14,7 +14,7 @@ "magento/module-ui": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json index fa4b5071d4dd69aa36e719f79f419d36c5bf8689..48d6562c5c77e8912bb88ae1395cc87bcb657423 100644 --- a/app/code/Magento/Checkout/composer.json +++ b/app/code/Magento/Checkout/composer.json @@ -27,7 +27,7 @@ "magento/module-cookie": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Checkout/i18n/en_US.csv b/app/code/Magento/Checkout/i18n/en_US.csv index 53e6ef67d68cd0f2c9697282a95481590fe6ab9a..8d297c4060abd71e5e7cf9a4d43a22dbfe8007f4 100644 --- a/app/code/Magento/Checkout/i18n/en_US.csv +++ b/app/code/Magento/Checkout/i18n/en_US.csv @@ -62,7 +62,7 @@ Checkout,Checkout Error!,Error! "DB exception","DB exception" Message,Message -"<a href=""%1"" onclick=""this.target='_blank'"" class=""print"">Print receipt</a>","<a href=""%1"" onclick=""this.target='_blank'"" class=""print"">Print receipt</a>" +"Print receipt","Print receipt" "Apply Discount Code","Apply Discount Code" "Enter discount code","Enter discount code" "Apply Discount","Apply Discount" diff --git a/app/code/Magento/Checkout/view/frontend/templates/button.phtml b/app/code/Magento/Checkout/view/frontend/templates/button.phtml index e2bcd76cba35bbbf3dc843a0dfdbb800831104d8..c3edfe30f8bdd79afb8870bb81e8ac269c557f2c 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/button.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/button.phtml @@ -10,6 +10,8 @@ <?php /** @var $block \Magento\Checkout\Block\Onepage\Success */ ?> <?php if ($block->getCanViewOrder() && $block->getCanPrintOrder()) :?> - <?= /* @escapeNotVerified */ __('<a href="%1" onclick="this.target=\'_blank\'" class="print">Print receipt</a>', $block->getPrintUrl()) ?> + <a href="<?= /* @escapeNotVerified */ $block->getPrintUrl() ?>" target="_blank" class="print"> + <?= /* @escapeNotVerified */ __('Print receipt') ?> + </a> <?= $block->getChildHtml() ?> <?php endif;?> diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json index c4f690db9cd1fe8b1a9bb4ed003b554f653b7fc8..3094908e69ca0cde95cff37e43d0701ce3d772c4 100644 --- a/app/code/Magento/Cms/composer.json +++ b/app/code/Magento/Cms/composer.json @@ -18,7 +18,7 @@ "magento/module-cms-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "102.0.0", + "version": "102.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Config/Block/System/Config/Form.php b/app/code/Magento/Config/Block/System/Config/Form.php index c540b8a3b0bb78dfed638c801a0e333a87c489f1..c17df229cf5490b6d4c81d0baf7a12a98df420fd 100644 --- a/app/code/Magento/Config/Block/System/Config/Form.php +++ b/app/code/Magento/Config/Block/System/Config/Form.php @@ -8,6 +8,7 @@ namespace Magento\Config\Block\System\Config; use Magento\Config\App\Config\Type\System; use Magento\Config\Model\Config\Reader\Source\Deployed\SettingChecker; use Magento\Config\Model\Config\Structure\ElementVisibilityInterface; +use Magento\Framework\App\Config\Data\ProcessorInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\ObjectManager; @@ -429,6 +430,18 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic if ($data === null) { $path = $field->getConfigPath() !== null ? $field->getConfigPath() : $path; $data = $this->getConfigValue($path); + if ($field->hasBackendModel()) { + $backendModel = $field->getBackendModel(); + // Backend models which implement ProcessorInterface are processed by ScopeConfigInterface + if (!$backendModel instanceof ProcessorInterface) { + $backendModel->setPath($path) + ->setValue($data) + ->setWebsite($this->getWebsiteCode()) + ->setStore($this->getStoreCode()) + ->afterLoad(); + $data = $backendModel->getValue(); + } + } } return $data; diff --git a/app/code/Magento/Config/Model/Config/Backend/Serialized.php b/app/code/Magento/Config/Model/Config/Backend/Serialized.php index 634f470e87567883482c15fc644970def54211eb..3d5713357c39c13f5707bc8ca552101ad4fd02ce 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Serialized.php +++ b/app/code/Magento/Config/Model/Config/Backend/Serialized.php @@ -5,7 +5,6 @@ */ namespace Magento\Config\Model\Config\Backend; -use Magento\Framework\App\Config\Data\ProcessorInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\Serializer\Json; @@ -13,7 +12,7 @@ use Magento\Framework\Serialize\Serializer\Json; * @api * @since 100.0.2 */ -class Serialized extends \Magento\Framework\App\Config\Value implements ProcessorInterface +class Serialized extends \Magento\Framework\App\Config\Value { /** * @var Json @@ -68,12 +67,4 @@ class Serialized extends \Magento\Framework\App\Config\Value implements Processo parent::beforeSave(); return $this; } - - /** - * @inheritdoc - */ - public function processValue($value) - { - return empty($value) ? '' : $this->serializer->unserialize($value); - } } diff --git a/app/code/Magento/Config/Test/Unit/Block/System/Config/FormTest.php b/app/code/Magento/Config/Test/Unit/Block/System/Config/FormTest.php index e4170fbe8732eb0c0f5cae87e32cf6df84aada8c..72e8386bddaf6c3debeb26f6cb41e118fd8329dc 100644 --- a/app/code/Magento/Config/Test/Unit/Block/System/Config/FormTest.php +++ b/app/code/Magento/Config/Test/Unit/Block/System/Config/FormTest.php @@ -548,7 +548,7 @@ class FormTest extends \PHPUnit\Framework\TestCase false, 'some_value', null, - 0, + 1, false, false, false @@ -560,7 +560,7 @@ class FormTest extends \PHPUnit\Framework\TestCase true, 'Config Value', null, - 0, + 1, true, false, true diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json index fb4c80115334de64f8ff0da42fb87be4fa0781e9..a29f65473ab016f68708099ba19b640676e02935 100644 --- a/app/code/Magento/Config/composer.json +++ b/app/code/Magento/Config/composer.json @@ -13,7 +13,7 @@ "magento/module-deploy": "100.2.*" }, "type": "magento2-module", - "version": "101.0.0", + "version": "101.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index a62ce29813ce3f96ac1bf221fd0ff1ff62b63251..3b60f57c2f923e03c9253af43598268b9aceb323 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -24,7 +24,7 @@ "magento/module-product-links-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Contact/Controller/Index/Post.php b/app/code/Magento/Contact/Controller/Index/Post.php index 3374ff1fa5cf4440c1a61e8cb025a2d4004e9755..ee2d23b74df24e82461240a7a824f242dd33c164 100644 --- a/app/code/Magento/Contact/Controller/Index/Post.php +++ b/app/code/Magento/Contact/Controller/Index/Post.php @@ -9,12 +9,13 @@ namespace Magento\Contact\Controller\Index; use Magento\Contact\Model\ConfigInterface; use Magento\Contact\Model\MailInterface; use Magento\Framework\App\Action\Context; -use Magento\Framework\App\ObjectManager; use Magento\Framework\App\Request\DataPersistorInterface; use Magento\Framework\Controller\Result\Redirect; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\HTTP\PhpEnvironment\Request; use Psr\Log\LoggerInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\DataObject; class Post extends \Magento\Contact\Controller\Index { @@ -56,7 +57,7 @@ class Post extends \Magento\Contact\Controller\Index $this->context = $context; $this->mail = $mail; $this->dataPersistor = $dataPersistor; - $this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance()->get(LoggerInterface::class); + $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class); } /** @@ -71,45 +72,33 @@ class Post extends \Magento\Contact\Controller\Index } try { $this->sendEmail($this->validatedParams()); - $this->messageManager->addSuccess( + $this->messageManager->addSuccessMessage( __('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.') ); - $this->getDataPersistor()->clear('contact_us'); + $this->dataPersistor->clear('contact_us'); } catch (LocalizedException $e) { $this->messageManager->addErrorMessage($e->getMessage()); - $this->getDataPersistor()->set('contact_us', $this->getRequest()->getParams()); + $this->dataPersistor->set('contact_us', $this->getRequest()->getParams()); } catch (\Exception $e) { $this->logger->critical($e); $this->messageManager->addErrorMessage( __('An error occurred while processing your form. Please try again later.') ); - $this->getDataPersistor()->set('contact_us', $this->getRequest()->getParams()); + $this->dataPersistor->set('contact_us', $this->getRequest()->getParams()); } return $this->resultRedirectFactory->create()->setPath('contact/index'); } - /** - * Get Data Persistor - * - * @return DataPersistorInterface - */ - private function getDataPersistor() - { - if ($this->dataPersistor === null) { - $this->dataPersistor = ObjectManager::getInstance() - ->get(DataPersistorInterface::class); - } - - return $this->dataPersistor; - } - /** * @param array $post Post data from contact form * @return void */ private function sendEmail($post) { - $this->mail->send($post['email'], ['data' => new \Magento\Framework\DataObject($post)]); + $this->mail->send( + $post['email'], + ['data' => new DataObject($post)] + ); } /** diff --git a/app/code/Magento/Contact/Model/Mail.php b/app/code/Magento/Contact/Model/Mail.php index d63efbbca573b94a0b8754763dd8c33fecdc46e5..43c1974252b5a7d14ce6e5fb8a4b3c6c21f8077a 100644 --- a/app/code/Magento/Contact/Model/Mail.php +++ b/app/code/Magento/Contact/Model/Mail.php @@ -6,9 +6,10 @@ namespace Magento\Contact\Model; use Magento\Framework\Mail\Template\TransportBuilder; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Translate\Inline\StateInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\Area; class Mail implements MailInterface { @@ -49,8 +50,7 @@ class Mail implements MailInterface $this->contactsConfig = $contactsConfig; $this->transportBuilder = $transportBuilder; $this->inlineTranslation = $inlineTranslation; - $this->storeManager = $storeManager ?: - ObjectManager::getInstance()->get(StoreManagerInterface::class); + $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); } /** @@ -71,7 +71,7 @@ class Mail implements MailInterface ->setTemplateIdentifier($this->contactsConfig->emailTemplate()) ->setTemplateOptions( [ - 'area' => 'frontend', + 'area' => Area::AREA_FRONTEND, 'store' => $this->storeManager->getStore()->getId() ] ) diff --git a/app/code/Magento/Customer/Api/CustomerRepositoryInterface.php b/app/code/Magento/Customer/Api/CustomerRepositoryInterface.php index a18540d8cf9d57a87fbc76c64f93f08ff58f415d..2133ae5a323b4ec2de7b6a62b1cc4e7274dbd14b 100644 --- a/app/code/Magento/Customer/Api/CustomerRepositoryInterface.php +++ b/app/code/Magento/Customer/Api/CustomerRepositoryInterface.php @@ -38,7 +38,7 @@ interface CustomerRepositoryInterface public function get($email, $websiteId = null); /** - * Get customer by customer ID. + * Get customer by Customer ID. * * @param int $customerId * @return \Magento\Customer\Api\Data\CustomerInterface @@ -70,7 +70,7 @@ interface CustomerRepositoryInterface public function delete(\Magento\Customer\Api\Data\CustomerInterface $customer); /** - * Delete customer by ID. + * Delete customer by Customer ID. * * @param int $customerId * @return bool true on success diff --git a/app/code/Magento/Customer/Block/Address/Edit.php b/app/code/Magento/Customer/Block/Address/Edit.php index 6362f28a4f96d0aab16f0e0afafa4ce36aabc431..e9e894b2bc130e5ecf3ad39c10cadc50e245fc68 100644 --- a/app/code/Magento/Customer/Block/Address/Edit.php +++ b/app/code/Magento/Customer/Block/Address/Edit.php @@ -5,7 +5,9 @@ */ namespace Magento\Customer\Block\Address; +use Magento\Customer\Model\AttributeChecker; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\App\ObjectManager; /** * Customer address edit block @@ -46,6 +48,11 @@ class Edit extends \Magento\Directory\Block\Data */ protected $dataObjectHelper; + /** + * @var AttributeChecker + */ + private $attributeChecker; + /** * Constructor * @@ -61,7 +68,7 @@ class Edit extends \Magento\Directory\Block\Data * @param \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper * @param array $data - * + * @param AttributeChecker $attributeChecker * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -76,13 +83,16 @@ class Edit extends \Magento\Directory\Block\Data \Magento\Customer\Api\Data\AddressInterfaceFactory $addressDataFactory, \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer, \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, - array $data = [] + array $data = [], + AttributeChecker $attributeChecker = null ) { $this->_customerSession = $customerSession; $this->_addressRepository = $addressRepository; $this->addressDataFactory = $addressDataFactory; $this->currentCustomer = $currentCustomer; $this->dataObjectHelper = $dataObjectHelper; + $this->attributeChecker = $attributeChecker ?: ObjectManager::getInstance()->get(AttributeChecker::class); + parent::__construct( $context, $directoryHelper, @@ -352,4 +362,16 @@ class Edit extends \Magento\Directory\Block\Data { return $this->_scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE); } + + /** + * Checks whether it is allowed to show an attribute on the form. + * + * @param string $attributeCode + * @param string $formName + * @return bool + */ + public function isAttributeAllowedOnForm($attributeCode, $formName) + { + return $this->attributeChecker->isAttributeAllowedOnForm($attributeCode, $formName); + } } diff --git a/app/code/Magento/Customer/Helper/Address.php b/app/code/Magento/Customer/Helper/Address.php index 8dac704aaa08535f3ffe704907cedf24fbd2b90e..c74c62dc6d98cd153e7eeb52a061ec9d1f234b17 100644 --- a/app/code/Magento/Customer/Helper/Address.php +++ b/app/code/Magento/Customer/Helper/Address.php @@ -8,9 +8,7 @@ namespace Magento\Customer\Helper; use Magento\Customer\Api\AddressMetadataInterface; use Magento\Customer\Api\CustomerMetadataInterface; use Magento\Customer\Api\Data\AttributeMetadataInterface; -use Magento\Customer\Model\Metadata\AttributeResolver; use Magento\Directory\Model\Country\Format; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\NoSuchEntityException; /** @@ -95,11 +93,6 @@ class Address extends \Magento\Framework\App\Helper\AbstractHelper */ protected $_addressConfig; - /** - * @var AttributeResolver - */ - private $attributeResolver; - /** * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Framework\View\Element\BlockFactory $blockFactory @@ -107,7 +100,6 @@ class Address extends \Magento\Framework\App\Helper\AbstractHelper * @param CustomerMetadataInterface $customerMetadataService * @param AddressMetadataInterface $addressMetadataService * @param \Magento\Customer\Model\Address\Config $addressConfig - * @param AttributeResolver|null $attributeResolver */ public function __construct( \Magento\Framework\App\Helper\Context $context, @@ -115,15 +107,13 @@ class Address extends \Magento\Framework\App\Helper\AbstractHelper \Magento\Store\Model\StoreManagerInterface $storeManager, CustomerMetadataInterface $customerMetadataService, AddressMetadataInterface $addressMetadataService, - \Magento\Customer\Model\Address\Config $addressConfig, - AttributeResolver $attributeResolver = null + \Magento\Customer\Model\Address\Config $addressConfig ) { $this->_blockFactory = $blockFactory; $this->_storeManager = $storeManager; $this->_customerMetadataService = $customerMetadataService; $this->_addressMetadataService = $addressMetadataService; $this->_addressConfig = $addressConfig; - $this->attributeResolver = $attributeResolver ?: ObjectManager::getInstance()->get(AttributeResolver::class); parent::__construct($context); } @@ -401,31 +391,4 @@ class Address extends \Magento\Framework\App\Helper\AbstractHelper } return false; } - - /** - * Checks whether it is allowed to show an attribute on the form - * - * This check relies on the attribute's property 'getUsedInForms' which contains a list of forms - * where allowed to render specified attribute. - * - * @param string $attributeCode - * @param string $formName - * @return bool - */ - public function isAttributeAllowedOnForm($attributeCode, $formName) - { - $isAllowed = false; - $attributeMetadata = $this->_addressMetadataService->getAttributeMetadata($attributeCode); - if ($attributeMetadata) { - /** @var \Magento\Customer\Model\Attribute $attribute */ - $attribute = $this->attributeResolver->getModelByAttribute( - \Magento\Customer\Api\AddressMetadataManagementInterface::ENTITY_TYPE_ADDRESS, - $attributeMetadata - ); - $usedInForms = $attribute->getUsedInForms(); - $isAllowed = in_array($formName, $usedInForms, true); - } - - return $isAllowed; - } } diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 59205a4d918384c7bedc306bf80f07c32bbdc1a9..ba646549f6919a5f933831cdb33b05930988a2d8 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -531,12 +531,8 @@ class AccountManagement implements AccountManagementInterface $this->getEmailNotification()->passwordResetConfirmation($customer); break; default: - throw new InputException( - __( - 'Invalid value of "%value" provided for the %fieldName field.', - ['value' => $template, 'fieldName' => 'email type'] - ) - ); + $this->handleUnknownTemplate($template); + break; } return true; } catch (MailException $e) { @@ -546,6 +542,25 @@ class AccountManagement implements AccountManagementInterface return false; } + /** + * Handle not supported template + * + * @param string $template + * @throws InputException + */ + private function handleUnknownTemplate($template) + { + throw new InputException(__( + 'Invalid value of "%value" provided for the %fieldName field. Possible values: %template1 or %template2.', + [ + 'value' => $template, + 'fieldName' => 'template', + 'template1' => AccountManagement::EMAIL_REMINDER, + 'template2' => AccountManagement::EMAIL_RESET + ] + )); + } + /** * {@inheritdoc} */ diff --git a/app/code/Magento/Customer/Model/AttributeChecker.php b/app/code/Magento/Customer/Model/AttributeChecker.php new file mode 100644 index 0000000000000000000000000000000000000000..6cc27697ccff7cc5baf0cc8141e9001b2b2f908d --- /dev/null +++ b/app/code/Magento/Customer/Model/AttributeChecker.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Customer\Model; + +use Magento\Customer\Api\AddressMetadataInterface; +use Magento\Customer\Api\AddressMetadataManagementInterface; +use Magento\Customer\Model\Metadata\AttributeResolver; +use Magento\Framework\App\Helper\Context; + +/** + * Customer attribute checker. + */ +class AttributeChecker +{ + /** + * @var AddressMetadataInterface + */ + private $addressMetadata; + + /** + * @var AttributeResolver + */ + private $attributeResolver; + + /** + * @param AddressMetadataInterface $addressMetadata + * @param AttributeResolver $attributeResolver + */ + public function __construct( + AddressMetadataInterface $addressMetadata, + AttributeResolver $attributeResolver + ) { + $this->addressMetadata = $addressMetadata; + $this->attributeResolver = $attributeResolver; + } + + /** + * Checks whether it is allowed to show an attribute on the form + * + * This check relies on the attribute's property 'getUsedInForms' which contains a list of forms + * where allowed to render specified attribute. + * + * @param string $attributeCode + * @param string $formName + * @return bool + */ + public function isAttributeAllowedOnForm($attributeCode, $formName) + { + $isAllowed = false; + $attributeMetadata = $this->addressMetadata->getAttributeMetadata($attributeCode); + if ($attributeMetadata) { + /** @var Attribute $attribute */ + $attribute = $this->attributeResolver->getModelByAttribute( + AddressMetadataManagementInterface::ENTITY_TYPE_ADDRESS, + $attributeMetadata + ); + $usedInForms = $attribute->getUsedInForms(); + $isAllowed = in_array($formName, $usedInForms, true); + } + + return $isAllowed; + } +} diff --git a/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php b/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php index 7b42e8b7774c85cd026f0fa436fcde737337aed7..50785247d7965b4beaa573814b74179f277e6f8d 100644 --- a/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php +++ b/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php @@ -7,7 +7,6 @@ namespace Magento\Customer\Test\Unit\Helper; use Magento\Customer\Api\AddressMetadataInterface; -use Magento\Customer\Api\AddressMetadataManagementInterface; use Magento\Customer\Api\CustomerMetadataInterface; /** @@ -36,9 +35,6 @@ class AddressTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Customer\Model\Address\Config|\PHPUnit_Framework_MockObject_MockObject */ protected $addressConfig; - /** @var \Magento\Customer\Model\Metadata\AttributeResolver|\PHPUnit_Framework_MockObject_MockObject */ - protected $attributeResolver; - /** @var \PHPUnit_Framework_MockObject_MockObject|AddressMetadataInterface */ private $addressMetadataService; @@ -55,7 +51,6 @@ class AddressTest extends \PHPUnit\Framework\TestCase $this->customerMetadataService = $arguments['customerMetadataService']; $this->addressConfig = $arguments['addressConfig']; $this->addressMetadataService = $arguments['addressMetadataService']; - $this->attributeResolver = $arguments['attributeResolver']; $this->helper = $objectManagerHelper->getObject($className, $arguments); } @@ -408,68 +403,4 @@ class AddressTest extends \PHPUnit\Framework\TestCase ['invalid_code', false], ]; } - - /** - * @dataProvider attributeOnFormDataProvider - * @param bool $isAllowed - * @param bool $isMetadataExists - * @param string $attributeCode - * @param string $formName - * @param array $attributeFormsList - */ - public function testIsAttributeAllowedOnForm( - $isAllowed, - $isMetadataExists, - $attributeCode, - $formName, - array $attributeFormsList - ) { - $attributeMetadata = null; - if ($isMetadataExists) { - $attributeMetadata = $this->getMockBuilder(\Magento\Customer\Api\Data\AttributeMetadataInterface::class) - ->getMockForAbstractClass(); - $attribute = $this->getMockBuilder(\Magento\Customer\Model\Attribute::class) - ->disableOriginalConstructor() - ->getMock(); - $this->attributeResolver->expects($this->once()) - ->method('getModelByAttribute') - ->with(AddressMetadataManagementInterface::ENTITY_TYPE_ADDRESS, $attributeMetadata) - ->willReturn($attribute); - $attribute->expects($this->once()) - ->method('getUsedInForms') - ->willReturn($attributeFormsList); - } - $this->addressMetadataService->expects($this->once()) - ->method('getAttributeMetadata') - ->with($attributeCode) - ->willReturn($attributeMetadata); - $this->assertEquals($isAllowed, $this->helper->isAttributeAllowedOnForm($attributeCode, $formName)); - } - - public function attributeOnFormDataProvider() - { - return [ - 'metadata not exists' => [ - 'isAllowed' => false, - 'isMetadataExists' => false, - 'attributeCode' => 'attribute_code', - 'formName' => 'form_name', - 'attributeFormsList' => [], - ], - 'form not in the list' => [ - 'isAllowed' => false, - 'isMetadataExists' => true, - 'attributeCode' => 'attribute_code', - 'formName' => 'form_name', - 'attributeFormsList' => ['form_1', 'form_2'], - ], - 'allowed' => [ - 'isAllowed' => true, - 'isMetadataExists' => true, - 'attributeCode' => 'attribute_code', - 'formName' => 'form_name', - 'attributeFormsList' => ['form_name', 'form_1', 'form_2'], - ], - ]; - } } diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php index 34662eecc0c1c9e41d6169e0fcfdb74f57330e58..2a6b9fe6fd4ea44edfed07f85aaaf36d69357eca 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php @@ -1173,10 +1173,6 @@ class AccountManagementTest extends \PHPUnit\Framework\TestCase $this->assertTrue($this->accountManagement->initiatePasswordReset($email, $template)); } - /** - * @expectedException \Magento\Framework\Exception\InputException - * @expectedExceptionMessage Invalid value of "" provided for the email type field - */ public function testInitiatePasswordResetNoTemplate() { $storeId = 1; @@ -1192,6 +1188,10 @@ class AccountManagementTest extends \PHPUnit\Framework\TestCase $this->prepareInitiatePasswordReset($email, $templateIdentifier, $sender, $storeId, $customerId, $hash); + $this->expectException(\Magento\Framework\Exception\InputException::class); + $this->expectExceptionMessage( + 'Invalid value of "" provided for the template field. Possible values: email_reminder or email_reset.' + ); $this->accountManagement->initiatePasswordReset($email, $template); } diff --git a/app/code/Magento/Customer/Test/Unit/Model/AttributeCheckerTest.php b/app/code/Magento/Customer/Test/Unit/Model/AttributeCheckerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..480f5be96e318367a34ecfa3bfff0d2f9b31330e --- /dev/null +++ b/app/code/Magento/Customer/Test/Unit/Model/AttributeCheckerTest.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Customer\Test\Unit\Model; + +use Magento\Customer\Api\AddressMetadataInterface; +use Magento\Customer\Api\AddressMetadataManagementInterface; +use Magento\Customer\Api\Data\AttributeMetadataInterface; +use Magento\Customer\Model\AttributeChecker; +use Magento\Customer\Model\Attribute; +use Magento\Customer\Model\Metadata\AttributeResolver; + +class AttributeCheckerTest extends \PHPUnit\Framework\TestCase +{ + /** @var AttributeChecker|\PHPUnit_Framework_MockObject_MockObject */ + private $model; + + /** @var AttributeResolver|\PHPUnit_Framework_MockObject_MockObject */ + private $attributeResolver; + + /** @var AddressMetadataInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $addressMetadataService; + + protected function setUp() + { + $this->addressMetadataService = $this->getMockForAbstractClass(AddressMetadataInterface::class); + $this->attributeResolver = $this->getMockBuilder(AttributeResolver::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = new AttributeChecker( + $this->addressMetadataService, + $this->attributeResolver + ); + } + + /** + * @param bool $isAllowed + * @param bool $isMetadataExists + * @param string $attributeCode + * @param string $formName + * @param array $attributeFormsList + * + * @dataProvider attributeOnFormDataProvider + */ + public function testIsAttributeAllowedOnForm( + $isAllowed, + $isMetadataExists, + $attributeCode, + $formName, + array $attributeFormsList + ) { + $attributeMetadata = null; + if ($isMetadataExists) { + $attributeMetadata = $this->getMockForAbstractClass(AttributeMetadataInterface::class); + $attribute = $this->getMockBuilder(Attribute::class) + ->disableOriginalConstructor() + ->getMock(); + $this->attributeResolver->expects($this->once()) + ->method('getModelByAttribute') + ->with(AddressMetadataManagementInterface::ENTITY_TYPE_ADDRESS, $attributeMetadata) + ->willReturn($attribute); + $attribute->expects($this->once()) + ->method('getUsedInForms') + ->willReturn($attributeFormsList); + } + $this->addressMetadataService->expects($this->once()) + ->method('getAttributeMetadata') + ->with($attributeCode) + ->willReturn($attributeMetadata); + + $this->assertEquals($isAllowed, $this->model->isAttributeAllowedOnForm($attributeCode, $formName)); + } + + public function attributeOnFormDataProvider() + { + return [ + 'metadata not exists' => [ + 'isAllowed' => false, + 'isMetadataExists' => false, + 'attributeCode' => 'attribute_code', + 'formName' => 'form_name', + 'attributeFormsList' => [], + ], + 'form not in the list' => [ + 'isAllowed' => false, + 'isMetadataExists' => true, + 'attributeCode' => 'attribute_code', + 'formName' => 'form_name', + 'attributeFormsList' => ['form_1', 'form_2'], + ], + 'allowed' => [ + 'isAllowed' => true, + 'isMetadataExists' => true, + 'attributeCode' => 'attribute_code', + 'formName' => 'form_name', + 'attributeFormsList' => ['form_name', 'form_1', 'form_2'], + ], + ]; + } +} diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json index 0e8ebf957edf57b29157e54f2040066ac127f53b..61fcb62932992ab4e16bce2e0b347388bb6be42e 100644 --- a/app/code/Magento/Customer/composer.json +++ b/app/code/Magento/Customer/composer.json @@ -29,7 +29,7 @@ "magento/module-customer-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "101.0.0", + "version": "101.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Customer/etc/config.xml b/app/code/Magento/Customer/etc/config.xml index c35e9fa4b4c8a81e4213c397797dc9db9f00b75a..da4b80536e631781050273dbe407e57f41eaa6f2 100644 --- a/app/code/Magento/Customer/etc/config.xml +++ b/app/code/Magento/Customer/etc/config.xml @@ -56,7 +56,7 @@ <fax_show/> </address> <startup> - <redirect_dashboard>1</redirect_dashboard> + <redirect_dashboard>0</redirect_dashboard> </startup> <address_templates> <text>{{depend prefix}}{{var prefix}} {{/depend}}{{var firstname}} {{depend middlename}}{{var middlename}} {{/depend}}{{var lastname}}{{depend suffix}} {{var suffix}}{{/depend}} diff --git a/app/code/Magento/Customer/etc/webapi.xml b/app/code/Magento/Customer/etc/webapi.xml index 26a9c41f20c0d8b80d535f2a8ebe59cd322e5774..c536e26bcc82aa38bdd976fe7a0b7aad1d652311 100644 --- a/app/code/Magento/Customer/etc/webapi.xml +++ b/app/code/Magento/Customer/etc/webapi.xml @@ -128,7 +128,7 @@ <resource ref="anonymous"/> </resources> </route> - <route url="/V1/customers/:id" method="PUT"> + <route url="/V1/customers/:customerId" method="PUT"> <service class="Magento\Customer\Api\CustomerRepositoryInterface" method="save"/> <resources> <resource ref="Magento_Customer::manage"/> diff --git a/app/code/Magento/CustomerAnalytics/composer.json b/app/code/Magento/CustomerAnalytics/composer.json index 36e7492decc50fdaef50668ad2059820632dcc47..d34d6ba751e2afcd8d0113cdfb22baa1d508c922 100644 --- a/app/code/Magento/CustomerAnalytics/composer.json +++ b/app/code/Magento/CustomerAnalytics/composer.json @@ -7,7 +7,7 @@ "magento/module-customer": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0-dev", + "version": "100.2.0", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/CustomerImportExport/Model/Import/Customer.php b/app/code/Magento/CustomerImportExport/Model/Import/Customer.php index bee4479526037eebc841b70b3e3344efa345e13c..016dca2fa526c5cca2ba86387772fe3dbccdfe40 100644 --- a/app/code/Magento/CustomerImportExport/Model/Import/Customer.php +++ b/app/code/Magento/CustomerImportExport/Model/Import/Customer.php @@ -270,13 +270,29 @@ class Customer extends AbstractCustomer $this->_connection->insertOnDuplicate( $this->_entityTable, $entitiesToUpdate, - $this->customerFields + $this->getCustomerEntityFieldsToUpdate($entitiesToUpdate) ); } return $this; } + /** + * Filter the entity that are being updated so we only change fields found in the importer file + * + * @param array $entitiesToUpdate + * @return array + */ + private function getCustomerEntityFieldsToUpdate(array $entitiesToUpdate): array + { + $firstCustomer = reset($entitiesToUpdate); + $columnsToUpdate = array_keys($firstCustomer); + $customerFieldsToUpdate = array_filter($this->customerFields, function ($field) use ($columnsToUpdate) { + return in_array($field, $columnsToUpdate); + }); + return $customerFieldsToUpdate; + } + /** * Save customer attributes. * diff --git a/app/code/Magento/Deploy/Model/Filesystem.php b/app/code/Magento/Deploy/Model/Filesystem.php index 3dd28f4d3e82090d43fd881ad281d19c5e7465fa..0557914f48d24b1c26f46099733f2c91d8600b99 100644 --- a/app/code/Magento/Deploy/Model/Filesystem.php +++ b/app/code/Magento/Deploy/Model/Filesystem.php @@ -5,17 +5,16 @@ */ namespace Magento\Deploy\Model; -use Symfony\Component\Console\Output\OutputInterface; -use Magento\Framework\App\State; -use Magento\Framework\App\DeploymentConfig\Writer; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Validator\Locale; use Magento\User\Model\ResourceModel\User\Collection as UserCollection; +use Symfony\Component\Console\Output\OutputInterface; /** * Generate static files, compile * - * Сlear generated/code, generated/metadata/, var/view_preprocessed and pub/static directories + * Clear generated/code, generated/metadata/, var/view_preprocessed and pub/static directories * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -50,21 +49,6 @@ class Filesystem */ const DEFAULT_THEME = 'Magento/blank'; - /** - * @var \Magento\Framework\App\DeploymentConfig\Writer - */ - private $writer; - - /** - * @var \Magento\Framework\App\DeploymentConfig\Reader - */ - private $reader; - - /** - * @var \Magento\Framework\ObjectManagerInterface - */ - private $objectManager; - /** * @var \Magento\Framework\Filesystem */ @@ -101,33 +85,35 @@ class Filesystem private $userCollection; /** - * @param \Magento\Framework\App\DeploymentConfig\Writer $writer - * @param \Magento\Framework\App\DeploymentConfig\Reader $reader - * @param \Magento\Framework\ObjectManagerInterface $objectManager + * @var Locale + */ + private $locale; + + /** * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Framework\App\Filesystem\DirectoryList $directoryList * @param \Magento\Framework\Filesystem\Driver\File $driverFile * @param \Magento\Store\Model\Config\StoreView $storeView * @param \Magento\Framework\ShellInterface $shell + * @param UserCollection $userCollection + * @param Locale $locale */ public function __construct( - \Magento\Framework\App\DeploymentConfig\Writer $writer, - \Magento\Framework\App\DeploymentConfig\Reader $reader, - \Magento\Framework\ObjectManagerInterface $objectManager, \Magento\Framework\Filesystem $filesystem, \Magento\Framework\App\Filesystem\DirectoryList $directoryList, \Magento\Framework\Filesystem\Driver\File $driverFile, \Magento\Store\Model\Config\StoreView $storeView, - \Magento\Framework\ShellInterface $shell + \Magento\Framework\ShellInterface $shell, + UserCollection $userCollection, + Locale $locale ) { - $this->writer = $writer; - $this->reader = $reader; - $this->objectManager = $objectManager; $this->filesystem = $filesystem; $this->directoryList = $directoryList; $this->driverFile = $driverFile; $this->storeView = $storeView; $this->shell = $shell; + $this->userCollection = $userCollection; + $this->locale = $locale; $this->functionCallPath = PHP_BINARY . ' -f ' . BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento '; } @@ -141,7 +127,7 @@ class Filesystem public function regenerateStatic( OutputInterface $output ) { - // Сlear generated/code, generated/metadata/, var/view_preprocessed and pub/static directories + // Clear generated/code, generated/metadata/, var/view_preprocessed and pub/static directories $this->cleanupFilesystem( [ DirectoryList::CACHE, @@ -193,7 +179,7 @@ class Filesystem private function getAdminUserInterfaceLocales() { $locales = []; - foreach ($this->getUserCollection() as $user) { + foreach ($this->userCollection as $user) { $locales[] = $user->getInterfaceLocale(); } return $locales; @@ -203,6 +189,7 @@ class Filesystem * Get used store and admin user locales * * @return array + * @throws \InvalidArgumentException if unknown locale is provided by the store configuration */ private function getUsedLocales() { @@ -210,25 +197,18 @@ class Filesystem $this->storeView->retrieveLocales(), $this->getAdminUserInterfaceLocales() ); - return array_unique($usedLocales); - } - - /** - * Get user collection - * - * @return UserCollection - * @deprecated 100.1.0 Added to not break backward compatibility of the constructor signature - * by injecting the new dependency directly. - * The method can be removed in a future major release, when constructor signature can be changed. - */ - private function getUserCollection() - { - if (!($this->userCollection instanceof UserCollection)) { - return \Magento\Framework\App\ObjectManager::getInstance()->get( - UserCollection::class - ); - } - return $this->userCollection; + return array_map( + function ($locale) { + if (!$this->locale->isValid($locale)) { + throw new \InvalidArgumentException( + $locale . + ' argument has invalid value, run info:language:list for list of available locales' + ); + } + return $locale; + }, + array_unique($usedLocales) + ); } /** diff --git a/app/code/Magento/Deploy/Package/Bundle/RequireJs.php b/app/code/Magento/Deploy/Package/Bundle/RequireJs.php index 73a15554f8b78f8a76f4aef673c07124251c4cfc..c7c9e5315c7abe7a14929d79d910eda2ee9ce0a9 100644 --- a/app/code/Magento/Deploy/Package/Bundle/RequireJs.php +++ b/app/code/Magento/Deploy/Package/Bundle/RequireJs.php @@ -240,9 +240,12 @@ class RequireJs implements BundleInterface private function getFileContent($sourcePath) { if (!isset($this->fileContent[$sourcePath])) { - $this->fileContent[$sourcePath] = utf8_encode( - $this->staticDir->readFile($this->minification->addMinifiedSign($sourcePath)) - ); + $content = $this->staticDir->readFile($this->minification->addMinifiedSign($sourcePath)); + if (mb_detect_encoding($content) !== "UTF-8") { + $content = mb_convert_encoding($content, "UTF-8"); + } + + $this->fileContent[$sourcePath] = $content; } return $this->fileContent[$sourcePath]; } diff --git a/app/code/Magento/Deploy/Test/Unit/Model/FilesystemTest.php b/app/code/Magento/Deploy/Test/Unit/Model/FilesystemTest.php index 673f31c04ffd3c51c4dca01bd711908c71025120..d14c86c4a3264ca49f00e0f4c315dcaaa715e7ad 100644 --- a/app/code/Magento/Deploy/Test/Unit/Model/FilesystemTest.php +++ b/app/code/Magento/Deploy/Test/Unit/Model/FilesystemTest.php @@ -5,47 +5,64 @@ */ namespace Magento\Deploy\Test\Unit\Model; +use Magento\Deploy\Model\Filesystem as DeployFilesystem; +use Magento\Framework\Filesystem; +use Magento\Framework\Filesystem\Directory\WriteInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\ShellInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Store\Model\Config\StoreView; +use Magento\User\Model\ResourceModel\User\Collection; +use Magento\User\Model\User; +use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Symfony\Component\Console\Output\OutputInterface; +use Magento\Framework\Validator\Locale; +use Magento\Framework\Setup\Lists; + +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class FilesystemTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Store\Model\Config\StoreView + * @var StoreView|MockObject */ - private $storeViewMock; + private $storeView; /** - * @var \Magento\Framework\ShellInterface + * @var ShellInterface|MockObject */ - private $shellMock; + private $shell; /** - * @var \Magento\User\Model\ResourceModel\User\Collection + * @var OutputInterface|MockObject */ - private $userCollectionMock; + private $output; /** - * @var \Symfony\Component\Console\Output\OutputInterface + * @var Filesystem|MockObject */ - private $outputMock; + private $filesystem; /** - * @var \Magento\Framework\Filesystem + * @var WriteInterface|MockObject */ - private $filesystemMock; + private $directoryWrite; /** - * @var \Magento\Framework\Filesystem\Directory\WriteInterface + * @var Collection|MockObject */ - private $directoryWriteMock; + private $userCollection; /** - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface|MockObject */ - private $objectManagerMock; + private $objectManager; /** - * @var \Magento\Deploy\Model\Filesystem + * @var DeployFilesystem */ - private $filesystem; + private $deployFilesystem; /** * @var string @@ -54,75 +71,127 @@ class FilesystemTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->storeViewMock = $this->createMock(\Magento\Store\Model\Config\StoreView::class); - $this->shellMock = $this->createMock(\Magento\Framework\ShellInterface::class); - $this->userCollectionMock = $this->createMock(\Magento\User\Model\ResourceModel\User\Collection::class); - $this->outputMock = $this->createMock(\Symfony\Component\Console\Output\OutputInterface::class); - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); - $this->filesystemMock = $this->createMock(\Magento\Framework\Filesystem::class); - $this->directoryWriteMock = $this->createMock(\Magento\Framework\Filesystem\Directory\WriteInterface::class); - $this->filesystemMock->expects($this->any()) - ->method('getDirectoryWrite') - ->willReturn($this->directoryWriteMock); - $this->filesystem = $objectManager->getObject( - \Magento\Deploy\Model\Filesystem::class, + $objectManager = new ObjectManager($this); + + $this->storeView = $this->createMock(StoreView::class); + $this->shell = $this->createMock(ShellInterface::class); + $this->output = $this->createMock(OutputInterface::class); + $this->objectManager = $this->createMock(ObjectManagerInterface::class); + $this->filesystem = $this->createMock(Filesystem::class); + $this->directoryWrite = $this->createMock(WriteInterface::class); + $this->filesystem->method('getDirectoryWrite') + ->willReturn($this->directoryWrite); + + $this->userCollection = $this->createMock(Collection::class); + + $lists = $this->getMockBuilder(Lists::class) + ->disableOriginalConstructor() + ->getMock(); + $lists->method('getLocaleList') + ->willReturn([ + 'fr_FR' => 'France', + 'de_DE' => 'Germany', + 'nl_NL' => 'Netherlands', + 'en_US' => 'USA' + ]); + $locale = $objectManager->getObject(Locale::class, ['lists' => $lists]); + + $this->deployFilesystem = $objectManager->getObject( + DeployFilesystem::class, [ - 'storeView' => $this->storeViewMock, - 'shell' => $this->shellMock, - 'filesystem' => $this->filesystemMock + 'storeView' => $this->storeView, + 'shell' => $this->shell, + 'filesystem' => $this->filesystem, + 'userCollection' => $this->userCollection, + 'locale' => $locale ] ); - $userCollection = new \ReflectionProperty(\Magento\Deploy\Model\Filesystem::class, 'userCollection'); - $userCollection->setAccessible(true); - $userCollection->setValue($this->filesystem, $this->userCollectionMock); - $this->cmdPrefix = PHP_BINARY . ' -f ' . BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento '; } public function testRegenerateStatic() { $storeLocales = ['fr_FR', 'de_DE', 'nl_NL']; - $adminUserInterfaceLocales = ['de_DE', 'en_US']; - $this->storeViewMock->expects($this->once()) - ->method('retrieveLocales') + $this->storeView->method('retrieveLocales') ->willReturn($storeLocales); - $userMock = $this->createMock(\Magento\User\Model\User::class); - $userMock->expects($this->once()) - ->method('getInterfaceLocale') - ->willReturn('en_US'); - $this->userCollectionMock->expects($this->once()) - ->method('getIterator') - ->willReturn(new \ArrayIterator([$userMock])); - - $usedLocales = array_unique( - array_merge($storeLocales, $adminUserInterfaceLocales) - ); - $staticContentDeployCmd = $this->cmdPrefix . 'setup:static-content:deploy -f ' - . implode(' ', $usedLocales); + $setupDiCompileCmd = $this->cmdPrefix . 'setup:di:compile'; - $this->shellMock->expects($this->at(0)) + $this->shell->expects(self::at(0)) ->method('execute') ->with($setupDiCompileCmd); - $this->shellMock->expects($this->at(1)) + + $this->initAdminLocaleMock('en_US'); + + $usedLocales = ['fr_FR', 'de_DE', 'nl_NL', 'en_US']; + $staticContentDeployCmd = $this->cmdPrefix . 'setup:static-content:deploy -f ' + . implode(' ', $usedLocales); + $this->shell->expects(self::at(1)) ->method('execute') ->with($staticContentDeployCmd); - $this->outputMock->expects($this->at(0)) + $this->output->expects(self::at(0)) ->method('writeln') ->with('Starting compilation'); - $this->outputMock->expects($this->at(2)) + $this->output->expects(self::at(2)) ->method('writeln') ->with('Compilation complete'); - $this->outputMock->expects($this->at(3)) + $this->output->expects(self::at(3)) ->method('writeln') ->with('Starting deployment of static content'); - $this->outputMock->expects($this->at(5)) + $this->output->expects(self::at(5)) ->method('writeln') ->with('Deployment of static content complete'); - $this->filesystem->regenerateStatic($this->outputMock); + $this->deployFilesystem->regenerateStatic($this->output); + } + + /** + * Checks a case when configuration contains incorrect locale code. + * + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage ;echo argument has invalid value, run info:language:list for list of available locales + */ + public function testGenerateStaticForNotAllowedStoreViewLocale() + { + $storeLocales = ['fr_FR', 'de_DE', ';echo']; + $this->storeView->method('retrieveLocales') + ->willReturn($storeLocales); + + $this->initAdminLocaleMock('en_US'); + + $this->deployFilesystem->regenerateStatic($this->output); + } + + /** + * Checks as case when admin locale is incorrect. + * + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage ;echo argument has invalid value, run info:language:list for list of available locales + */ + public function testGenerateStaticForNotAllowedAdminLocale() + { + $storeLocales = ['fr_FR', 'de_DE', 'en_US']; + $this->storeView->method('retrieveLocales') + ->willReturn($storeLocales); + + $this->initAdminLocaleMock(';echo'); + + $this->deployFilesystem->regenerateStatic($this->output); + } + + /** + * Initializes admin user locale. + * + * @param string $locale + */ + private function initAdminLocaleMock($locale) + { + /** @var User|MockObject $user */ + $user = $this->createMock(User::class); + $user->method('getInterfaceLocale') + ->willReturn($locale); + $this->userCollection->method('getIterator') + ->willReturn(new \ArrayIterator([$user])); } } diff --git a/app/code/Magento/Deploy/composer.json b/app/code/Magento/Deploy/composer.json index 8092f80be0e1a98701aaf118744ea78f11ec4269..e33d2e72f64a418362a935618ca5d76e7cd5290f 100644 --- a/app/code/Magento/Deploy/composer.json +++ b/app/code/Magento/Deploy/composer.json @@ -10,7 +10,7 @@ "magento/module-config": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json index a0782be817c0afdd3be09e8bed2de8d6fcc7c130..518f2cc77c07e04f14f14b92534d556573762f72 100644 --- a/app/code/Magento/Developer/composer.json +++ b/app/code/Magento/Developer/composer.json @@ -8,7 +8,7 @@ "magento/module-config": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Email/Test/Unit/Model/Template/FilterTest.php b/app/code/Magento/Email/Test/Unit/Model/Template/FilterTest.php index 8bfa2fc7d64ccb9c3fba467ab885d0b1fd9cba67..2eb8f582c54fa57a7e3aceecb5945fe6ef8ad99a 100644 --- a/app/code/Magento/Email/Test/Unit/Model/Template/FilterTest.php +++ b/app/code/Magento/Email/Test/Unit/Model/Template/FilterTest.php @@ -369,7 +369,7 @@ class FilterTest extends \PHPUnit\Framework\TestCase '<html><head><style type="text/css">div { color: #111; }</style></head><p></p></html>', 'p { color: #000 }', [ - '<head><style type="text/css">div { color: #111; }</style></head>', + '<style type="text/css">div { color: #111; }</style>', '<p style="color: #000;"></p>', ], ], diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json index bf7eadd9f708f1e305afcf3e4ca0b13e1fe07d0c..b74763a22ec14456b20a59850b520ef9b377e2c4 100644 --- a/app/code/Magento/GoogleAnalytics/composer.json +++ b/app/code/Magento/GoogleAnalytics/composer.json @@ -12,7 +12,7 @@ "magento/module-config": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php b/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php index 91cfbefbd57a22f0071d1508e2039fbec7a65d1c..e490ee4018376c084dc900e165ccd7f5bae30dd7 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/History/Download.php @@ -39,7 +39,7 @@ class Download extends \Magento\ImportExport\Controller\Adminhtml\History */ public function execute() { - $fileName = $this->getRequest()->getParam('filename'); + $fileName = basename($this->getRequest()->getParam('filename')); /** @var \Magento\ImportExport\Helper\Report $reportHelper */ $reportHelper = $this->_objectManager->get(\Magento\ImportExport\Helper\Report::class); diff --git a/app/code/Magento/ImportExport/Test/Unit/Controller/Adminhtml/History/DownloadTest.php b/app/code/Magento/ImportExport/Test/Unit/Controller/Adminhtml/History/DownloadTest.php index 73b97dfc6775104bdd104ea13542ae8a28aefee2..3eb14e673f648bc54ba0cb116b9c64c9ebc9ff6b 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Controller/Adminhtml/History/DownloadTest.php +++ b/app/code/Magento/ImportExport/Test/Unit/Controller/Adminhtml/History/DownloadTest.php @@ -72,8 +72,9 @@ class DownloadTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->request = $this->createPartialMock(\Magento\Framework\App\Request\Http::class, ['getParam']); - $this->request->expects($this->any())->method('getParam')->with('filename')->willReturn('filename'); + $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) + ->disableOriginalConstructor() + ->getMock(); $this->reportHelper = $this->createPartialMock( \Magento\ImportExport\Helper\Report::class, ['importFileExists', 'getReportSize', 'getReportOutput'] @@ -126,11 +127,12 @@ class DownloadTest extends \PHPUnit\Framework\TestCase } /** - * Test execute() + * Tests execute() */ public function testExecute() { - $this->reportHelper->expects($this->any())->method('importFileExists')->willReturn(true); + $this->reportHelper->expects($this->atLeastOnce())->method('importFileExists')->willReturn(true); + $this->resultRaw->expects($this->once())->method('setContents'); $this->downloadController->execute(); } @@ -140,7 +142,8 @@ class DownloadTest extends \PHPUnit\Framework\TestCase */ public function testExecuteFileNotFound() { - $this->reportHelper->expects($this->any())->method('importFileExists')->willReturn(false); + $this->request->method('getParam')->with('filename')->willReturn('filename'); + $this->reportHelper->method('importFileExists')->willReturn(false); $this->resultRaw->expects($this->never())->method('setContents'); $this->downloadController->execute(); } diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json index 623346e0a77828fce1990096149757fcec327a0d..23ed2f6346ef7b45b6c148f940eb27a1481dcf54 100644 --- a/app/code/Magento/ImportExport/composer.json +++ b/app/code/Magento/ImportExport/composer.json @@ -12,7 +12,7 @@ "ext-ctype": "*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/CarrierFinder.php b/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/CarrierFinder.php new file mode 100644 index 0000000000000000000000000000000000000000..0eb2afd04140a09cb10a74dabee705f65f401322 --- /dev/null +++ b/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/CarrierFinder.php @@ -0,0 +1,63 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\InstantPurchase\Model\ShippingMethodChoose; + +use Magento\Customer\Model\Address; +use Magento\Framework\DataObject; +use Magento\Shipping\Model\Config as CarriersConfig; +use Magento\Store\Model\StoreManagerInterface; + +/** + * Collect shipping rates for customer address without packaging estiamtion. + */ +class CarrierFinder +{ + /** + * @var CarriersConfig + */ + private $carriersConfig; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * CarrierFinder constructor. + * @param CarriersConfig $carriersConfig + * @param StoreManagerInterface $storeManager + */ + public function __construct( + CarriersConfig $carriersConfig, + StoreManagerInterface $storeManager + ) { + $this->carriersConfig = $carriersConfig; + $this->storeManager = $storeManager; + } + + /** + * Finds carriers delivering to customer address + * + * @param Address $address + * @return array + */ + public function getCarriersForCustomerAddress(Address $address): array + { + $request = new DataObject([ + 'dest_country_id' => $address->getCountryId() + ]); + + $carriers = []; + foreach ($this->carriersConfig->getActiveCarriers($this->storeManager->getStore()->getId()) as $carrier) { + $checked = $carrier->checkAvailableShipCountries($request); + if (false !== $checked && null === $checked->getErrorMessage() && !empty($checked->getAllowedMethods())) { + $carriers[] = $checked; + } + } + + return $carriers; + } +} diff --git a/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/CheapestMethodChooser.php b/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/CheapestMethodChooser.php index a9abf09c8b22c94f645ebd21d9341479b4297444..f01bde29cbc7d511874686a47b6717cad8473d30 100644 --- a/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/CheapestMethodChooser.php +++ b/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/CheapestMethodChooser.php @@ -6,7 +6,6 @@ namespace Magento\InstantPurchase\Model\ShippingMethodChoose; use Magento\Customer\Model\Address; -use Magento\Quote\Api\Data\ShippingMethodInterface; use Magento\Quote\Api\Data\ShippingMethodInterfaceFactory; /** @@ -20,21 +19,21 @@ class CheapestMethodChooser implements ShippingMethodChooserInterface private $shippingMethodFactory; /** - * @var ShippingRateFinder + * @var CarrierFinder */ - private $shippingRateFinder; + private $carrierFinder; /** * CheapestMethodChooser constructor. * @param ShippingMethodInterfaceFactory $shippingMethodFactory - * @param ShippingRateFinder $shippingRateFinder + * @param CarrierFinder $carrierFinder */ public function __construct( ShippingMethodInterfaceFactory $shippingMethodFactory, - ShippingRateFinder $shippingRateFinder + CarrierFinder $carrierFinder ) { $this->shippingMethodFactory = $shippingMethodFactory; - $this->shippingRateFinder = $shippingRateFinder; + $this->carrierFinder = $carrierFinder; } /** @@ -58,7 +57,7 @@ class CheapestMethodChooser implements ShippingMethodChooserInterface */ private function areShippingMethodsAvailable(Address $address): bool { - $shippingRatesForAddress = $this->shippingRateFinder->getRatesForCustomerAddress($address); - return !empty($shippingRatesForAddress); + $carriersForAddress = $this->carrierFinder->getCarriersForCustomerAddress($address); + return !empty($carriersForAddress); } } diff --git a/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/ShippingRateFinder.php b/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/ShippingRateFinder.php deleted file mode 100644 index 065f3fe946e7109bbec93b4cb08feab3ee858373..0000000000000000000000000000000000000000 --- a/app/code/Magento/InstantPurchase/Model/ShippingMethodChoose/ShippingRateFinder.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\InstantPurchase\Model\ShippingMethodChoose; - -use Magento\Customer\Model\Address; -use Magento\Quote\Model\Quote\Address\RateCollectorInterfaceFactory; -use Magento\Quote\Model\Quote\Address\RateRequest; -use Magento\Quote\Model\Quote\Address\RateRequestFactory; -use Magento\Store\Model\StoreManagerInterface; - -/** - * Collect shipping rates for customer address without packaging estiamtion. - */ -class ShippingRateFinder -{ - /** - * @var RateRequestFactory - */ - private $rateRequestFactory; - /** - * @var StoreManagerInterface - */ - private $storeManager; - /** - * @var RateCollectorInterfaceFactory - */ - private $rateCollectorFactory; - - /** - * RateCheck constructor. - * @param RateRequestFactory $rateRequestFactory - * @param RateCollectorInterfaceFactory $rateCollectorFactory - * @param StoreManagerInterface $storeManager - */ - public function __construct( - RateRequestFactory $rateRequestFactory, - RateCollectorInterfaceFactory $rateCollectorFactory, - StoreManagerInterface $storeManager - ) { - $this->rateRequestFactory = $rateRequestFactory; - $this->storeManager = $storeManager; - $this->rateCollectorFactory = $rateCollectorFactory; - } - - /** - * Finds shipping rates for an address. - * - * @param Address $address - * @return array - */ - public function getRatesForCustomerAddress(Address $address): array - { - /** @var $request RateRequest */ - $request = $this->rateRequestFactory->create(); - $request->setDestCountryId($address->getCountryId()); - $request->setDestRegionId($address->getRegionId()); - $request->setDestRegionCode($address->getRegionCode()); - $request->setDestStreet($address->getStreetFull()); - $request->setDestCity($address->getCity()); - $request->setDestPostcode($address->getPostcode()); - $request->setStoreId($this->storeManager->getStore()->getId()); - $request->setWebsiteId($this->storeManager->getWebsite()->getId()); - $request->setBaseCurrency($this->storeManager->getStore()->getBaseCurrency()); - $request->setPackageCurrency($this->storeManager->getStore()->getCurrentCurrency()); - // Because of wrong compare operator in \Magento\OfflineShipping\Model\Carrier\Tablerate on line: 167 - $request->setPackageQty(-1); - - $result = $this->rateCollectorFactory->create()->collectRates($request)->getResult(); - - $shippingRates = []; - - if ($result) { - $shippingRates = $result->getAllRates(); - } - - return $shippingRates; - } -} diff --git a/app/code/Magento/InstantPurchase/composer.json b/app/code/Magento/InstantPurchase/composer.json index df13e10f55b8fef052e0d47b604231c5820a9a2e..1c3b97a6beb9449b70a7658e424bbf50114dcf13 100644 --- a/app/code/Magento/InstantPurchase/composer.json +++ b/app/code/Magento/InstantPurchase/composer.json @@ -13,6 +13,7 @@ "magento/module-catalog": "102.0.*", "magento/module-customer": "101.0.*", "magento/module-sales": "101.0.*", + "magento/module-shipping": "100.2.*", "magento/module-quote": "101.0.*", "magento/module-vault": "101.0.*", "magento/framework": "100.2.*" diff --git a/app/code/Magento/Paypal/Model/Config.php b/app/code/Magento/Paypal/Model/Config.php index acb0444d508038b7ee058af9900c6ac0ab88f574..08b646a66189804651f5ec94a31d7bdaa2c73fe4 100644 --- a/app/code/Magento/Paypal/Model/Config.php +++ b/app/code/Magento/Paypal/Model/Config.php @@ -226,6 +226,7 @@ class Config extends AbstractConfig 'TWD', 'THB', 'USD', + 'INR', ]; /** diff --git a/app/code/Magento/Quote/Setup/UpgradeSchema.php b/app/code/Magento/Quote/Setup/UpgradeSchema.php index e4912892dbe17a3aeddc80faa570975b48de7fa2..1bb20a669bdf2693ce65f0ae97c6809da998de61 100644 --- a/app/code/Magento/Quote/Setup/UpgradeSchema.php +++ b/app/code/Magento/Quote/Setup/UpgradeSchema.php @@ -48,17 +48,17 @@ class UpgradeSchema implements UpgradeSchemaInterface } //drop foreign key for single DB case if (version_compare($context->getVersion(), '2.0.3', '<') - && $setup->tableExists($setup->getTable('quote_item')) + && $setup->tableExists($setup->getTable('quote_item', self::$connectionName)) ) { - $setup->getConnection()->dropForeignKey( - $setup->getTable('quote_item'), + $setup->getConnection(self::$connectionName)->dropForeignKey( + $setup->getTable('quote_item', self::$connectionName), $setup->getFkName('quote_item', 'product_id', 'catalog_product_entity', 'entity_id') ); } if (version_compare($context->getVersion(), '2.0.5', '<')) { - $connection = $setup->getConnection(); + $connection = $setup->getConnection(self::$connectionName); $connection->modifyColumn( - $setup->getTable('quote_address'), + $setup->getTable('quote_address', self::$connectionName), 'shipping_method', [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json index 5d4c5f35a3a24f7383c18cffd3e8961b46060751..a892697802e63de0f4f4de752428712064cd09c1 100644 --- a/app/code/Magento/Quote/composer.json +++ b/app/code/Magento/Quote/composer.json @@ -23,7 +23,7 @@ "magento/module-webapi": "100.2.*" }, "type": "magento2-module", - "version": "101.0.0", + "version": "101.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/QuoteAnalytics/composer.json b/app/code/Magento/QuoteAnalytics/composer.json index 7f38e489ab0b0f5131c4ee665a03f1d8a49fb052..abbb0ce7a042ba696adc92047667a9d2eac485db 100644 --- a/app/code/Magento/QuoteAnalytics/composer.json +++ b/app/code/Magento/QuoteAnalytics/composer.json @@ -7,7 +7,7 @@ "magento/module-quote": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0-dev", + "version": "100.2.0", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json index 74ed132bc65d2de3379df36a6efa779719df6990..1058052dd11221bd5e9acc1071e3740918574bae 100644 --- a/app/code/Magento/Reports/composer.json +++ b/app/code/Magento/Reports/composer.json @@ -22,7 +22,7 @@ "magento/framework": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json index f3b36e8b3f3fa24dc850ea4ce48f612e64f1ff7e..47680b454c29f631231f31f767700efceed59902 100644 --- a/app/code/Magento/Review/composer.json +++ b/app/code/Magento/Review/composer.json @@ -18,7 +18,7 @@ "magento/module-review-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/ReviewAnalytics/composer.json b/app/code/Magento/ReviewAnalytics/composer.json index b31c420e181bfa550f32880892c3d619ca52011b..965b6294db16a4e0815b872a0f563d5986b91c5a 100644 --- a/app/code/Magento/ReviewAnalytics/composer.json +++ b/app/code/Magento/ReviewAnalytics/composer.json @@ -7,7 +7,7 @@ "magento/module-review": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0-dev", + "version": "100.2.0", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedAtListProvider.php b/app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedAtListProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..846fa46572fdecbdea836317f36599612630e2a4 --- /dev/null +++ b/app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedAtListProvider.php @@ -0,0 +1,60 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\ResourceModel\Provider; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; + +/** + * Retrieves ID's of not synced by `updated_at` column entities. + * The result should contain list of entities ID's from the main table which have `updated_at` column greater + * than in the grid table. + */ +class UpdatedAtListProvider implements NotSyncedDataProviderInterface +{ + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var AdapterInterface + */ + private $connection; + + /** + * @param ResourceConnection $resourceConnection + */ + public function __construct(ResourceConnection $resourceConnection) + { + $this->connection = $resourceConnection->getConnection('sales'); + $this->resourceConnection = $resourceConnection; + } + + /** + * @inheritdoc + */ + public function getIds($mainTableName, $gridTableName) + { + $mainTableName = $this->resourceConnection->getTableName($mainTableName); + $gridTableName = $this->resourceConnection->getTableName($gridTableName); + $select = $this->connection->select() + ->from($mainTableName, [$mainTableName . '.entity_id']) + ->joinInner( + [$gridTableName => $gridTableName], + sprintf( + '%s.entity_id = %s.entity_id AND %s.updated_at > %s.updated_at', + $mainTableName, + $gridTableName, + $mainTableName, + $gridTableName + ), + [] + ); + + return $this->connection->fetchAll($select, [], \Zend_Db::FETCH_COLUMN); + } +} diff --git a/app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedIdListProvider.php b/app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedIdListProvider.php index 59906c79215fa41b25aca8245c2467266cffc9d4..42c6e9d6503158276c6b368fcc04507c99ecf51a 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedIdListProvider.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedIdListProvider.php @@ -38,10 +38,12 @@ class UpdatedIdListProvider implements NotSyncedDataProviderInterface */ public function getIds($mainTableName, $gridTableName) { + $mainTableName = $this->resourceConnection->getTableName($mainTableName); + $gridTableName = $this->resourceConnection->getTableName($gridTableName); $select = $this->getConnection()->select() - ->from($this->getConnection()->getTableName($mainTableName), [$mainTableName . '.entity_id']) + ->from($mainTableName, [$mainTableName . '.entity_id']) ->joinLeft( - [$gridTableName => $this->getConnection()->getTableName($gridTableName)], + [$gridTableName => $gridTableName], sprintf( '%s.%s = %s.%s', $mainTableName, diff --git a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Provider/NotSyncedDataProviderTest.php b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Provider/NotSyncedDataProviderTest.php index 8e248d239a501da1fa2855179682d2940a2db4cd..5ed60f8de306f65e1ed1adf0e33a9c0ed65b9a3d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Provider/NotSyncedDataProviderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Provider/NotSyncedDataProviderTest.php @@ -5,15 +5,11 @@ */ namespace Magento\Sales\Test\Unit\Model\ResourceModel\Provider; -use Magento\Framework\ObjectManager\TMap; use Magento\Framework\ObjectManager\TMapFactory; use Magento\Sales\Model\ResourceModel\Provider\NotSyncedDataProvider; use Magento\Sales\Model\ResourceModel\Provider\NotSyncedDataProviderInterface; use PHPUnit_Framework_MockObject_MockObject as MockObject; -/** - * Class NotSyncedDataProviderTest - */ class NotSyncedDataProviderTest extends \PHPUnit\Framework\TestCase { public function testGetIdsEmpty() @@ -23,30 +19,14 @@ class NotSyncedDataProviderTest extends \PHPUnit\Framework\TestCase ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $tMap = $this->getMockBuilder(TMap::class) - ->disableOriginalConstructor() - ->getMock(); - $tMapFactory->expects(static::once()) - ->method('create') - ->with( - [ - 'array' => [], - 'type' => NotSyncedDataProviderInterface::class - ] - ) - ->willReturn($tMap); - $tMap->expects(static::once()) - ->method('getIterator') - ->willReturn(new \ArrayIterator([])); + $tMapFactory->method('create') + ->willReturn([]); - $provider = new NotSyncedDataProvider($tMapFactory, []); - static::assertEquals([], $provider->getIds('main_table', 'grid_table')); + $provider = new NotSyncedDataProvider($tMapFactory); + self::assertEquals([], $provider->getIds('main_table', 'grid_table')); } - /** - * @covers \Magento\Sales\Model\ResourceModel\Provider\NotSyncedDataProvider::getIds - */ public function testGetIds() { /** @var TMapFactory|MockObject $tMapFactory */ @@ -54,46 +34,31 @@ class NotSyncedDataProviderTest extends \PHPUnit\Framework\TestCase ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $tMap = $this->getMockBuilder(TMap::class) - ->disableOriginalConstructor() - ->getMock(); $provider1 = $this->getMockBuilder(NotSyncedDataProviderInterface::class) ->getMockForAbstractClass(); - $provider1->expects(static::once()) - ->method('getIds') + $provider1->method('getIds') ->willReturn([1, 2]); $provider2 = $this->getMockBuilder(NotSyncedDataProviderInterface::class) ->getMockForAbstractClass(); - $provider2->expects(static::once()) - ->method('getIds') + $provider2->method('getIds') ->willReturn([2, 3, 4]); - $tMapFactory->expects(static::once()) - ->method('create') - ->with( + $tMapFactory->method('create') + ->with(self::equalTo( [ - 'array' => [ - 'provider1' => NotSyncedDataProviderInterface::class, - 'provider2' => NotSyncedDataProviderInterface::class - ], + 'array' => [$provider1, $provider2], 'type' => NotSyncedDataProviderInterface::class ] - ) - ->willReturn($tMap); - $tMap->expects(static::once()) - ->method('getIterator') - ->willReturn(new \ArrayIterator([$provider1, $provider2])); + )) + ->willReturn([$provider1, $provider2]); - $provider = new NotSyncedDataProvider( - $tMapFactory, - [ - 'provider1' => NotSyncedDataProviderInterface::class, - 'provider2' => NotSyncedDataProviderInterface::class, - ] - ); + $provider = new NotSyncedDataProvider($tMapFactory, [$provider1, $provider2]); - static::assertEquals([1, 2, 3, 4], array_values($provider->getIds('main_table', 'grid_table'))); + self::assertEquals( + [1, 2, 3, 4], + array_values($provider->getIds('main_table', 'grid_table')) + ); } } diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json index c4a99e5b45076d8465642594cc025f7a746bac41..9761f82d1894aff5881756eb5718520f912ad4e6 100644 --- a/app/code/Magento/Sales/composer.json +++ b/app/code/Magento/Sales/composer.json @@ -32,7 +32,7 @@ "magento/module-sales-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "101.0.0", + "version": "101.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 9de3f238d6a395965d8766e77b2981f88157acb4..22ddc7b333574db38629f0fe5124bd031c972e1e 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -470,6 +470,15 @@ <argument name="entityRelationComposite" xsi:type="object">CreditmemoRelationsComposite</argument> </arguments> </type> + + <virtualType name="Magento\Sales\Model\ResourceModel\Provider\NotSyncedOrderDataProvider" type="Magento\Sales\Model\ResourceModel\Provider\NotSyncedDataProvider"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="default" xsi:type="string">Magento\Sales\Model\ResourceModel\Provider\UpdatedIdListProvider</item> + <item name="updated_at" xsi:type="string">Magento\Sales\Model\ResourceModel\Provider\UpdatedAtListProvider</item> + </argument> + </arguments> + </virtualType> <virtualType name="Magento\Sales\Model\ResourceModel\Order\Grid" type="Magento\Sales\Model\ResourceModel\Grid"> <arguments> <argument name="mainTableName" xsi:type="string">sales_order</argument> @@ -520,6 +529,7 @@ <item name="payment_method" xsi:type="string">sales_order_payment.method</item> <item name="total_refunded" xsi:type="string">sales_order.total_refunded</item> </argument> + <argument name="notSyncedDataProvider" xsi:type="object">Magento\Sales\Model\ResourceModel\Provider\NotSyncedOrderDataProvider</argument> </arguments> </virtualType> <virtualType name="ShipmentGridAggregator" type="Magento\Sales\Model\ResourceModel\Grid"> diff --git a/app/code/Magento/SalesAnalytics/composer.json b/app/code/Magento/SalesAnalytics/composer.json index 7c9270a503b0d0aaf824c879ff6396fe0ad906d6..344971d7056cfb88649a7a98d0b0e8788d22b18b 100644 --- a/app/code/Magento/SalesAnalytics/composer.json +++ b/app/code/Magento/SalesAnalytics/composer.json @@ -7,7 +7,7 @@ "magento/module-sales": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0-dev", + "version": "100.2.0", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/SalesRule/Model/Quote/Discount.php b/app/code/Magento/SalesRule/Model/Quote/Discount.php index bee007b41181fd60c2e32086a513a8b4a59d208e..693a61b272f66e7128b3c369fd024a1ffe6418d1 100644 --- a/app/code/Magento/SalesRule/Model/Quote/Discount.php +++ b/app/code/Magento/SalesRule/Model/Quote/Discount.php @@ -179,7 +179,7 @@ class Discount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal $roundingDelta[$key] = 0.0000001; } foreach ($item->getChildren() as $child) { - $ratio = $child->getBaseRowTotal() / $parentBaseRowTotal; + $ratio = $parentBaseRowTotal != 0 ? $child->getBaseRowTotal() / $parentBaseRowTotal : 0; foreach ($keys as $key) { if (!$item->hasData($key)) { continue; diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Quote/DiscountTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Quote/DiscountTest.php index a1c325f39a94759b497a1ef98675515ef23528a9..671f20a27a4606e12fd5e9ac25fbd020adfa7da1 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/Quote/DiscountTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/Quote/DiscountTest.php @@ -229,7 +229,30 @@ class DiscountTest extends \PHPUnit\Framework\TestCase { $data = [ // 3 items, each $100, testing that discount are distributed to item correctly - 'three_items' => [ + [ + 'child_item_data' => [ + 'item1' => [ + 'base_row_total' => 0, + ] + ], + 'parent_item_data' => [ + 'discount_amount' => 20, + 'base_discount_amount' => 10, + 'original_discount_amount' => 40, + 'base_original_discount_amount' => 20, + 'base_row_total' => 0, + ], + 'expected_child_item_data' => [ + 'item1' => [ + 'discount_amount' => 0, + 'base_discount_amount' => 0, + 'original_discount_amount' => 0, + 'base_original_discount_amount' => 0, + ] + ], + ], + [ + // 3 items, each $100, testing that discount are distributed to item correctly 'child_item_data' => [ 'item1' => [ 'base_row_total' => 100, diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json index 60ba6550cddf478494eccf5065543993ba78f3bc..c6aecd101fc6fee6dc8a14d44a818739a37e53c2 100644 --- a/app/code/Magento/Search/composer.json +++ b/app/code/Magento/Search/composer.json @@ -11,7 +11,7 @@ "magento/module-ui": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json index 06fa1e5295c6009c37190efa67957e04b26bba71..a7a2a3d48b06e30f2cb0769fdcbadace2b17ec98 100644 --- a/app/code/Magento/Shipping/composer.json +++ b/app/code/Magento/Shipping/composer.json @@ -25,7 +25,7 @@ "magento/module-config": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Signifyd/composer.json b/app/code/Magento/Signifyd/composer.json index f11b23cc3b6c411cfb91472ee550204d36ae7cce..a162cef1614cad8f5089f53d1591021fab5f9aae 100644 --- a/app/code/Magento/Signifyd/composer.json +++ b/app/code/Magento/Signifyd/composer.json @@ -3,21 +3,21 @@ "description": "Submitting Case Entry to Signifyd on Order Creation", "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", - "magento/module-config": "100.2.*", - "magento/framework": "100.2.*", - "magento/module-sales": "100.2.*", + "magento/module-config": "101.0.*", + "magento/framework": "101.0.*", + "magento/module-sales": "101.0.*", "magento/module-store": "100.2.*", - "magento/module-customer": "100.2.*", + "magento/module-customer": "101.0.*", "magento/module-directory": "100.2.*", "magento/module-checkout": "100.2.*", "magento/module-backend": "100.2.*", "magento/module-payment": "100.2.*" }, "suggest": { - "magento/module-config": "100.2.*" + "magento/module-config": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0-dev", + "version": "100.2.1", "license": [ "proprietary" ], diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json index 71d9198a332a72a38fab0cedc8dfac1ef4199a9d..88be3616eebd05bfee6474f704389a3a0127d32d 100644 --- a/app/code/Magento/Sitemap/composer.json +++ b/app/code/Magento/Sitemap/composer.json @@ -18,7 +18,7 @@ "magento/module-config": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index 662414049c9556446b3021be0959fc80c3808361..f9eb84e2f9fa1010b126310f61ab18c741f0209a 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -14,7 +14,7 @@ "magento/module-deploy": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Store/etc/config.xml b/app/code/Magento/Store/etc/config.xml index 470337a97dcd93a862b3ae7f05549bf1ec237819..bb5b23620df4b0bc9dd7e3666082658068d3ccac 100644 --- a/app/code/Magento/Store/etc/config.xml +++ b/app/code/Magento/Store/etc/config.xml @@ -115,6 +115,10 @@ <file> <protected_extensions> <php>php</php> + <php3>php3</php3> + <php4>php4</php4> + <php5>php5</php5> + <php7>php7</php7> <htaccess>htaccess</htaccess> <jsp>jsp</jsp> <pl>pl</pl> diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index 2429607dc8716157fe9627889335712f3b8a07dc..787d58891c9e09c90c69da2ecc97764851d0aa93 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -6,7 +6,7 @@ "magento/framework": "101.0.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Tax/Model/Plugin/OrderSave.php b/app/code/Magento/Tax/Model/Plugin/OrderSave.php index 720328524868833b4bb501b3858b79490977a88b..3c87086cdf585b285fbe49fda23912c167851c26 100644 --- a/app/code/Magento/Tax/Model/Plugin/OrderSave.php +++ b/app/code/Magento/Tax/Model/Plugin/OrderSave.php @@ -163,7 +163,9 @@ class OrderSave if (isset($quoteItemId['id'])) { //This is a product item $item = $order->getItemByQuoteItemId($quoteItemId['id']); - $itemId = $item->getId(); + if ($item !== null && $item->getId()) { + $itemId = $item->getId(); + } } elseif (isset($quoteItemId['associated_item_id'])) { //This item is associated with a product item $item = $order->getItemByQuoteItemId($quoteItemId['associated_item_id']); diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json index 140b0ee8450cd3872f7882af4bb5c9dbfa24c472..1d09fb64eed893b1257cc3c6f399bda00ca77322 100644 --- a/app/code/Magento/Tax/composer.json +++ b/app/code/Magento/Tax/composer.json @@ -22,7 +22,7 @@ "magento/module-tax-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Theme/Model/Config/Processor/DesignTheme.php b/app/code/Magento/Theme/Model/Config/Processor/DesignTheme.php index 258be67979ed2fd5e896dc0b68b74ef2b73bca1a..d9d2c0e041e990d6b008be0816c67e613a3d4032 100644 --- a/app/code/Magento/Theme/Model/Config/Processor/DesignTheme.php +++ b/app/code/Magento/Theme/Model/Config/Processor/DesignTheme.php @@ -72,8 +72,8 @@ class DesignTheme implements PreProcessorInterface private function changeThemeFullPathToIdentifier($configItems) { $theme = null; - if ($this->arrayManager->exists(DesignInterface::XML_PATH_THEME_ID, $configItems)) { - $themeIdentifier = $this->arrayManager->get(DesignInterface::XML_PATH_THEME_ID, $configItems); + $themeIdentifier = $this->arrayManager->get(DesignInterface::XML_PATH_THEME_ID, $configItems); + if (!empty($themeIdentifier)) { if (!is_numeric($themeIdentifier)) { // workaround for case when db is not available try { diff --git a/app/code/Magento/Theme/Test/Unit/Model/Config/Processor/DesignThemeTest.php b/app/code/Magento/Theme/Test/Unit/Model/Config/Processor/DesignThemeTest.php index 1f3ab5642f47190569de2837b491f9207fc3a943..bb2160f1e293de80dbcbd3e5685e06452447d1dd 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Config/Processor/DesignThemeTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Config/Processor/DesignThemeTest.php @@ -5,7 +5,6 @@ */ namespace Magento\Theme\Test\Unit\Model\Config\Processor; -use Magento\Config\App\Config\Source\DumpConfigSourceAggregated; use Magento\Framework\Stdlib\ArrayManager; use Magento\Framework\View\Design\Theme\ListInterface; use Magento\Theme\Model\Config\Processor\DesignTheme; @@ -78,6 +77,7 @@ class DesignThemeTest extends \PHPUnit\Framework\TestCase /** * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function getDumpConfigDataProvider() { @@ -163,6 +163,22 @@ class DesignThemeTest extends \PHPUnit\Framework\TestCase ], ], ], + [ + [ + 'websites' => [ + 'base' => [ + 'design' => ['theme' => ['theme_id' => '']], + ], + ], + ], + [ + 'websites' => [ + 'base' => [ + 'design' => ['theme' => ['theme_id' => '']], + ], + ], + ], + ], ]; } } diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index 3d3161c476ef1791797c76467e2d18124d68537a..4593eccd23dea1c3a06f47791e2c8b3e12f79b23 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -22,7 +22,7 @@ "magento/module-directory": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json index f7c581340eb2e1caf2997e1e109499a591041be4..a2504cdfbb9cd9da1b1f17743a08b6cdab199d1d 100644 --- a/app/code/Magento/Translation/composer.json +++ b/app/code/Magento/Translation/composer.json @@ -12,7 +12,7 @@ "magento/module-deploy": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json index f93b97b1b30fe32dd9785b6d04ba74fad37f0423..1f58c55ce61b683d7fad83f62d35982917fc5e37 100644 --- a/app/code/Magento/Ui/composer.json +++ b/app/code/Magento/Ui/composer.json @@ -13,7 +13,7 @@ "magento/module-config": "101.0.*" }, "type": "magento2-module", - "version": "101.0.0", + "version": "101.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json index db825c41f392b9ef94ec39344ef2adb186925000..32086222e43f147748f721b95978de56f9ba89ef 100644 --- a/app/code/Magento/UrlRewrite/composer.json +++ b/app/code/Magento/UrlRewrite/composer.json @@ -12,7 +12,7 @@ "magento/module-cms-url-rewrite": "100.2.*" }, "type": "magento2-module", - "version": "101.0.0", + "version": "101.0.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php b/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php index ee7d65e4847925068d0db6b97aa9acb9cd1d1610..3df6966fb01b38976d57061366dee93ce24e2588 100644 --- a/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php +++ b/app/code/Magento/Webapi/Model/Rest/Swagger/Generator.php @@ -204,14 +204,17 @@ class Generator extends AbstractSchemaGenerator protected function generatePathInfo($methodName, $httpMethodData, $tagName) { $methodData = $httpMethodData[Converter::KEY_METHOD]; + + $operationId = $this->typeProcessor->getOperationName($tagName, $methodData[Converter::KEY_METHOD]); + $operationId .= ucfirst($methodName); + $pathInfo = [ 'tags' => [$tagName], 'description' => $methodData['documentation'], - 'operationId' => $this->typeProcessor->getOperationName($tagName, $methodData[Converter::KEY_METHOD]) . - ucfirst($methodName) + 'operationId' => $operationId, ]; - $parameters = $this->generateMethodParameters($httpMethodData); + $parameters = $this->generateMethodParameters($httpMethodData, $operationId); if ($parameters) { $pathInfo['parameters'] = $parameters; } @@ -265,11 +268,12 @@ class Generator extends AbstractSchemaGenerator * Generate parameters based on method data * * @param array $httpMethodData + * @param string $operationId * @return array * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - private function generateMethodParameters($httpMethodData) + private function generateMethodParameters($httpMethodData, $operationId) { $bodySchema = []; $parameters = []; @@ -335,7 +339,7 @@ class Generator extends AbstractSchemaGenerator if ($bodySchema) { $bodyParam = []; - $bodyParam['name'] = '$body'; + $bodyParam['name'] = $operationId . 'Body'; $bodyParam['in'] = 'body'; $bodyParam['schema'] = $bodySchema; $parameters[] = $bodyParam; diff --git a/app/code/Magento/Webapi/Test/Unit/Model/Rest/Swagger/GeneratorTest.php b/app/code/Magento/Webapi/Test/Unit/Model/Rest/Swagger/GeneratorTest.php index 9883c3a2766e9668960fae48e0e441f280d8d274..611517df51657a8ae788d57e8110db815f73b242 100644 --- a/app/code/Magento/Webapi/Test/Unit/Model/Rest/Swagger/GeneratorTest.php +++ b/app/code/Magento/Webapi/Test/Unit/Model/Rest/Swagger/GeneratorTest.php @@ -223,7 +223,7 @@ class GeneratorTest extends \PHPUnit\Framework\TestCase ] ], // @codingStandardsIgnoreStart - '{"swagger":"2.0","info":{"version":"","title":""},"host":"magento.host","basePath":"/rest/default","schemes":["http://"],"tags":[{"name":"testModule5AllSoapAndRestV2","description":"AllSoapAndRestInterface"}],"paths":{"/V1/testModule5":{"post":{"tags":["testModule5AllSoapAndRestV2"],"description":"Add new item.","operationId":"' . self::OPERATION_NAME . 'Post","parameters":[{"name":"$body","in":"body","schema":{"required":["item"],"properties":{"item":{"$ref":"#/definitions/test-module5-v2-entity-all-soap-and-rest"}},"type":"object"}}],"responses":{"200":{"description":"200 Success.","schema":{"$ref":"#/definitions/test-module5-v2-entity-all-soap-and-rest"}},"401":{"description":"401 Unauthorized","schema":{"$ref":"#/definitions/error-response"}},"500":{"description":"Internal Server error","schema":{"$ref":"#/definitions/error-response"}},"default":{"description":"Unexpected error","schema":{"$ref":"#/definitions/error-response"}}}}}},"definitions":{"error-response":{"type":"object","properties":{"message":{"type":"string","description":"Error message"},"errors":{"$ref":"#/definitions/error-errors"},"code":{"type":"integer","description":"Error code"},"parameters":{"$ref":"#/definitions/error-parameters"},"trace":{"type":"string","description":"Stack trace"}},"required":["message"]},"error-errors":{"type":"array","description":"Errors list","items":{"$ref":"#/definitions/error-errors-item"}},"error-errors-item":{"type":"object","description":"Error details","properties":{"message":{"type":"string","description":"Error message"},"parameters":{"$ref":"#/definitions/error-parameters"}}},"error-parameters":{"type":"array","description":"Error parameters list","items":{"$ref":"#/definitions/error-parameters-item"}},"error-parameters-item":{"type":"object","description":"Error parameters item","properties":{"resources":{"type":"string","description":"ACL resource"},"fieldName":{"type":"string","description":"Missing or invalid field name"},"fieldValue":{"type":"string","description":"Incorrect field value"}}},"test-module5-v2-entity-all-soap-and-rest":{"type":"object","description":"Some Data Object","properties":{"price":{"type":"integer"}},"required":["price"]}}}' + '{"swagger":"2.0","info":{"version":"","title":""},"host":"magento.host","basePath":"/rest/default","schemes":["http://"],"tags":[{"name":"testModule5AllSoapAndRestV2","description":"AllSoapAndRestInterface"}],"paths":{"/V1/testModule5":{"post":{"tags":["testModule5AllSoapAndRestV2"],"description":"Add new item.","operationId":"' . self::OPERATION_NAME . 'Post","parameters":[{"name":"operationNamePostBody","in":"body","schema":{"required":["item"],"properties":{"item":{"$ref":"#/definitions/test-module5-v2-entity-all-soap-and-rest"}},"type":"object"}}],"responses":{"200":{"description":"200 Success.","schema":{"$ref":"#/definitions/test-module5-v2-entity-all-soap-and-rest"}},"401":{"description":"401 Unauthorized","schema":{"$ref":"#/definitions/error-response"}},"500":{"description":"Internal Server error","schema":{"$ref":"#/definitions/error-response"}},"default":{"description":"Unexpected error","schema":{"$ref":"#/definitions/error-response"}}}}}},"definitions":{"error-response":{"type":"object","properties":{"message":{"type":"string","description":"Error message"},"errors":{"$ref":"#/definitions/error-errors"},"code":{"type":"integer","description":"Error code"},"parameters":{"$ref":"#/definitions/error-parameters"},"trace":{"type":"string","description":"Stack trace"}},"required":["message"]},"error-errors":{"type":"array","description":"Errors list","items":{"$ref":"#/definitions/error-errors-item"}},"error-errors-item":{"type":"object","description":"Error details","properties":{"message":{"type":"string","description":"Error message"},"parameters":{"$ref":"#/definitions/error-parameters"}}},"error-parameters":{"type":"array","description":"Error parameters list","items":{"$ref":"#/definitions/error-parameters-item"}},"error-parameters-item":{"type":"object","description":"Error parameters item","properties":{"resources":{"type":"string","description":"ACL resource"},"fieldName":{"type":"string","description":"Missing or invalid field name"},"fieldValue":{"type":"string","description":"Incorrect field value"}}},"test-module5-v2-entity-all-soap-and-rest":{"type":"object","description":"Some Data Object","properties":{"price":{"type":"integer"}},"required":["price"]}}}' // @codingStandardsIgnoreEnd ], [ diff --git a/app/code/Magento/WishlistAnalytics/composer.json b/app/code/Magento/WishlistAnalytics/composer.json index 20f414c00c320f4e5709f1ea1f490741a7c17012..11bd71276427ca0d26950768a31a3d67b94242ac 100644 --- a/app/code/Magento/WishlistAnalytics/composer.json +++ b/app/code/Magento/WishlistAnalytics/composer.json @@ -7,7 +7,7 @@ "magento/module-wishlist": "100.2.*" }, "type": "magento2-module", - "version": "100.2.0-dev", + "version": "100.2.0", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json index 7251ba69b0f3c8e12f4c92082f6c248572850630..b5db1aa32b4a1252b1f09a5aeca9924504ce9d7c 100644 --- a/app/design/frontend/Magento/luma/composer.json +++ b/app/design/frontend/Magento/luma/composer.json @@ -7,7 +7,7 @@ "magento/framework": "101.0.*" }, "type": "magento2-theme", - "version": "100.2.0", + "version": "100.2.1", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/app/etc/di.xml b/app/etc/di.xml index 71168ab5220f781490d22e019bea285935457cec..e17505e78da311b5451ea8cb4ac7a4566ff7c91c 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1337,4 +1337,11 @@ <argument name="defaultExceptionMessageFactory" xsi:type="object">Magento\Framework\Message\ExceptionMessageFactory</argument> </arguments> </type> + <type name="Magento\Framework\Mview\View\Subscription"> + <arguments> + <argument name="ignoredUpdateColumns" xsi:type="array"> + <item name="updated_at" xsi:type="string">updated_at</item> + </argument> + </arguments> + </type> </config> diff --git a/bin/.htaccess b/bin/.htaccess index 896fbc5a341ea313ff3abd503808842757678c1d..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/bin/.htaccess +++ b/bin/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all \ No newline at end of file +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/composer.json b/composer.json index 07f6146ff8f733bdd96337fb22e1b68623f79c9e..be9457595726163f6a84d21c6e0454298dd78cee 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "magento/magento2ce", "description": "Magento 2 (Open Source)", "type": "project", - "version": "2.2.1-dev", + "version": "2.2.2-dev", "license": [ "OSL-3.0", "AFL-3.0" @@ -42,7 +42,7 @@ "composer/composer": "1.4.1", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", - "pelago/emogrifier": "0.1.1", + "pelago/emogrifier": "1.2.0", "tubalmartin/cssmin": "4.1.0", "magento/magento-composer-installer": ">=0.1.11", "braintree/braintree_php": "3.25.0", @@ -84,43 +84,43 @@ "replace": { "magento/module-marketplace": "100.2.0", "magento/module-admin-notification": "100.2.0", - "magento/module-advanced-pricing-import-export": "100.2.0", - "magento/module-analytics": "100.2.0-dev", + "magento/module-advanced-pricing-import-export": "100.2.1", + "magento/module-analytics": "100.2.0", "magento/module-authorization": "100.2.0", "magento/module-authorizenet": "100.2.0", - "magento/module-backend": "100.2.0", + "magento/module-backend": "100.2.1", "magento/module-backup": "100.2.0", - "magento/module-braintree": "100.2.0", - "magento/module-bundle": "100.2.0", + "magento/module-braintree": "100.2.1", + "magento/module-bundle": "100.2.1", "magento/module-bundle-import-export": "100.2.0", "magento/module-cache-invalidate": "100.2.0", "magento/module-captcha": "100.2.0", - "magento/module-catalog": "102.0.0", - "magento/module-catalog-analytics": "100.2.0-dev", - "magento/module-catalog-import-export": "100.2.0", - "magento/module-catalog-inventory": "100.2.0", - "magento/module-catalog-rule": "101.0.0", + "magento/module-catalog": "102.0.1", + "magento/module-catalog-analytics": "100.2.0", + "magento/module-catalog-import-export": "100.2.1", + "magento/module-catalog-inventory": "100.2.1", + "magento/module-catalog-rule": "101.0.1", "magento/module-catalog-rule-configurable": "100.2.0", - "magento/module-catalog-search": "100.2.0", - "magento/module-catalog-url-rewrite": "100.2.0", + "magento/module-catalog-search": "100.2.1", + "magento/module-catalog-url-rewrite": "100.2.1", "magento/module-catalog-widget": "100.2.0", - "magento/module-checkout": "100.2.0", + "magento/module-checkout": "100.2.1", "magento/module-checkout-agreements": "100.2.0", - "magento/module-cms": "102.0.0", + "magento/module-cms": "102.0.1", "magento/module-cms-url-rewrite": "100.2.0", - "magento/module-config": "101.0.0", + "magento/module-config": "101.0.1", "magento/module-configurable-import-export": "100.2.0", - "magento/module-configurable-product": "100.2.0", + "magento/module-configurable-product": "100.2.1", "magento/module-configurable-product-sales": "100.2.0", "magento/module-contact": "100.2.0", "magento/module-cookie": "100.2.0", "magento/module-cron": "100.2.0", "magento/module-currency-symbol": "100.2.0", - "magento/module-customer": "101.0.0", - "magento/module-customer-analytics": "100.2.0-dev", + "magento/module-customer": "101.0.1", + "magento/module-customer-analytics": "100.2.0", "magento/module-customer-import-export": "100.2.0", - "magento/module-deploy": "100.2.0", - "magento/module-developer": "100.2.0", + "magento/module-deploy": "100.2.1", + "magento/module-developer": "100.2.1", "magento/module-dhl": "100.2.0", "magento/module-directory": "100.2.0", "magento/module-downloadable": "100.2.0", @@ -131,11 +131,11 @@ "magento/module-fedex": "100.2.0", "magento/module-gift-message": "100.2.0", "magento/module-google-adwords": "100.2.0", - "magento/module-google-analytics": "100.2.0", + "magento/module-google-analytics": "100.2.1", "magento/module-google-optimizer": "100.2.0", "magento/module-grouped-import-export": "100.2.0", "magento/module-grouped-product": "100.2.0", - "magento/module-import-export": "100.2.0", + "magento/module-import-export": "100.2.1", "magento/module-indexer": "100.2.0", "magento/module-instant-purchase": "100.2.0", "magento/module-integration": "100.2.0", @@ -153,39 +153,39 @@ "magento/module-persistent": "100.2.0", "magento/module-product-alert": "100.2.0", "magento/module-product-video": "100.2.0", - "magento/module-quote": "101.0.0", - "magento/module-quote-analytics": "100.2.0-dev", + "magento/module-quote": "101.0.1", + "magento/module-quote-analytics": "100.2.0", "magento/module-release-notification": "100.2.0", - "magento/module-reports": "100.2.0", + "magento/module-reports": "100.2.1", "magento/module-require-js": "100.2.0", - "magento/module-review": "100.2.0", - "magento/module-review-analytics": "100.2.0-dev", + "magento/module-review": "100.2.1", + "magento/module-review-analytics": "100.2.0", "magento/module-robots": "100.2.0", "magento/module-rss": "100.2.0", "magento/module-rule": "100.2.0", - "magento/module-sales": "101.0.0", - "magento/module-sales-analytics": "100.2.0-dev", + "magento/module-sales": "101.0.1", + "magento/module-sales-analytics": "100.2.0", "magento/module-sales-inventory": "100.2.0", "magento/module-sales-rule": "101.0.0", "magento/module-sales-sequence": "100.2.0", "magento/module-sample-data": "100.2.0", - "magento/module-search": "100.2.0", + "magento/module-search": "100.2.1", "magento/module-security": "100.2.0", "magento/module-send-friend": "100.2.0", - "magento/module-shipping": "100.2.0", - "magento/module-signifyd": "100.2.0", - "magento/module-sitemap": "100.2.0", - "magento/module-store": "100.2.0", - "magento/module-swagger": "100.2.0", + "magento/module-shipping": "100.2.1", + "magento/module-signifyd": "100.2.1", + "magento/module-sitemap": "100.2.1", + "magento/module-store": "100.2.1", + "magento/module-swagger": "100.2.1", "magento/module-swatches": "100.2.0", "magento/module-swatches-layered-navigation": "100.2.0", - "magento/module-tax": "100.2.0", + "magento/module-tax": "100.2.1", "magento/module-tax-import-export": "100.2.0", - "magento/module-theme": "100.2.0", - "magento/module-translation": "100.2.0", - "magento/module-ui": "101.0.0", + "magento/module-theme": "100.2.1", + "magento/module-translation": "100.2.1", + "magento/module-ui": "101.0.1", "magento/module-ups": "100.2.0", - "magento/module-url-rewrite": "101.0.0", + "magento/module-url-rewrite": "101.0.1", "magento/module-user": "101.0.0", "magento/module-usps": "100.2.0", "magento/module-variable": "100.2.0", @@ -196,10 +196,10 @@ "magento/module-weee": "100.2.0", "magento/module-widget": "101.0.0", "magento/module-wishlist": "101.0.0", - "magento/module-wishlist-analytics": "100.2.0-dev", + "magento/module-wishlist-analytics": "100.2.0", "magento/theme-adminhtml-backend": "100.2.0", "magento/theme-frontend-blank": "100.2.0", - "magento/theme-frontend-luma": "100.2.0", + "magento/theme-frontend-luma": "100.2.1", "magento/language-de_de": "100.2.0", "magento/language-en_us": "100.2.0", "magento/language-es_es": "100.2.0", @@ -207,7 +207,7 @@ "magento/language-nl_nl": "100.2.0", "magento/language-pt_br": "100.2.0", "magento/language-zh_hans_cn": "100.2.0", - "magento/framework": "101.0.0", + "magento/framework": "101.0.1", "trentrichardson/jquery-timepicker-addon": "1.4.3", "components/jquery": "1.11.0", "blueimp/jquery-file-upload": "5.6.14", diff --git a/composer.lock b/composer.lock index 95b0874999035bfac01fa594cd9be2a1d6b32ba1..c126da645a6defe360a25b31ddfddb133f99c1a2 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": "99d9f3e6dd367aa12805bfbf64342ffe", - "content-hash": "77b4e986abaee3aada29cd9aa9ff9531", + "hash": "923fde043cfee16a442bb4e85cc032c6", + "content-hash": "da93a2422778d99a80c69037a53d447a", "packages": [ { "name": "braintree/braintree_php", @@ -960,27 +960,31 @@ }, { "name": "pelago/emogrifier", - "version": "v0.1.1", + "version": "V1.2.0", "source": { "type": "git", "url": "https://github.com/jjriv/emogrifier.git", - "reference": "ed72bcd6a3c7014862ff86d026193667a172fedf" + "reference": "a1db453bb504597d821efcc04b21c79a6021e00c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jjriv/emogrifier/zipball/ed72bcd6a3c7014862ff86d026193667a172fedf", - "reference": "ed72bcd6a3c7014862ff86d026193667a172fedf", + "url": "https://api.github.com/repos/jjriv/emogrifier/zipball/a1db453bb504597d821efcc04b21c79a6021e00c", + "reference": "a1db453bb504597d821efcc04b21c79a6021e00c", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": ">=5.4.0" + "php": ">=5.4.0,<=7.1.99" }, "require-dev": { - "phpunit/phpunit": "~4.6.0", - "squizlabs/php_codesniffer": "~2.3.0" + "phpunit/phpunit": "4.8.27", + "squizlabs/php_codesniffer": "2.6.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, "autoload": { "psr-4": { "Pelago\\": "Classes/" @@ -1012,7 +1016,7 @@ ], "description": "Converts CSS styles into inline style attributes in your HTML code", "homepage": "http://www.pelagodesign.com/sidecar/emogrifier/", - "time": "2015-05-15 11:37:51" + "time": "2017-03-02 12:51:48" }, { "name": "phpseclib/phpseclib", @@ -1530,16 +1534,16 @@ }, { "name": "symfony/console", - "version": "v2.8.28", + "version": "v2.8.29", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f81549d2c5fdee8d711c9ab3c7e7362353ea5853" + "reference": "89143ce2b463515a75b5f5e9650e6ecfb2684158" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f81549d2c5fdee8d711c9ab3c7e7362353ea5853", - "reference": "f81549d2c5fdee8d711c9ab3c7e7362353ea5853", + "url": "https://api.github.com/repos/symfony/console/zipball/89143ce2b463515a75b5f5e9650e6ecfb2684158", + "reference": "89143ce2b463515a75b5f5e9650e6ecfb2684158", "shasum": "" }, "require": { @@ -1587,7 +1591,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-10-01 21:00:16" + "time": "2017-11-07 14:08:47" }, { "name": "symfony/debug", @@ -1648,16 +1652,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.28", + "version": "v2.8.29", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "7fe089232554357efb8d4af65ce209fc6e5a2186" + "reference": "b59aacf238fadda50d612c9de73b74751872a903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7fe089232554357efb8d4af65ce209fc6e5a2186", - "reference": "7fe089232554357efb8d4af65ce209fc6e5a2186", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b59aacf238fadda50d612c9de73b74751872a903", + "reference": "b59aacf238fadda50d612c9de73b74751872a903", "shasum": "" }, "require": { @@ -1704,20 +1708,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-10-01 21:00:16" + "time": "2017-11-05 15:25:56" }, { "name": "symfony/filesystem", - "version": "v3.3.10", + "version": "v3.3.11", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "90bc45abf02ae6b7deb43895c1052cb0038506f1" + "reference": "77db266766b54db3ee982fe51868328b887ce15c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/90bc45abf02ae6b7deb43895c1052cb0038506f1", - "reference": "90bc45abf02ae6b7deb43895c1052cb0038506f1", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/77db266766b54db3ee982fe51868328b887ce15c", + "reference": "77db266766b54db3ee982fe51868328b887ce15c", "shasum": "" }, "require": { @@ -1753,20 +1757,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2017-10-03 13:33:10" + "time": "2017-11-07 14:12:55" }, { "name": "symfony/finder", - "version": "v3.3.10", + "version": "v3.3.11", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "773e19a491d97926f236942484cb541560ce862d" + "reference": "138af5ec075d4b1d1bd19de08c38a34bb2d7d880" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/773e19a491d97926f236942484cb541560ce862d", - "reference": "773e19a491d97926f236942484cb541560ce862d", + "url": "https://api.github.com/repos/symfony/finder/zipball/138af5ec075d4b1d1bd19de08c38a34bb2d7d880", + "reference": "138af5ec075d4b1d1bd19de08c38a34bb2d7d880", "shasum": "" }, "require": { @@ -1802,7 +1806,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-10-02 06:42:24" + "time": "2017-11-05 15:47:03" }, { "name": "symfony/polyfill-mbstring", @@ -1865,16 +1869,16 @@ }, { "name": "symfony/process", - "version": "v2.8.28", + "version": "v2.8.29", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "26c9fb02bf06bd6b90f661a5bd17e510810d0176" + "reference": "d25449e031f600807949aab7cadbf267712f4eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/26c9fb02bf06bd6b90f661a5bd17e510810d0176", - "reference": "26c9fb02bf06bd6b90f661a5bd17e510810d0176", + "url": "https://api.github.com/repos/symfony/process/zipball/d25449e031f600807949aab7cadbf267712f4eee", + "reference": "d25449e031f600807949aab7cadbf267712f4eee", "shasum": "" }, "require": { @@ -1910,7 +1914,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-10-01 21:00:16" + "time": "2017-11-05 15:25:56" }, { "name": "tedivm/jshrink", @@ -4079,16 +4083,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.2.9", + "version": "v2.2.10", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "eace538b022a2b7db59ef7b5460cb8c66cb20b50" + "reference": "b0e0f1d3d0b36a728768f9c44b074b22eb4b4c64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/eace538b022a2b7db59ef7b5460cb8c66cb20b50", - "reference": "eace538b022a2b7db59ef7b5460cb8c66cb20b50", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/b0e0f1d3d0b36a728768f9c44b074b22eb4b4c64", + "reference": "b0e0f1d3d0b36a728768f9c44b074b22eb4b4c64", "shasum": "" }, "require": { @@ -4160,7 +4164,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2017-11-02 12:46:49" + "time": "2017-11-09 13:20:53" }, { "name": "gecko-packages/gecko-php-unit", @@ -5872,16 +5876,16 @@ }, { "name": "symfony/config", - "version": "v3.3.10", + "version": "v3.3.11", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "4ab62407bff9cd97c410a7feaef04c375aaa5cfd" + "reference": "8d2649077dc54dfbaf521d31f217383d82303c5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/4ab62407bff9cd97c410a7feaef04c375aaa5cfd", - "reference": "4ab62407bff9cd97c410a7feaef04c375aaa5cfd", + "url": "https://api.github.com/repos/symfony/config/zipball/8d2649077dc54dfbaf521d31f217383d82303c5f", + "reference": "8d2649077dc54dfbaf521d31f217383d82303c5f", "shasum": "" }, "require": { @@ -5930,20 +5934,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2017-10-04 18:56:58" + "time": "2017-11-07 14:16:22" }, { "name": "symfony/dependency-injection", - "version": "v3.3.10", + "version": "v3.3.11", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "8ebad929aee3ca185b05f55d9cc5521670821ad1" + "reference": "50cdc753c61a4268608226647b0ce72e33a4a2b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/8ebad929aee3ca185b05f55d9cc5521670821ad1", - "reference": "8ebad929aee3ca185b05f55d9cc5521670821ad1", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/50cdc753c61a4268608226647b0ce72e33a4a2b1", + "reference": "50cdc753c61a4268608226647b0ce72e33a4a2b1", "shasum": "" }, "require": { @@ -6000,20 +6004,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2017-10-04 17:15:30" + "time": "2017-11-07 14:12:55" }, { "name": "symfony/options-resolver", - "version": "v3.3.10", + "version": "v3.3.11", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6" + "reference": "623d9c210a137205f7e6e98166105625402cbb2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/ee4e22978fe885b54ee5da8c7964f0a5301abfb6", - "reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/623d9c210a137205f7e6e98166105625402cbb2f", + "reference": "623d9c210a137205f7e6e98166105625402cbb2f", "shasum": "" }, "require": { @@ -6054,7 +6058,7 @@ "configuration", "options" ], - "time": "2017-07-29 21:54:42" + "time": "2017-11-05 15:47:03" }, { "name": "symfony/polyfill-php54", @@ -6286,16 +6290,16 @@ }, { "name": "symfony/stopwatch", - "version": "v3.3.10", + "version": "v3.3.11", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "170edf8b3247d7b6779eb6fa7428f342702ca184" + "reference": "1e93c3139ef6c799831fe03efd0fb1c7aecb3365" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/170edf8b3247d7b6779eb6fa7428f342702ca184", - "reference": "170edf8b3247d7b6779eb6fa7428f342702ca184", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/1e93c3139ef6c799831fe03efd0fb1c7aecb3365", + "reference": "1e93c3139ef6c799831fe03efd0fb1c7aecb3365", "shasum": "" }, "require": { @@ -6331,7 +6335,7 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2017-10-02 06:42:24" + "time": "2017-11-10 19:02:53" }, { "name": "theseer/fdomdocument", diff --git a/dev/.htaccess b/dev/.htaccess index 93169e4eb44ffa5e6251f3532bb1902854703f07..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/dev/.htaccess +++ b/dev/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/JsonGenerationFromDataObjectTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/JsonGenerationFromDataObjectTest.php index 67068e3a11aa9093ea8fac4997f52668b5ff5f64..9a3fac9e8739ff60e322ef807c6a2699a1fa7e23 100644 --- a/dev/tests/api-functional/testsuite/Magento/Webapi/JsonGenerationFromDataObjectTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Webapi/JsonGenerationFromDataObjectTest.php @@ -10,6 +10,7 @@ namespace Magento\Webapi; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\App\ProductMetadataInterface; +use Magento\Store\Model\StoreManagerInterface; /** * Test REST schema generation mechanisms. @@ -34,10 +35,10 @@ class JsonGenerationFromDataObjectTest extends \Magento\TestFramework\TestCase\W { $this->_markTestAsRestOnly("JSON generation tests are intended to be executed for REST adapter only."); - $this->storeCode = Bootstrap::getObjectManager()->get(\Magento\Store\Model\StoreManagerInterface::class) + $this->storeCode = Bootstrap::getObjectManager()->get(StoreManagerInterface::class) ->getStore()->getCode(); - $this->productMetadata = Bootstrap::getObjectManager()->get(\Magento\Framework\App\ProductMetadataInterface::class); + $this->productMetadata = Bootstrap::getObjectManager()->get(ProductMetadataInterface::class); parent::setUp(); } @@ -197,7 +198,7 @@ class JsonGenerationFromDataObjectTest extends \Magento\TestFramework\TestCase\W 'required' => true ], [ - 'name' => '$body', + 'name' => 'testModule5AllSoapAndRestV1NestedUpdatePutBody', 'in' => 'body', 'schema' => [ 'required' => [ diff --git a/dev/tests/functional/.htaccess.sample b/dev/tests/functional/.htaccess.sample index d089eb3c4f848b6c247eedc8746747faab4d3e8d..67c2f3fe2d027314bbfa03a1ae5167f356c32262 100644 --- a/dev/tests/functional/.htaccess.sample +++ b/dev/tests/functional/.htaccess.sample @@ -1,6 +1,11 @@ ############################################## ## Allow access to command.php, website.php, export.php, pathChecker.php, locales.php, deleteMagentoGeneratedCode.php and log.php <FilesMatch "command.php|website.php|export.php|pathChecker.php|deleteMagentoGeneratedCode.php|log.php|locales.php"> - order allow,deny - allow from all + <IfVersion < 2.4> + order allow,deny + allow from all + </IfVersion> + <IfVersion >= 2.4> + Require all granted + </IfVersion> </FilesMatch> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerBackendEntity.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerBackendEntity.xml index 4692d21575813e13b38da4f3fcd55b0cd8d4933b..5990157d6c5ea581d74b189f08ec6713c3484777 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerBackendEntity.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerBackendEntity.xml @@ -8,7 +8,6 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Customer\Test\TestCase\CreateExistingCustomerBackendEntity" summary="Create Existing Customer from Backend" ticketId="MAGETWO-43685"> <variation name="CreateExistingCustomerBackendEntity1" summary="Create existing customer on Backend."> - <data name="tag" xsi:type="string">stable:no</data> <data name="customer/dataset" xsi:type="string">default</data> <constraint name="Magento\Customer\Test\Constraint\AssertCustomerBackendDuplicateErrorMessage" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/LoginCustomerOnFrontendStep.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/LoginCustomerOnFrontendStep.php index dc5d6076731c65c7e79b0753ac677ba543215dca..7e4dee70726797493155fd5fd91cc47129a0f2f3 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/LoginCustomerOnFrontendStep.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestStep/LoginCustomerOnFrontendStep.php @@ -75,6 +75,8 @@ class LoginCustomerOnFrontendStep implements TestStepInterface $this->cmsIndex->getCmsPageBlock()->waitPageInit(); $this->customerAccountLogin->getLoginBlock()->login($this->customer); $this->cmsIndex->getCmsPageBlock()->waitPageInit(); + $this->cmsIndex->getLinksBlock()->openLink('My Account'); + $this->cmsIndex->getCmsPageBlock()->waitPageInit(); } /** diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml index 9d1c356136130a2bae37d118295e5765663e3cac..2b407e3d39200506957077bb033bccfc470f8e92 100644 --- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml +++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.xml @@ -42,7 +42,6 @@ <constraint name="Magento\Install\Test\Constraint\AssertRewritesEnabled" /> </variation> <variation name="InstallTestVariation5" summary="Install with enabled secure urls"> - <data name="tag" xsi:type="string">stable:no</data> <data name="user/dataset" xsi:type="string">default</data> <data name="install/httpsFront" xsi:type="string">Use HTTPS for Magento Storefront</data> <data name="install/httpsAdmin" xsi:type="string">Use HTTPS for Magento Admin</data> diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Install/Test/etc/di.xml new file mode 100644 index 0000000000000000000000000000000000000000..aea0106d1ca16b7b80b03b8fe3a4599d4f2bfe7d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Install/Test/etc/di.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\Config\Test\Handler\ConfigData\ConfigDataInterface" type="Magento\Config\Test\Handler\ConfigData\Curl" /> + <preference for="Magento\Integration\Test\Handler\Integration\IntegrationInterface" type="Magento\Integration\Test\Handler\Integration\Curl" /> +</config> diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductWithSeveralWebsitesUrlRewriteTest.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductWithSeveralWebsitesUrlRewriteTest.xml index 91de39b384c354f23a55d848345019510968eadb..98e3f9e38382d89a0dc3002865580b8a31ab670e 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductWithSeveralWebsitesUrlRewriteTest.xml +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductWithSeveralWebsitesUrlRewriteTest.xml @@ -8,7 +8,6 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\UrlRewrite\Test\TestCase\CreateProductWithSeveralWebsitesUrlRewriteTest" summary="Test product url rewrites when it is created in several websites"> <variation name="CreateSimpleProductEntityWithSeveralWebsites" summary="Create product with several websites and check URL Rewites" ticketId="MAGETWO-27238"> - <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> diff --git a/dev/tests/integration/testsuite/Magento/Braintree/Controller/Adminhtml/Payment/GetClientTokenTest.php b/dev/tests/integration/testsuite/Magento/Braintree/Controller/Adminhtml/Payment/GetClientTokenTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7546f20a42de9d30b6bf59ed3e2fa764de8ed8a6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Braintree/Controller/Adminhtml/Payment/GetClientTokenTest.php @@ -0,0 +1,151 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Braintree\Controller\Adminhtml\Payment; + +use Braintree\Configuration; +use Magento\Backend\Model\Session\Quote; +use Magento\Braintree\Gateway\Config\Config; +use Magento\Braintree\Model\Adapter\BraintreeAdapter; +use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Store\Api\StoreRepositoryInterface; +use Magento\TestFramework\TestCase\AbstractBackendController; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +class GetClientTokenTest extends AbstractBackendController +{ + /** + * @var Quote + */ + private $quoteSession; + + /** + * @var ObjectManager|MockObject $stubObjectManager + */ + private $stubObjectManager; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->quoteSession = $this->_objectManager->get(Quote::class); + + $this->stubObjectManager = $this->getMockBuilder(ObjectManager::class) + ->disableOriginalConstructor() + ->getMock(); + + $adapterFactory = new BraintreeAdapterFactory( + $this->stubObjectManager, + $this->_objectManager->get(Config::class) + ); + + $this->_objectManager->addSharedInstance($adapterFactory, BraintreeAdapterFactory::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->_objectManager->removeSharedInstance(BraintreeAdapterFactory::class); + parent::tearDown(); + } + + /** + * Checks if client token will retrieved from Braintree initialized with default scope. + * + * @magentoDataFixture Magento/Braintree/_files/payment_configuration.php + * @magentoAppArea adminhtml + */ + public function testExecute() + { + $this->perform( + 'def_merchant_id', + 'def_public_key', + 'def_private_key' + ); + } + + /** + * Checks if client token will be retrieved from Braintree initialized per store. + * + * @magentoDataFixture Magento/Braintree/_files/payment_configuration.php + * @magentoAppArea adminhtml + */ + public function testExecuteWithStoreConfiguration() + { + /** @var StoreRepositoryInterface $storeRepository */ + $storeRepository = $this->_objectManager->get(StoreRepositoryInterface::class); + $store = $storeRepository->get('test'); + $this->quoteSession->setStoreId($store->getId()); + + $this->perform( + 'store_merchant_id', + 'store_public_key', + 'def_private_key' // should be read from default scope + ); + } + + /** + * Checks if client token will be retrieved from Braintree initialized per website. + * + * @magentoDataFixture Magento/Braintree/_files/payment_configuration.php + * @magentoAppArea adminhtml + */ + public function testExecuteWithWebsiteConfiguration() + { + /** @var StoreRepositoryInterface $storeRepository */ + $storeRepository = $this->_objectManager->get(StoreRepositoryInterface::class); + $store = $storeRepository->get('fixture_second_store'); + $this->quoteSession->setStoreId($store->getId()); + + $this->perform( + 'website_merchant_id', + 'def_public_key', // should be read from default scope + 'website_private_key' + ); + } + + private function perform($merchantId, $publicKey, $privateKey) + { + $args = [ + 'merchantId' => $merchantId, + 'publicKey' => $publicKey, + 'privateKey' => $privateKey, + 'environment' => 'sandbox' + ]; + + $adapter = $this->getMockBuilder(BraintreeAdapter::class) + ->setConstructorArgs($args) + ->setMethods(['generate']) + ->getMock(); + $adapter->method('generate') + ->willReturn('client_token'); + + $this->stubObjectManager->method('create') + ->with(BraintreeAdapter::class, $args) + ->willReturn($adapter); + + $this->dispatch('backend/braintree/payment/getClientToken'); + + /** @var SerializerInterface $serializer */ + $serializer = $this->_objectManager->get(SerializerInterface::class); + $decoded = $serializer->unserialize($this->getResponse()->getBody()); + $this->performAsserts($decoded['clientToken'], $merchantId, $publicKey, $privateKey); + } + + private function performAsserts($clientToken, $merchantId, $publicKey, $privateKey) + { + self::assertEquals('client_token', $clientToken); + self::assertEquals(Configuration::merchantId(), $merchantId); + self::assertEquals(Configuration::publicKey(), $publicKey); + self::assertEquals(Configuration::privateKey(), $privateKey); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Braintree/_files/payment_configuration.php b/dev/tests/integration/testsuite/Magento/Braintree/_files/payment_configuration.php new file mode 100644 index 0000000000000000000000000000000000000000..da87ad5311d9217b909088ff7d304c4869901618 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Braintree/_files/payment_configuration.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Config\Model\Config; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var EncryptorInterface $encryptor */ +$encryptor = $objectManager->get(EncryptorInterface::class); + +$processConfigData = function (Config $config, array $data) { + foreach ($data as $key => $value) { + $config->setDataByPath($key, $value); + $config->save(); + } +}; + +// save payment configuration for the default scope +$configData = [ + 'payment/braintree/merchant_id' => 'def_merchant_id', + 'payment/braintree/public_key' => $encryptor->encrypt('def_public_key'), + 'payment/braintree/private_key' => $encryptor->encrypt('def_private_key'), +]; +/** @var Config $defConfig */ +$defConfig = $objectManager->create(Config::class); +$defConfig->setScope(ScopeConfigInterface::SCOPE_TYPE_DEFAULT); +$processConfigData($defConfig, $configData); + +// save payment configuration per store +require __DIR__ . '/../../Store/_files/store.php'; +$storeConfigData = [ + 'payment/braintree/merchant_id' => 'store_merchant_id', + 'payment/braintree/public_key' => $encryptor->encrypt('store_public_key'), +]; +/** @var Config $storeConfig */ +$storeConfig = $objectManager->create(Config::class); +$storeConfig->setScope(ScopeInterface::SCOPE_STORES); +$storeConfig->setStore('test'); +$processConfigData($storeConfig, $storeConfigData); + +// save payment website config data +require __DIR__ . '/../../Store/_files/second_website_with_two_stores.php'; +$websiteConfigData = [ + 'payment/braintree/merchant_id' => 'website_merchant_id', + 'payment/braintree/private_key' => $encryptor->encrypt('website_private_key'), +]; +/** @var Config $websiteConfig */ +$websiteConfig = $objectManager->create(Config::class); +$websiteConfig->setScope(ScopeInterface::SCOPE_WEBSITES); +$websiteConfig->setWebsite($websiteId); +$processConfigData($websiteConfig, $websiteConfigData); diff --git a/dev/tests/integration/testsuite/Magento/Braintree/_files/payment_configuration_rollback.php b/dev/tests/integration/testsuite/Magento/Braintree/_files/payment_configuration_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..0c0391769b09317bbd9a7c6a34d7751b038e949b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Braintree/_files/payment_configuration_rollback.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Storage\WriterInterface; +use Magento\Store\Api\StoreRepositoryInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +$deleteConfigData = function (WriterInterface $writer, $scope, $scopeId) { + $configData = [ + 'payment/braintree/merchant_id', + 'payment/braintree/public_key', + 'payment/braintree/private_key', + ]; + foreach ($configData as $path) { + $writer->delete($path, $scope, $scopeId); + } +}; + +/** @var WriterInterface $configWriter */ +$configWriter = $objectManager->get(WriterInterface::class); +$deleteConfigData($configWriter, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null); + +/** @var StoreRepositoryInterface $storeRepository */ +$storeRepository = $objectManager->get(StoreRepositoryInterface::class); +$store = $storeRepository->get('test'); +$deleteConfigData($configWriter, ScopeInterface::SCOPE_STORES, $store->getId()); + +/** @var WebsiteRepositoryInterface $websiteRepository */ +$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class); +$website = $websiteRepository->get('test'); +$deleteConfigData($configWriter, ScopeInterface::SCOPE_WEBSITES, $website->getId()); + +require __DIR__ . '/../../Store/_files/second_website_with_two_stores_rollback.php'; +require __DIR__ . '/../../Store/_files/store_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/CategoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cea50218638cb0399af257c50f70c2a64b14fb7d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/CategoryTest.php @@ -0,0 +1,209 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Model\Indexer\Product; + +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\Product; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Model\ResourceModel\Product as ProductResource; +use Magento\Indexer\Model\Indexer; +use PHPUnit\Framework\TestCase; + +/** + * @magentoDataFixture Magento/Catalog/_files/indexer_catalog_product_categories.php + * @magentoDataFixture Magento/Catalog/_files/indexer_catalog_products.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + */ +class CategoryTest extends TestCase +{ + const DEFAULT_ROOT_CATEGORY = 2; + + /** + * @var Indexer + */ + private $indexer; + + /** + * @var ProductResource + */ + private $productResource; + + protected function setUp() + { + /** @var Indexer indexer */ + $this->indexer = Bootstrap::getObjectManager()->create( + Indexer::class + ); + $this->indexer->load('catalog_product_category'); + /** @var ProductResource $productResource */ + $this->productResource = Bootstrap::getObjectManager()->get( + ProductResource::class + ); + } + + /** + * Check that given product is only visible in given categories. + * + * @param Product $product + * @param Category[] $categoriesIn Categories the product is supposed + * to be in. + * @param Category[] $categories Whole list of categories. + * + * @return void + */ + private function assertProductIn( + Product $product, + array $categoriesIn, + array $categories + ) { + foreach ($categories as $category) { + $visible = in_array($category, $categoriesIn, true); + $this->assertEquals( + $visible, + (bool)$this->productResource->canBeShowInCategory( + $product, + $category->getId() + ), + 'Product "' .$product->getName() .'" is' + .($visible? '' : ' not') .' supposed to be in category "' + .$category->getName() .'"' + ); + } + } + + /** + * @magentoAppArea adminhtml + */ + public function testReindexAll() + { + //Category #1 is base category for this case, Category #2 is non-anchor + //sub-category of Category #1, Category #3 is anchor sub-category of + //Category #2, Category #4 is anchor sub-category of Category #1 + //Products are not yet assigned to categories + $categories = $this->loadCategories(4); + $products = $this->loadProducts(3); + + //Leaving Product #1 unassigned, Product #2 is assigned to Category #3, + //Product #3 assigned to Category #3 and #4. + $products[0]->setCategoryIds(null); + $this->productResource->save($products[0]); + $products[1]->setCategoryIds([$categories[2]->getId()]); + $this->productResource->save($products[1]); + $products[2]->setCategoryIds([ + $categories[2]->getId(), + $categories[3]->getId(), + ]); + $this->productResource->save($products[2]); + //Reindexing + $this->clearIndex(); + $this->indexer->reindexAll(); + + //Checking that Category #1 shows only Product #2 and #3 since + //Product #1 is not assigned to any category, Product #2 is assigned to + //it's sub-subcategory and Product #3 is assigned to a sub-subcategory + //and a subcategory. + //Category #2 doesn't have any products on display because while it's + //sub-category has products it's a non-anchor category. + //Category #3 has 2 products directly assigned to it. + //Category #4 only has 1 product directly assigned to it. + $this->assertProductIn($products[0], [], $categories); + $this->assertProductIn( + $products[1], + [$categories[0],$categories[2]], + $categories + ); + $this->assertProductIn( + $products[2], + [$categories[0], $categories[2], $categories[3]], + $categories + ); + + //Reassigning products a bit + $products[0]->setCategoryIds([$categories[0]->getId()]); + $this->productResource->save($products[0]); + $products[1]->setCategoryIds([]); + $this->productResource->save($products[1]); + $products[2]->setCategoryIds([ + $categories[1]->getId(), + $categories[2]->getId(), + $categories[3]->getId(), + ]); + $this->productResource->save($products[2]); + //Reindexing + $this->clearIndex(); + $this->indexer->reindexAll(); + //Checking that Category #1 now also shows Product #1 because it was + //directly assigned to it and not showing Product #2 because it was + //unassigned from Category #3. + //Category #2 now shows Product #3 because it was directly assigned + //to it. + //Category #3 now shows only Product #3 because Product #2 + //was unassigned. + //Category #4 still shows only Product #3. + $this->assertProductIn($products[0], [$categories[0]], $categories); + $this->assertProductIn($products[1], [], $categories); + $this->assertProductIn($products[2], $categories, $categories); + + $this->clearIndex(); + } + + /** + * Load categories from the fixture. + * + * @param int $limit + * @param int $offset + * @return Category[] + */ + private function loadCategories(int $limit, int $offset = 0): array + { + /** @var Category $category */ + $category = Bootstrap::getObjectManager()->create( + Category::class + ); + + $result = $category + ->getCollection() + ->addAttributeToSelect('name') + ->getItems(); + $result = array_slice($result, 2); + + return array_slice($result, $offset, $limit); + } + + /** + * Load products from the fixture. + * + * @param int $limit + * @param int $offset + * @return Product[] + */ + private function loadProducts(int $limit, int $offset = 0): array + { + /** @var Product[] $result */ + $result = []; + $ids = range($offset + 1, $offset + $limit); + foreach ($ids as $id) { + /** @var \Magento\Catalog\Model\Product $product */ + $product = Bootstrap::getObjectManager()->create( + Product::class + ); + $result[] = $product->load($id); + } + + return $result; + } + + /** + * Clear index data. + */ + private function clearIndex() + { + $this->productResource->getConnection()->delete( + $this->productResource->getTable('catalog_category_product_index') + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_category_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_category_rollback.php index faa4fd6f4575ef7a64525fd4319a9d3e950d14d3..51a8fc6b7e978ebf26323ad114ed75c39c8edd84 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_category_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_category_rollback.php @@ -16,7 +16,7 @@ $registry->register('isSecureArea', true); /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */ $collection = $objectManager->create(\Magento\Catalog\Model\ResourceModel\Category\Collection::class); $collection - ->addAttributeToFilter('level', 2) + ->addAttributeToFilter('level', ['gteq' => 2]) ->load() ->delete(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_product_categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_product_categories.php new file mode 100644 index 0000000000000000000000000000000000000000..075422d5f0d787e533469a453551052bba4747c1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_product_categories.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var $category \Magento\Catalog\Model\Category */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Catalog\Model\Category $categoryFirst */ +$categoryFirst = $objectManager->create(\Magento\Catalog\Model\Category::class); +$categoryFirst->setName('Category 1') + ->setPath('1/2') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setIsActive(true) + ->setPosition(1) + ->setDefaultSortBy('name') + ->setIsAnchor(true) + ->save(); + +/** @var \Magento\Catalog\Model\Category $categorySecond */ +$categorySecond = $objectManager->create(\Magento\Catalog\Model\Category::class); +$categorySecond->setName('Category 2') + ->setPath($categoryFirst->getPath()) + ->setLevel(3) + ->setAvailableSortBy('name') + ->setIsActive(true) + ->setPosition(1) + ->setDefaultSortBy('name') + ->setIsAnchor(false) + ->save(); + +/** @var \Magento\Catalog\Model\Category $categoryThird */ +$categoryThird = $objectManager->create(\Magento\Catalog\Model\Category::class); +$categoryThird->setName('Category 3') + ->setPath($categorySecond->getPath()) + ->setLevel(4) + ->setAvailableSortBy('name') + ->setIsActive(true) + ->setPosition(1) + ->setDefaultSortBy('name') + ->setIsAnchor(true) + ->save(); + +/** @var \Magento\Catalog\Model\Category $categoryFourth */ +$categoryFourth = $objectManager->create(\Magento\Catalog\Model\Category::class); +$categoryFourth->setName('Category 4') + ->setPath($categoryFirst->getPath()) + ->setLevel(3) + ->setAvailableSortBy('name') + ->setIsActive(true) + ->setPosition(2) + ->setDefaultSortBy('name') + ->setIsAnchor(true) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_product_categories_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_product_categories_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..755f324b18cb2851b4f96d28087fd36608bc2ded --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/indexer_catalog_product_categories_rollback.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\ObjectManagerInterface $objectManager */ +$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\Model\ResourceModel\Product\Collection $collection */ +$collection = $objectManager->create( + \Magento\Catalog\Model\ResourceModel\Category\Collection::class +); +$collection + ->addAttributeToFilter('level', ['gteq' => 2]) + ->load() + ->delete(); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Config/Block/System/Config/_files/test_config.xml b/dev/tests/integration/testsuite/Magento/Config/Block/System/Config/_files/test_config.xml index ab530e01f8b6a49cecdad4f86e45ba58ac98c37e..2fd972939117b20f6a51b70b1769a32b462c152f 100644 --- a/dev/tests/integration/testsuite/Magento/Config/Block/System/Config/_files/test_config.xml +++ b/dev/tests/integration/testsuite/Magento/Config/Block/System/Config/_files/test_config.xml @@ -10,7 +10,7 @@ <test_section> <test_group> <test_field_encrypted backend_model="Magento\Config\Model\Config\Backend\Encrypted">{ENCRYPTED_VALUE}</test_field_encrypted> - <test_field_serialized backend_model="Magento\Config\Model\Config\Backend\Serialized">["value1","value2"]</test_field_serialized> + <test_field_serialized>["value1","value2"]</test_field_serialized> <test_field>test config value</test_field> </test_group> </test_section> diff --git a/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php index b8dbfec59845b17d95fd20e8a53da53e62d21f1f..2d76632cae0b759397228ffef012637bb6ded44a 100644 --- a/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php @@ -24,7 +24,7 @@ class IndexTest extends \Magento\TestFramework\TestCase\AbstractController $this->assertRedirect($this->stringContains('contact/index')); $this->assertSessionMessages( $this->contains( - "Thanks for contacting us with your comments and questions. We'll respond to you very soon." + "Thanks for contacting us with your comments and questions. We'll respond to you very soon." ), \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS ); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index fd3755fa6ea5cfcaa079f64caa56d89c600e9170..a01006a06a2e3b1beb98ba29b64b8ee0db6530db 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -10,12 +10,20 @@ namespace Magento\Customer\Controller; use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Model\Account\Redirect; +use Magento\Customer\Model\Session; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Value; +use Magento\Framework\App\Http; use Magento\Framework\Data\Form\FormKey; use Magento\Framework\Message\MessageInterface; use Magento\Store\Model\ScopeInterface; use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Request; +use Magento\TestFramework\Response; +use Zend\Stdlib\Parameters; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -30,9 +38,9 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController */ protected function login($customerId) { - /** @var \Magento\Customer\Model\Session $session */ + /** @var Session $session */ $session = Bootstrap::getObjectManager() - ->get(\Magento\Customer\Model\Session::class); + ->get(Session::class); $session->loginById($customerId); } @@ -130,8 +138,8 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController $this->assertFalse((bool)preg_match('/' . $token . '/m', $text)); $this->assertRedirect($this->stringContains('customer/account/createpassword')); - /** @var \Magento\Customer\Model\Session $customer */ - $session = Bootstrap::getObjectManager()->get(\Magento\Customer\Model\Session::class); + /** @var Session $customer */ + $session = Bootstrap::getObjectManager()->get(Session::class); $this->assertEquals($token, $session->getRpToken()); $this->assertEquals($customer->getId(), $session->getRpCustomerId()); $this->assertNotContains($token, $response->getHeader('Location')->getFieldValue()); @@ -151,8 +159,8 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController $customer->changeResetPasswordLinkToken($token); $customer->save(); - /** @var \Magento\Customer\Model\Session $customer */ - $session = Bootstrap::getObjectManager()->get(\Magento\Customer\Model\Session::class); + /** @var Session $customer */ + $session = Bootstrap::getObjectManager()->get(Session::class); $session->setRpToken($token); $session->setRpCustomerId($customer->getId()); @@ -652,6 +660,50 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController ); } + /** + * Test redirect customer to account dashboard after logging in. + * + * @param bool|null $redirectDashboard + * @param string $redirectUrl + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/Customer/_files/customer.php + * @dataProvider loginPostRedirectDataProvider + */ + public function testLoginPostRedirect($redirectDashboard, string $redirectUrl) + { + if (isset($redirectDashboard)) { + $this->_objectManager->get(ScopeConfigInterface::class)->setValue('customer/startup/redirect_dashboard', $redirectDashboard); + } + + $this->_objectManager->get(Redirect::class)->setRedirectCookie('test'); + + $configValue = $this->_objectManager->create(Value::class); + $configValue->load('web/unsecure/base_url', 'path'); + $baseUrl = $configValue->getValue() ?: 'http://localhost/'; + + $request = $this->prepareRequest(); + $app = $this->_objectManager->create(Http::class, ['_request' => $request]); + $response = $app->launch(); + + $this->assertResponseRedirect($response, $baseUrl . $redirectUrl); + $this->assertTrue($this->_objectManager->get(Session::class)->isLoggedIn()); + } + + /** + * Data provider for testLoginPostRedirect. + * + * @return array + */ + public function loginPostRedirectDataProvider() + { + return [ + [null, 'index.php/'], + [0, 'index.php/'], + [1, 'index.php/customer/account/'], + ]; + } + /** * @return void */ @@ -717,4 +769,40 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController return $customer; } + + /** + * Prepare request for customer login. + * + * @return Request + */ + private function prepareRequest() + { + $post = new Parameters([ + 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(), + 'login' => [ + 'username' => 'customer@example.com', + 'password' => 'password' + ] + ]); + $request = $this->getRequest(); + $formKey = $this->_objectManager->get(FormKey::class); + $request->setParam('form_key', $formKey->getFormKey()); + $request->setMethod(Request::METHOD_POST); + $request->setRequestUri('customer/account/loginPost/'); + $request->setPost($post); + return $request; + } + + /** + * Assert response is redirect. + * + * @param Response $response + * @param string $redirectUrl + * @return void + */ + private function assertResponseRedirect(Response $response, string $redirectUrl) + { + $this->assertTrue($response->isRedirect()); + $this->assertSame($redirectUrl, $response->getHeader('Location')->getUri()); + } } diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php deleted file mode 100644 index 4d19e973556c034ebce2f89d82cbe183d85c4439..0000000000000000000000000000000000000000 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -namespace Magento\Downloadable\Controller\Adminhtml\Downloadable; - -/** - * Magento\Downloadable\Controller\Adminhtml\Downloadable\File - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - * @magentoAppArea adminhtml - */ -class FileTest extends \Magento\TestFramework\TestCase\AbstractBackendController -{ - public function testUploadAction() - { - copy(dirname(__DIR__) . '/_files/sample.txt', dirname(__DIR__) . '/_files/sample.tmp'); - $_FILES = [ - 'samples' => [ - 'name' => 'sample.txt', - 'type' => 'text/plain', - 'tmp_name' => dirname(__DIR__) . '/_files/sample.tmp', - 'error' => 0, - 'size' => 0, - ], - ]; - - $this->dispatch('backend/admin/downloadable_file/upload/type/samples'); - $body = $this->getResponse()->getBody(); - $result = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Framework\Json\Helper\Data::class - )->jsonDecode( - $body - ); - $this->assertEquals(0, $result['error']); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/.htaccess b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/.htaccess index 14249c50bd7605225950b2d372f352a2dba9252a..118789f3d955b474b963edb3afff24b2a829de96 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/.htaccess +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/.htaccess @@ -1 +1,7 @@ -Deny from all \ No newline at end of file +<IfVersion < 2.4> + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/cache/.htaccess b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/cache/.htaccess index 14249c50bd7605225950b2d372f352a2dba9252a..118789f3d955b474b963edb3afff24b2a829de96 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/cache/.htaccess +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/cache/.htaccess @@ -1 +1,7 @@ -Deny from all \ No newline at end of file +<IfVersion < 2.4> + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/.htaccess b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/.htaccess index 14249c50bd7605225950b2d372f352a2dba9252a..118789f3d955b474b963edb3afff24b2a829de96 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/.htaccess +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/.htaccess @@ -1 +1,7 @@ -Deny from all \ No newline at end of file +<IfVersion < 2.4> + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/cache/.htaccess b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/cache/.htaccess index 14249c50bd7605225950b2d372f352a2dba9252a..118789f3d955b474b963edb3afff24b2a829de96 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/cache/.htaccess +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/cache/.htaccess @@ -1 +1,7 @@ -Deny from all \ No newline at end of file +<IfVersion < 2.4> + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/.htaccess b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/.htaccess index 14249c50bd7605225950b2d372f352a2dba9252a..118789f3d955b474b963edb3afff24b2a829de96 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/.htaccess +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/.htaccess @@ -1 +1,7 @@ -Deny from all \ No newline at end of file +<IfVersion < 2.4> + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/cache/.htaccess b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/cache/.htaccess index 14249c50bd7605225950b2d372f352a2dba9252a..118789f3d955b474b963edb3afff24b2a829de96 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/cache/.htaccess +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/cache/.htaccess @@ -1 +1,7 @@ -Deny from all \ No newline at end of file +<IfVersion < 2.4> + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/dev/tests/integration/testsuite/Magento/Framework/Css/PreProcessor/Adapter/CssInlinerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Css/PreProcessor/Adapter/CssInlinerTest.php index f1468f718df619c3922da42203921cdbe8a2d44e..63c14b4293f7b108ca90b4a5f3097b3a82614c39 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Css/PreProcessor/Adapter/CssInlinerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Css/PreProcessor/Adapter/CssInlinerTest.php @@ -76,12 +76,10 @@ class CssInlinerTest extends \PHPUnit\Framework\TestCase $emogrifier->setHtml($html); $result = $emogrifier->emogrify(); /** - * Tests a bug in the library where there's no spaces to CSS string before passing to Emogrifier - * to fix known parsing issue with library. - * This test should will fail when this bug is fixed in the library and we should fix the adapter. - * https://github.com/jjriv/emogrifier/issues/370 + * This test was implemented for the issue which existed in the older version of Emogrifier. + * Test was updated, as the library got updated as well. */ - $this->assertNotContains($cssExpected, $result); + $this->assertContains($cssExpected, $result); } /** diff --git a/dev/tests/integration/testsuite/Magento/PageCache/Block/System/Config/Form/Field/ExportTest.php b/dev/tests/integration/testsuite/Magento/PageCache/Block/System/Config/Form/Field/ExportTest.php index 8abe1e9711d998f8b0b677da258f85fddb96453a..19e6bf450e01cb7e3cc09ca5dd7f898b9a41d8c6 100644 --- a/dev/tests/integration/testsuite/Magento/PageCache/Block/System/Config/Form/Field/ExportTest.php +++ b/dev/tests/integration/testsuite/Magento/PageCache/Block/System/Config/Form/Field/ExportTest.php @@ -15,6 +15,8 @@ class ExportTest extends \Magento\TestFramework\TestCase\AbstractBackendControll * @covers \Magento\PageCache\Block\System\Config\Form\Field\Export::_getElementHtml * @covers \Magento\PageCache\Block\System\Config\Form\Field\Export\Varnish5::getVarnishVersion * @covers \Magento\PageCache\Block\System\Config\Form\Field\Export\Varnish4::getVarnishVersion + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled */ public function testExportButtons() { diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php index 157999224d7b8a506d479edcb6d5fca68f07b7a2..95e3abbfe6ff15d69624458e5dc8c128ed8df809 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php @@ -142,6 +142,8 @@ class ExpressTest extends \Magento\TestFramework\TestCase\AbstractController * Test return action with configurable product. * * @magentoDataFixture Magento/Paypal/_files/quote_express_configurable.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ public function testReturnAction() { diff --git a/dev/tests/integration/testsuite/Magento/Paypal/_files/configurable_attribute.php b/dev/tests/integration/testsuite/Magento/Paypal/_files/configurable_attribute.php new file mode 100644 index 0000000000000000000000000000000000000000..12f63993cb2d31858423ad8a9c8a346fa87760f0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Paypal/_files/configurable_attribute.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright © Magento, Inc. 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' => 0, + 'is_visible_in_advanced_search' => 0, + 'is_comparable' => 0, + 'is_filterable' => 0, + 'is_filterable_in_search' => 0, + '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/Paypal/_files/product_configurable.php b/dev/tests/integration/testsuite/Magento/Paypal/_files/product_configurable.php new file mode 100644 index 0000000000000000000000000000000000000000..7851abd965d8c4884dcd4d634efe9e59ebd70887 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Paypal/_files/product_configurable.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © Magento, Inc. 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; + +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 = [101, 201]; +array_shift($options); //remove the first option which is empty + +foreach ($options as $option) { + /** @var $product Product */ + $product = Bootstrap::getObjectManager()->create(Product::class); + $productId = array_shift($productIds); + $product->setTypeId(Type::TYPE_SIMPLE) + ->setId($productId) + ->setAttributeSetId($attributeSetId) + ->setWebsiteIds([1]) + ->setName('Configurable Option' . $option->getLabel()) + ->setSku('simple_' . $productId) + ->setPrice($productId) + ->setTestConfigurable($option->getValue()) + ->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData([ + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 0, + 'is_in_stock' => 1 + ]); + + $product = $productRepository->save($product); + + /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */ + $stockItem = Bootstrap::getObjectManager()->create(\Magento\CatalogInventory\Model\Stock\Item::class); + $stockItem->load($productId, 'product_id'); + + if (!$stockItem->getProductId()) { + $stockItem->setProductId($productId); + } + $stockItem->setUseConfigManageStock(1); + $stockItem->setQty(1000); + $stockItem->setIsQtyDecimal(0); + $stockItem->setIsInStock(1); + $stockItem->save(); + + $attributeValues[] = [ + 'label' => 'test', + 'attribute_id' => $attribute->getId(), + 'value_index' => $option->getValue(), + ]; + $associatedProductIds[] = $product->getId(); +} + +/** @var $product Product */ +$product = Bootstrap::getObjectManager()->create(Product::class); + +/** @var Factory $optionsFactory */ +$optionsFactory = Bootstrap::getObjectManager()->create(Factory::class); + +$configurableAttributesData = [ + [ + 'attribute_id' => $attribute->getId(), + 'code' => $attribute->getAttributeCode(), + 'label' => $attribute->getStoreLabel(), + 'position' => '0', + 'values' => $attributeValues, + ], +]; + +$configurableOptions = $optionsFactory->create($configurableAttributesData); + +$extensionConfigurableAttributes = $product->getExtensionAttributes(); +$extensionConfigurableAttributes->setConfigurableProductOptions($configurableOptions); +$extensionConfigurableAttributes->setConfigurableProductLinks($associatedProductIds); + +$product->setExtensionAttributes($extensionConfigurableAttributes); + +// Remove any previously created product with the same id. +/** @var \Magento\Framework\Registry $registry */ +$registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +try { + $productToDelete = $productRepository->getById(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(100) + ->setAttributeSetId($attributeSetId) + ->setWebsiteIds([1]) + ->setName('Configurable Product') + ->setSku('configurable_express') + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData([ + 'use_config_manage_stock' => 1, + 'is_in_stock' => 1 + ]); + +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_express_configurable.php b/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_express_configurable.php index b3f14b188a32a75732e2e99f389ec35cdb7585e1..cf90172368d5cc6d4c5323e663e46e8095c11eac 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_express_configurable.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_express_configurable.php @@ -11,7 +11,7 @@ use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\Quote\Address\Rate; use Magento\TestFramework\Helper\Bootstrap; -require __DIR__ . '/../../../Magento/ConfigurableProduct/_files/product_configurable.php'; +require __DIR__ . '/product_configurable.php'; /** @var $objectManager \Magento\TestFramework\ObjectManager */ $objectManager = Bootstrap::getObjectManager(); @@ -19,7 +19,7 @@ $objectManager = Bootstrap::getObjectManager(); /** @var $product \Magento\Catalog\Model\Product */ /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ $productRepository = $objectManager->create(ProductRepositoryInterface::class); -$product = $productRepository->get('configurable'); +$product = $productRepository->get('configurable_express'); /** @var $options Collection */ $options = $objectManager->create(Collection::class); @@ -27,8 +27,8 @@ $option = $options->setAttributeFilter($attribute->getId())->getFirstItem(); $requestInfo = new \Magento\Framework\DataObject( [ - 'product' => 2, - 'selected_configurable_option' => 2, + 'product' => 1, + 'selected_configurable_option' => 1, 'qty' => 1, 'super_attribute' => [ $attribute->getId() => $option->getId() diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/GridAsyncInsertTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/GridAsyncInsertTest.php new file mode 100644 index 0000000000000000000000000000000000000000..726057cb86bb7b9e9f481668c8c5e47eea8c40a4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/GridAsyncInsertTest.php @@ -0,0 +1,134 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model; + +use Magento\Framework\Api\SearchCriteria; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\ResourceModel\Grid as AbstractGrid; +use Magento\Sales\Model\ResourceModel\Order\Grid; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; + +class GridAsyncInsertTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var GridAsyncInsert + */ + private $gridAsyncInsert; + + /** + * @var AdapterInterface + */ + private $connection; + + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * @var AbstractGrid + */ + private $grid; + + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + + /** @var ResourceConnection $resourceConnection */ + $resourceConnection = $this->objectManager->get(ResourceConnection::class); + $this->connection = $resourceConnection->getConnection('sales'); + $this->orderRepository = $this->objectManager->get(OrderRepositoryInterface::class); + $this->grid = $this->objectManager->get(Grid::class); + + $this->gridAsyncInsert = $this->objectManager->create( + GridAsyncInsert::class, + [ + 'entityGrid' => $this->grid + ] + ); + } + + /** + * Checks a case when order's grid should be updated asynchronously. + * + * @magentoConfigFixture default/dev/grid/async_indexing 1 + * @magentoDataFixture Magento/Sales/_files/order.php + */ + public function testExecuteAsyncUpdateOrderGrid() + { + $order = $this->getOrder('100000001'); + $this->performUpdateAssertions($order); + + // to un-sync main table and grid table need to wait at least one second + sleep(1); + $order->setStatus('complete'); + $this->orderRepository->save($order); + + $gridRow = $this->getGridRow($order->getEntityId()); + self::assertNotEquals($order->getStatus(), $gridRow['status']); + + $this->gridAsyncInsert->asyncInsert(); + $this->performUpdateAssertions($order); + } + + /** + * Loads order entity by provided order increment ID. + * + * @param string $incrementId + * @return OrderInterface + */ + private function getOrder(string $incrementId) : OrderInterface + { + /** @var SearchCriteria $searchCriteria */ + $searchCriteria = $this->objectManager->get(SearchCriteriaBuilder::class) + ->addFilter('increment_id', $incrementId) + ->create(); + + $items = $this->orderRepository->getList($searchCriteria) + ->getItems(); + + return array_pop($items); + } + + /** + * Gets row from `sales_order_grid` table by order's ID. + * + * @param int $entityId + * @return array + */ + private function getGridRow(int $entityId) : array + { + $tableName = $this->grid->getGridTable(); + $select = $this->connection->select() + ->from($tableName) + ->where($tableName . '.entity_id = ?', $entityId); + + return $this->connection->fetchRow($select); + } + + /** + * Perform assertions for updating grid test. + * + * @param OrderInterface $order + */ + private function performUpdateAssertions(OrderInterface $order) + { + $gridRow = $this->getGridRow($order->getEntityId()); + + self::assertEquals($order->getStatus(), $gridRow['status']); + self::assertEquals($order->getUpdatedAt(), $gridRow['updated_at']); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Theme/Model/Config/Processor/DesignThemeTest.php b/dev/tests/integration/testsuite/Magento/Theme/Model/Config/Processor/DesignThemeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..01c8ebca57ac2dcb97e0c9f04c7b5396047046e6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Theme/Model/Config/Processor/DesignThemeTest.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Theme\Model\Config\Processor; + +use Magento\TestFramework\Helper\Bootstrap; + +class DesignThemeTest extends \PHPUnit\Framework\TestCase +{ + /** + * Verifies that empty 'design/theme/theme_id' config value is processed without errors. + */ + public function testProcessWithEmptyThemeId() + { + $designTheme = Bootstrap::getObjectManager()->create(DesignTheme::class); + + $config = [ + 'default' => [ + 'design' => ['theme' => ['theme_id' => '']], + ], + ]; + + $this->assertEquals($config, $designTheme->process($config)); + } +} diff --git a/generated/.htaccess b/generated/.htaccess index 93169e4eb44ffa5e6251f3532bb1902854703f07..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/generated/.htaccess +++ b/generated/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/lib/.htaccess b/lib/.htaccess index 93169e4eb44ffa5e6251f3532bb1902854703f07..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/lib/.htaccess +++ b/lib/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/CssInliner.php b/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/CssInliner.php index 342283c312293fdb16ee642ca28eb9fec09a6dcd..7164e68c709fb81630dfe230d440f080f6712a8e 100644 --- a/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/CssInliner.php +++ b/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/CssInliner.php @@ -41,13 +41,7 @@ class CssInliner */ public function setCss($css) { - /** - * Adds space to CSS string before passing to Emogrifier to fix known parsing issue with library. - * https://github.com/jjriv/emogrifier/issues/370 - */ - $cssWithAddedSpaces = preg_replace('#([\{\}>])#i', ' $1 ', $css); - - $this->emogrifier->setCss($cssWithAddedSpaces); + $this->emogrifier->setCss($css); } /** diff --git a/lib/internal/Magento/Framework/CurrencyInterface.php b/lib/internal/Magento/Framework/CurrencyInterface.php index 4dbde431041fc8d66a012cfd01f22b97d7fb7adf..44a7d3b90081e16742391320eb73726dd315c626 100644 --- a/lib/internal/Magento/Framework/CurrencyInterface.php +++ b/lib/internal/Magento/Framework/CurrencyInterface.php @@ -240,7 +240,7 @@ interface CurrencyInterface * Returns the set service class * * @return \Zend_Currency_CurrencyInterface - * @deprecated + * @deprecated 101.0.1 * @see \Magento\Directory\Model\Currency\Import\ImportInterface */ public function getService(); @@ -250,7 +250,7 @@ interface CurrencyInterface * * @param string|\Zend_Currency_CurrencyInterface $service Service class * @return \Zend_Currency_CurrencyInterface - * @deprecated + * @deprecated 101.0.1 * @see \Magento\Directory\Model\Currency\Import\ImportInterface */ public function setService($service); diff --git a/lib/internal/Magento/Framework/Module/Setup/Migration.php b/lib/internal/Magento/Framework/Module/Setup/Migration.php index 467ee6146ade74c3c39311b38dfe381149800e3b..604a98f1c0dd3c04b0b81bfb73a46e488cc8bb07 100644 --- a/lib/internal/Magento/Framework/Module/Setup/Migration.php +++ b/lib/internal/Magento/Framework/Module/Setup/Migration.php @@ -703,7 +703,7 @@ class Migration * @return string|int|float|bool|array|null * @throws \InvalidArgumentException * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @deprecated + * @deprecated 101.0.1 * @see \Magento\Framework\Module\Setup\Migration::jsonDecode */ protected function _jsonDecode($encodedValue, $objectDecodeType = 1) diff --git a/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php b/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php index 0c32665a54219c2b1b84b29297865948d22a96a3..3fd8ea93c9bbe8985e9fa3349f4a396d71358f4e 100644 --- a/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php +++ b/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php @@ -263,7 +263,6 @@ class ViewTest extends \PHPUnit\Framework\TestCase $currentVersionId = 3; $lastVersionId = 1; $listId = [2, 3]; - $defaultBatchSize = 1000; $this->stateMock->expects($this->any()) ->method('getViewId') @@ -297,7 +296,7 @@ class ViewTest extends \PHPUnit\Framework\TestCase 'getList' )->with( $lastVersionId, - $lastVersionId + $defaultBatchSize + $currentVersionId )->will( $this->returnValue($listId) ); @@ -327,7 +326,6 @@ class ViewTest extends \PHPUnit\Framework\TestCase $currentVersionId = 3; $lastVersionId = 1; $listId = [2, 3]; - $defaultBatchSize = 1000; $this->stateMock->expects($this->any()) ->method('getViewId') @@ -360,7 +358,7 @@ class ViewTest extends \PHPUnit\Framework\TestCase 'getList' )->with( $lastVersionId, - $lastVersionId + $defaultBatchSize + $currentVersionId )->will( $this->returnValue($listId) ); diff --git a/lib/internal/Magento/Framework/Mview/View.php b/lib/internal/Magento/Framework/Mview/View.php index b489dd7d59e4347ef8aadd3c0cec22c8dc14f755..1f1bde6bb021c28205894de82a16ff7e391fae76 100644 --- a/lib/internal/Magento/Framework/Mview/View.php +++ b/lib/internal/Magento/Framework/Mview/View.php @@ -21,6 +21,11 @@ class View extends \Magento\Framework\DataObject implements ViewInterface */ const DEFAULT_BATCH_SIZE = 1000; + /** + * Max versions to load from database at a time + */ + private static $maxVersionQueryBatch = 100000; + /** * @var string */ @@ -272,14 +277,19 @@ class View extends \Magento\Framework\DataObject implements ViewInterface try { $this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save(); + $versionBatchSize = self::$maxVersionQueryBatch; $batchSize = isset($this->changelogBatchSize[$this->getChangelog()->getViewId()]) ? $this->changelogBatchSize[$this->getChangelog()->getViewId()] : self::DEFAULT_BATCH_SIZE; - for ($versionFrom = $lastVersionId; $versionFrom < $currentVersionId; $versionFrom += $batchSize) { - $ids = $this->getChangelog()->getList($versionFrom, $versionFrom + $batchSize); + for ($versionFrom = $lastVersionId; $versionFrom < $currentVersionId; $versionFrom += $versionBatchSize) { + // Don't go past the current version for atomicy. + $versionTo = min($currentVersionId, $versionFrom + $versionBatchSize); + $ids = $this->getChangelog()->getList($versionFrom, $versionTo); - if (!empty($ids)) { + // We run the actual indexer in batches. Chunked AFTER loading to avoid duplicates in separate chunks. + $chunks = array_chunk($ids, $batchSize); + foreach ($chunks as $ids) { $action->execute($ids); } } diff --git a/lib/internal/Magento/Framework/Mview/View/Subscription.php b/lib/internal/Magento/Framework/Mview/View/Subscription.php index e621909ec99b6cc881699b586ea72ed435efabb6..4f5c65c799be8b9fcd852d7391990d3d2db61376 100644 --- a/lib/internal/Magento/Framework/Mview/View/Subscription.php +++ b/lib/internal/Magento/Framework/Mview/View/Subscription.php @@ -10,6 +10,8 @@ namespace Magento\Framework\Mview\View; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Ddl\Trigger; +use Magento\Framework\DB\Ddl\TriggerFactory; +use Magento\Framework\Mview\ViewInterface; class Subscription implements SubscriptionInterface { @@ -21,12 +23,12 @@ class Subscription implements SubscriptionInterface protected $connection; /** - * @var \Magento\Framework\DB\Ddl\TriggerFactory + * @var TriggerFactory */ protected $triggerFactory; /** - * @var \Magento\Framework\Mview\View\CollectionInterface + * @var CollectionInterface */ protected $viewCollection; @@ -57,21 +59,31 @@ class Subscription implements SubscriptionInterface */ protected $resource; + /** + * List of columns that can be updated in a subscribed table + * without creating a new change log entry + * + * @var array + */ + private $ignoredUpdateColumns = []; + /** * @param ResourceConnection $resource - * @param \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory - * @param \Magento\Framework\Mview\View\CollectionInterface $viewCollection - * @param \Magento\Framework\Mview\ViewInterface $view + * @param TriggerFactory $triggerFactory + * @param CollectionInterface $viewCollection + * @param ViewInterface $view * @param string $tableName * @param string $columnName + * @param array $ignoredUpdateColumns */ public function __construct( ResourceConnection $resource, - \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory, - \Magento\Framework\Mview\View\CollectionInterface $viewCollection, - \Magento\Framework\Mview\ViewInterface $view, + TriggerFactory $triggerFactory, + CollectionInterface $viewCollection, + ViewInterface $view, $tableName, - $columnName + $columnName, + array $ignoredUpdateColumns = [] ) { $this->connection = $resource->getConnection(); $this->triggerFactory = $triggerFactory; @@ -80,12 +92,13 @@ class Subscription implements SubscriptionInterface $this->tableName = $tableName; $this->columnName = $columnName; $this->resource = $resource; + $this->ignoredUpdateColumns = $ignoredUpdateColumns; } /** - * Create subsciption + * Create subscription * - * @return \Magento\Framework\Mview\View\SubscriptionInterface + * @return SubscriptionInterface */ public function create() { @@ -102,7 +115,7 @@ class Subscription implements SubscriptionInterface // Add statements for linked views foreach ($this->getLinkedViews() as $view) { - /** @var \Magento\Framework\Mview\ViewInterface $view */ + /** @var ViewInterface $view */ $trigger->addStatement($this->buildStatement($event, $view->getChangelog())); } @@ -116,7 +129,7 @@ class Subscription implements SubscriptionInterface /** * Remove subscription * - * @return \Magento\Framework\Mview\View\SubscriptionInterface + * @return SubscriptionInterface */ public function remove() { @@ -131,7 +144,7 @@ class Subscription implements SubscriptionInterface // Add statements for linked views foreach ($this->getLinkedViews() as $view) { - /** @var \Magento\Framework\Mview\ViewInterface $view */ + /** @var ViewInterface $view */ $trigger->addStatement($this->buildStatement($event, $view->getChangelog())); } @@ -154,10 +167,10 @@ class Subscription implements SubscriptionInterface protected function getLinkedViews() { if (!$this->linkedViews) { - $viewList = $this->viewCollection->getViewsByStateMode(\Magento\Framework\Mview\View\StateInterface::MODE_ENABLED); + $viewList = $this->viewCollection->getViewsByStateMode(StateInterface::MODE_ENABLED); foreach ($viewList as $view) { - /** @var \Magento\Framework\Mview\ViewInterface $view */ + /** @var ViewInterface $view */ // Skip the current view if ($view->getId() == $this->getView()->getId()) { continue; @@ -175,35 +188,58 @@ class Subscription implements SubscriptionInterface } /** - * Build trigger statement for INSER, UPDATE, DELETE events + * Build trigger statement for INSERT, UPDATE, DELETE events * * @param string $event - * @param \Magento\Framework\Mview\View\ChangelogInterface $changelog + * @param ChangelogInterface $changelog * @return string */ protected function buildStatement($event, $changelog) { switch ($event) { case Trigger::EVENT_INSERT: + $trigger = "INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);"; + break; + case Trigger::EVENT_UPDATE: - return sprintf( - "INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);", - $this->connection->quoteIdentifier($this->resource->getTableName($changelog->getName())), - $this->connection->quoteIdentifier($changelog->getColumnName()), - $this->connection->quoteIdentifier($this->getColumnName()) - ); + $trigger = "INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);"; + + if ($this->connection->isTableExists($this->getTableName()) + && $describe = $this->connection->describeTable($this->getTableName()) + ) { + $columnNames = array_column($describe, 'COLUMN_NAME'); + $columnNames = array_diff($columnNames, $this->ignoredUpdateColumns); + if ($columnNames) { + $columns = []; + foreach ($columnNames as $columnName) { + $columns[] = sprintf( + 'NEW.%1$s != OLD.%1$s', + $this->connection->quoteIdentifier($columnName) + ); + } + $trigger = sprintf( + "IF (%s) THEN %s END IF;", + implode(' OR ', $columns), + $trigger + ); + } + } + break; case Trigger::EVENT_DELETE: - return sprintf( - "INSERT IGNORE INTO %s (%s) VALUES (OLD.%s);", - $this->connection->quoteIdentifier($this->resource->getTableName($changelog->getName())), - $this->connection->quoteIdentifier($changelog->getColumnName()), - $this->connection->quoteIdentifier($this->getColumnName()) - ); + $trigger = "INSERT IGNORE INTO %s (%s) VALUES (OLD.%s);"; + break; default: return ''; } + + return sprintf( + $trigger, + $this->connection->quoteIdentifier($this->resource->getTableName($changelog->getName())), + $this->connection->quoteIdentifier($changelog->getColumnName()), + $this->connection->quoteIdentifier($this->getColumnName()) + ); } /** @@ -225,7 +261,7 @@ class Subscription implements SubscriptionInterface /** * Retrieve View related to subscription * - * @return \Magento\Framework\Mview\ViewInterface + * @return ViewInterface * @codeCoverageIgnore */ public function getView() diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime.php b/lib/internal/Magento/Framework/Stdlib/DateTime.php index 36db84860b373c6bd9bda49a2c49954b2fd557be..5a1902426e7ae2291307d4f8314f0996f4f97318 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime.php @@ -79,7 +79,7 @@ class DateTime * @param int $time * @return string The given time in given format * - * @deprecated + * @deprecated 101.0.1 * @see Use Intl library for datetime handling: http://php.net/manual/en/book.intl.php * * @codeCoverageIgnore @@ -95,7 +95,7 @@ class DateTime * @param string $timeStr * @return int * - * @deprecated + * @deprecated 101.0.1 * @see Use Intl library for datetime handling: http://php.net/manual/en/book.intl.php * * @codeCoverageIgnore diff --git a/lib/internal/Magento/Framework/View/Asset/Bundle.php b/lib/internal/Magento/Framework/View/Asset/Bundle.php index bdaf13ddbbb27a7b00c62383d1760a27f565ab6d..80f35f9d57075a96f1669616697d37672f488e6b 100644 --- a/lib/internal/Magento/Framework/View/Asset/Bundle.php +++ b/lib/internal/Magento/Framework/View/Asset/Bundle.php @@ -212,7 +212,11 @@ class Bundle $assetContentType = $asset->getContentType(); $assetKey = $this->getAssetKey($asset); if (!isset($this->assetsContent[$assetContextCode][$assetContentType][$assetKey])) { - $this->assetsContent[$assetContextCode][$assetContentType][$assetKey] = utf8_encode($asset->getContent()); + $content = $asset->getContent(); + if (mb_detect_encoding($content) !== "UTF-8") { + $content = mb_convert_encoding($content, "UTF-8"); + } + $this->assetsContent[$assetContextCode][$assetContentType][$assetKey] = $content; } return $this->assetsContent[$assetContextCode][$assetContentType][$assetKey]; diff --git a/lib/internal/Magento/Framework/Webapi/Rest/Request/Deserializer/Json.php b/lib/internal/Magento/Framework/Webapi/Rest/Request/Deserializer/Json.php index c2e7c324d1282bade8951bac5633152ba7e4eaea..7cd9a167809a2543efc3ce29acffa0af5ab91dd8 100644 --- a/lib/internal/Magento/Framework/Webapi/Rest/Request/Deserializer/Json.php +++ b/lib/internal/Magento/Framework/Webapi/Rest/Request/Deserializer/Json.php @@ -14,7 +14,7 @@ class Json implements \Magento\Framework\Webapi\Rest\Request\DeserializerInterfa { /** * @var \Magento\Framework\Json\Decoder - * @deprecated + * @deprecated 101.0.1 */ protected $decoder; diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 55d6e55d4977f7c8a02debdd44fd3ee5fa350dfd..aee3e0442c2592d00979bff9206972d3650996f2 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -2,7 +2,7 @@ "name": "magento/framework", "description": "N/A", "type": "magento2-library", - "version": "101.0.0", + "version": "101.0.1", "license": [ "OSL-3.0", "AFL-3.0" @@ -21,7 +21,7 @@ "lib-libxml": "*", "ext-xsl": "*", "symfony/process": "~2.1", - "colinmollenhour/php-redis-session-abstract": "~1.2.2", + "colinmollenhour/php-redis-session-abstract": "1.3.4", "composer/composer": "1.4.1", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", diff --git a/phpserver/.htaccess b/phpserver/.htaccess index 93169e4eb44ffa5e6251f3532bb1902854703f07..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/phpserver/.htaccess +++ b/phpserver/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/pub/.htaccess b/pub/.htaccess index 047ba279f86515fcaf678d38e157f642092f76f5..8ba04ff4415f359e50ec91618b6c61bd5cbaaf05 100644 --- a/pub/.htaccess +++ b/pub/.htaccess @@ -190,8 +190,13 @@ ## Deny access to release notes to prevent disclosure of the installed Magento version <Files RELEASE_NOTES.txt> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> # For 404s and 403s that aren't handled by the application, show plain 404 response @@ -207,8 +212,13 @@ ErrorDocument 403 /errors/404.php ########################################### ## Deny access to cron.php <Files cron.php> - order allow,deny - deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> <IfModule mod_headers.c> diff --git a/pub/media/customer/.htaccess b/pub/media/customer/.htaccess index 93169e4eb44ffa5e6251f3532bb1902854703f07..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/pub/media/customer/.htaccess +++ b/pub/media/customer/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/pub/media/downloadable/.htaccess b/pub/media/downloadable/.htaccess index 93169e4eb44ffa5e6251f3532bb1902854703f07..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/pub/media/downloadable/.htaccess +++ b/pub/media/downloadable/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/pub/media/import/.htaccess b/pub/media/import/.htaccess index 93169e4eb44ffa5e6251f3532bb1902854703f07..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/pub/media/import/.htaccess +++ b/pub/media/import/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/pub/media/theme_customization/.htaccess b/pub/media/theme_customization/.htaccess index ae8ddd114d94ebf5b20f70f8bcd988aa9fab4511..2b93da6b4c0792595ff0778ff7b669241b52cedc 100644 --- a/pub/media/theme_customization/.htaccess +++ b/pub/media/theme_customization/.htaccess @@ -1,5 +1,10 @@ Options -Indexes <Files ~ "\.xml$"> - Order allow,deny - Deny from all + <IfVersion < 2.4> + order allow,deny + deny from all + </IfVersion> + <IfVersion >= 2.4> + Require all denied + </IfVersion> </Files> diff --git a/setup/config/.htaccess b/setup/config/.htaccess index 281d5c33db37cd1cc887dbb2d36897b897835071..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/setup/config/.htaccess +++ b/setup/config/.htaccess @@ -1,2 +1,8 @@ -order allow,deny -deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/setup/performance-toolkit/.htaccess b/setup/performance-toolkit/.htaccess index 281d5c33db37cd1cc887dbb2d36897b897835071..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/setup/performance-toolkit/.htaccess +++ b/setup/performance-toolkit/.htaccess @@ -1,2 +1,8 @@ -order allow,deny -deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/setup/src/.htaccess b/setup/src/.htaccess index 281d5c33db37cd1cc887dbb2d36897b897835071..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/setup/src/.htaccess +++ b/setup/src/.htaccess @@ -1,2 +1,8 @@ -order allow,deny -deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/setup/src/Magento/Setup/Model/ConfigGenerator.php b/setup/src/Magento/Setup/Model/ConfigGenerator.php index e3ab070bd8fbaba2c433d0410b7757d7b421aa9d..7e5b0c162a393161c38d6d09c5fdfd0352354d7f 100644 --- a/setup/src/Magento/Setup/Model/ConfigGenerator.php +++ b/setup/src/Magento/Setup/Model/ConfigGenerator.php @@ -47,7 +47,7 @@ class ConfigGenerator /** * @var Random - * @deprecated since 100.2.0 + * @deprecated 100.2.0 */ protected $random; diff --git a/setup/view/.htaccess b/setup/view/.htaccess index 281d5c33db37cd1cc887dbb2d36897b897835071..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/setup/view/.htaccess +++ b/setup/view/.htaccess @@ -1,2 +1,8 @@ -order allow,deny -deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/var/.htaccess b/var/.htaccess index 896fbc5a341ea313ff3abd503808842757678c1d..707c26b075e166bccee3cea4f8a52e7fe34269c1 100755 --- a/var/.htaccess +++ b/var/.htaccess @@ -1,2 +1,8 @@ -Order deny,allow -Deny from all \ No newline at end of file +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + diff --git a/vendor/.htaccess b/vendor/.htaccess index cb24fd7fc0b3a0e46f6cad19e834117476bd0341..707c26b075e166bccee3cea4f8a52e7fe34269c1 100644 --- a/vendor/.htaccess +++ b/vendor/.htaccess @@ -1,2 +1,8 @@ -Order allow,deny -Deny from all +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> +